diff --git a/pkg/controller/gitrepo/gitrepo_reconcile.go b/pkg/controller/gitrepo/gitrepo_reconcile.go index c2b9f7ca..ea908284 100644 --- a/pkg/controller/gitrepo/gitrepo_reconcile.go +++ b/pkg/controller/gitrepo/gitrepo_reconcile.go @@ -28,7 +28,6 @@ const ( // Reconcile will create or delete a git repository based on the event. // The Controller will requeue the Request to be processed again if the returned error is non-nil or // Result.Requeue is true, otherwise upon completion it will remove the work from the queue. - // ATTENTION: do not manipulate the spec here, this will lead to loops, as the specs are // defined in the gitrepotemplates of the other CRDs (tenant, cluster). func (r *ReconcileGitRepo) Reconcile(request reconcile.Request) (reconcile.Result, error) { @@ -105,22 +104,11 @@ func (r *ReconcileGitRepo) Reconcile(request reconcile.Request) (reconcile.Resul if !r.repoExists(repo) { reqLogger.Info("creating git repo", SecretEndpointName, repoOptions.URL) - err = repo.Create() + err := repo.Create() if err != nil { return r.handleRepoError(err, instance, repo) } - - err = repo.CommitTemplateFiles() - if err != nil { - return r.handleRepoError(err, instance, repo) - - } - reqLogger.Info("successfully created the repository") - phase := synv1alpha1.Created - instance.Status.Phase = &phase - instance.Status.URL = repo.FullURL().String() - return r.client.Status().Update(context.TODO(), instance) } err = repo.CommitTemplateFiles() @@ -145,6 +133,8 @@ func (r *ReconcileGitRepo) Reconcile(request reconcile.Request) (reconcile.Resul } phase := synv1alpha1.Created instance.Status.Phase = &phase + instance.Status.URL = repo.FullURL().String() + instance.Status.Type = synv1alpha1.GitType(repo.Type()) return r.client.Status().Update(context.TODO(), instance) }) diff --git a/pkg/controller/gitrepo/gitrepo_reconcile_test.go b/pkg/controller/gitrepo/gitrepo_reconcile_test.go index 479f39e9..1f6fd88b 100644 --- a/pkg/controller/gitrepo/gitrepo_reconcile_test.go +++ b/pkg/controller/gitrepo/gitrepo_reconcile_test.go @@ -52,7 +52,7 @@ func TestReconcileGitRepo_Reconcile(t *testing.T) { name: "testrep", namespace: "testnamespace", secretName: "testsecret", - URL: "something", + URL: "some.example.com", }, wantErr: true, }, @@ -61,19 +61,19 @@ func TestReconcileGitRepo_Reconcile(t *testing.T) { fields: fields{ name: "anothertest", namespace: "namespace", - displayName: "desc", + displayName: "This is the name", tenantName: "sometenant", secretName: "testsecret", - URL: "another", + URL: "git.corp.net", }, }, } - manager.Register(&testRepoImplementation{}) + testRepo := &testRepoImplementation{} + manager.Register(testRepo) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - repo := &synv1alpha1.GitRepo{ ObjectMeta: metav1.ObjectMeta{ Name: tt.fields.name, @@ -140,22 +140,25 @@ func TestReconcileGitRepo_Reconcile(t *testing.T) { assert.Equal(t, tt.fields.displayName, savedGitRepoOpt.DisplayName) assert.Equal(t, tt.fields.tenantName, gitRepo.Labels[apis.LabelNameTenant]) assert.Equal(t, synv1alpha1.Created, *gitRepo.Status.Phase) + assert.Equal(t, tt.fields.URL+"/"+tt.fields.namespace+"/"+tt.fields.name, gitRepo.Status.URL) + assert.Equal(t, synv1alpha1.GitType("test"), gitRepo.Status.Type) } }) } } type testRepoImplementation struct { - //meh + options manager.RepoOptions } func (t testRepoImplementation) IsType(URL *url.URL) (bool, error) { - return strings.Contains(URL.String(), "another"), nil + return strings.HasPrefix(URL.String(), "git"), nil } func (t testRepoImplementation) New(options manager.RepoOptions) (manager.Repo, error) { + t.options = options savedGitRepoOpt = options - return testRepoImplementation{}, nil + return t, nil } func (t testRepoImplementation) Type() string { @@ -163,7 +166,7 @@ func (t testRepoImplementation) Type() string { } func (t testRepoImplementation) FullURL() *url.URL { - return &url.URL{} + return t.options.URL } func (t testRepoImplementation) Create() error { diff --git a/pkg/git/gitlab/gitlab_test.go b/pkg/git/gitlab/gitlab_test.go index 8316c634..b137ff27 100644 --- a/pkg/git/gitlab/gitlab_test.go +++ b/pkg/git/gitlab/gitlab_test.go @@ -121,7 +121,7 @@ func testGetCreateServer() *httptest.Server { response = http.StatusInternalServerError } res.WriteHeader(response) - _, _ = res.Write([]byte(`{"id":3,"description":"` + *createProjectOptions.Description + `","default_branch":"master","visibility":"private","ssh_url_to_repo":"git@example.com:diaspora/diaspora-project-site.git","http_url_to_repo":"http://example.com/diaspora/diaspora-project-site.git","web_url":"http://example.com/diaspora/diaspora-project-site","readme_url":"http://example.com/diaspora/diaspora-project-site/blob/master/README.md","tag_list":["example","disapora project"],"owner":{"id":3,"name":"Diaspora","created_at":"2013-09-30T13:46:02Z"},"name":"`+ *createProjectOptions.Name +`","name_with_namespace":"group1 / Diaspora Project Site","path":"diaspora-project-site","path_with_namespace":"group1/diaspora-project-site","issues_enabled":true,"open_issues_count":1,"merge_requests_enabled":true,"jobs_enabled":true,"wiki_enabled":true,"snippets_enabled":false,"resolve_outdated_diff_discussions":false,"container_registry_enabled":false,"container_expiration_policy":{"cadence":"7d","enabled":false,"keep_n":null,"older_than":null,"name_regex":null,"next_run_at":"2020-01-07T21:42:58.658Z"},"created_at":"2013-09-30T13:46:02Z","last_activity_at":"2013-09-30T13:46:02Z","creator_id":2,"namespace":{"id":2,"name":"group1","path":"group1","kind":"group","full_path":"group1","parent_id":null,"members_count_with_descendants":2},"import_status":"none","import_error":null,"permissions":{"project_access":{"access_level":10,"notification_level":3},"group_access":{"access_level":50,"notification_level":3}},"archived":false,"avatar_url":"http://example.com/uploads/project/avatar/3/uploads/avatar.png","license_url":"http://example.com/diaspora/diaspora-client/blob/master/LICENSE","license":{"key":"lgpl-3.0","name":"GNU Lesser General Public License v3.0","nickname":"GNU LGPLv3","html_url":"http://choosealicense.com/licenses/lgpl-3.0/","source_url":"http://www.gnu.org/licenses/lgpl-3.0.txt"},"shared_runners_enabled":true,"forks_count":0,"star_count":0,"runners_token":"b8bc4a7a29eb76ea83cf79e4908c2b","ci_default_git_depth":50,"public_jobs":true,"shared_with_groups":[{"group_id":4,"group_name":"Twitter","group_full_path":"twitter","group_access_level":30},{"group_id":3,"group_name":"Gitlab Org","group_full_path":"gitlab-org","group_access_level":10}],"repository_storage":"default","only_allow_merge_if_pipeline_succeeds":false,"only_allow_merge_if_all_discussions_are_resolved":false,"remove_source_branch_after_merge":false,"printing_merge_requests_link_enabled":true,"request_access_enabled":false,"merge_method":"merge","auto_devops_enabled":true,"auto_devops_deploy_strategy":"continuous","approvals_before_merge":0,"mirror":false,"mirror_user_id":45,"mirror_trigger_builds":false,"only_mirror_protected_branches":false,"mirror_overwrites_diverged_branches":false,"external_authorization_classification_label":null,"packages_enabled":true,"service_desk_enabled":false,"service_desk_address":null,"autoclose_referenced_issues":true,"suggestion_commit_message":null,"statistics":{"commit_count":37,"storage_size":1038090,"repository_size":1038090,"wiki_size":0,"lfs_objects_size":0,"job_artifacts_size":0,"packages_size":0},"_links":{"self":"http://example.com/api/v4/projects","issues":"http://example.com/api/v4/projects/1/issues","merge_requests":"http://example.com/api/v4/projects/1/merge_requests","repo_branches":"http://example.com/api/v4/projects/1/repository_branches","labels":"http://example.com/api/v4/projects/1/labels","events":"http://example.com/api/v4/projects/1/events","members":"http://example.com/api/v4/projects/1/members"}}`)) + _, _ = res.Write([]byte(`{"id":3,"description":"` + *createProjectOptions.Description + `","default_branch":"master","visibility":"private","ssh_url_to_repo":"git@example.com:diaspora/diaspora-project-site.git","http_url_to_repo":"http://example.com/diaspora/diaspora-project-site.git","web_url":"http://example.com/diaspora/diaspora-project-site","readme_url":"http://example.com/diaspora/diaspora-project-site/blob/master/README.md","tag_list":["example","disapora project"],"owner":{"id":3,"name":"Diaspora","created_at":"2013-09-30T13:46:02Z"},"name":"` + *createProjectOptions.Name + `","name_with_namespace":"group1 / Diaspora Project Site","path":"diaspora-project-site","path_with_namespace":"group1/diaspora-project-site","issues_enabled":true,"open_issues_count":1,"merge_requests_enabled":true,"jobs_enabled":true,"wiki_enabled":true,"snippets_enabled":false,"resolve_outdated_diff_discussions":false,"container_registry_enabled":false,"container_expiration_policy":{"cadence":"7d","enabled":false,"keep_n":null,"older_than":null,"name_regex":null,"next_run_at":"2020-01-07T21:42:58.658Z"},"created_at":"2013-09-30T13:46:02Z","last_activity_at":"2013-09-30T13:46:02Z","creator_id":2,"namespace":{"id":2,"name":"group1","path":"group1","kind":"group","full_path":"group1","parent_id":null,"members_count_with_descendants":2},"import_status":"none","import_error":null,"permissions":{"project_access":{"access_level":10,"notification_level":3},"group_access":{"access_level":50,"notification_level":3}},"archived":false,"avatar_url":"http://example.com/uploads/project/avatar/3/uploads/avatar.png","license_url":"http://example.com/diaspora/diaspora-client/blob/master/LICENSE","license":{"key":"lgpl-3.0","name":"GNU Lesser General Public License v3.0","nickname":"GNU LGPLv3","html_url":"http://choosealicense.com/licenses/lgpl-3.0/","source_url":"http://www.gnu.org/licenses/lgpl-3.0.txt"},"shared_runners_enabled":true,"forks_count":0,"star_count":0,"runners_token":"b8bc4a7a29eb76ea83cf79e4908c2b","ci_default_git_depth":50,"public_jobs":true,"shared_with_groups":[{"group_id":4,"group_name":"Twitter","group_full_path":"twitter","group_access_level":30},{"group_id":3,"group_name":"Gitlab Org","group_full_path":"gitlab-org","group_access_level":10}],"repository_storage":"default","only_allow_merge_if_pipeline_succeeds":false,"only_allow_merge_if_all_discussions_are_resolved":false,"remove_source_branch_after_merge":false,"printing_merge_requests_link_enabled":true,"request_access_enabled":false,"merge_method":"merge","auto_devops_enabled":true,"auto_devops_deploy_strategy":"continuous","approvals_before_merge":0,"mirror":false,"mirror_user_id":45,"mirror_trigger_builds":false,"only_mirror_protected_branches":false,"mirror_overwrites_diverged_branches":false,"external_authorization_classification_label":null,"packages_enabled":true,"service_desk_enabled":false,"service_desk_address":null,"autoclose_referenced_issues":true,"suggestion_commit_message":null,"statistics":{"commit_count":37,"storage_size":1038090,"repository_size":1038090,"wiki_size":0,"lfs_objects_size":0,"job_artifacts_size":0,"packages_size":0},"_links":{"self":"http://example.com/api/v4/projects","issues":"http://example.com/api/v4/projects/1/issues","merge_requests":"http://example.com/api/v4/projects/1/merge_requests","repo_branches":"http://example.com/api/v4/projects/1/repository_branches","labels":"http://example.com/api/v4/projects/1/labels","events":"http://example.com/api/v4/projects/1/events","members":"http://example.com/api/v4/projects/1/members"}}`)) }) mux.HandleFunc("/api/v4/namespaces/group1", func(res http.ResponseWriter, req *http.Request) { @@ -281,7 +281,7 @@ func testGetUpdateServer(fail bool) *httptest.Server { response = http.StatusInternalServerError } res.WriteHeader(response) - _, _ = res.Write([]byte(`{"id":3,"description":"`+*editProjectOptions.Description+`","default_branch":"master","visibility":"private","ssh_url_to_repo":"git@example.com:luzifern/luzifern-project-site.git","http_url_to_repo":"http://example.com/diaspora/diaspora-project-site.git","web_url":"http://example.com/diaspora/diaspora-project-site","readme_url":"http://example.com/diaspora/diaspora-project-site/blob/master/README.md","tag_list":["example","disapora project"],"owner":{"id":3,"name":"Diaspora","created_at":"2013-09-30T13:46:02Z"},"name":"repo","name_with_namespace":"group1 / Diaspora Project Site","path":"diaspora-project-site","path_with_namespace":"group1/diaspora-project-site","issues_enabled":true,"open_issues_count":1,"merge_requests_enabled":true,"jobs_enabled":true,"wiki_enabled":true,"snippets_enabled":false,"resolve_outdated_diff_discussions":false,"container_registry_enabled":false,"container_expiration_policy":{"cadence":"7d","enabled":false,"keep_n":null,"older_than":null,"name_regex":null,"next_run_at":"2020-01-07T21:42:58.658Z"},"created_at":"2013-09-30T13:46:02Z","last_activity_at":"2013-09-30T13:46:02Z","creator_id":2,"namespace":{"id":2,"name":"group1","path":"group1","kind":"group","full_path":"group1","parent_id":null,"members_count_with_descendants":2},"import_status":"none","import_error":null,"permissions":{"project_access":{"access_level":10,"notification_level":3},"group_access":{"access_level":50,"notification_level":3}},"archived":false,"avatar_url":"http://example.com/uploads/project/avatar/3/uploads/avatar.png","license_url":"http://example.com/diaspora/diaspora-client/blob/master/LICENSE","license":{"key":"lgpl-3.0","name":"GNU Lesser General Public License v3.0","nickname":"GNU LGPLv3","html_url":"http://choosealicense.com/licenses/lgpl-3.0/","source_url":"http://www.gnu.org/licenses/lgpl-3.0.txt"},"shared_runners_enabled":true,"forks_count":0,"star_count":0,"runners_token":"b8bc4a7a29eb76ea83cf79e4908c2b","ci_default_git_depth":50,"public_jobs":true,"shared_with_groups":[{"group_id":4,"group_name":"Twitter","group_full_path":"twitter","group_access_level":30},{"group_id":3,"group_name":"Gitlab Org","group_full_path":"gitlab-org","group_access_level":10}],"repository_storage":"default","only_allow_merge_if_pipeline_succeeds":false,"only_allow_merge_if_all_discussions_are_resolved":false,"remove_source_branch_after_merge":false,"printing_merge_requests_link_enabled":true,"request_access_enabled":false,"merge_method":"merge","auto_devops_enabled":true,"auto_devops_deploy_strategy":"continuous","approvals_before_merge":0,"mirror":false,"mirror_user_id":45,"mirror_trigger_builds":false,"only_mirror_protected_branches":false,"mirror_overwrites_diverged_branches":false,"external_authorization_classification_label":null,"packages_enabled":true,"service_desk_enabled":false,"service_desk_address":null,"autoclose_referenced_issues":true,"suggestion_commit_message":null,"statistics":{"commit_count":37,"storage_size":1038090,"repository_size":1038090,"wiki_size":0,"lfs_objects_size":0,"job_artifacts_size":0,"packages_size":0},"_links":{"self":"http://example.com/api/v4/projects","issues":"http://example.com/api/v4/projects/1/issues","merge_requests":"http://example.com/api/v4/projects/1/merge_requests","repo_branches":"http://example.com/api/v4/projects/1/repository_branches","labels":"http://example.com/api/v4/projects/1/labels","events":"http://example.com/api/v4/projects/1/events","members":"http://example.com/api/v4/projects/1/members"}}`)) + _, _ = res.Write([]byte(`{"id":3,"description":"` + *editProjectOptions.Description + `","default_branch":"master","visibility":"private","ssh_url_to_repo":"git@example.com:luzifern/luzifern-project-site.git","http_url_to_repo":"http://example.com/diaspora/diaspora-project-site.git","web_url":"http://example.com/diaspora/diaspora-project-site","readme_url":"http://example.com/diaspora/diaspora-project-site/blob/master/README.md","tag_list":["example","disapora project"],"owner":{"id":3,"name":"Diaspora","created_at":"2013-09-30T13:46:02Z"},"name":"repo","name_with_namespace":"group1 / Diaspora Project Site","path":"diaspora-project-site","path_with_namespace":"group1/diaspora-project-site","issues_enabled":true,"open_issues_count":1,"merge_requests_enabled":true,"jobs_enabled":true,"wiki_enabled":true,"snippets_enabled":false,"resolve_outdated_diff_discussions":false,"container_registry_enabled":false,"container_expiration_policy":{"cadence":"7d","enabled":false,"keep_n":null,"older_than":null,"name_regex":null,"next_run_at":"2020-01-07T21:42:58.658Z"},"created_at":"2013-09-30T13:46:02Z","last_activity_at":"2013-09-30T13:46:02Z","creator_id":2,"namespace":{"id":2,"name":"group1","path":"group1","kind":"group","full_path":"group1","parent_id":null,"members_count_with_descendants":2},"import_status":"none","import_error":null,"permissions":{"project_access":{"access_level":10,"notification_level":3},"group_access":{"access_level":50,"notification_level":3}},"archived":false,"avatar_url":"http://example.com/uploads/project/avatar/3/uploads/avatar.png","license_url":"http://example.com/diaspora/diaspora-client/blob/master/LICENSE","license":{"key":"lgpl-3.0","name":"GNU Lesser General Public License v3.0","nickname":"GNU LGPLv3","html_url":"http://choosealicense.com/licenses/lgpl-3.0/","source_url":"http://www.gnu.org/licenses/lgpl-3.0.txt"},"shared_runners_enabled":true,"forks_count":0,"star_count":0,"runners_token":"b8bc4a7a29eb76ea83cf79e4908c2b","ci_default_git_depth":50,"public_jobs":true,"shared_with_groups":[{"group_id":4,"group_name":"Twitter","group_full_path":"twitter","group_access_level":30},{"group_id":3,"group_name":"Gitlab Org","group_full_path":"gitlab-org","group_access_level":10}],"repository_storage":"default","only_allow_merge_if_pipeline_succeeds":false,"only_allow_merge_if_all_discussions_are_resolved":false,"remove_source_branch_after_merge":false,"printing_merge_requests_link_enabled":true,"request_access_enabled":false,"merge_method":"merge","auto_devops_enabled":true,"auto_devops_deploy_strategy":"continuous","approvals_before_merge":0,"mirror":false,"mirror_user_id":45,"mirror_trigger_builds":false,"only_mirror_protected_branches":false,"mirror_overwrites_diverged_branches":false,"external_authorization_classification_label":null,"packages_enabled":true,"service_desk_enabled":false,"service_desk_address":null,"autoclose_referenced_issues":true,"suggestion_commit_message":null,"statistics":{"commit_count":37,"storage_size":1038090,"repository_size":1038090,"wiki_size":0,"lfs_objects_size":0,"job_artifacts_size":0,"packages_size":0},"_links":{"self":"http://example.com/api/v4/projects","issues":"http://example.com/api/v4/projects/1/issues","merge_requests":"http://example.com/api/v4/projects/1/merge_requests","repo_branches":"http://example.com/api/v4/projects/1/repository_branches","labels":"http://example.com/api/v4/projects/1/labels","events":"http://example.com/api/v4/projects/1/events","members":"http://example.com/api/v4/projects/1/members"}}`)) }) deleteOk := func(res http.ResponseWriter, req *http.Request) { @@ -311,9 +311,9 @@ func TestGitlab_Update(t *testing.T) { name: "update successful", fields: fields{ project: &gitlab.Project{ - ID: 3, - Path: "updated", - Name: "repo", + ID: 3, + Path: "updated", + Name: "repo", Description: "newDesc", }, }, @@ -324,9 +324,9 @@ func TestGitlab_Update(t *testing.T) { name: "update failed", fields: fields{ project: &gitlab.Project{ - ID: 1, - Path: "updated", - Name: "repo", + ID: 1, + Path: "updated", + Name: "repo", Description: "newDesc", }, }, @@ -343,9 +343,9 @@ func TestGitlab_Update(t *testing.T) { g := &Gitlab{ ops: manager.RepoOptions{ - URL: serverURL, - Path: tt.fields.project.Path, - RepoName: tt.fields.project.Name, + URL: serverURL, + Path: tt.fields.project.Path, + RepoName: tt.fields.project.Name, DisplayName: tt.fields.project.Description, }, project: tt.fields.project, diff --git a/pkg/git/manager/manager.go b/pkg/git/manager/manager.go index 2f09345b..8e89d1e3 100644 --- a/pkg/git/manager/manager.go +++ b/pkg/git/manager/manager.go @@ -42,14 +42,14 @@ func NewRepo(opts RepoOptions) (Repo, error) { // RepoOptions hold the options for creating a repository. The credentials are required to work. The deploykeys are // optional but desired. type RepoOptions struct { - Credentials Credentials - DeployKeys map[string]synv1alpha1.DeployKey - Logger logr.Logger - URL *url.URL - Path string - RepoName string - DisplayName string - TemplateFiles map[string]string + Credentials Credentials + DeployKeys map[string]synv1alpha1.DeployKey + Logger logr.Logger + URL *url.URL + Path string + RepoName string + DisplayName string + TemplateFiles map[string]string } // Credentials holds the authentication information for the API. Most of the times this