service/codebase/service.go (217 lines of code) (raw):

package codebase import ( "context" "fmt" "time" "ddm-admin-console/service" "ddm-admin-console/service/k8s" "github.com/pkg/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/rest" "sigs.k8s.io/controller-runtime/pkg/client" pkgScheme "sigs.k8s.io/controller-runtime/pkg/scheme" ) const ( defaultBranch = "master" gerritCreatorUsername = "user" gerritCreatorPassword = "password" RegistryCodebaseType = "registry" ) type Service struct { service.UserConfig k8sClient client.Client scheme *runtime.Scheme namespace string restConfig *rest.Config } type ErrAlreadyExists string func (e ErrAlreadyExists) Error() string { return string(e) } func IsErrAlreadyExists(err error) bool { switch errors.Cause(err).(type) { case ErrAlreadyExists: return true } return false } func Make(sch *runtime.Scheme, k8sConfig *rest.Config, namespace string) (*Service, error) { builder := pkgScheme.Builder{GroupVersion: schema.GroupVersion{Group: "v2.edp.epam.com", Version: "v1alpha1"}} builder.Register(&Codebase{}, &CodebaseBranch{}, &CodebaseBranchList{}, &CodebaseList{}) if err := builder.AddToScheme(sch); err != nil { return nil, errors.Wrap(err, "error during builder add to scheme") } cl, err := client.New(k8sConfig, client.Options{ Scheme: sch, }) if err != nil { return nil, errors.Wrap(err, "unable to init k8s jenkins client") } return &Service{ k8sClient: cl, scheme: sch, namespace: namespace, UserConfig: service.UserConfig{ RestConfig: k8sConfig, }, restConfig: k8sConfig, }, nil } func (s *Service) GetAll() ([]Codebase, error) { var lst CodebaseList if err := s.k8sClient.List(context.Background(), &lst, &client.ListOptions{Namespace: s.namespace}); err != nil { return nil, errors.Wrap(err, "unable to get codebases") } return lst.Items, nil } func (s *Service) GetAllByType(tp string) ([]Codebase, error) { all, err := s.GetAll() if err != nil { return nil, errors.Wrap(err, "unable to get all codebases") } result := make([]Codebase, 0, len(all)) for _, v := range all { if v.Spec.Type == tp { result = append(result, v) } } return result, nil } func (s *Service) Get(name string) (*Codebase, error) { var cb Codebase if err := s.k8sClient.Get(context.Background(), types.NamespacedName{Namespace: s.namespace, Name: name}, &cb); err != nil { return nil, errors.Wrapf(err, "unable to get codebase: %s", name) } return &cb, nil } func (s *Service) Create(cb *Codebase) error { cb.Namespace = s.namespace if err := s.k8sClient.Create(context.Background(), cb); err != nil { return errors.Wrapf(err, "unable to create codebase: %+v", cb) } return nil } func (s *Service) CreateBranch(branch *CodebaseBranch) error { branch.Namespace = s.namespace if err := s.k8sClient.Create(context.Background(), branch); err != nil { return errors.Wrap(err, "unable to create codebase branch") } return nil } func (s *Service) Update(ctx context.Context, cb *Codebase) error { if err := s.k8sClient.Update(ctx, cb); err != nil { return errors.Wrapf(err, "unable to update codebase: %+v", cb) } return nil } func (s *Service) Delete(name string) error { cb, err := s.Get(name) if err != nil { return errors.Wrapf(err, "unable to get codebase: %s", name) } fg := metav1.DeletePropagationForeground if err := s.k8sClient.Delete(context.Background(), cb, &client.DeleteOptions{ PropagationPolicy: &fg, }); err != nil { return errors.Wrapf(err, "unable to delete codebase: %+v", cb) } return nil } func (s *Service) GetAllBranches(ctx context.Context) ([]CodebaseBranch, error) { var lst CodebaseBranchList if err := s.k8sClient.List(ctx, &lst, &client.ListOptions{Namespace: s.namespace}); err != nil { return nil, errors.Wrap(err, "unable to get all codebase branches") } return lst.Items, nil } func (s *Service) GetBranchesByCodebase(ctx context.Context, codebaseName string) ([]CodebaseBranch, error) { branches, err := s.GetAllBranches(ctx) if err != nil { return nil, errors.Wrap(err, "unable to get all branches") } filteredBranches := make([]CodebaseBranch, 0, len(branches)) for _, br := range branches { if br.Spec.CodebaseName == codebaseName { filteredBranches = append(filteredBranches, br) } } return filteredBranches, nil } func (s *Service) CreateDefaultBranch(cb *Codebase) error { blockOwnerDel := true buildNo := "0" branch := CodebaseBranch{ TypeMeta: metav1.TypeMeta{ APIVersion: "v2.edp.epam.com/v1alpha1", Kind: "CodebaseBranch", }, ObjectMeta: metav1.ObjectMeta{ Name: fmt.Sprintf("%s-%s", cb.Name, defaultBranch), OwnerReferences: []metav1.OwnerReference{ { APIVersion: "v2.edp.epam.com/v1alpha1", Kind: "Codebase", Name: cb.Name, UID: cb.UID, BlockOwnerDeletion: &blockOwnerDel, }, }, }, Spec: CodebaseBranchSpec{ BranchName: defaultBranch, Version: cb.Spec.Versioning.StartFrom, Release: false, CodebaseName: cb.Name, }, Status: CodebaseBranchStatus{ Build: &buildNo, Status: "initialized", LastTimeUpdated: time.Now(), LastSuccessfulBuild: nil, Username: "", Action: "codebase_branch_registration", Result: "success", Value: "inactive", }, } if err := s.CreateBranch(&branch); err != nil { return errors.Wrap(err, "unable to create branch") } return nil } func (s *Service) ServiceForContext(ctx context.Context) (ServiceInterface, error) { userConfig, changed := s.UserConfig.CreateConfig(ctx) if !changed { return s, nil } svc, err := Make(s.scheme, userConfig, s.namespace) if err != nil { return nil, errors.Wrap(err, "unable to create service for context") } return svc, nil } func (s *Service) CreateTempSecrets(cb *Codebase, k8sService k8s.ServiceInterface, gerritCreatorSecretName string) error { secret, err := k8sService.GetSecret(gerritCreatorSecretName) if err != nil { return errors.Wrap(err, "unable to get secret") } username, ok := secret.Data[gerritCreatorUsername] if !ok { return errors.Wrap(err, "gerrit creator secret does not have username") } pwd, ok := secret.Data[gerritCreatorPassword] if !ok { return errors.Wrap(err, "gerrit creator secret does not have password") } repoSecretName := fmt.Sprintf("repository-codebase-%s-temp", cb.Name) if err := k8sService.RecreateSecret(repoSecretName, map[string][]byte{ "username": username, gerritCreatorPassword: pwd, }); err != nil { return errors.Wrapf(err, "unable to create secret: %s", repoSecretName) } return nil }