From 9d179e6d1d7b986e0ea7348f8a674e9159c79147 Mon Sep 17 00:00:00 2001 From: Anatolii Bazko Date: Fri, 27 Oct 2023 15:53:21 +0200 Subject: [PATCH 1/2] feat: Allow to configure 2 github providers simultaneously Signed-off-by: Anatolii Bazko --- pkg/deploy/server/server_configmap.go | 2 +- pkg/deploy/server/server_deployment.go | 35 +++-- pkg/deploy/server/server_deployment_test.go | 162 +++++++++++--------- pkg/deploy/server/server_util.go | 22 +-- 4 files changed, 125 insertions(+), 96 deletions(-) diff --git a/pkg/deploy/server/server_configmap.go b/pkg/deploy/server/server_configmap.go index efba7f2cc..190ac9904 100644 --- a/pkg/deploy/server/server_configmap.go +++ b/pkg/deploy/server/server_configmap.go @@ -258,7 +258,7 @@ func (s *CheServerReconciler) getCheConfigMapData(ctx *chetypes.DeployContext) ( s.updateUserClusterRoles(ctx, cheEnv) - for _, oauthProvider := range []string{"bitbucket", "gitlab", "github", constants.AzureDevOpsOAuth} { + for _, oauthProvider := range []string{"bitbucket", "gitlab", constants.AzureDevOpsOAuth} { err := s.updateIntegrationServerEndpoints(ctx, cheEnv, oauthProvider) if err != nil { return nil, err diff --git a/pkg/deploy/server/server_deployment.go b/pkg/deploy/server/server_deployment.go index 93d36a93a..e81e5ce16 100644 --- a/pkg/deploy/server/server_deployment.go +++ b/pkg/deploy/server/server_deployment.go @@ -12,6 +12,10 @@ package server import ( + "sort" + "strconv" + "strings" + "github.com/eclipse-che/che-operator/pkg/common/chetypes" "github.com/eclipse-che/che-operator/pkg/common/constants" defaults "github.com/eclipse-che/che-operator/pkg/common/operator-defaults" @@ -264,22 +268,31 @@ func MountBitBucketOAuthConfig(ctx *chetypes.DeployContext, deployment *appsv1.D } func MountGitHubOAuthConfig(ctx *chetypes.DeployContext, deployment *appsv1.Deployment) error { - secret, err := getOAuthConfig(ctx, "github") - if secret == nil { + secrets, err := getAllGitProviderOAuthConfigs(ctx, "github") + if err != nil { return err } - mountVolumes(deployment, secret, constants.GitHubOAuthConfigMountPath) - mountEnv(deployment, "CHE_OAUTH2_GITHUB_CLIENTID__FILEPATH", constants.GitHubOAuthConfigMountPath+"/"+constants.GitHubOAuthConfigClientIdFileName) - mountEnv(deployment, "CHE_OAUTH2_GITHUB_CLIENTSECRET__FILEPATH", constants.GitHubOAuthConfigMountPath+"/"+constants.GitHubOAuthConfigClientSecretFileName) + sort.Slice(secrets, func(i, j int) bool { + return strings.Compare(secrets[i].Annotations[constants.CheEclipseOrgScmServerEndpoint], secrets[j].Annotations[constants.CheEclipseOrgScmServerEndpoint]) < 0 + }) - oauthEndpoint := secret.Annotations[constants.CheEclipseOrgScmServerEndpoint] - if oauthEndpoint != "" { - mountEnv(deployment, "CHE_INTEGRATION_GITHUB_OAUTH__ENDPOINT", oauthEndpoint) - } + for i := 0; i < len(secrets); i++ { + secret := secrets[i] + suffix := map[bool]string{false: "__" + strconv.Itoa(i+1), true: ""}[i == 0] + + mountVolumes(deployment, &secret, constants.GitHubOAuthConfigMountPath+suffix) + mountEnv(deployment, "CHE_OAUTH2_GITHUB_CLIENTID__FILEPATH"+suffix, constants.GitHubOAuthConfigMountPath+suffix+"/"+constants.GitHubOAuthConfigClientIdFileName) + mountEnv(deployment, "CHE_OAUTH2_GITHUB_CLIENTSECRET__FILEPATH"+suffix, constants.GitHubOAuthConfigMountPath+suffix+"/"+constants.GitHubOAuthConfigClientSecretFileName) - if secret.Annotations[constants.CheEclipseOrgScmGitHubDisableSubdomainIsolation] != "" { - mountEnv(deployment, "CHE_INTEGRATION_GITHUB_DISABLE__SUBDOMAIN__ISOLATION", secret.Annotations[constants.CheEclipseOrgScmGitHubDisableSubdomainIsolation]) + oauthEndpoint := secret.Annotations[constants.CheEclipseOrgScmServerEndpoint] + if oauthEndpoint != "" { + mountEnv(deployment, "CHE_INTEGRATION_GITHUB_OAUTH__ENDPOINT"+suffix, oauthEndpoint) + } + + if secret.Annotations[constants.CheEclipseOrgScmGitHubDisableSubdomainIsolation] != "" { + mountEnv(deployment, "CHE_INTEGRATION_GITHUB_DISABLE__SUBDOMAIN__ISOLATION"+suffix, secret.Annotations[constants.CheEclipseOrgScmGitHubDisableSubdomainIsolation]) + } } return nil diff --git a/pkg/deploy/server/server_deployment_test.go b/pkg/deploy/server/server_deployment_test.go index 7d4fba302..22a987290 100644 --- a/pkg/deploy/server/server_deployment_test.go +++ b/pkg/deploy/server/server_deployment_test.go @@ -287,95 +287,109 @@ func TestMountBitbucketOAuthEnvVar(t *testing.T) { } func TestMountGitHubOAuthEnvVar(t *testing.T) { - type testCase struct { - name string - initObjects []runtime.Object - expectedIdKeyPath string - expectedSecretKeyPath string - expectedOAuthEndpoint string - expectedDisableSubdomainIsolation string - expectedVolume corev1.Volume - expectedVolumeMount corev1.VolumeMount + secret1 := &corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + Kind: "Secret", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "github-oauth-config", + Namespace: "eclipse-che", + Labels: map[string]string{ + "app.kubernetes.io/part-of": "che.eclipse.org", + "app.kubernetes.io/component": "oauth-scm-configuration", + }, + Annotations: map[string]string{ + "che.eclipse.org/oauth-scm-server": "github", + "che.eclipse.org/scm-server-endpoint": "endpoint_1", + "che.eclipse.org/scm-github-disable-subdomain-isolation": "true", + }, + }, + Data: map[string][]byte{ + "id": []byte("some_id_1"), + "secret": []byte("some_secret_1"), + }, } - testCases := []testCase{ - { - name: "Test", - initObjects: []runtime.Object{ - &corev1.Secret{ - TypeMeta: metav1.TypeMeta{ - Kind: "Secret", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "github-oauth-config", - Namespace: "eclipse-che", - Labels: map[string]string{ - "app.kubernetes.io/part-of": "che.eclipse.org", - "app.kubernetes.io/component": "oauth-scm-configuration", - }, - Annotations: map[string]string{ - "che.eclipse.org/oauth-scm-server": "github", - "che.eclipse.org/scm-server-endpoint": "endpoint_1", - "che.eclipse.org/scm-github-disable-subdomain-isolation": "true", - }, - }, - Data: map[string][]byte{ - "id": []byte("some_id"), - "secret": []byte("some_secret"), - }, - }, - }, - expectedIdKeyPath: "/che-conf/oauth/github/id", - expectedSecretKeyPath: "/che-conf/oauth/github/secret", - expectedOAuthEndpoint: "endpoint_1", - expectedDisableSubdomainIsolation: "true", - expectedVolume: corev1.Volume{ - Name: "github-oauth-config", - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: "github-oauth-config", - }, - }, + secret2 := &corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + Kind: "Secret", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "github-oauth-config_2", + Namespace: "eclipse-che", + Labels: map[string]string{ + "app.kubernetes.io/part-of": "che.eclipse.org", + "app.kubernetes.io/component": "oauth-scm-configuration", }, - expectedVolumeMount: corev1.VolumeMount{ - Name: "github-oauth-config", - MountPath: "/che-conf/oauth/github", + Annotations: map[string]string{ + "che.eclipse.org/oauth-scm-server": "github", + "che.eclipse.org/scm-server-endpoint": "endpoint_2", + "che.eclipse.org/scm-github-disable-subdomain-isolation": "false", }, }, + Data: map[string][]byte{ + "id": []byte("some_id_2"), + "secret": []byte("some_secret_2"), + }, } - for _, testCase := range testCases { - t.Run(testCase.name, func(t *testing.T) { - ctx := test.GetDeployContext(nil, testCase.initObjects) + ctx := test.GetDeployContext(nil, []runtime.Object{secret1, secret2}) - server := NewCheServerReconciler() - deployment, err := server.getDeploymentSpec(ctx) - assert.Nil(t, err, "Unexpected error %v", err) + server := NewCheServerReconciler() + deployment, err := server.getDeploymentSpec(ctx) + assert.Nil(t, err, "Unexpected error %v", err) - container := &deployment.Spec.Template.Spec.Containers[0] + container := &deployment.Spec.Template.Spec.Containers[0] - value := utils.GetEnvByName("CHE_OAUTH2_GITHUB_CLIENTID__FILEPATH", container.Env) - assert.Equal(t, testCase.expectedIdKeyPath, value) + assert.Equal(t, "/che-conf/oauth/github/id", utils.GetEnvByName("CHE_OAUTH2_GITHUB_CLIENTID__FILEPATH", container.Env)) + assert.Equal(t, "/che-conf/oauth/github__2/id", utils.GetEnvByName("CHE_OAUTH2_GITHUB_CLIENTID__FILEPATH__2", container.Env)) - value = utils.GetEnvByName("CHE_OAUTH2_GITHUB_CLIENTSECRET__FILEPATH", container.Env) - assert.Equal(t, testCase.expectedSecretKeyPath, value) + assert.Equal(t, "/che-conf/oauth/github/secret", utils.GetEnvByName("CHE_OAUTH2_GITHUB_CLIENTSECRET__FILEPATH", container.Env)) + assert.Equal(t, "/che-conf/oauth/github__2/secret", utils.GetEnvByName("CHE_OAUTH2_GITHUB_CLIENTSECRET__FILEPATH__2", container.Env)) - value = utils.GetEnvByName("CHE_INTEGRATION_GITHUB_OAUTH__ENDPOINT", container.Env) - assert.Equal(t, testCase.expectedOAuthEndpoint, value) + assert.Equal(t, "endpoint_1", utils.GetEnvByName("CHE_INTEGRATION_GITHUB_OAUTH__ENDPOINT", container.Env)) + assert.Equal(t, "endpoint_2", utils.GetEnvByName("CHE_INTEGRATION_GITHUB_OAUTH__ENDPOINT__2", container.Env)) - value = utils.GetEnvByName("CHE_INTEGRATION_GITHUB_DISABLE__SUBDOMAIN__ISOLATION", container.Env) - assert.Equal(t, testCase.expectedDisableSubdomainIsolation, value) + assert.Equal(t, "true", utils.GetEnvByName("CHE_INTEGRATION_GITHUB_DISABLE__SUBDOMAIN__ISOLATION", container.Env)) + assert.Equal(t, "false", utils.GetEnvByName("CHE_INTEGRATION_GITHUB_DISABLE__SUBDOMAIN__ISOLATION__2", container.Env)) - volume := test.FindVolume(deployment.Spec.Template.Spec.Volumes, "github-oauth-config") - assert.NotNil(t, volume) - assert.Equal(t, testCase.expectedVolume, volume) + assert.Equal(t, + corev1.Volume{ + Name: "github-oauth-config", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: "github-oauth-config", + }, + }, + }, + test.FindVolume(deployment.Spec.Template.Spec.Volumes, "github-oauth-config")) + + assert.Equal(t, + corev1.Volume{ + Name: "github-oauth-config_2", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: "github-oauth-config_2", + }, + }, + }, + test.FindVolume(deployment.Spec.Template.Spec.Volumes, "github-oauth-config_2")) - volumeMount := test.FindVolumeMount(container.VolumeMounts, "github-oauth-config") - assert.NotNil(t, volumeMount) - assert.Equal(t, testCase.expectedVolumeMount, volumeMount) - }) - } + assert.Equal(t, + corev1.VolumeMount{ + Name: "github-oauth-config", + MountPath: "/che-conf/oauth/github", + }, + test.FindVolumeMount(container.VolumeMounts, "github-oauth-config")) + + assert.Equal(t, + corev1.VolumeMount{ + Name: "github-oauth-config_2", + MountPath: "/che-conf/oauth/github__2", + }, + test.FindVolumeMount(container.VolumeMounts, "github-oauth-config_2")) } func TestMountAzureDevOpsOAuthEnvVar(t *testing.T) { diff --git a/pkg/deploy/server/server_util.go b/pkg/deploy/server/server_util.go index 89f770d1c..206d32b4f 100644 --- a/pkg/deploy/server/server_util.go +++ b/pkg/deploy/server/server_util.go @@ -26,20 +26,22 @@ func getComponentName(ctx *chetypes.DeployContext) string { } func getOAuthConfig(ctx *chetypes.DeployContext, oauthProvider string) (*corev1.Secret, error) { - secrets, err := deploy.GetSecrets(ctx, map[string]string{ - constants.KubernetesPartOfLabelKey: constants.CheEclipseOrg, - constants.KubernetesComponentLabelKey: constants.OAuthScmConfiguration, - }, map[string]string{ - constants.CheEclipseOrgOAuthScmServer: oauthProvider, - }) - - if err != nil { + if secrets, err := getAllGitProviderOAuthConfigs(ctx, oauthProvider); err != nil { return nil, err } else if len(secrets) == 0 { return nil, nil - } else if len(secrets) > 1 { + } else if len(secrets) == 1 { + return &secrets[0], nil + } else { return nil, fmt.Errorf("More than 1 OAuth %s configuration secrets found", oauthProvider) } +} - return &secrets[0], nil +func getAllGitProviderOAuthConfigs(ctx *chetypes.DeployContext, oauthProvider string) ([]corev1.Secret, error) { + return deploy.GetSecrets(ctx, map[string]string{ + constants.KubernetesPartOfLabelKey: constants.CheEclipseOrg, + constants.KubernetesComponentLabelKey: constants.OAuthScmConfiguration, + }, map[string]string{ + constants.CheEclipseOrgOAuthScmServer: oauthProvider, + }) } From 86d17e088356734218c4cb3d1432563d182d4562 Mon Sep 17 00:00:00 2001 From: Anatolii Bazko Date: Fri, 27 Oct 2023 16:25:06 +0200 Subject: [PATCH 2/2] fix Signed-off-by: Anatolii Bazko --- pkg/common/constants/constants.go | 1 + pkg/deploy/server/server_deployment.go | 8 +++++++- pkg/deploy/server/server_util.go | 22 ++++++++++------------ 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/pkg/common/constants/constants.go b/pkg/common/constants/constants.go index f3964f5c5..cbe603dc7 100644 --- a/pkg/common/constants/constants.go +++ b/pkg/common/constants/constants.go @@ -66,6 +66,7 @@ const ( BitBucketOAuthConfigMountPath = "/che-conf/oauth/bitbucket" BitBucketOAuthConfigPrivateKeyFileName = "private.key" BitBucketOAuthConfigConsumerKeyFileName = "consumer.key" + GitHubOAuth = "github" GitHubOAuthConfigMountPath = "/che-conf/oauth/github" GitHubOAuthConfigClientIdFileName = "id" GitHubOAuthConfigClientSecretFileName = "secret" diff --git a/pkg/deploy/server/server_deployment.go b/pkg/deploy/server/server_deployment.go index e81e5ce16..21bacc2b4 100644 --- a/pkg/deploy/server/server_deployment.go +++ b/pkg/deploy/server/server_deployment.go @@ -268,7 +268,13 @@ func MountBitBucketOAuthConfig(ctx *chetypes.DeployContext, deployment *appsv1.D } func MountGitHubOAuthConfig(ctx *chetypes.DeployContext, deployment *appsv1.Deployment) error { - secrets, err := getAllGitProviderOAuthConfigs(ctx, "github") + secrets, err := deploy.GetSecrets(ctx, map[string]string{ + constants.KubernetesPartOfLabelKey: constants.CheEclipseOrg, + constants.KubernetesComponentLabelKey: constants.OAuthScmConfiguration, + }, map[string]string{ + constants.CheEclipseOrgOAuthScmServer: constants.GitHubOAuth, + }) + if err != nil { return err } diff --git a/pkg/deploy/server/server_util.go b/pkg/deploy/server/server_util.go index 206d32b4f..89f770d1c 100644 --- a/pkg/deploy/server/server_util.go +++ b/pkg/deploy/server/server_util.go @@ -26,22 +26,20 @@ func getComponentName(ctx *chetypes.DeployContext) string { } func getOAuthConfig(ctx *chetypes.DeployContext, oauthProvider string) (*corev1.Secret, error) { - if secrets, err := getAllGitProviderOAuthConfigs(ctx, oauthProvider); err != nil { + secrets, err := deploy.GetSecrets(ctx, map[string]string{ + constants.KubernetesPartOfLabelKey: constants.CheEclipseOrg, + constants.KubernetesComponentLabelKey: constants.OAuthScmConfiguration, + }, map[string]string{ + constants.CheEclipseOrgOAuthScmServer: oauthProvider, + }) + + if err != nil { return nil, err } else if len(secrets) == 0 { return nil, nil - } else if len(secrets) == 1 { - return &secrets[0], nil - } else { + } else if len(secrets) > 1 { return nil, fmt.Errorf("More than 1 OAuth %s configuration secrets found", oauthProvider) } -} -func getAllGitProviderOAuthConfigs(ctx *chetypes.DeployContext, oauthProvider string) ([]corev1.Secret, error) { - return deploy.GetSecrets(ctx, map[string]string{ - constants.KubernetesPartOfLabelKey: constants.CheEclipseOrg, - constants.KubernetesComponentLabelKey: constants.OAuthScmConfiguration, - }, map[string]string{ - constants.CheEclipseOrgOAuthScmServer: oauthProvider, - }) + return &secrets[0], nil }