Skip to content

Commit

Permalink
feat: Allow proxy to be saved when creating repoCreds (#11351) (#11425)
Browse files Browse the repository at this point in the history
* fix: allow proxy to be saved in repoCreds (https + github app)

Signed-off-by: Nathanael Liechti <technat@technat.ch>

* chore: changes from codegen

Signed-off-by: Nathanael Liechti <technat@technat.ch>

* chore: add unit test for CreateRepoCreds

Signed-off-by: Nathanael Liechti <technat@technat.ch>

Signed-off-by: Nathanael Liechti <technat@technat.ch>
  • Loading branch information
the-technat committed Dec 6, 2022
1 parent d269988 commit 4018fd8
Show file tree
Hide file tree
Showing 9 changed files with 715 additions and 600 deletions.
4 changes: 4 additions & 0 deletions assets/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -7034,6 +7034,10 @@
"type": "string",
"title": "Password for authenticating at the repo server"
},
"proxy": {
"type": "string",
"title": "Proxy specifies the HTTP/HTTPS proxy used to access repos at the repo server"
},
"sshPrivateKey": {
"type": "string",
"title": "SSHPrivateKey contains the private key data for authenticating at the repo server using SSH (only Git repos)"
Expand Down
1,184 changes: 613 additions & 571 deletions pkg/apis/application/v1alpha1/generated.pb.go

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions pkg/apis/application/v1alpha1/generated.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions pkg/apis/application/v1alpha1/openapi_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions pkg/apis/application/v1alpha1/repository_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ type RepoCreds struct {
EnableOCI bool `json:"enableOCI,omitempty" protobuf:"bytes,11,opt,name=enableOCI"`
// Type specifies the type of the repoCreds. Can be either "git" or "helm. "git" is assumed if empty or absent.
Type string `json:"type,omitempty" protobuf:"bytes,12,opt,name=type"`
// Proxy specifies the HTTP/HTTPS proxy used to access repos at the repo server
Proxy string `json:"proxy,omitempty" protobuf:"bytes,19,opt,name=proxy"`
}

// Repository is a repository holding application configurations
Expand Down Expand Up @@ -162,6 +164,9 @@ func (repo *Repository) CopyCredentialsFrom(source *RepoCreds) {
if repo.GitHubAppEnterpriseBaseURL == "" {
repo.GitHubAppEnterpriseBaseURL = source.GitHubAppEnterpriseBaseURL
}
if repo.Proxy == "" {
repo.Proxy = source.Proxy
}
}
}

Expand Down
8 changes: 6 additions & 2 deletions ui/src/app/settings/components/repos-list/repos-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ interface NewHTTPSRepoCredsParams {
password: string;
tlsClientCertData: string;
tlsClientCertKey: string;
proxy: string;
}

interface NewGitHubAppRepoCredsParams {
Expand All @@ -74,6 +75,7 @@ interface NewGitHubAppRepoCredsParams {
githubAppEnterpriseBaseURL: string;
tlsClientCertData: string;
tlsClientCertKey: string;
proxy: string;
}

export enum ConnectionMethod {
Expand Down Expand Up @@ -630,7 +632,8 @@ export class ReposList extends React.Component<
username: params.username,
password: params.password,
tlsClientCertData: params.tlsClientCertData,
tlsClientCertKey: params.tlsClientCertKey
tlsClientCertKey: params.tlsClientCertKey,
proxy: params.proxy
});
} else {
this.setState({connecting: true});
Expand Down Expand Up @@ -676,7 +679,8 @@ export class ReposList extends React.Component<
githubAppInstallationId: params.githubAppInstallationId,
githubAppEnterpriseBaseURL: params.githubAppEnterpriseBaseURL,
tlsClientCertData: params.tlsClientCertData,
tlsClientCertKey: params.tlsClientCertKey
tlsClientCertKey: params.tlsClientCertKey,
proxy: params.proxy
});
} else {
this.setState({connecting: true});
Expand Down
12 changes: 8 additions & 4 deletions ui/src/app/shared/services/repocreds-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,19 @@ export class RepoCredsService {
username,
password,
tlsClientCertData,
tlsClientCertKey
tlsClientCertKey,
proxy
}: {
url: string;
username: string;
password: string;
tlsClientCertData: string;
tlsClientCertKey: string;
proxy: string;
}): Promise<models.RepoCreds> {
return requests
.post('/repocreds')
.send({url, username, password, tlsClientCertData, tlsClientCertKey})
.send({url, username, password, tlsClientCertData, tlsClientCertKey, proxy})
.then(res => res.body as models.RepoCreds);
}

