func/pkg/pipelines/tekton/resources_pac.go

110 lines
3.5 KiB
Go

package tekton
import (
"context"
"fmt"
"github.com/openshift-pipelines/pipelines-as-code/pkg/apis/pipelinesascode/v1alpha1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/equality"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
fn "knative.dev/func/pkg/functions"
"knative.dev/func/pkg/k8s"
"knative.dev/func/pkg/pipelines"
"knative.dev/func/pkg/pipelines/tekton/pac"
)
// ensurePACSecretExists checks that up-to-date secret holding credentials needed for PAC is on the cluster
func ensurePACSecretExists(ctx context.Context, f fn.Function, namespace string, credentials pipelines.PacMetadata, labels map[string]string) error {
dockerConfigJSONContent, err := k8s.HandleDockerCfgJSONContent(credentials.RegistryUsername, credentials.RegistryPassword, "", credentials.RegistryServer)
if err != nil {
return err
}
// Check whether we need to create or update the Secret
secret := corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: getPipelineSecretName(f),
Labels: labels,
Annotations: f.Deploy.Annotations,
},
Type: corev1.SecretTypeOpaque,
Data: map[string][]byte{},
}
secret.Data["config.json"] = dockerConfigJSONContent
secret.Data["provider.token"] = []byte(credentials.PersonalAccessToken)
secret.Data["webhook.secret"] = []byte(credentials.WebhookSecret)
return k8s.EnsureSecretExist(ctx, secret, namespace)
}
// ensurePACRepositoryExists checks that up-to-date Repository CR is present on the cluster
func ensurePACRepositoryExists(ctx context.Context, f fn.Function, namespace string, metadata pipelines.PacMetadata, labels map[string]string) error {
client, namespace, err := pac.NewTektonPacClientAndResolvedNamespace(namespace)
if err != nil {
return err
}
repoName := getPipelineRepositoryName(f)
repo := v1alpha1.Repository{
ObjectMeta: metav1.ObjectMeta{
Name: repoName,
Labels: labels,
Annotations: f.Deploy.Annotations,
},
Spec: v1alpha1.RepositorySpec{
URL: f.Build.Git.URL,
GitProvider: &v1alpha1.GitProvider{
Type: metadata.GitProvider,
Secret: &v1alpha1.Secret{
Name: getPipelineSecretName(f),
},
WebhookSecret: &v1alpha1.Secret{
Name: getPipelineSecretName(f),
},
},
},
}
repoNotFound := false
existingRepo, err := client.Repositories(namespace).Get(ctx, repoName, metav1.GetOptions{})
if err != nil {
if !k8serrors.IsNotFound(err) {
return err
}
repoNotFound = true
}
// TODO we should also compare labels and annotations
if repoNotFound || !equality.Semantic.DeepDerivative(existingRepo.Spec, repo.Spec) {
// Decide whether create or update
if repoNotFound {
_, err = client.Repositories(namespace).Create(ctx, &repo, metav1.CreateOptions{})
} else {
_, err = client.Repositories(namespace).Update(ctx, &repo, metav1.UpdateOptions{})
}
if err != nil {
return err
}
}
return nil
}
// deletePACRepositories deletes all Repository resources present on the cluster that match input list options
func deletePACRepositories(ctx context.Context, namespaceOverride string, listOptions metav1.ListOptions) error {
client, namespace, err := pac.NewTektonPacClientAndResolvedNamespace(namespaceOverride)
if err != nil {
return err
}
return client.Repositories(namespace).DeleteCollection(ctx, metav1.DeleteOptions{}, listOptions)
}
// getPipelineRepositoryName generates name for Repository CR
func getPipelineRepositoryName(f fn.Function) string {
return fmt.Sprintf("%s-repo", getPipelineName(f))
}