github.com/argoproj/argo-cd/v3@v3.2.1/applicationset/generators/scm_provider_test.go (about)

     1  package generators
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/assert"
     7  	"github.com/stretchr/testify/require"
     8  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
     9  
    10  	"github.com/argoproj/argo-cd/v3/applicationset/services/scm_provider"
    11  	argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
    12  )
    13  
    14  func TestSCMProviderGenerateParams(t *testing.T) {
    15  	t.Parallel()
    16  
    17  	cases := []struct {
    18  		name          string
    19  		repos         []*scm_provider.Repository
    20  		values        map[string]string
    21  		expected      []map[string]any
    22  		expectedError error
    23  	}{
    24  		{
    25  			name: "Multiple repos with labels",
    26  			repos: []*scm_provider.Repository{
    27  				{
    28  					Organization: "myorg",
    29  					Repository:   "repo1",
    30  					RepositoryId: 190320251,
    31  					URL:          "git@github.com:myorg/repo1.git",
    32  					Branch:       "main",
    33  					SHA:          "0bc57212c3cbbec69d20b34c507284bd300def5b",
    34  					Labels:       []string{"prod", "staging"},
    35  				},
    36  				{
    37  					Organization: "myorg",
    38  					Repository:   "repo2",
    39  					RepositoryId: 190320252,
    40  					URL:          "git@github.com:myorg/repo2.git",
    41  					Branch:       "main",
    42  					SHA:          "59d0",
    43  				},
    44  			},
    45  			expected: []map[string]any{
    46  				{
    47  					"organization":     "myorg",
    48  					"repository":       "repo1",
    49  					"repository_id":    190320251,
    50  					"url":              "git@github.com:myorg/repo1.git",
    51  					"branch":           "main",
    52  					"branchNormalized": "main",
    53  					"sha":              "0bc57212c3cbbec69d20b34c507284bd300def5b",
    54  					"short_sha":        "0bc57212",
    55  					"short_sha_7":      "0bc5721",
    56  					"labels":           "prod,staging",
    57  				},
    58  				{
    59  					"organization":     "myorg",
    60  					"repository":       "repo2",
    61  					"repository_id":    190320252,
    62  					"url":              "git@github.com:myorg/repo2.git",
    63  					"branch":           "main",
    64  					"branchNormalized": "main",
    65  					"sha":              "59d0",
    66  					"short_sha":        "59d0",
    67  					"short_sha_7":      "59d0",
    68  					"labels":           "",
    69  				},
    70  			},
    71  		},
    72  		{
    73  			name: "Value interpolation",
    74  			repos: []*scm_provider.Repository{
    75  				{
    76  					Organization: "myorg",
    77  					Repository:   "repo3",
    78  					RepositoryId: 190320253,
    79  					URL:          "git@github.com:myorg/repo3.git",
    80  					Branch:       "main",
    81  					SHA:          "0bc57212c3cbbec69d20b34c507284bd300def5b",
    82  					Labels:       []string{"prod", "staging"},
    83  				},
    84  			},
    85  			values: map[string]string{
    86  				"foo":                    "bar",
    87  				"should_i_force_push_to": "{{ branch }}?",
    88  			},
    89  			expected: []map[string]any{
    90  				{
    91  					"organization":                  "myorg",
    92  					"repository":                    "repo3",
    93  					"repository_id":                 190320253,
    94  					"url":                           "git@github.com:myorg/repo3.git",
    95  					"branch":                        "main",
    96  					"branchNormalized":              "main",
    97  					"sha":                           "0bc57212c3cbbec69d20b34c507284bd300def5b",
    98  					"short_sha":                     "0bc57212",
    99  					"short_sha_7":                   "0bc5721",
   100  					"labels":                        "prod,staging",
   101  					"values.foo":                    "bar",
   102  					"values.should_i_force_push_to": "main?",
   103  				},
   104  			},
   105  		},
   106  		{
   107  			name: "Repos with and without id",
   108  			repos: []*scm_provider.Repository{
   109  				{
   110  					Organization: "myorg",
   111  					Repository:   "repo4",
   112  					RepositoryId: "idaz09",
   113  					URL:          "git@github.com:myorg/repo4.git",
   114  					Branch:       "main",
   115  					SHA:          "0bc57212c3cbbec69d20b34c507284bd300def5b",
   116  				},
   117  				{
   118  					Organization: "myorg",
   119  					Repository:   "repo5",
   120  					URL:          "git@github.com:myorg/repo5.git",
   121  					Branch:       "main",
   122  					SHA:          "0bc57212c3cbbec69d20b34c507284bd300def5b",
   123  				},
   124  			},
   125  			expected: []map[string]any{
   126  				{
   127  					"organization":     "myorg",
   128  					"repository":       "repo4",
   129  					"repository_id":    "idaz09",
   130  					"url":              "git@github.com:myorg/repo4.git",
   131  					"branch":           "main",
   132  					"branchNormalized": "main",
   133  					"sha":              "0bc57212c3cbbec69d20b34c507284bd300def5b",
   134  					"short_sha":        "0bc57212",
   135  					"short_sha_7":      "0bc5721",
   136  					"labels":           "",
   137  				},
   138  				{
   139  					"organization":     "myorg",
   140  					"repository":       "repo5",
   141  					"repository_id":    nil,
   142  					"url":              "git@github.com:myorg/repo5.git",
   143  					"branch":           "main",
   144  					"branchNormalized": "main",
   145  					"sha":              "0bc57212c3cbbec69d20b34c507284bd300def5b",
   146  					"short_sha":        "0bc57212",
   147  					"short_sha_7":      "0bc5721",
   148  					"labels":           "",
   149  				},
   150  			},
   151  		},
   152  	}
   153  
   154  	for _, testCase := range cases {
   155  		testCaseCopy := testCase
   156  
   157  		t.Run(testCaseCopy.name, func(t *testing.T) {
   158  			t.Parallel()
   159  
   160  			mockProvider := &scm_provider.MockProvider{
   161  				Repos: testCaseCopy.repos,
   162  			}
   163  			scmGenerator := &SCMProviderGenerator{overrideProvider: mockProvider, SCMConfig: SCMConfig{enableSCMProviders: true}}
   164  			applicationSetInfo := argoprojiov1alpha1.ApplicationSet{
   165  				ObjectMeta: metav1.ObjectMeta{
   166  					Name: "set",
   167  				},
   168  				Spec: argoprojiov1alpha1.ApplicationSetSpec{
   169  					Generators: []argoprojiov1alpha1.ApplicationSetGenerator{{
   170  						SCMProvider: &argoprojiov1alpha1.SCMProviderGenerator{
   171  							Values: testCaseCopy.values,
   172  						},
   173  					}},
   174  				},
   175  			}
   176  
   177  			got, err := scmGenerator.GenerateParams(&applicationSetInfo.Spec.Generators[0], &applicationSetInfo, nil)
   178  
   179  			if testCaseCopy.expectedError != nil {
   180  				assert.EqualError(t, err, testCaseCopy.expectedError.Error())
   181  			} else {
   182  				require.NoError(t, err)
   183  				assert.Equal(t, testCaseCopy.expected, got)
   184  			}
   185  		})
   186  	}
   187  }
   188  
   189  func TestAllowedSCMProvider(t *testing.T) {
   190  	t.Parallel()
   191  
   192  	cases := []struct {
   193  		name           string
   194  		providerConfig *argoprojiov1alpha1.SCMProviderGenerator
   195  	}{
   196  		{
   197  			name: "Error Github",
   198  			providerConfig: &argoprojiov1alpha1.SCMProviderGenerator{
   199  				Github: &argoprojiov1alpha1.SCMProviderGeneratorGithub{
   200  					API: "https://myservice.mynamespace.svc.cluster.local",
   201  				},
   202  			},
   203  		},
   204  		{
   205  			name: "Error Gitlab",
   206  			providerConfig: &argoprojiov1alpha1.SCMProviderGenerator{
   207  				Gitlab: &argoprojiov1alpha1.SCMProviderGeneratorGitlab{
   208  					API: "https://myservice.mynamespace.svc.cluster.local",
   209  				},
   210  			},
   211  		},
   212  		{
   213  			name: "Error Gitea",
   214  			providerConfig: &argoprojiov1alpha1.SCMProviderGenerator{
   215  				Gitea: &argoprojiov1alpha1.SCMProviderGeneratorGitea{
   216  					API: "https://myservice.mynamespace.svc.cluster.local",
   217  				},
   218  			},
   219  		},
   220  		{
   221  			name: "Error Bitbucket",
   222  			providerConfig: &argoprojiov1alpha1.SCMProviderGenerator{
   223  				BitbucketServer: &argoprojiov1alpha1.SCMProviderGeneratorBitbucketServer{
   224  					API: "https://myservice.mynamespace.svc.cluster.local",
   225  				},
   226  			},
   227  		},
   228  		{
   229  			name: "Error AzureDevops",
   230  			providerConfig: &argoprojiov1alpha1.SCMProviderGenerator{
   231  				AzureDevOps: &argoprojiov1alpha1.SCMProviderGeneratorAzureDevOps{
   232  					API: "https://myservice.mynamespace.svc.cluster.local",
   233  				},
   234  			},
   235  		},
   236  	}
   237  
   238  	for _, testCase := range cases {
   239  		testCaseCopy := testCase
   240  
   241  		t.Run(testCaseCopy.name, func(t *testing.T) {
   242  			t.Parallel()
   243  
   244  			scmGenerator := &SCMProviderGenerator{
   245  				SCMConfig: SCMConfig{
   246  					allowedSCMProviders: []string{
   247  						"github.myorg.com",
   248  						"gitlab.myorg.com",
   249  						"gitea.myorg.com",
   250  						"bitbucket.myorg.com",
   251  						"azuredevops.myorg.com",
   252  					},
   253  					enableSCMProviders: true,
   254  				},
   255  			}
   256  
   257  			applicationSetInfo := argoprojiov1alpha1.ApplicationSet{
   258  				ObjectMeta: metav1.ObjectMeta{
   259  					Name: "set",
   260  				},
   261  				Spec: argoprojiov1alpha1.ApplicationSetSpec{
   262  					Generators: []argoprojiov1alpha1.ApplicationSetGenerator{{
   263  						SCMProvider: testCaseCopy.providerConfig,
   264  					}},
   265  				},
   266  			}
   267  
   268  			_, err := scmGenerator.GenerateParams(&applicationSetInfo.Spec.Generators[0], &applicationSetInfo, nil)
   269  
   270  			require.Error(t, err, "Must return an error")
   271  			var expectedError ErrDisallowedSCMProvider
   272  			assert.ErrorAs(t, err, &expectedError)
   273  		})
   274  	}
   275  }
   276  
   277  func TestSCMProviderDisabled_SCMGenerator(t *testing.T) {
   278  	generator := &SCMProviderGenerator{SCMConfig: SCMConfig{enableSCMProviders: false}}
   279  
   280  	applicationSetInfo := argoprojiov1alpha1.ApplicationSet{
   281  		ObjectMeta: metav1.ObjectMeta{
   282  			Name: "set",
   283  		},
   284  		Spec: argoprojiov1alpha1.ApplicationSetSpec{
   285  			Generators: []argoprojiov1alpha1.ApplicationSetGenerator{{
   286  				SCMProvider: &argoprojiov1alpha1.SCMProviderGenerator{
   287  					Github: &argoprojiov1alpha1.SCMProviderGeneratorGithub{
   288  						API: "https://myservice.mynamespace.svc.cluster.local",
   289  					},
   290  				},
   291  			}},
   292  		},
   293  	}
   294  
   295  	_, err := generator.GenerateParams(&applicationSetInfo.Spec.Generators[0], &applicationSetInfo, nil)
   296  	assert.ErrorIs(t, err, ErrSCMProvidersDisabled)
   297  }