Expand All @@ -42,7 +44,8 @@ export class RepoCredsService {
githubAppInstallationId,
githubAppEnterpriseBaseURL,
tlsClientCertData,
tlsClientCertKey
tlsClientCertKey,
proxy
}: {
url: string;
githubAppPrivateKey: string;
Expand All @@ -51,10 +54,11 @@ export class RepoCredsService {
githubAppEnterpriseBaseURL: string;
tlsClientCertData: string;
tlsClientCertKey: string;
proxy: string;
}): Promise<models.RepoCreds> {
return requests
.post('/repocreds')
.send({url, githubAppPrivateKey, githubAppId, githubAppInstallationId, githubAppEnterpriseBaseURL, tlsClientCertData, tlsClientCertKey})
.send({url, githubAppPrivateKey, githubAppId, githubAppInstallationId, githubAppEnterpriseBaseURL, tlsClientCertData, tlsClientCertKey, proxy})
.then(res => res.body as models.RepoCreds);
}

Expand Down
2 changes: 2 additions & 0 deletions util/db/repository_secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ func (s *secretsRepositoryBackend) secretToRepoCred(secret *corev1.Secret) (*app
Type: string(secret.Data["type"]),
GithubAppPrivateKey: string(secret.Data["githubAppPrivateKey"]),
GitHubAppEnterpriseBaseURL: string(secret.Data["githubAppEnterpriseBaseUrl"]),
Proxy: string(secret.Data["proxy"]),
}

enableOCI, err := boolOrFalse(secret, "enableOCI")
Expand Down Expand Up @@ -431,6 +432,7 @@ func repoCredsToSecret(repoCreds *appsv1.RepoCreds, secret *corev1.Secret) {
updateSecretInt(secret, "githubAppID", repoCreds.GithubAppId)
updateSecretInt(secret, "githubAppInstallationID", repoCreds.GithubAppInstallationId)
updateSecretString(secret, "githubAppEnterpriseBaseUrl", repoCreds.GitHubAppEnterpriseBaseURL)
updateSecretString(secret, "proxy", repoCreds.Proxy)
addSecretMetadata(secret, common.LabelValueSecretTypeRepoCreds)
}

Expand Down
90 changes: 67 additions & 23 deletions util/db/repository_secrets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"

"context"

"github.com/stretchr/testify/assert"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
Expand Down Expand Up @@ -406,39 +407,82 @@ func TestSecretsRepositoryBackend_DeleteRepository(t *testing.T) {
}

