Seed job SCM may now be configured with github-branch-source/GitHubAppCredentials (#719)
* Now allowing seed jobs to be configured with GithubAppCredential * fmt * Validation for GithubAppCredentials type seed job SCM secret * GithubAppCredentials validation error messages were not referring to actual GithubAppCredentials fields * cleanup
This commit is contained in:
parent
13f871b1e4
commit
46f64fea6a
|
|
@ -527,6 +527,7 @@ const (
|
|||
BasicSSHCredentialType JenkinsCredentialType = "basicSSHUserPrivateKey"
|
||||
// UsernamePasswordCredentialType define username & password Jenkins credential type
|
||||
UsernamePasswordCredentialType JenkinsCredentialType = "usernamePassword"
|
||||
GithubAppCredentialType JenkinsCredentialType = "githubApp"
|
||||
// ExternalCredentialType defines other credential type
|
||||
ExternalCredentialType JenkinsCredentialType = "external"
|
||||
)
|
||||
|
|
@ -536,6 +537,7 @@ var AllowedJenkinsCredentialMap = map[string]string{
|
|||
string(NoJenkinsCredentialCredentialType): "",
|
||||
string(BasicSSHCredentialType): "",
|
||||
string(UsernamePasswordCredentialType): "",
|
||||
string(GithubAppCredentialType): "",
|
||||
string(ExternalCredentialType): "",
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ const (
|
|||
// PrivateKeySecretKey is private key data key in Kubernetes secret used to create Jenkins SSH credential
|
||||
PrivateKeySecretKey = "privateKey"
|
||||
|
||||
AppIDSecretKey = "appId"
|
||||
|
||||
// JenkinsCredentialTypeLabelName is label for kubernetes-credentials-provider-plugin which determine Jenkins
|
||||
// credential type
|
||||
JenkinsCredentialTypeLabelName = "jenkins.io/credentials-type"
|
||||
|
|
|
|||
|
|
@ -55,7 +55,8 @@ func (s *seedJobs) ValidateSeedJobs(jenkins v1alpha2.Jenkins) ([]string, error)
|
|||
}
|
||||
|
||||
if seedJob.JenkinsCredentialType == v1alpha2.BasicSSHCredentialType ||
|
||||
seedJob.JenkinsCredentialType == v1alpha2.UsernamePasswordCredentialType {
|
||||
seedJob.JenkinsCredentialType == v1alpha2.UsernamePasswordCredentialType ||
|
||||
seedJob.JenkinsCredentialType == v1alpha2.GithubAppCredentialType {
|
||||
secret := &v1.Secret{}
|
||||
namespaceName := types.NamespacedName{Namespace: jenkins.Namespace, Name: seedJob.CredentialID}
|
||||
err := s.Client.Get(context.TODO(), namespaceName, secret)
|
||||
|
|
@ -79,6 +80,13 @@ func (s *seedJobs) ValidateSeedJobs(jenkins v1alpha2.Jenkins) ([]string, error)
|
|||
}
|
||||
}
|
||||
}
|
||||
if seedJob.JenkinsCredentialType == v1alpha2.GithubAppCredentialType {
|
||||
if msg := validateGithubAppSecret(*secret); len(msg) > 0 {
|
||||
for _, m := range msg {
|
||||
messages = append(messages, fmt.Sprintf("seedJob `%s` %s", seedJob.ID, m))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(seedJob.BuildPeriodically) > 0 {
|
||||
|
|
@ -219,6 +227,26 @@ func validateUsernamePasswordSecret(secret v1.Secret) []string {
|
|||
return messages
|
||||
}
|
||||
|
||||
func validateGithubAppSecret(secret v1.Secret) []string {
|
||||
var messages []string
|
||||
appid, exists := secret.Data[AppIDSecretKey]
|
||||
if !exists {
|
||||
messages = append(messages, fmt.Sprintf("required data '%s' not found in secret '%s'", AppIDSecretKey, secret.ObjectMeta.Name))
|
||||
}
|
||||
if len(appid) == 0 {
|
||||
messages = append(messages, fmt.Sprintf("required data '%s' is empty in secret '%s'", AppIDSecretKey, secret.ObjectMeta.Name))
|
||||
}
|
||||
pkey, exists := secret.Data[PrivateKeySecretKey]
|
||||
if !exists {
|
||||
messages = append(messages, fmt.Sprintf("required data '%s' not found in secret '%s'", PrivateKeySecretKey, secret.ObjectMeta.Name))
|
||||
}
|
||||
if len(pkey) == 0 {
|
||||
messages = append(messages, fmt.Sprintf("required data '%s' is empty in secret '%s'", PrivateKeySecretKey, secret.ObjectMeta.Name))
|
||||
}
|
||||
|
||||
return messages
|
||||
}
|
||||
|
||||
func validatePrivateKey(privateKey string) error {
|
||||
_, err := ssh.ParseRawPrivateKey([]byte(privateKey))
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -676,6 +676,213 @@ func TestValidateSeedJobs(t *testing.T) {
|
|||
|
||||
assert.Equal(t, result, []string{"seedJob `example` required data 'password' not found in secret 'deploy-keys'", "seedJob `example` required data 'password' is empty in secret 'deploy-keys'"})
|
||||
})
|
||||
t.Run("Valid with appId and privateKey", func(t *testing.T) {
|
||||
jenkins := v1alpha2.Jenkins{
|
||||
ObjectMeta: jenkinsObjectMeta,
|
||||
Spec: v1alpha2.JenkinsSpec{
|
||||
SeedJobs: []v1alpha2.SeedJob{
|
||||
{
|
||||
ID: "example",
|
||||
CredentialID: "deploy-keys",
|
||||
JenkinsCredentialType: v1alpha2.GithubAppCredentialType,
|
||||
Targets: "cicd/jobs/*.jenkins",
|
||||
RepositoryBranch: "master",
|
||||
RepositoryURL: "https://github.com/jenkinsci/kubernetes-operator.git",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
secret := &corev1.Secret{
|
||||
TypeMeta: secretTypeMeta,
|
||||
ObjectMeta: secretObjectMeta,
|
||||
Data: map[string][]byte{
|
||||
AppIDSecretKey: []byte("some-id"),
|
||||
PrivateKeySecretKey: []byte("some-key"),
|
||||
},
|
||||
}
|
||||
fakeClient := fake.NewClientBuilder().Build()
|
||||
err := fakeClient.Create(context.TODO(), secret)
|
||||
assert.NoError(t, err)
|
||||
|
||||
config := configuration.Configuration{
|
||||
Client: fakeClient,
|
||||
ClientSet: kubernetes.Clientset{},
|
||||
Notifications: nil,
|
||||
Jenkins: &v1alpha2.Jenkins{},
|
||||
}
|
||||
|
||||
seedJobs := New(nil, config)
|
||||
result, err := seedJobs.ValidateSeedJobs(jenkins)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Nil(t, result)
|
||||
})
|
||||
t.Run("Invalid with empty app id", func(t *testing.T) {
|
||||
jenkins := v1alpha2.Jenkins{
|
||||
ObjectMeta: jenkinsObjectMeta,
|
||||
Spec: v1alpha2.JenkinsSpec{
|
||||
SeedJobs: []v1alpha2.SeedJob{
|
||||
{
|
||||
ID: "example",
|
||||
CredentialID: "deploy-keys",
|
||||
JenkinsCredentialType: v1alpha2.GithubAppCredentialType,
|
||||
Targets: "cicd/jobs/*.jenkins",
|
||||
RepositoryBranch: "master",
|
||||
RepositoryURL: "https://github.com/jenkinsci/kubernetes-operator.git",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
secret := &corev1.Secret{
|
||||
TypeMeta: secretTypeMeta,
|
||||
ObjectMeta: secretObjectMeta,
|
||||
Data: map[string][]byte{
|
||||
AppIDSecretKey: []byte(""),
|
||||
PrivateKeySecretKey: []byte("some-key"),
|
||||
},
|
||||
}
|
||||
fakeClient := fake.NewClientBuilder().Build()
|
||||
err := fakeClient.Create(context.TODO(), secret)
|
||||
assert.NoError(t, err)
|
||||
|
||||
config := configuration.Configuration{
|
||||
Client: fakeClient,
|
||||
ClientSet: kubernetes.Clientset{},
|
||||
Notifications: nil,
|
||||
Jenkins: &v1alpha2.Jenkins{},
|
||||
}
|
||||
|
||||
seedJobs := New(nil, config)
|
||||
result, err := seedJobs.ValidateSeedJobs(jenkins)
|
||||
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, result, []string{"seedJob `example` required data 'appId' is empty in secret 'deploy-keys'"})
|
||||
})
|
||||
t.Run("Invalid with empty private key", func(t *testing.T) {
|
||||
jenkins := v1alpha2.Jenkins{
|
||||
ObjectMeta: jenkinsObjectMeta,
|
||||
Spec: v1alpha2.JenkinsSpec{
|
||||
SeedJobs: []v1alpha2.SeedJob{
|
||||
{
|
||||
ID: "example",
|
||||
CredentialID: "deploy-keys",
|
||||
JenkinsCredentialType: v1alpha2.GithubAppCredentialType,
|
||||
Targets: "cicd/jobs/*.jenkins",
|
||||
RepositoryBranch: "master",
|
||||
RepositoryURL: "https://github.com/jenkinsci/kubernetes-operator.git",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
secret := &corev1.Secret{
|
||||
TypeMeta: secretTypeMeta,
|
||||
ObjectMeta: secretObjectMeta,
|
||||
Data: map[string][]byte{
|
||||
AppIDSecretKey: []byte("some-id"),
|
||||
PrivateKeySecretKey: []byte(""),
|
||||
},
|
||||
}
|
||||
fakeClient := fake.NewClientBuilder().Build()
|
||||
err := fakeClient.Create(context.TODO(), secret)
|
||||
assert.NoError(t, err)
|
||||
|
||||
config := configuration.Configuration{
|
||||
Client: fakeClient,
|
||||
ClientSet: kubernetes.Clientset{},
|
||||
Notifications: nil,
|
||||
Jenkins: &v1alpha2.Jenkins{},
|
||||
}
|
||||
|
||||
seedJobs := New(nil, config)
|
||||
result, err := seedJobs.ValidateSeedJobs(jenkins)
|
||||
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, result, []string{"seedJob `example` required data 'privateKey' is empty in secret 'deploy-keys'"})
|
||||
})
|
||||
t.Run("Invalid without app id", func(t *testing.T) {
|
||||
jenkins := v1alpha2.Jenkins{
|
||||
ObjectMeta: jenkinsObjectMeta,
|
||||
Spec: v1alpha2.JenkinsSpec{
|
||||
SeedJobs: []v1alpha2.SeedJob{
|
||||
{
|
||||
ID: "example",
|
||||
CredentialID: "deploy-keys",
|
||||
JenkinsCredentialType: v1alpha2.GithubAppCredentialType,
|
||||
Targets: "cicd/jobs/*.jenkins",
|
||||
RepositoryBranch: "master",
|
||||
RepositoryURL: "https://github.com/jenkinsci/kubernetes-operator.git",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
secret := &corev1.Secret{
|
||||
TypeMeta: secretTypeMeta,
|
||||
ObjectMeta: secretObjectMeta,
|
||||
Data: map[string][]byte{
|
||||
PrivateKeySecretKey: []byte("some-key"),
|
||||
},
|
||||
}
|
||||
fakeClient := fake.NewClientBuilder().Build()
|
||||
err := fakeClient.Create(context.TODO(), secret)
|
||||
assert.NoError(t, err)
|
||||
|
||||
config := configuration.Configuration{
|
||||
Client: fakeClient,
|
||||
ClientSet: kubernetes.Clientset{},
|
||||
Notifications: nil,
|
||||
Jenkins: &v1alpha2.Jenkins{},
|
||||
}
|
||||
|
||||
seedJobs := New(nil, config)
|
||||
result, err := seedJobs.ValidateSeedJobs(jenkins)
|
||||
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, result, []string{"seedJob `example` required data 'appId' not found in secret 'deploy-keys'", "seedJob `example` required data 'appId' is empty in secret 'deploy-keys'"})
|
||||
})
|
||||
t.Run("Invalid without private key", func(t *testing.T) {
|
||||
jenkins := v1alpha2.Jenkins{
|
||||
ObjectMeta: jenkinsObjectMeta,
|
||||
Spec: v1alpha2.JenkinsSpec{
|
||||
SeedJobs: []v1alpha2.SeedJob{
|
||||
{
|
||||
ID: "example",
|
||||
CredentialID: "deploy-keys",
|
||||
JenkinsCredentialType: v1alpha2.GithubAppCredentialType,
|
||||
Targets: "cicd/jobs/*.jenkins",
|
||||
RepositoryBranch: "master",
|
||||
RepositoryURL: "https://github.com/jenkinsci/kubernetes-operator.git",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
secret := &corev1.Secret{
|
||||
TypeMeta: secretTypeMeta,
|
||||
ObjectMeta: secretObjectMeta,
|
||||
Data: map[string][]byte{
|
||||
AppIDSecretKey: []byte("some-username"),
|
||||
},
|
||||
}
|
||||
fakeClient := fake.NewClientBuilder().Build()
|
||||
err := fakeClient.Create(context.TODO(), secret)
|
||||
assert.NoError(t, err)
|
||||
|
||||
config := configuration.Configuration{
|
||||
Client: fakeClient,
|
||||
ClientSet: kubernetes.Clientset{},
|
||||
Notifications: nil,
|
||||
Jenkins: &v1alpha2.Jenkins{},
|
||||
}
|
||||
|
||||
seedJobs := New(nil, config)
|
||||
result, err := seedJobs.ValidateSeedJobs(jenkins)
|
||||
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, result, []string{"seedJob `example` required data 'privateKey' not found in secret 'deploy-keys'", "seedJob `example` required data 'privateKey' is empty in secret 'deploy-keys'"})
|
||||
})
|
||||
t.Run("Invalid with wrong cron spec", func(t *testing.T) {
|
||||
jenkins := v1alpha2.Jenkins{
|
||||
Spec: v1alpha2.JenkinsSpec{
|
||||
|
|
|
|||
Loading…
Reference in New Issue