func TestSecretsRepositoryBackend_CreateRepoCreds(t *testing.T) {

clientset := getClientset(map[string]string{})
testee := &secretsRepositoryBackend{db: &db{
ns: testNamespace,
kubeclientset: clientset,
settingsMgr: settings.NewSettingsManager(context.TODO(), clientset, testNamespace),
}}

input := &appsv1.RepoCreds{
URL: "git@github.com:argoproj",
Username: "someUsername",
Password: "somePassword",
EnableOCI: true,
testCases := []struct {
name string
repoCreds appsv1.RepoCreds
// Note: URL needs to be a different one for every testCase
// otherwise we would need to use the DeleteRepoCreds method to clean up the secret after each test
// which results in an unwanted dependency in a unit test
}{
{
name: "minimal_https_fields",
repoCreds: appsv1.RepoCreds{
URL: "git@github.com:argoproj",
Username: "someUsername",
Password: "somePassword",
EnableOCI: true,
},
},
{
name: "with_proxy",
repoCreds: appsv1.RepoCreds{
URL: "git@github.com:kubernetes",
Username: "anotherUsername",
Password: "anotherPassword",
Proxy: "https://proxy.argoproj.io:3128",
},
},
}

output, err := testee.CreateRepoCreds(context.TODO(), input)
assert.NoError(t, err)
assert.Same(t, input, output)

secret, err := clientset.CoreV1().Secrets(testNamespace).Get(
context.TODO(),
RepoURLToSecretName(credSecretPrefix, input.URL),
metav1.GetOptions{},
)
assert.NotNil(t, secret)
assert.NoError(t, err)

assert.Equal(t, common.AnnotationValueManagedByArgoCD, secret.Annotations[common.AnnotationKeyManagedBy])
assert.Equal(t, common.LabelValueSecretTypeRepoCreds, secret.Labels[common.LabelKeySecretType])
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
output, err := testee.CreateRepoCreds(context.TODO(), &testCase.repoCreds)
assert.NoError(t, err)
assert.Same(t, &testCase.repoCreds, output)

secret, err := clientset.CoreV1().Secrets(testNamespace).Get(
context.TODO(),
RepoURLToSecretName(credSecretPrefix, testCase.repoCreds.URL),
metav1.GetOptions{},
)
assert.NotNil(t, secret)
assert.NoError(t, err)

assert.Equal(t, common.AnnotationValueManagedByArgoCD, secret.Annotations[common.AnnotationKeyManagedBy])
assert.Equal(t, common.LabelValueSecretTypeRepoCreds, secret.Labels[common.LabelKeySecretType])

// check every possible field of the secret if it has the same (default) value as the repoCred struct
// non-string fields must be parsed so that their default value matches the one of the corresponding type
assert.Equal(t, testCase.repoCreds.URL, string(secret.Data["url"]))
assert.Equal(t, testCase.repoCreds.Username, string(secret.Data["username"]))
assert.Equal(t, testCase.repoCreds.Password, string(secret.Data["password"]))
if enableOCI, err := strconv.ParseBool(string(secret.Data["githubAppPrivateKey"])); err == nil {
assert.Equal(t, strconv.FormatBool(testCase.repoCreds.EnableOCI), enableOCI)
}
assert.Equal(t, testCase.repoCreds.SSHPrivateKey, string(secret.Data["sshPrivateKey"]))
assert.Equal(t, testCase.repoCreds.TLSClientCertData, string(secret.Data["tlsClientCertData"]))
assert.Equal(t, testCase.repoCreds.TLSClientCertKey, string(secret.Data["tlsClientCertKey"]))
assert.Equal(t, testCase.repoCreds.Type, string(secret.Data["type"]))
assert.Equal(t, testCase.repoCreds.GithubAppPrivateKey, string(secret.Data["githubAppPrivateKey"]))
if githubAppPrivateKey, err := strconv.ParseInt(string(secret.Data["githubAppPrivateKey"]), 10, 64); err == nil {
assert.Equal(t, testCase.repoCreds.GithubAppId, githubAppPrivateKey)
}
if githubAppID, err := strconv.ParseInt(string(secret.Data["githubAppId"]), 10, 64); err == nil {
assert.Equal(t, testCase.repoCreds.GithubAppInstallationId, githubAppID)
}
assert.Equal(t, testCase.repoCreds.GitHubAppEnterpriseBaseURL, string(secret.Data["githubAppEnterpriseUrl"]))
assert.Equal(t, testCase.repoCreds.Proxy, string(secret.Data["proxy"]))

assert.Equal(t, input.URL, string(secret.Data["url"]))
assert.Equal(t, input.Username, string(secret.Data["username"]))
assert.Equal(t, input.Password, string(secret.Data["password"]))
assert.Equal(t, strconv.FormatBool(input.EnableOCI), string(secret.Data["enableOCI"]))
})
}
}

func TestSecretsRepositoryBackend_GetRepoCreds(t *testing.T) {
Expand Down

0 comments on commit 4018fd8

Please sign in to comment.