diff --git a/e2e/config.go b/e2e/config.go index 61626bc9b0..96b5f137cc 100644 --- a/e2e/config.go +++ b/e2e/config.go @@ -135,7 +135,7 @@ func newOAuthConfig(c *rest.Config) (*OauthClient, error) { return &OauthClient{restClient: client}, nil } -func addKnownTypes(scheme *runtime.Scheme) (error) { +func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &orgv1.CheCluster{}, &orgv1.CheClusterList{}, diff --git a/e2e/delete.go b/e2e/delete.go index 8baa3c390d..97bdf8e9a5 100644 --- a/e2e/delete.go +++ b/e2e/delete.go @@ -13,7 +13,6 @@ package main import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - ) func deleteNamespace() (err error) { diff --git a/e2e/deserialize.go b/e2e/deserialize.go index c8274272c6..91ba65830c 100644 --- a/e2e/deserialize.go +++ b/e2e/deserialize.go @@ -121,7 +121,6 @@ func deserializeOperatorRoleBinding() (operatorServiceAccountRoleBinding *rbac.R return operatorServiceAccountRoleBinding, nil } - func deserializeOperatorClusterRoleBinding() (operatorServiceAccountClusterRoleBinding *rbac.ClusterRoleBinding, err error) { fileLocation, err := filepath.Abs("deploy/cluster_role_binding.yaml") if err != nil { @@ -140,4 +139,4 @@ func deserializeOperatorClusterRoleBinding() (operatorServiceAccountClusterRoleB } operatorServiceAccountClusterRoleBinding = object.(*rbac.ClusterRoleBinding) return operatorServiceAccountClusterRoleBinding, nil -} \ No newline at end of file +} diff --git a/e2e/get.go b/e2e/get.go index 016a466e9d..9d59206143 100644 --- a/e2e/get.go +++ b/e2e/get.go @@ -17,16 +17,16 @@ import ( "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -func getOauthClient(name string)(oAuthClient *oauth.OAuthClient, err error) { + +func getOauthClient(name string) (oAuthClient *oauth.OAuthClient, err error) { oAuthClient = &oauth.OAuthClient{} err = oauthClientSet.restClient.Get().Name(name).Resource("oauthclients").Do().Into(oAuthClient) if err != nil && errors.IsNotFound(err) { return nil, err } - return oAuthClient,nil + return oAuthClient, nil } - func getConfigMap(cmName string) (cm *corev1.ConfigMap, err error) { cm, err = client.clientset.CoreV1().ConfigMaps(namespace).Get(cmName, metav1.GetOptions{}) @@ -35,4 +35,4 @@ func getConfigMap(cmName string) (cm *corev1.ConfigMap, err error) { } return cm, nil -} \ No newline at end of file +} diff --git a/e2e/patch.go b/e2e/patch.go index a359da1948..d45061bd9e 100644 --- a/e2e/patch.go +++ b/e2e/patch.go @@ -20,9 +20,9 @@ import ( func patchCustomResource(path string, value bool) (err error) { type PatchSpec struct { - Operation string `json:"op"` - Path string `json:"path"` - Value bool `json:"value"` + Operation string `json:"op"` + Path string `json:"path"` + Value bool `json:"value"` } fields := make([]PatchSpec, 1) @@ -42,4 +42,4 @@ func patchCustomResource(path string, value bool) (err error) { } return nil -} \ No newline at end of file +} diff --git a/e2e/watch.go b/e2e/watch.go index 219f76043f..911d1420e4 100644 --- a/e2e/watch.go +++ b/e2e/watch.go @@ -34,5 +34,3 @@ func VerifyCheRunning(status string) (deployed bool, err error) { } } } - - diff --git a/pkg/controller/che/che_controller.go b/pkg/controller/che/che_controller.go index 28e31461a3..991112054e 100644 --- a/pkg/controller/che/che_controller.go +++ b/pkg/controller/che/che_controller.go @@ -14,6 +14,12 @@ package che import ( "context" "fmt" + "github.com/eclipse/che-operator/pkg/deploy/devfile-registry" + "github.com/eclipse/che-operator/pkg/deploy/gateway" + "github.com/eclipse/che-operator/pkg/deploy/identity-provider" + "github.com/eclipse/che-operator/pkg/deploy/plugin-registry" + "github.com/eclipse/che-operator/pkg/deploy/postgres" + "github.com/eclipse/che-operator/pkg/deploy/server" "strconv" "time" @@ -615,11 +621,11 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e externalDB := instance.Spec.Database.ExternalDb if !externalDB { if cheMultiUser == "false" { - if util.K8sclient.IsDeploymentExists(deploy.PostgresDeploymentName, instance.Namespace) { - util.K8sclient.DeleteDeployment(deploy.PostgresDeploymentName, instance.Namespace) + if util.K8sclient.IsDeploymentExists(postgres.PostgresDeploymentName, instance.Namespace) { + util.K8sclient.DeleteDeployment(postgres.PostgresDeploymentName, instance.Namespace) } } else { - postgresLabels := deploy.GetLabels(instance, deploy.PostgresDeploymentName) + postgresLabels := deploy.GetLabels(instance, postgres.PostgresDeploymentName) // Create a new postgres service serviceStatus := deploy.SyncServiceToCluster(deployContext, "postgres", []string{"postgres"}, []int32{5432}, postgresLabels) @@ -648,10 +654,10 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e } // Create a new Postgres deployment - deploymentStatus := deploy.SyncPostgresDeploymentToCluster(deployContext) + deploymentStatus := postgres.SyncPostgresDeploymentToCluster(deployContext) if !tests { if !deploymentStatus.Continue { - logrus.Infof("Waiting on deployment '%s' to be ready", deploy.PostgresDeploymentName) + logrus.Infof("Waiting on deployment '%s' to be ready", postgres.PostgresDeploymentName) if deploymentStatus.Err != nil { logrus.Error(deploymentStatus.Err) } @@ -671,11 +677,11 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e } identityProviderPostgresPassword = password } - pgCommand := deploy.GetPostgresProvisionCommand(identityProviderPostgresPassword) + pgCommand := identity_provider.GetPostgresProvisionCommand(identityProviderPostgresPassword) dbStatus := instance.Status.DbProvisoned // provision Db and users for Che and Keycloak servers if !dbStatus { - podToExec, err := util.K8sclient.GetDeploymentPod(deploy.PostgresDeploymentName, instance.Namespace) + podToExec, err := util.K8sclient.GetDeploymentPod(postgres.PostgresDeploymentName, instance.Namespace) if err != nil { return reconcile.Result{}, err } @@ -705,7 +711,7 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e } // create Che service and route - serviceStatus := deploy.SyncCheServiceToCluster(deployContext) + serviceStatus := server.SyncCheServiceToCluster(deployContext) if !tests { if !serviceStatus.Continue { logrus.Infof("Waiting on service '%s' to be ready", deploy.CheServiceName) @@ -766,7 +772,7 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e } // create and provision Keycloak related objects - provisioned, err := deploy.SyncIdentityProviderToCluster(deployContext, cheHost, protocol, cheFlavor) + provisioned, err := identity_provider.SyncIdentityProviderToCluster(deployContext, cheHost, protocol, cheFlavor) if !tests { if !provisioned { if err != nil { @@ -776,7 +782,7 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e } } - provisioned, err = deploy.SyncDevfileRegistryToCluster(deployContext, cheHost) + provisioned, err = devfile_registry.SyncDevfileRegistryToCluster(deployContext, cheHost) if !tests { if !provisioned { if err != nil { @@ -786,7 +792,7 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e } } - provisioned, err = deploy.SyncPluginRegistryToCluster(deployContext, cheHost) + provisioned, err = plugin_registry.SyncPluginRegistryToCluster(deployContext, cheHost) if !tests { if !provisioned { if err != nil { @@ -805,10 +811,10 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e // create Che ConfigMap which is synced with CR and is not supposed to be manually edited // controller will reconcile this CM with CR spec - cheConfigMap, err := deploy.SyncCheConfigMapToCluster(deployContext) + cheConfigMap, err := server.SyncCheConfigMapToCluster(deployContext) if !tests { if cheConfigMap == nil { - logrus.Infof("Waiting on config map '%s' to be created", deploy.CheConfigMapName) + logrus.Infof("Waiting on config map '%s' to be created", server.CheConfigMapName) if err != nil { logrus.Error(err) } @@ -820,19 +826,19 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e // which will automatically trigger Che rolling update var cmResourceVersion string if tests { - cmResourceVersion = r.GetEffectiveConfigMap(instance, deploy.CheConfigMapName).ResourceVersion + cmResourceVersion = r.GetEffectiveConfigMap(instance, server.CheConfigMapName).ResourceVersion } else { cmResourceVersion = cheConfigMap.ResourceVersion } - err = deploy.SyncGatewayToCluster(deployContext) + err = gateway.SyncGatewayToCluster(deployContext) if err != nil { logrus.Errorf("Failed to create the Server Gateway: %s", err) return reconcile.Result{}, err } // Create a new che deployment - deploymentStatus := deploy.SyncCheDeploymentToCluster(deployContext, cmResourceVersion) + deploymentStatus := server.SyncCheDeploymentToCluster(deployContext, cmResourceVersion) if !tests { if !deploymentStatus.Continue { logrus.Infof("Waiting on deployment '%s' to be ready", cheFlavor) @@ -1007,7 +1013,7 @@ func getDefaultCheHost(deployContext *deploy.DeployContext) (string, error) { func getServerExposingServiceName(cr *orgv1.CheCluster) string { if cr.Spec.Server.ServerExposureStrategy == "single-host" && deploy.GetSingleHostExposureType(cr) == "gateway" { - return deploy.GatewayServiceName + return gateway.GatewayServiceName } return deploy.CheServiceName } diff --git a/pkg/controller/che/che_controller_test.go b/pkg/controller/che/che_controller_test.go index 83ac6dd99c..91d7986397 100644 --- a/pkg/controller/che/che_controller_test.go +++ b/pkg/controller/che/che_controller_test.go @@ -13,6 +13,7 @@ package che import ( "context" + identity_provider "github.com/eclipse/che-operator/pkg/deploy/identity-provider" "io/ioutil" "os" "time" @@ -189,7 +190,7 @@ func TestCheController(t *testing.T) { if err = r.client.Get(context.TODO(), types.NamespacedName{Name: cheCR.Name, Namespace: cheCR.Namespace}, cheCR); err != nil { t.Errorf("Failed to get the Che custom resource %s: %s", cheCR.Name, err) } - if err = deploy.CreateIdentityProviderItems(deployContext, "che"); err != nil { + if err = identity_provider.CreateIdentityProviderItems(deployContext, "che"); err != nil { t.Errorf("Failed to create the items for the identity provider: %s", err) } oAuthClientName := cheCR.Spec.Auth.OAuthClientName diff --git a/pkg/controller/che/proxy.go b/pkg/controller/che/proxy.go index 42aede2bf2..6c89e0152d 100644 --- a/pkg/controller/che/proxy.go +++ b/pkg/controller/che/proxy.go @@ -13,6 +13,7 @@ package che import ( "context" + "github.com/eclipse/che-operator/pkg/deploy/server" orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" "github.com/eclipse/che-operator/pkg/deploy" @@ -55,6 +56,6 @@ func (r *ReconcileChe) putOpenShiftCertsIntoConfigMap(deployContext *deploy.Depl } } - certConfigMap, err := deploy.SyncTrustStoreConfigMapToCluster(deployContext) + certConfigMap, err := server.SyncTrustStoreConfigMapToCluster(deployContext) return certConfigMap != nil, err } diff --git a/pkg/controller/che/update.go b/pkg/controller/che/update.go index 54a9f61477..2d131b5628 100644 --- a/pkg/controller/che/update.go +++ b/pkg/controller/che/update.go @@ -13,9 +13,9 @@ package che import ( "context" + identity_provider "github.com/eclipse/che-operator/pkg/deploy/identity-provider" orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" - "github.com/eclipse/che-operator/pkg/deploy" "github.com/eclipse/che-operator/pkg/util" oauth "github.com/openshift/api/oauth/v1" "github.com/sirupsen/logrus" @@ -51,7 +51,7 @@ func (r *ReconcileChe) ReconcileIdentityProvider(instance *orgv1.CheCluster, isO if err := r.client.Get(context.TODO(), types.NamespacedName{Name: "keycloak", Namespace: instance.Namespace}, keycloakDeployment); err != nil { logrus.Errorf("Deployment %s not found: %s", keycloakDeployment.Name, err) } - deleteOpenShiftIdentityProviderProvisionCommand := deploy.GetDeleteOpenShiftIdentityProviderProvisionCommand(instance, isOpenShift4) + deleteOpenShiftIdentityProviderProvisionCommand := identity_provider.GetDeleteOpenShiftIdentityProviderProvisionCommand(instance, isOpenShift4) podToExec, err := util.K8sclient.GetDeploymentPod(keycloakDeployment.Name, instance.Namespace) if err != nil { logrus.Errorf("Failed to retrieve pod name. Further exec will fail") diff --git a/pkg/deploy/update.go b/pkg/deploy/checluster.go similarity index 100% rename from pkg/deploy/update.go rename to pkg/deploy/checluster.go diff --git a/pkg/deploy/configmap.go b/pkg/deploy/configmap.go index 9e28cb5703..ab71f0fbfa 100644 --- a/pkg/deploy/configmap.go +++ b/pkg/deploy/configmap.go @@ -27,7 +27,7 @@ import ( ) func SyncConfigMapToCluster(deployContext *DeployContext, specConfigMap *corev1.ConfigMap) (*corev1.ConfigMap, error) { - clusterConfigMap, err := getClusterConfigMap(specConfigMap.Name, specConfigMap.Namespace, deployContext.ClusterAPI.Client) + clusterConfigMap, err := GetClusterConfigMap(specConfigMap.Name, specConfigMap.Namespace, deployContext.ClusterAPI.Client) if err != nil { return nil, err } @@ -79,7 +79,7 @@ func GetSpecConfigMap( return configMap, nil } -func getClusterConfigMap(name string, namespace string, client runtimeClient.Client) (*corev1.ConfigMap, error) { +func GetClusterConfigMap(name string, namespace string, client runtimeClient.Client) (*corev1.ConfigMap, error) { configMap := &corev1.ConfigMap{} namespacedName := types.NamespacedName{ Namespace: namespace, diff --git a/pkg/deploy/const.go b/pkg/deploy/const.go new file mode 100644 index 0000000000..27b0262b49 --- /dev/null +++ b/pkg/deploy/const.go @@ -0,0 +1,9 @@ +package deploy + +const ( + DevfileRegistry = "devfile-registry" +) + +const ( + PluginRegistry = "plugin-registry" +) diff --git a/pkg/deploy/data_types.go b/pkg/deploy/data_types.go index 1a04762ef4..be3449d662 100644 --- a/pkg/deploy/data_types.go +++ b/pkg/deploy/data_types.go @@ -25,9 +25,9 @@ type ProvisioningStatus struct { } type DeployContext struct { - CheCluster *orgv1.CheCluster - ClusterAPI ClusterAPI - Proxy *Proxy + CheCluster *orgv1.CheCluster + ClusterAPI ClusterAPI + Proxy *Proxy DefaultCheHost string } diff --git a/pkg/deploy/defaults.go b/pkg/deploy/defaults.go index fd58f7ceef..bdc92689ab 100644 --- a/pkg/deploy/defaults.go +++ b/pkg/deploy/defaults.go @@ -14,12 +14,14 @@ package deploy import ( "fmt" + "gopkg.in/yaml.v2" "io/ioutil" "os" "strings" - util "github.com/eclipse/che-operator/pkg/util" + "github.com/eclipse/che-operator/pkg/util" "github.com/sirupsen/logrus" + appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/apps/v1" "k8s.io/client-go/kubernetes/scheme" @@ -105,30 +107,6 @@ func InitDefaults(defaultsPath string) { } } -func InitDefaultsFromEnv() { - defaultCheVersion = getDefaultFromEnv("CHE_VERSION") - defaultCheServerImage = getDefaultFromEnv(util.GetArchitectureDependentEnv("RELATED_IMAGE_che_server")) - defaultPluginRegistryImage = getDefaultFromEnv(util.GetArchitectureDependentEnv("RELATED_IMAGE_plugin_registry")) - defaultDevfileRegistryImage = getDefaultFromEnv(util.GetArchitectureDependentEnv("RELATED_IMAGE_devfile_registry")) - defaultPvcJobsImage = getDefaultFromEnv(util.GetArchitectureDependentEnv("RELATED_IMAGE_pvc_jobs")) - defaultPostgresImage = getDefaultFromEnv(util.GetArchitectureDependentEnv("RELATED_IMAGE_postgres")) - defaultKeycloakImage = getDefaultFromEnv(util.GetArchitectureDependentEnv("RELATED_IMAGE_keycloak")) - defaultSingleHostGatewayImage = getDefaultFromEnv(util.GetArchitectureDependentEnv("RELATED_IMAGE_single_host_gateway")) - defaultSingleHostGatewayConfigSidecarImage = getDefaultFromEnv(util.GetArchitectureDependentEnv("RELATED_IMAGE_single_host_gateway_config_sidecar")) - - // CRW images for that are mentioned in the Che server che.properties - // For CRW these should be synced by hand with images stored in RH registries - // instead of being synced by script with the content of the upstream `che.properties` file - defaultCheWorkspacePluginBrokerMetadataImage = getDefaultFromEnv(util.GetArchitectureDependentEnv("RELATED_IMAGE_che_workspace_plugin_broker_metadata")) - defaultCheWorkspacePluginBrokerArtifactsImage = getDefaultFromEnv(util.GetArchitectureDependentEnv("RELATED_IMAGE_che_workspace_plugin_broker_artifacts")) - defaultCheServerSecureExposerJwtProxyImage = getDefaultFromEnv(util.GetArchitectureDependentEnv("RELATED_IMAGE_che_server_secure_exposer_jwt_proxy_image")) - - // Don't get some k8s specific env - if !util.IsOpenShift { - defaultCheTLSSecretsCreationJobImage = getDefaultFromEnv(util.GetArchitectureDependentEnv("RELATED_IMAGE_che_tls_secrets_creation_job")) - } -} - func InitDefaultsFromFile(defaultsPath string) { operatorDeployment := getDefaultsFromFile(defaultsPath) @@ -364,3 +342,50 @@ func getOrganizationFromImage(image string) string { } return organization } + +func InitDefaultsFromEnv() { + defaultCheVersion = getDefaultFromEnv("CHE_VERSION") + defaultCheServerImage = getDefaultFromEnv(util.GetArchitectureDependentEnv("RELATED_IMAGE_che_server")) + defaultPluginRegistryImage = getDefaultFromEnv(util.GetArchitectureDependentEnv("RELATED_IMAGE_plugin_registry")) + defaultDevfileRegistryImage = getDefaultFromEnv(util.GetArchitectureDependentEnv("RELATED_IMAGE_devfile_registry")) + defaultPvcJobsImage = getDefaultFromEnv(util.GetArchitectureDependentEnv("RELATED_IMAGE_pvc_jobs")) + defaultPostgresImage = getDefaultFromEnv(util.GetArchitectureDependentEnv("RELATED_IMAGE_postgres")) + defaultKeycloakImage = getDefaultFromEnv(util.GetArchitectureDependentEnv("RELATED_IMAGE_keycloak")) + defaultSingleHostGatewayImage = getDefaultFromEnv(util.GetArchitectureDependentEnv("RELATED_IMAGE_single_host_gateway")) + defaultSingleHostGatewayConfigSidecarImage = getDefaultFromEnv(util.GetArchitectureDependentEnv("RELATED_IMAGE_single_host_gateway_config_sidecar")) + + // CRW images for that are mentioned in the Che server che.properties + // For CRW these should be synced by hand with images stored in RH registries + // instead of being synced by script with the content of the upstream `che.properties` file + defaultCheWorkspacePluginBrokerMetadataImage = getDefaultFromEnv(util.GetArchitectureDependentEnv("RELATED_IMAGE_che_workspace_plugin_broker_metadata")) + defaultCheWorkspacePluginBrokerArtifactsImage = getDefaultFromEnv(util.GetArchitectureDependentEnv("RELATED_IMAGE_che_workspace_plugin_broker_artifacts")) + defaultCheServerSecureExposerJwtProxyImage = getDefaultFromEnv(util.GetArchitectureDependentEnv("RELATED_IMAGE_che_server_secure_exposer_jwt_proxy_image")) + + // Don't get some k8s specific env + if !util.IsOpenShift { + defaultCheTLSSecretsCreationJobImage = getDefaultFromEnv(util.GetArchitectureDependentEnv("RELATED_IMAGE_che_tls_secrets_creation_job")) + } +} + +func InitTestDefaultsFromDeployment(deploymentFile string) error { + operator := &appsv1.Deployment{} + data, err := ioutil.ReadFile(deploymentFile) + if err != nil { + return err + } + + err = yaml.Unmarshal(data, operator) + if err != nil { + return err + } + + for _, env := range operator.Spec.Template.Spec.Containers[0].Env { + err = os.Setenv(env.Name, env.Value) + if err != nil { + return err + } + } + + InitDefaultsFromEnv() + return nil +} diff --git a/pkg/deploy/defaults_test.go b/pkg/deploy/defaults_test.go index 2db6df3abe..bab27a0670 100644 --- a/pkg/deploy/defaults_test.go +++ b/pkg/deploy/defaults_test.go @@ -13,68 +13,29 @@ package deploy import ( "fmt" - "io/ioutil" "os" "testing" + "github.com/eclipse/che-operator/pkg/util" + orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" - util "github.com/eclipse/che-operator/pkg/util" - "gopkg.in/yaml.v2" - appsv1 "k8s.io/api/apps/v1" ) -var ( - cheVersionTest string - cheServerImageTest string - pluginRegistryImageTest string - devfileRegistryImageTest string - pvcJobsImageTest string - postgresImageTest string - keycloakImageTest string - brokerMetadataTest string - brokerArtifactsTest string - jwtProxyTest string - tlsJobImageTest string -) +func TestDefaultFromEnv(t *testing.T) { -func init() { - operator := &appsv1.Deployment{} - data, err := ioutil.ReadFile("../../deploy/operator.yaml") - yaml.Unmarshal(data, operator) - if err == nil { - for _, env := range operator.Spec.Template.Spec.Containers[0].Env { - os.Setenv(env.Name, env.Value) - switch env.Name { - case "CHE_VERSION": - cheVersionTest = env.Value - case util.GetArchitectureDependentEnv("RELATED_IMAGE_che_server"): - cheServerImageTest = env.Value - case util.GetArchitectureDependentEnv("RELATED_IMAGE_plugin_registry"): - pluginRegistryImageTest = env.Value - case util.GetArchitectureDependentEnv("RELATED_IMAGE_devfile_registry"): - devfileRegistryImageTest = env.Value - case util.GetArchitectureDependentEnv("RELATED_IMAGE_che_tls_secrets_creation_job"): - tlsJobImageTest = env.Value - case util.GetArchitectureDependentEnv("RELATED_IMAGE_pvc_jobs"): - pvcJobsImageTest = env.Value - case util.GetArchitectureDependentEnv("RELATED_IMAGE_postgres"): - postgresImageTest = env.Value - case util.GetArchitectureDependentEnv("RELATED_IMAGE_keycloak"): - keycloakImageTest = env.Value - case util.GetArchitectureDependentEnv("RELATED_IMAGE_che_workspace_plugin_broker_metadata"): - brokerMetadataTest = env.Value - case util.GetArchitectureDependentEnv("RELATED_IMAGE_che_workspace_plugin_broker_artifacts"): - brokerArtifactsTest = env.Value - case util.GetArchitectureDependentEnv("RELATED_IMAGE_che_server_secure_exposer_jwt_proxy_image"): - jwtProxyTest = env.Value - } - } - } + cheVersionTest := os.Getenv("CHE_VERSION") - InitDefaultsFromEnv() -} + cheServerImageTest := os.Getenv(util.GetArchitectureDependentEnv("RELATED_IMAGE_che_server")) + + pluginRegistryImageTest := os.Getenv(util.GetArchitectureDependentEnv("RELATED_IMAGE_plugin_registry")) + devfileRegistryImageTest := os.Getenv(util.GetArchitectureDependentEnv("RELATED_IMAGE_devfile_registry")) + pvcJobsImageTest := os.Getenv(util.GetArchitectureDependentEnv("RELATED_IMAGE_pvc_jobs")) + postgresImageTest := os.Getenv(util.GetArchitectureDependentEnv("RELATED_IMAGE_postgres")) + keycloakImageTest := os.Getenv(util.GetArchitectureDependentEnv("RELATED_IMAGE_keycloak")) + brokerMetadataTest := os.Getenv(util.GetArchitectureDependentEnv("RELATED_IMAGE_che_workspace_plugin_broker_metadata")) + brokerArtifactsTest := os.Getenv(util.GetArchitectureDependentEnv("RELATED_IMAGE_che_workspace_plugin_broker_artifacts")) + jwtProxyTest := os.Getenv(util.GetArchitectureDependentEnv("RELATED_IMAGE_che_server_secure_exposer_jwt_proxy_image")) -func TestDefaultFromEnv(t *testing.T) { if DefaultCheVersion() != cheVersionTest { t.Errorf("Expected %s but was %s", cheVersionTest, DefaultCheVersion()) } diff --git a/pkg/deploy/deployment.go b/pkg/deploy/deployment.go index 36d27b2546..5eb8472cb3 100644 --- a/pkg/deploy/deployment.go +++ b/pkg/deploy/deployment.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2012-2019 Red Hat, Inc. +// Copyright (c) 2012-2020 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -26,7 +26,7 @@ import ( runtimeClient "sigs.k8s.io/controller-runtime/pkg/client" ) -var deploymentDiffOpts = cmp.Options{ +var DeploymentDiffOpts = cmp.Options{ cmpopts.IgnoreFields(appsv1.Deployment{}, "TypeMeta", "ObjectMeta", "Status"), cmpopts.IgnoreFields(appsv1.DeploymentSpec{}, "Replicas", "RevisionHistoryLimit", "ProgressDeadlineSeconds"), cmpopts.IgnoreFields(appsv1.DeploymentStrategy{}, "RollingUpdate"), @@ -51,7 +51,7 @@ func SyncDeploymentToCluster( additionalDeploymentDiffOpts cmp.Options, additionalDeploymentMerge func(*appsv1.Deployment, *appsv1.Deployment) *appsv1.Deployment) DeploymentProvisioningStatus { - clusterDeployment, err := getClusterDeployment(specDeployment.Name, specDeployment.Namespace, deployContext.ClusterAPI.Client) + clusterDeployment, err := GetClusterDeployment(specDeployment.Name, specDeployment.Namespace, deployContext.ClusterAPI.Client) if err != nil { return DeploymentProvisioningStatus{ ProvisioningStatus: ProvisioningStatus{Err: err}, @@ -82,7 +82,7 @@ func SyncDeploymentToCluster( } } - diff := cmp.Diff(clusterDeployment, specDeployment, deploymentDiffOpts) + diff := cmp.Diff(clusterDeployment, specDeployment, DeploymentDiffOpts) if len(diff) > 0 { logrus.Infof("Updating existed object: %s, name: %s", specDeployment.Kind, specDeployment.Name) fmt.Printf("Difference:\n%s", diff) @@ -103,7 +103,7 @@ func SyncDeploymentToCluster( } } -func getClusterDeployment(name string, namespace string, client runtimeClient.Client) (*appsv1.Deployment, error) { +func GetClusterDeployment(name string, namespace string, client runtimeClient.Client) (*appsv1.Deployment, error) { deployment := &appsv1.Deployment{} namespacedName := types.NamespacedName{ Namespace: namespace, diff --git a/pkg/deploy/deployment_registry.go b/pkg/deploy/deployment_registry.go deleted file mode 100644 index c81af2bfe7..0000000000 --- a/pkg/deploy/deployment_registry.go +++ /dev/null @@ -1,219 +0,0 @@ -// -// Copyright (c) 2012-2019 Red Hat, Inc. -// This program and the accompanying materials are made -// available under the terms of the Eclipse Public License 2.0 -// which is available at https://www.eclipse.org/legal/epl-2.0/ -// -// SPDX-License-Identifier: EPL-2.0 -// -// Contributors: -// Red Hat, Inc. - initial API and implementation -// -package deploy - -import ( - "github.com/eclipse/che-operator/pkg/util" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" -) - -func SyncPluginRegistryDeploymentToCluster(deployContext *DeployContext) DeploymentProvisioningStatus { - registryType := "plugin" - registryImage := util.GetValue(deployContext.CheCluster.Spec.Server.PluginRegistryImage, DefaultPluginRegistryImage(deployContext.CheCluster)) - registryImagePullPolicy := corev1.PullPolicy(util.GetValue(string(deployContext.CheCluster.Spec.Server.PluginRegistryPullPolicy), DefaultPullPolicyFromDockerImage(registryImage))) - registryMemoryLimit := util.GetValue(string(deployContext.CheCluster.Spec.Server.PluginRegistryMemoryLimit), DefaultPluginRegistryMemoryLimit) - registryMemoryRequest := util.GetValue(string(deployContext.CheCluster.Spec.Server.PluginRegistryMemoryRequest), DefaultPluginRegistryMemoryRequest) - probePath := "/v3/plugins/" - pluginImagesEnv := util.GetEnvByRegExp("^.*plugin_registry_image.*$") - - clusterDeployment, err := getClusterDeployment(PluginRegistry, deployContext.CheCluster.Namespace, deployContext.ClusterAPI.Client) - if err != nil { - return DeploymentProvisioningStatus{ - ProvisioningStatus: ProvisioningStatus{Err: err}, - } - } - - specDeployment, err := getSpecRegistryDeployment( - deployContext, - registryType, - registryImage, - pluginImagesEnv, - registryImagePullPolicy, - registryMemoryLimit, - registryMemoryRequest, - probePath) - - if err != nil { - return DeploymentProvisioningStatus{ - ProvisioningStatus: ProvisioningStatus{Err: err}, - } - } - - return SyncDeploymentToCluster(deployContext, specDeployment, clusterDeployment, nil, nil) -} - -func SyncDevfileRegistryDeploymentToCluster(deployContext *DeployContext) DeploymentProvisioningStatus { - registryType := "devfile" - registryImage := util.GetValue(deployContext.CheCluster.Spec.Server.DevfileRegistryImage, DefaultDevfileRegistryImage(deployContext.CheCluster)) - registryImagePullPolicy := corev1.PullPolicy(util.GetValue(string(deployContext.CheCluster.Spec.Server.PluginRegistryPullPolicy), DefaultPullPolicyFromDockerImage(registryImage))) - registryMemoryLimit := util.GetValue(string(deployContext.CheCluster.Spec.Server.DevfileRegistryMemoryLimit), DefaultDevfileRegistryMemoryLimit) - registryMemoryRequest := util.GetValue(string(deployContext.CheCluster.Spec.Server.DevfileRegistryMemoryRequest), DefaultDevfileRegistryMemoryRequest) - probePath := "/devfiles/" - devfileImagesEnv := util.GetEnvByRegExp("^.*devfile_registry_image.*$") - - clusterDeployment, err := getClusterDeployment(DevfileRegistry, deployContext.CheCluster.Namespace, deployContext.ClusterAPI.Client) - if err != nil { - return DeploymentProvisioningStatus{ - ProvisioningStatus: ProvisioningStatus{Err: err}, - } - } - - specDeployment, err := getSpecRegistryDeployment( - deployContext, - registryType, - registryImage, - devfileImagesEnv, - registryImagePullPolicy, - registryMemoryLimit, - registryMemoryRequest, - probePath) - - if err != nil { - return DeploymentProvisioningStatus{ - ProvisioningStatus: ProvisioningStatus{Err: err}, - } - } - - return SyncDeploymentToCluster(deployContext, specDeployment, clusterDeployment, nil, nil) -} - -func getSpecRegistryDeployment( - deployContext *DeployContext, - registryType string, - registryImage string, - env []corev1.EnvVar, - registryImagePullPolicy corev1.PullPolicy, - registryMemoryLimit string, - registryMemoryRequest string, - probePath string) (*appsv1.Deployment, error) { - - terminationGracePeriodSeconds := int64(30) - name := registryType + "-registry" - labels := GetLabels(deployContext.CheCluster, name) - _25Percent := intstr.FromString("25%") - _1 := int32(1) - _2 := int32(2) - isOptional := true - deployment := &appsv1.Deployment{ - TypeMeta: metav1.TypeMeta{ - Kind: "Deployment", - APIVersion: "apps/v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: deployContext.CheCluster.Namespace, - Labels: labels, - }, - Spec: appsv1.DeploymentSpec{ - Replicas: &_1, - RevisionHistoryLimit: &_2, - Selector: &metav1.LabelSelector{MatchLabels: labels}, - Strategy: appsv1.DeploymentStrategy{ - Type: appsv1.RollingUpdateDeploymentStrategyType, - RollingUpdate: &appsv1.RollingUpdateDeployment{ - MaxSurge: &_25Percent, - MaxUnavailable: &_25Percent, - }, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: labels, - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "che-" + name, - Image: registryImage, - ImagePullPolicy: registryImagePullPolicy, - Ports: []corev1.ContainerPort{ - { - Name: "http", - ContainerPort: 8080, - Protocol: "TCP", - }, - }, - Env: env, - EnvFrom: []corev1.EnvFromSource{ - { - ConfigMapRef: &corev1.ConfigMapEnvSource{ - Optional: &isOptional, - LocalObjectReference: corev1.LocalObjectReference{ - Name: registryType + "-registry", - }, - }, - }, - }, - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceMemory: resource.MustParse(registryMemoryRequest), - }, - Limits: corev1.ResourceList{ - corev1.ResourceMemory: resource.MustParse(registryMemoryLimit), - }, - }, - ReadinessProbe: &corev1.Probe{ - Handler: corev1.Handler{ - HTTPGet: &corev1.HTTPGetAction{ - Path: "/" + registryType + "s/", - Port: intstr.IntOrString{ - Type: intstr.Int, - IntVal: int32(8080), - }, - Scheme: corev1.URISchemeHTTP, - }, - }, - InitialDelaySeconds: 3, - FailureThreshold: 10, - TimeoutSeconds: 3, - PeriodSeconds: 10, - SuccessThreshold: 1, - }, - LivenessProbe: &corev1.Probe{ - Handler: corev1.Handler{ - HTTPGet: &corev1.HTTPGetAction{ - Path: "/" + registryType + "s/", - Port: intstr.IntOrString{ - Type: intstr.Int, - IntVal: int32(8080), - }, - Scheme: corev1.URISchemeHTTP, - }, - }, - InitialDelaySeconds: 30, - FailureThreshold: 10, - TimeoutSeconds: 3, - SuccessThreshold: 1, - PeriodSeconds: 10, - }, - }, - }, - RestartPolicy: "Always", - TerminationGracePeriodSeconds: &terminationGracePeriodSeconds, - }, - }, - }, - } - - if !util.IsTestMode() { - err := controllerutil.SetControllerReference(deployContext.CheCluster, deployment, deployContext.ClusterAPI.Scheme) - if err != nil { - return nil, err - } - } - - return deployment, nil -} diff --git a/pkg/deploy/devfile-registry/deployment.go b/pkg/deploy/devfile-registry/deployment.go new file mode 100644 index 0000000000..d0669261dd --- /dev/null +++ b/pkg/deploy/devfile-registry/deployment.go @@ -0,0 +1,54 @@ +// +// Copyright (c) 2020-2020 Red Hat, Inc. +// This program and the accompanying materials are made +// available under the terms of the Eclipse Public License 2.0 +// which is available at https://www.eclipse.org/legal/epl-2.0/ +// +// SPDX-License-Identifier: EPL-2.0 +// +// Contributors: +// Red Hat, Inc. - initial API and implementation +// +package devfile_registry + +import ( + "github.com/eclipse/che-operator/pkg/deploy" + "github.com/eclipse/che-operator/pkg/deploy/registry" + "github.com/eclipse/che-operator/pkg/util" + v1 "k8s.io/api/core/v1" +) + +func SyncDevfileRegistryDeploymentToCluster(deployContext *deploy.DeployContext) deploy.DeploymentProvisioningStatus { + registryType := "devfile" + registryImage := util.GetValue(deployContext.CheCluster.Spec.Server.DevfileRegistryImage, deploy.DefaultDevfileRegistryImage(deployContext.CheCluster)) + registryImagePullPolicy := v1.PullPolicy(util.GetValue(string(deployContext.CheCluster.Spec.Server.PluginRegistryPullPolicy), deploy.DefaultPullPolicyFromDockerImage(registryImage))) + registryMemoryLimit := util.GetValue(string(deployContext.CheCluster.Spec.Server.DevfileRegistryMemoryLimit), deploy.DefaultDevfileRegistryMemoryLimit) + registryMemoryRequest := util.GetValue(string(deployContext.CheCluster.Spec.Server.DevfileRegistryMemoryRequest), deploy.DefaultDevfileRegistryMemoryRequest) + probePath := "/devfiles/" + devfileImagesEnv := util.GetEnvByRegExp("^.*devfile_registry_image.*$") + + clusterDeployment, err := deploy.GetClusterDeployment(deploy.DevfileRegistry, deployContext.CheCluster.Namespace, deployContext.ClusterAPI.Client) + if err != nil { + return deploy.DeploymentProvisioningStatus{ + ProvisioningStatus: deploy.ProvisioningStatus{Err: err}, + } + } + + specDeployment, err := registry.GetSpecRegistryDeployment( + deployContext, + registryType, + registryImage, + devfileImagesEnv, + registryImagePullPolicy, + registryMemoryLimit, + registryMemoryRequest, + probePath) + + if err != nil { + return deploy.DeploymentProvisioningStatus{ + ProvisioningStatus: deploy.ProvisioningStatus{Err: err}, + } + } + + return deploy.SyncDeploymentToCluster(deployContext, specDeployment, clusterDeployment, nil, nil) +} diff --git a/pkg/deploy/devfile-registry/devfile_registry.go b/pkg/deploy/devfile-registry/devfile_registry.go new file mode 100644 index 0000000000..ea06f928b0 --- /dev/null +++ b/pkg/deploy/devfile-registry/devfile_registry.go @@ -0,0 +1,118 @@ +// +// Copyright (c) 2012-2020 Red Hat, Inc. +// This program and the accompanying materials are made +// available under the terms of the Eclipse Public License 2.0 +// which is available at https://www.eclipse.org/legal/epl-2.0/ +// +// SPDX-License-Identifier: EPL-2.0 +// +// Contributors: +// Red Hat, Inc. - initial API and implementation +// +package devfile_registry + +import ( + "encoding/json" + "fmt" + + orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" + "github.com/eclipse/che-operator/pkg/deploy" + "github.com/eclipse/che-operator/pkg/deploy/expose" + "github.com/eclipse/che-operator/pkg/util" + "github.com/sirupsen/logrus" +) + +type DevFileRegistryConfigMap struct { + CheDevfileImagesRegistryURL string `json:"CHE_DEVFILE_IMAGES_REGISTRY_URL"` + CheDevfileImagesRegistryOrganization string `json:"CHE_DEVFILE_IMAGES_REGISTRY_ORGANIZATION"` + CheDevfileRegistryURL string `json:"CHE_DEVFILE_REGISTRY_URL"` +} + +/** + * Create devfile registry resources unless an external registry is used. + */ +func SyncDevfileRegistryToCluster(deployContext *deploy.DeployContext, cheHost string) (bool, error) { + devfileRegistryURL := deployContext.CheCluster.Spec.Server.DevfileRegistryUrl + if !deployContext.CheCluster.Spec.Server.ExternalDevfileRegistry { + additionalLabels := (map[bool]string{true: deployContext.CheCluster.Spec.Server.DevfileRegistryRoute.Labels, false: deployContext.CheCluster.Spec.Server.DevfileRegistryIngress.Labels})[util.IsOpenShift] + endpoint, done, err := expose.Expose(deployContext, cheHost, deploy.DevfileRegistry, additionalLabels) + if !done { + return false, err + } + + if devfileRegistryURL == "" { + if deployContext.CheCluster.Spec.Server.TlsSupport { + devfileRegistryURL = "https://" + endpoint + } else { + devfileRegistryURL = "http://" + endpoint + } + } + + configMapData := getDevfileRegistryConfigMapData(deployContext.CheCluster, devfileRegistryURL) + configMapSpec, err := deploy.GetSpecConfigMap(deployContext, deploy.DevfileRegistry, configMapData) + if err != nil { + return false, err + } + + configMap, err := deploy.SyncConfigMapToCluster(deployContext, configMapSpec) + if configMap == nil { + return false, err + } + + // Create a new registry service + registryLabels := deploy.GetLabels(deployContext.CheCluster, deploy.DevfileRegistry) + serviceStatus := deploy.SyncServiceToCluster(deployContext, deploy.DevfileRegistry, []string{"http"}, []int32{8080}, registryLabels) + if !util.IsTestMode() { + if !serviceStatus.Continue { + logrus.Info("Waiting on service '" + deploy.DevfileRegistry + "' to be ready") + if serviceStatus.Err != nil { + logrus.Error(serviceStatus.Err) + } + + return false, serviceStatus.Err + } + } + + // Deploy devfile registry + deploymentStatus := SyncDevfileRegistryDeploymentToCluster(deployContext) + if !util.IsTestMode() { + if !deploymentStatus.Continue { + logrus.Info("Waiting on deployment '" + deploy.DevfileRegistry + "' to be ready") + if deploymentStatus.Err != nil { + logrus.Error(deploymentStatus.Err) + } + + return false, deploymentStatus.Err + } + } + } + + if devfileRegistryURL != deployContext.CheCluster.Status.DevfileRegistryURL { + deployContext.CheCluster.Status.DevfileRegistryURL = devfileRegistryURL + if err := deploy.UpdateCheCRStatus(deployContext, "status: Devfile Registry URL", devfileRegistryURL); err != nil { + return false, err + } + } + + return true, nil +} + +func getDevfileRegistryConfigMapData(cr *orgv1.CheCluster, endpoint string) map[string]string { + devfileRegistryEnv := make(map[string]string) + data := &DevFileRegistryConfigMap{ + CheDevfileImagesRegistryURL: cr.Spec.Server.AirGapContainerRegistryHostname, + CheDevfileImagesRegistryOrganization: cr.Spec.Server.AirGapContainerRegistryOrganization, + CheDevfileRegistryURL: endpoint, + } + + out, err := json.Marshal(data) + if err != nil { + fmt.Println(err) + } + + err = json.Unmarshal(out, &devfileRegistryEnv) + if err != nil { + fmt.Println(err) + } + return devfileRegistryEnv +} diff --git a/pkg/deploy/devfile_registry.go b/pkg/deploy/devfile_registry.go deleted file mode 100644 index a5ddbef57b..0000000000 --- a/pkg/deploy/devfile_registry.go +++ /dev/null @@ -1,198 +0,0 @@ -// -// Copyright (c) 2012-2019 Red Hat, Inc. -// This program and the accompanying materials are made -// available under the terms of the Eclipse Public License 2.0 -// which is available at https://www.eclipse.org/legal/epl-2.0/ -// -// SPDX-License-Identifier: EPL-2.0 -// -// Contributors: -// Red Hat, Inc. - initial API and implementation -// -package deploy - -import ( - "encoding/json" - "fmt" - - orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" - "github.com/eclipse/che-operator/pkg/util" - "github.com/sirupsen/logrus" -) - -type DevFileRegistryConfigMap struct { - CheDevfileImagesRegistryURL string `json:"CHE_DEVFILE_IMAGES_REGISTRY_URL"` - CheDevfileImagesRegistryOrganization string `json:"CHE_DEVFILE_IMAGES_REGISTRY_ORGANIZATION"` - CheDevfileRegistryURL string `json:"CHE_DEVFILE_REGISTRY_URL"` -} - -const ( - DevfileRegistry = "devfile-registry" - devfileRegistryGatewayConfig = "che-gateway-route-devfile-registry" -) - -/** - * Create devfile registry resources unless an external registry is used. - */ -func SyncDevfileRegistryToCluster(deployContext *DeployContext, cheHost string) (bool, error) { - devfileRegistryURL := deployContext.CheCluster.Spec.Server.DevfileRegistryUrl - if !deployContext.CheCluster.Spec.Server.ExternalDevfileRegistry { - var endpoint string - var domain string - exposureStrategy := util.GetServerExposureStrategy(deployContext.CheCluster, DefaultServerExposureStrategy) - singleHostExposureType := GetSingleHostExposureType(deployContext.CheCluster) - useGateway := exposureStrategy == "single-host" && (util.IsOpenShift || singleHostExposureType == "gateway") - if exposureStrategy == "multi-host" { - // this won't get used on openshift, because there we're intentionally let Openshift decide on the domain name - domain = DevfileRegistry + "-" + deployContext.CheCluster.Namespace + "." + deployContext.CheCluster.Spec.K8s.IngressDomain - endpoint = domain - } else { - domain = cheHost - endpoint = domain + "/" + DevfileRegistry - } - if !util.IsOpenShift { - - if useGateway { - cfg := GetGatewayRouteConfig(deployContext, devfileRegistryGatewayConfig, "/"+DevfileRegistry, 10, "http://"+DevfileRegistry+":8080", true) - clusterCfg, err := SyncConfigMapToCluster(deployContext, &cfg) - if !util.IsTestMode() { - if clusterCfg == nil { - if err != nil { - logrus.Error(err) - } - return false, err - } - } - if err := DeleteIngressIfExists(DevfileRegistry, deployContext); !util.IsTestMode() && err != nil { - logrus.Error(err) - } - } else { - additionalLabels := deployContext.CheCluster.Spec.Server.DevfileRegistryIngress.Labels - ingress, err := SyncIngressToCluster(deployContext, DevfileRegistry, domain, DevfileRegistry, 8080, additionalLabels) - if !util.IsTestMode() { - if ingress == nil { - logrus.Infof("Waiting on ingress '%s' to be ready", DevfileRegistry) - if err != nil { - logrus.Error(err) - } - return false, err - } - } - if err := DeleteGatewayRouteConfig(devfileRegistryGatewayConfig, deployContext); !util.IsTestMode() && err != nil { - logrus.Error(err) - } - } - } else { - if useGateway { - cfg := GetGatewayRouteConfig(deployContext, devfileRegistryGatewayConfig, "/"+DevfileRegistry, 10, "http://"+DevfileRegistry+":8080", true) - clusterCfg, err := SyncConfigMapToCluster(deployContext, &cfg) - if !util.IsTestMode() { - if clusterCfg == nil { - if err != nil { - logrus.Error(err) - } - return false, err - } - } - if err := DeleteRouteIfExists(DevfileRegistry, deployContext); !util.IsTestMode() && err != nil { - logrus.Error(err) - } - } else { - // the empty string for a host is intentional here - we let OpenShift decide on the hostname - additionalLabels := deployContext.CheCluster.Spec.Server.DevfileRegistryRoute.Labels - route, err := SyncRouteToCluster(deployContext, DevfileRegistry, "", DevfileRegistry, 8080, additionalLabels) - if !util.IsTestMode() { - if route == nil { - logrus.Infof("Waiting on route '%s' to be ready", DevfileRegistry) - if err != nil { - logrus.Error(err) - } - - return false, err - } - } - if err := DeleteGatewayRouteConfig(devfileRegistryGatewayConfig, deployContext); !util.IsTestMode() && err != nil { - logrus.Error(err) - } - if !util.IsTestMode() { - endpoint = route.Spec.Host - } - } - } - - if devfileRegistryURL == "" { - if deployContext.CheCluster.Spec.Server.TlsSupport { - devfileRegistryURL = "https://" + endpoint - } else { - devfileRegistryURL = "http://" + endpoint - } - } - - configMapData := getDevfileRegistryConfigMapData(deployContext.CheCluster, devfileRegistryURL) - configMapSpec, err := GetSpecConfigMap(deployContext, DevfileRegistry, configMapData) - if err != nil { - return false, err - } - - configMap, err := SyncConfigMapToCluster(deployContext, configMapSpec) - if configMap == nil { - return false, err - } - - // Create a new registry service - registryLabels := GetLabels(deployContext.CheCluster, DevfileRegistry) - serviceStatus := SyncServiceToCluster(deployContext, DevfileRegistry, []string{"http"}, []int32{8080}, registryLabels) - if !util.IsTestMode() { - if !serviceStatus.Continue { - logrus.Info("Waiting on service '" + DevfileRegistry + "' to be ready") - if serviceStatus.Err != nil { - logrus.Error(serviceStatus.Err) - } - - return false, serviceStatus.Err - } - } - - // Deploy devfile registry - deploymentStatus := SyncDevfileRegistryDeploymentToCluster(deployContext) - if !util.IsTestMode() { - if !deploymentStatus.Continue { - logrus.Info("Waiting on deployment '" + DevfileRegistry + "' to be ready") - if deploymentStatus.Err != nil { - logrus.Error(deploymentStatus.Err) - } - - return false, deploymentStatus.Err - } - } - } - - if devfileRegistryURL != deployContext.CheCluster.Status.DevfileRegistryURL { - deployContext.CheCluster.Status.DevfileRegistryURL = devfileRegistryURL - if err := UpdateCheCRStatus(deployContext, "status: Devfile Registry URL", devfileRegistryURL); err != nil { - return false, err - } - } - - return true, nil -} - -func getDevfileRegistryConfigMapData(cr *orgv1.CheCluster, endpoint string) map[string]string { - devfileRegistryEnv := make(map[string]string) - data := &DevFileRegistryConfigMap{ - CheDevfileImagesRegistryURL: cr.Spec.Server.AirGapContainerRegistryHostname, - CheDevfileImagesRegistryOrganization: cr.Spec.Server.AirGapContainerRegistryOrganization, - CheDevfileRegistryURL: endpoint, - } - - out, err := json.Marshal(data) - if err != nil { - fmt.Println(err) - } - - err = json.Unmarshal(out, &devfileRegistryEnv) - if err != nil { - fmt.Println(err) - } - return devfileRegistryEnv -} diff --git a/pkg/deploy/expose/expose.go b/pkg/deploy/expose/expose.go new file mode 100644 index 0000000000..7c5bae938c --- /dev/null +++ b/pkg/deploy/expose/expose.go @@ -0,0 +1,120 @@ +// +// Copyright (c) 2020-2020 Red Hat, Inc. +// This program and the accompanying materials are made +// available under the terms of the Eclipse Public License 2.0 +// which is available at https://www.eclipse.org/legal/epl-2.0/ +// +// SPDX-License-Identifier: EPL-2.0 +// +// Contributors: +// Red Hat, Inc. - initial API and implementation +// +package expose + +import ( + "github.com/eclipse/che-operator/pkg/deploy" + "github.com/eclipse/che-operator/pkg/deploy/gateway" + "github.com/eclipse/che-operator/pkg/util" + "github.com/sirupsen/logrus" +) + +func Expose(deployContext *deploy.DeployContext, cheHost string, endpointName string, additionalLabels string) (endpont string, done bool, err error) { + exposureStrategy := util.GetServerExposureStrategy(deployContext.CheCluster, deploy.DefaultServerExposureStrategy) + var domain string + var endpoint string + var pathPrefix string + var stripPrefix bool + + if endpointName == "keycloak" { + pathPrefix = "auth" + stripPrefix = false + } else { + pathPrefix = endpointName + stripPrefix = true + } + if exposureStrategy == "multi-host" { + // this won't get used on openshift, because there we're intentionally let Openshift decide on the domain name + domain = endpointName + "-" + deployContext.CheCluster.Namespace + "." + deployContext.CheCluster.Spec.K8s.IngressDomain + endpoint = domain + } else { + domain = cheHost + if endpointName == "keycloak" { + // legacy + endpoint = domain + } else { + endpoint = domain + "/" + pathPrefix + } + } + + gatewayConfig := "che-gateway-route-" + endpointName + singleHostExposureType := deploy.GetSingleHostExposureType(deployContext.CheCluster) + useGateway := exposureStrategy == "single-host" && (util.IsOpenShift || singleHostExposureType == "gateway") + + if !util.IsOpenShift { + if useGateway { + cfg := gateway.GetGatewayRouteConfig(deployContext, gatewayConfig, "/"+pathPrefix, 10, "http://"+endpointName+":8080", stripPrefix) + clusterCfg, err := deploy.SyncConfigMapToCluster(deployContext, &cfg) + if !util.IsTestMode() { + if clusterCfg == nil { + if err != nil { + logrus.Error(err) + } + return "", false, err + } + } + if err := deploy.DeleteIngressIfExists(endpointName, deployContext); !util.IsTestMode() && err != nil { + logrus.Error(err) + } + } else { + ingress, err := deploy.SyncIngressToCluster(deployContext, endpointName, domain, endpointName, 8080, additionalLabels) + if !util.IsTestMode() { + if ingress == nil { + logrus.Infof("Waiting on ingress '%s' to be ready", endpointName) + if err != nil { + logrus.Error(err) + } + return "", false, err + } + } + if err := gateway.DeleteGatewayRouteConfig(gatewayConfig, deployContext); !util.IsTestMode() && err != nil { + logrus.Error(err) + } + } + } else { + if useGateway { + cfg := gateway.GetGatewayRouteConfig(deployContext, gatewayConfig, "/"+pathPrefix, 10, "http://"+endpointName+":8080", stripPrefix) + clusterCfg, err := deploy.SyncConfigMapToCluster(deployContext, &cfg) + if !util.IsTestMode() { + if clusterCfg == nil { + if err != nil { + logrus.Error(err) + } + return "", false, err + } + } + if err := deploy.DeleteRouteIfExists(endpointName, deployContext); !util.IsTestMode() && err != nil { + logrus.Error(err) + } + } else { + // the empty string for a host is intentional here - we let OpenShift decide on the hostname + route, err := deploy.SyncRouteToCluster(deployContext, endpointName, "", endpointName, 8080, additionalLabels) + if !util.IsTestMode() { + if route == nil { + logrus.Infof("Waiting on route '%s' to be ready", endpointName) + if err != nil { + logrus.Error(err) + } + + return "", false, err + } + } + if err := gateway.DeleteGatewayRouteConfig(gatewayConfig, deployContext); !util.IsTestMode() && err != nil { + logrus.Error(err) + } + if !util.IsTestMode() { + endpoint = route.Spec.Host + } + } + } + return endpoint, true, nil +} diff --git a/pkg/deploy/gateway.go b/pkg/deploy/gateway/gateway.go similarity index 86% rename from pkg/deploy/gateway.go rename to pkg/deploy/gateway/gateway.go index 60c1c2b33d..e68621c99d 100644 --- a/pkg/deploy/gateway.go +++ b/pkg/deploy/gateway/gateway.go @@ -1,10 +1,23 @@ -package deploy +// +// Copyright (c) 2020-2020 Red Hat, Inc. +// This program and the accompanying materials are made +// available under the terms of the Eclipse Public License 2.0 +// which is available at https://www.eclipse.org/legal/epl-2.0/ +// +// SPDX-License-Identifier: EPL-2.0 +// +// Contributors: +// Red Hat, Inc. - initial API and implementation +// +package gateway import ( "context" "fmt" "strconv" + "github.com/eclipse/che-operator/pkg/deploy" + orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" "github.com/eclipse/che-operator/pkg/util" "github.com/google/go-cmp/cmp" @@ -42,16 +55,16 @@ var ( ) // SyncGatewayToCluster installs or deletes the gateway based on the custom resource configuration -func SyncGatewayToCluster(deployContext *DeployContext) error { +func SyncGatewayToCluster(deployContext *deploy.DeployContext) error { if deployContext.CheCluster.Spec.Server.ServerExposureStrategy == "single-host" && - (GetSingleHostExposureType(deployContext.CheCluster) == "gateway") { + (deploy.GetSingleHostExposureType(deployContext.CheCluster) == "gateway") { return syncAll(deployContext) } return deleteAll(deployContext) } -func syncAll(deployContext *DeployContext) error { +func syncAll(deployContext *deploy.DeployContext) error { instance := deployContext.CheCluster sa := getGatewayServiceAccountSpec(instance) if err := sync(deployContext, &sa, serviceAccountDiffOpts); err != nil { @@ -74,7 +87,7 @@ func syncAll(deployContext *DeployContext) error { } depl := getGatewayDeploymentSpec(instance) - if err := sync(deployContext, &depl, deploymentDiffOpts); err != nil { + if err := sync(deployContext, &depl, deploy.DeploymentDiffOpts); err != nil { return err } @@ -91,7 +104,7 @@ func syncAll(deployContext *DeployContext) error { return nil } -func deleteAll(deployContext *DeployContext) error { +func deleteAll(deployContext *deploy.DeployContext) error { instance := deployContext.CheCluster clusterAPI := deployContext.ClusterAPI @@ -159,7 +172,7 @@ func deleteAll(deployContext *DeployContext) error { } // sync syncs the blueprint to the cluster in a generic (as much as Go allows) manner. -func sync(deployContext *DeployContext, blueprint metav1.Object, diffOpts cmp.Option) error { +func sync(deployContext *deploy.DeployContext, blueprint metav1.Object, diffOpts cmp.Option) error { clusterAPI := deployContext.ClusterAPI blueprintObject, ok := blueprint.(runtime.Object) @@ -246,7 +259,7 @@ func isUpdateUsingDeleteCreate(kind string) bool { return "Service" == kind || "Ingress" == kind || "Route" == kind } -func setOwnerReferenceAndConvertToRuntime(deployContext *DeployContext, obj metav1.Object) (runtime.Object, error) { +func setOwnerReferenceAndConvertToRuntime(deployContext *deploy.DeployContext, obj metav1.Object) (runtime.Object, error) { err := controllerutil.SetControllerReference(deployContext.CheCluster, obj, deployContext.ClusterAPI.Scheme) if err != nil { return nil, err @@ -260,7 +273,7 @@ func setOwnerReferenceAndConvertToRuntime(deployContext *DeployContext, obj meta return robj, nil } -func delete(clusterAPI ClusterAPI, obj metav1.Object) error { +func delete(clusterAPI deploy.ClusterAPI, obj metav1.Object) error { key := client.ObjectKey{Name: obj.GetName(), Namespace: obj.GetNamespace()} ro := obj.(runtime.Object) if getErr := clusterAPI.Client.Get(context.TODO(), key, ro); getErr == nil { @@ -277,7 +290,7 @@ func delete(clusterAPI ClusterAPI, obj metav1.Object) error { // GetGatewayRouteConfig creates a config map with traefik configuration for a single new route. // `serviceName` is an arbitrary name identifying the configuration. This should be unique within operator. Che server only creates // new configuration for workspaces, so the name should not resemble any of the names created by the Che server. -func GetGatewayRouteConfig(deployContext *DeployContext, serviceName string, pathPrefix string, priority int, internalUrl string, stripPrefix bool) corev1.ConfigMap { +func GetGatewayRouteConfig(deployContext *deploy.DeployContext, serviceName string, pathPrefix string, priority int, internalUrl string, stripPrefix bool) corev1.ConfigMap { pathRewrite := pathPrefix != "/" && stripPrefix data := `--- @@ -319,8 +332,8 @@ http: Name: serviceName, Namespace: deployContext.CheCluster.Namespace, Labels: util.MergeMaps( - GetLabels(deployContext.CheCluster, gatewayConfigComponentName), - util.GetMapValue(deployContext.CheCluster.Spec.Server.SingleHostGatewayConfigMapLabels, DefaultSingleHostGatewayConfigMapLabels)), + deploy.GetLabels(deployContext.CheCluster, gatewayConfigComponentName), + util.GetMapValue(deployContext.CheCluster.Spec.Server.SingleHostGatewayConfigMapLabels, deploy.DefaultSingleHostGatewayConfigMapLabels)), }, Data: map[string]string{ serviceName + ".yml": data, @@ -332,7 +345,7 @@ http: return ret } -func DeleteGatewayRouteConfig(serviceName string, deployContext *DeployContext) error { +func DeleteGatewayRouteConfig(serviceName string, deployContext *deploy.DeployContext) error { obj := &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: serviceName, @@ -345,8 +358,8 @@ func DeleteGatewayRouteConfig(serviceName string, deployContext *DeployContext) // below functions declare the desired states of the various objects required for the gateway -func getGatewayServerConfigSpec(deployContext *DeployContext) corev1.ConfigMap { - return GetGatewayRouteConfig(deployContext, gatewayServerConfigName, "/", 1, "http://"+CheServiceName+":8080", false) +func getGatewayServerConfigSpec(deployContext *deploy.DeployContext) corev1.ConfigMap { + return GetGatewayRouteConfig(deployContext, gatewayServerConfigName, "/", 1, "http://"+deploy.CheServiceName+":8080", false) } func getGatewayServiceAccountSpec(instance *orgv1.CheCluster) corev1.ServiceAccount { @@ -358,7 +371,7 @@ func getGatewayServiceAccountSpec(instance *orgv1.CheCluster) corev1.ServiceAcco ObjectMeta: metav1.ObjectMeta{ Name: GatewayServiceName, Namespace: instance.Namespace, - Labels: GetLabels(instance, GatewayServiceName), + Labels: deploy.GetLabels(instance, GatewayServiceName), }, } } @@ -372,7 +385,7 @@ func getGatewayRoleSpec(instance *orgv1.CheCluster) rbac.Role { ObjectMeta: metav1.ObjectMeta{ Name: GatewayServiceName, Namespace: instance.Namespace, - Labels: GetLabels(instance, GatewayServiceName), + Labels: deploy.GetLabels(instance, GatewayServiceName), }, Rules: []rbac.PolicyRule{ { @@ -393,7 +406,7 @@ func getGatewayRoleBindingSpec(instance *orgv1.CheCluster) rbac.RoleBinding { ObjectMeta: metav1.ObjectMeta{ Name: GatewayServiceName, Namespace: instance.Namespace, - Labels: GetLabels(instance, GatewayServiceName), + Labels: deploy.GetLabels(instance, GatewayServiceName), }, RoleRef: rbac.RoleRef{ APIGroup: "rbac.authorization.k8s.io", @@ -418,7 +431,7 @@ func getGatewayTraefikConfigSpec(instance *orgv1.CheCluster) corev1.ConfigMap { ObjectMeta: metav1.ObjectMeta{ Name: "che-gateway-config", Namespace: instance.Namespace, - Labels: GetLabels(instance, GatewayServiceName), + Labels: deploy.GetLabels(instance, GatewayServiceName), }, Data: map[string]string{ "traefik.yml": ` @@ -445,9 +458,9 @@ log: } func getGatewayDeploymentSpec(instance *orgv1.CheCluster) appsv1.Deployment { - gatewayImage := util.GetValue(instance.Spec.Server.SingleHostGatewayImage, DefaultSingleHostGatewayImage(instance)) - sidecarImage := util.GetValue(instance.Spec.Server.SingleHostGatewayConfigSidecarImage, DefaultSingleHostGatewayConfigSidecarImage(instance)) - configLabelsMap := util.GetMapValue(instance.Spec.Server.SingleHostGatewayConfigMapLabels, DefaultSingleHostGatewayConfigMapLabels) + gatewayImage := util.GetValue(instance.Spec.Server.SingleHostGatewayImage, deploy.DefaultSingleHostGatewayImage(instance)) + sidecarImage := util.GetValue(instance.Spec.Server.SingleHostGatewayConfigSidecarImage, deploy.DefaultSingleHostGatewayConfigSidecarImage(instance)) + configLabelsMap := util.GetMapValue(instance.Spec.Server.SingleHostGatewayConfigMapLabels, deploy.DefaultSingleHostGatewayConfigMapLabels) terminationGracePeriodSeconds := int64(10) configLabels := labels.FormatLabels(configLabelsMap) @@ -460,18 +473,18 @@ func getGatewayDeploymentSpec(instance *orgv1.CheCluster) appsv1.Deployment { ObjectMeta: metav1.ObjectMeta{ Name: GatewayServiceName, Namespace: instance.Namespace, - Labels: GetLabels(instance, GatewayServiceName), + Labels: deploy.GetLabels(instance, GatewayServiceName), }, Spec: appsv1.DeploymentSpec{ Selector: &metav1.LabelSelector{ - MatchLabels: GetLabels(instance, GatewayServiceName), + MatchLabels: deploy.GetLabels(instance, GatewayServiceName), }, Strategy: appsv1.DeploymentStrategy{ Type: appsv1.RollingUpdateDeploymentStrategyType, }, Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ - Labels: GetLabels(instance, GatewayServiceName), + Labels: deploy.GetLabels(instance, GatewayServiceName), }, Spec: corev1.PodSpec{ TerminationGracePeriodSeconds: &terminationGracePeriodSeconds, @@ -557,10 +570,10 @@ func getGatewayServiceSpec(instance *orgv1.CheCluster) corev1.Service { ObjectMeta: metav1.ObjectMeta{ Name: GatewayServiceName, Namespace: instance.Namespace, - Labels: GetLabels(instance, GatewayServiceName), + Labels: deploy.GetLabels(instance, GatewayServiceName), }, Spec: corev1.ServiceSpec{ - Selector: GetLabels(instance, GatewayServiceName), + Selector: deploy.GetLabels(instance, GatewayServiceName), SessionAffinity: corev1.ServiceAffinityNone, Type: corev1.ServiceTypeClusterIP, Ports: []corev1.ServicePort{ diff --git a/pkg/deploy/deployment_keycloak.go b/pkg/deploy/identity-provider/deployment_keycloak.go similarity index 91% rename from pkg/deploy/deployment_keycloak.go rename to pkg/deploy/identity-provider/deployment_keycloak.go index ab1b93ad47..da9e11a09e 100644 --- a/pkg/deploy/deployment_keycloak.go +++ b/pkg/deploy/identity-provider/deployment_keycloak.go @@ -9,10 +9,12 @@ // Contributors: // Red Hat, Inc. - initial API and implementation // -package deploy +package identity_provider import ( "context" + "github.com/eclipse/che-operator/pkg/deploy" + "github.com/eclipse/che-operator/pkg/deploy/postgres" "regexp" "strconv" "strings" @@ -56,32 +58,32 @@ var ( } ) -func SyncKeycloakDeploymentToCluster(deployContext *DeployContext) DeploymentProvisioningStatus { - clusterDeployment, err := getClusterDeployment(KeycloakDeploymentName, deployContext.CheCluster.Namespace, deployContext.ClusterAPI.Client) +func SyncKeycloakDeploymentToCluster(deployContext *deploy.DeployContext) deploy.DeploymentProvisioningStatus { + clusterDeployment, err := deploy.GetClusterDeployment(KeycloakDeploymentName, deployContext.CheCluster.Namespace, deployContext.ClusterAPI.Client) if err != nil { - return DeploymentProvisioningStatus{ - ProvisioningStatus: ProvisioningStatus{Err: err}, + return deploy.DeploymentProvisioningStatus{ + ProvisioningStatus: deploy.ProvisioningStatus{Err: err}, } } specDeployment, err := getSpecKeycloakDeployment(deployContext, clusterDeployment) if err != nil { - return DeploymentProvisioningStatus{ - ProvisioningStatus: ProvisioningStatus{Err: err}, + return deploy.DeploymentProvisioningStatus{ + ProvisioningStatus: deploy.ProvisioningStatus{Err: err}, } } - return SyncDeploymentToCluster(deployContext, specDeployment, clusterDeployment, keycloakCustomDiffOpts, keycloakAdditionalDeploymentMerge) + return deploy.SyncDeploymentToCluster(deployContext, specDeployment, clusterDeployment, keycloakCustomDiffOpts, keycloakAdditionalDeploymentMerge) } func getSpecKeycloakDeployment( - deployContext *DeployContext, + deployContext *deploy.DeployContext, clusterDeployment *appsv1.Deployment) (*appsv1.Deployment, error) { optionalEnv := true - labels := GetLabels(deployContext.CheCluster, KeycloakDeploymentName) - cheFlavor := DefaultCheFlavor(deployContext.CheCluster) - keycloakImage := util.GetValue(deployContext.CheCluster.Spec.Auth.IdentityProviderImage, DefaultKeycloakImage(deployContext.CheCluster)) - pullPolicy := corev1.PullPolicy(util.GetValue(string(deployContext.CheCluster.Spec.Auth.IdentityProviderImagePullPolicy), DefaultPullPolicyFromDockerImage(keycloakImage))) + labels := deploy.GetLabels(deployContext.CheCluster, KeycloakDeploymentName) + cheFlavor := deploy.DefaultCheFlavor(deployContext.CheCluster) + keycloakImage := util.GetValue(deployContext.CheCluster.Spec.Auth.IdentityProviderImage, deploy.DefaultKeycloakImage(deployContext.CheCluster)) + pullPolicy := corev1.PullPolicy(util.GetValue(string(deployContext.CheCluster.Spec.Auth.IdentityProviderImagePullPolicy), deploy.DefaultPullPolicyFromDockerImage(keycloakImage))) jbossDir := "/opt/eap" if cheFlavor == "che" { // writable dir in the upstream Keycloak image @@ -229,19 +231,19 @@ func getSpecKeycloakDeployment( }, { Name: "POSTGRES_PORT_5432_TCP_ADDR", - Value: util.GetValue(deployContext.CheCluster.Spec.Database.ChePostgresHostName, DefaultChePostgresHostName), + Value: util.GetValue(deployContext.CheCluster.Spec.Database.ChePostgresHostName, deploy.DefaultChePostgresHostName), }, { Name: "POSTGRES_PORT_5432_TCP_PORT", - Value: util.GetValue(deployContext.CheCluster.Spec.Database.ChePostgresPort, DefaultChePostgresPort), + Value: util.GetValue(deployContext.CheCluster.Spec.Database.ChePostgresPort, deploy.DefaultChePostgresPort), }, { Name: "POSTGRES_PORT", - Value: util.GetValue(deployContext.CheCluster.Spec.Database.ChePostgresPort, DefaultChePostgresPort), + Value: util.GetValue(deployContext.CheCluster.Spec.Database.ChePostgresPort, deploy.DefaultChePostgresPort), }, { Name: "POSTGRES_ADDR", - Value: util.GetValue(deployContext.CheCluster.Spec.Database.ChePostgresHostName, DefaultChePostgresHostName), + Value: util.GetValue(deployContext.CheCluster.Spec.Database.ChePostgresHostName, deploy.DefaultChePostgresHostName), }, { Name: "POSTGRES_DATABASE", @@ -269,7 +271,7 @@ func getSpecKeycloakDeployment( SecretKeyRef: &corev1.SecretKeySelector{ Key: "ca.crt", LocalObjectReference: corev1.LocalObjectReference{ - Name: CheTLSSelfSignedCertificateSecretName, + Name: deploy.CheTLSSelfSignedCertificateSecretName, }, Optional: &optionalEnv, }, @@ -356,11 +358,11 @@ func getSpecKeycloakDeployment( }, { Name: "KEYCLOAK_POSTGRESQL_SERVICE_HOST", - Value: util.GetValue(deployContext.CheCluster.Spec.Database.ChePostgresHostName, DefaultChePostgresHostName), + Value: util.GetValue(deployContext.CheCluster.Spec.Database.ChePostgresHostName, deploy.DefaultChePostgresHostName), }, { Name: "KEYCLOAK_POSTGRESQL_SERVICE_PORT", - Value: util.GetValue(deployContext.CheCluster.Spec.Database.ChePostgresPort, DefaultChePostgresPort), + Value: util.GetValue(deployContext.CheCluster.Spec.Database.ChePostgresPort, deploy.DefaultChePostgresPort), }, { Name: "DB_DATABASE", @@ -392,7 +394,7 @@ func getSpecKeycloakDeployment( SecretKeyRef: &corev1.SecretKeySelector{ Key: "ca.crt", LocalObjectReference: corev1.LocalObjectReference{ - Name: CheTLSSelfSignedCertificateSecretName, + Name: deploy.CheTLSSelfSignedCertificateSecretName, }, Optional: &optionalEnv, }, @@ -587,7 +589,7 @@ func getSpecKeycloakDeployment( return deployment, nil } -func getSecretResourceVersion(name string, namespace string, clusterAPI ClusterAPI) string { +func getSecretResourceVersion(name string, namespace string, clusterAPI deploy.ClusterAPI) string { secret := &corev1.Secret{} err := clusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: namespace}, secret) if err != nil { @@ -599,7 +601,7 @@ func getSecretResourceVersion(name string, namespace string, clusterAPI ClusterA return secret.ResourceVersion } -func isSslRequiredUpdatedForMasterRealm(deployContext *DeployContext) bool { +func isSslRequiredUpdatedForMasterRealm(deployContext *deploy.DeployContext) bool { if deployContext.CheCluster.Spec.Database.ExternalDb { return false } @@ -608,7 +610,7 @@ func isSslRequiredUpdatedForMasterRealm(deployContext *DeployContext) bool { return false } - clusterDeployment, _ := getClusterDeployment(KeycloakDeploymentName, deployContext.CheCluster.Namespace, deployContext.ClusterAPI.Client) + clusterDeployment, _ := deploy.GetClusterDeployment(KeycloakDeploymentName, deployContext.CheCluster.Namespace, deployContext.ClusterAPI.Client) if clusterDeployment == nil { return false } @@ -623,7 +625,7 @@ func isSslRequiredUpdatedForMasterRealm(deployContext *DeployContext) bool { } func getSslRequiredForMasterRealm(checluster *orgv1.CheCluster) (string, error) { - podName, err := util.K8sclient.GetDeploymentPod(PostgresDeploymentName, checluster.Namespace) + podName, err := util.K8sclient.GetDeploymentPod(postgres.PostgresDeploymentName, checluster.Namespace) if err != nil { return "", err } @@ -633,7 +635,7 @@ func getSslRequiredForMasterRealm(checluster *orgv1.CheCluster) (string, error) } func updateSslRequiredForMasterRealm(checluster *orgv1.CheCluster) error { - podName, err := util.K8sclient.GetDeploymentPod(PostgresDeploymentName, checluster.Namespace) + podName, err := util.K8sclient.GetDeploymentPod(postgres.PostgresDeploymentName, checluster.Namespace) if err != nil { return err } @@ -642,7 +644,7 @@ func updateSslRequiredForMasterRealm(checluster *orgv1.CheCluster) error { return err } -func ProvisionKeycloakResources(deployContext *DeployContext) error { +func ProvisionKeycloakResources(deployContext *deploy.DeployContext) error { if !deployContext.CheCluster.Spec.Database.ExternalDb { value, err := getSslRequiredForMasterRealm(deployContext.CheCluster) if err != nil { diff --git a/pkg/deploy/exec_commands.go b/pkg/deploy/identity-provider/exec.go similarity index 90% rename from pkg/deploy/exec_commands.go rename to pkg/deploy/identity-provider/exec.go index b5e5b13f41..7bc59178e9 100644 --- a/pkg/deploy/exec_commands.go +++ b/pkg/deploy/identity-provider/exec.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2012-2019 Red Hat, Inc. +// Copyright (c) 2020-2020 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -9,7 +9,7 @@ // Contributors: // Red Hat, Inc. - initial API and implementation // -package deploy +package identity_provider import ( "bytes" @@ -17,7 +17,8 @@ import ( "strings" "text/template" - orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" + v1 "github.com/eclipse/che-operator/pkg/apis/org/v1" + "github.com/eclipse/che-operator/pkg/deploy" "github.com/eclipse/che-operator/pkg/util" "github.com/sirupsen/logrus" ) @@ -33,10 +34,10 @@ func GetPostgresProvisionCommand(identityProviderPostgresPassword string) (comma return command } -func GetKeycloakProvisionCommand(cr *orgv1.CheCluster) (command string) { +func GetKeycloakProvisionCommand(cr *v1.CheCluster) (command string) { requiredActions := "" updateAdminPassword := cr.Spec.Auth.UpdateAdminPassword - cheFlavor := DefaultCheFlavor(cr) + cheFlavor := deploy.DefaultCheFlavor(cr) keycloakRealm := util.GetValue(cr.Spec.Auth.IdentityProviderRealm, cheFlavor) keycloakClientId := util.GetValue(cr.Spec.Auth.IdentityProviderClientId, cheFlavor+"-public") keycloakUserEnvVar := "${KEYCLOAK_USER}" @@ -77,8 +78,8 @@ func GetKeycloakProvisionCommand(cr *orgv1.CheCluster) (command string) { return command } -func GetOpenShiftIdentityProviderProvisionCommand(cr *orgv1.CheCluster, oAuthClientName string, oauthSecret string, isOpenShift4 bool) (command string, err error) { - cheFlavor := DefaultCheFlavor(cr) +func GetOpenShiftIdentityProviderProvisionCommand(cr *v1.CheCluster, oAuthClientName string, oauthSecret string, isOpenShift4 bool) (command string, err error) { + cheFlavor := deploy.DefaultCheFlavor(cr) openShiftApiUrl, err := util.GetClusterPublicHostname(isOpenShift4) if err != nil { logrus.Errorf("Failed to auto-detect public OpenShift API URL. Configure it in Identity provider details page in Keycloak admin console: %s", err) @@ -153,8 +154,8 @@ func GetOpenShiftIdentityProviderProvisionCommand(cr *orgv1.CheCluster, oAuthCli return command, nil } -func GetDeleteOpenShiftIdentityProviderProvisionCommand(cr *orgv1.CheCluster, isOpenShift4 bool) (command string) { - cheFlavor := DefaultCheFlavor(cr) +func GetDeleteOpenShiftIdentityProviderProvisionCommand(cr *v1.CheCluster, isOpenShift4 bool) (command string) { + cheFlavor := deploy.DefaultCheFlavor(cr) keycloakRealm := util.GetValue(cr.Spec.Auth.IdentityProviderRealm, cheFlavor) script := "/opt/jboss/keycloak/bin/kcadm.sh" keycloakUserEnvVar := "${KEYCLOAK_USER}" diff --git a/pkg/deploy/identity_provider.go b/pkg/deploy/identity-provider/identity_provider.go similarity index 54% rename from pkg/deploy/identity_provider.go rename to pkg/deploy/identity-provider/identity_provider.go index 9f2f61013f..8ff4686ae4 100644 --- a/pkg/deploy/identity_provider.go +++ b/pkg/deploy/identity-provider/identity_provider.go @@ -1,9 +1,23 @@ -package deploy +// +// Copyright (c) 2020-2020 Red Hat, Inc. +// This program and the accompanying materials are made +// available under the terms of the Eclipse Public License 2.0 +// which is available at https://www.eclipse.org/legal/epl-2.0/ +// +// SPDX-License-Identifier: EPL-2.0 +// +// Contributors: +// Red Hat, Inc. - initial API and implementation +// +package identity_provider import ( "context" "strings" + "github.com/eclipse/che-operator/pkg/deploy" + "github.com/eclipse/che-operator/pkg/deploy/expose" + "github.com/eclipse/che-operator/pkg/util" oauth "github.com/openshift/api/oauth/v1" "github.com/sirupsen/logrus" @@ -12,14 +26,14 @@ import ( ) const ( - keycloakGatewayConfig = "che-gateway-route-keycloak" + Keycloak = "keycloak" ) // SyncIdentityProviderToCluster instantiates the identity provider (Keycloak) in the cluster. Returns true if // the provisioning is complete, false if requeue of the reconcile request is needed. -func SyncIdentityProviderToCluster(deployContext *DeployContext, cheHost string, protocol string, cheFlavor string) (bool, error) { +func SyncIdentityProviderToCluster(deployContext *deploy.DeployContext, cheHost string, protocol string, cheFlavor string) (bool, error) { instance := deployContext.CheCluster - cheMultiUser := GetCheMultiUser(instance) + cheMultiUser := deploy.GetCheMultiUser(instance) tests := util.IsTestMode() isOpenShift := util.IsOpenShift @@ -35,9 +49,9 @@ func SyncIdentityProviderToCluster(deployContext *DeployContext, cheHost string, return true, nil } - keycloakLabels := GetLabels(instance, "keycloak") + keycloakLabels := deploy.GetLabels(instance, "keycloak") - serviceStatus := SyncServiceToCluster(deployContext, "keycloak", []string{"http"}, []int32{8080}, keycloakLabels) + serviceStatus := deploy.SyncServiceToCluster(deployContext, "keycloak", []string{"http"}, []int32{8080}, keycloakLabels) if !tests { if !serviceStatus.Continue { logrus.Info("Waiting on service 'keycloak' to be ready") @@ -49,99 +63,21 @@ func SyncIdentityProviderToCluster(deployContext *DeployContext, cheHost string, } } - exposureStrategy := util.GetServerExposureStrategy(instance, DefaultServerExposureStrategy) - singleHostExposureType := GetSingleHostExposureType(instance) - useGateway := exposureStrategy == "single-host" && (util.IsOpenShift || singleHostExposureType == "gateway") - - // create Keycloak ingresses when on k8s - var keycloakURL string - if !isOpenShift { - var host string - if exposureStrategy == "multi-host" { - host = "keycloak-" + deployContext.CheCluster.Namespace + "." + deployContext.CheCluster.Spec.K8s.IngressDomain - } else { - host = cheHost - } - if useGateway { - // try to guess where in the ingress-creating code the /auth endpoint is defined... - cfg := GetGatewayRouteConfig(deployContext, keycloakGatewayConfig, "/auth", 10, "http://keycloak:8080", false) - _, err := SyncConfigMapToCluster(deployContext, &cfg) - if !tests { - if err != nil { - logrus.Error(err) - } - } - - if err := DeleteIngressIfExists("keycloak", deployContext); !tests && err != nil { - logrus.Error(err) - } - - keycloakURL = protocol + "://" + cheHost - } else { - additionalLabels := deployContext.CheCluster.Spec.Auth.IdentityProviderIngress.Labels - ingress, err := SyncIngressToCluster(deployContext, "keycloak", host, "keycloak", 8080, additionalLabels) - if !tests { - if ingress == nil { - logrus.Info("Waiting on ingress 'keycloak' to be ready") - if err != nil { - logrus.Error(err) - } - - return false, err - } - } - - if err := DeleteGatewayRouteConfig(keycloakGatewayConfig, deployContext); !tests && err != nil { - logrus.Error(err) - } - - keycloakURL = protocol + "://" + host - } - } else { - if useGateway { - cfg := GetGatewayRouteConfig(deployContext, keycloakGatewayConfig, "/auth", 10, "http://keycloak:8080", false) - _, err := SyncConfigMapToCluster(deployContext, &cfg) - if !tests { - if err != nil { - logrus.Error(err) - } - } - keycloakURL = protocol + "://" + cheHost - - if err := DeleteRouteIfExists("keycloak", deployContext); !tests && err != nil { - logrus.Error(err) - } - } else { - // create Keycloak route - additionalLabels := deployContext.CheCluster.Spec.Auth.IdentityProviderRoute.Labels - route, err := SyncRouteToCluster(deployContext, "keycloak", "", "keycloak", 8080, additionalLabels) - if !tests { - if route == nil { - logrus.Info("Waiting on route 'keycloak' to be ready") - if err != nil { - logrus.Error(err) - } - - return false, err - } - - keycloakURL = protocol + "://" + route.Spec.Host - } - - if err := DeleteGatewayRouteConfig(keycloakGatewayConfig, deployContext); !tests && err != nil { - logrus.Error(err) - } - } + additionalLabels := (map[bool]string{true: instance.Spec.Auth.IdentityProviderRoute.Labels, false: instance.Spec.Auth.IdentityProviderIngress.Labels})[util.IsOpenShift] + endpoint, done, err := expose.Expose(deployContext, cheHost, Keycloak, additionalLabels) + if !done { + return false, err } + keycloakURL := protocol + "://" + endpoint if instance.Spec.Auth.IdentityProviderURL != keycloakURL { instance.Spec.Auth.IdentityProviderURL = keycloakURL - if err := UpdateCheCRSpec(deployContext, "Keycloak URL", keycloakURL); err != nil { + if err := deploy.UpdateCheCRSpec(deployContext, "Keycloak URL", keycloakURL); err != nil { return false, err } instance.Status.KeycloakURL = keycloakURL - if err := UpdateCheCRStatus(deployContext, "Keycloak URL", keycloakURL); err != nil { + if err := deploy.UpdateCheCRStatus(deployContext, "Keycloak URL", keycloakURL); err != nil { return false, err } } @@ -167,7 +103,7 @@ func SyncIdentityProviderToCluster(deployContext *DeployContext, cheHost string, for { instance.Status.KeycloakProvisoned = true - if err := UpdateCheCRStatus(deployContext, "status: provisioned with Keycloak", "true"); err != nil && + if err := deploy.UpdateCheCRStatus(deployContext, "status: provisioned with Keycloak", "true"); err != nil && errors.IsConflict(err) { reload(deployContext) @@ -193,7 +129,7 @@ func SyncIdentityProviderToCluster(deployContext *DeployContext, cheHost string, return true, nil } -func CreateIdentityProviderItems(deployContext *DeployContext, cheFlavor string) error { +func CreateIdentityProviderItems(deployContext *deploy.DeployContext, cheFlavor string) error { instance := deployContext.CheCluster tests := util.IsTestMode() isOpenShift4 := util.IsOpenShift4 @@ -202,7 +138,7 @@ func CreateIdentityProviderItems(deployContext *DeployContext, cheFlavor string) if len(oAuthClientName) < 1 { oAuthClientName = instance.Name + "-openshift-identity-provider-" + strings.ToLower(util.GeneratePasswd(6)) instance.Spec.Auth.OAuthClientName = oAuthClientName - if err := UpdateCheCRSpec(deployContext, "oAuthClient name", oAuthClientName); err != nil { + if err := deploy.UpdateCheCRSpec(deployContext, "oAuthClient name", oAuthClientName); err != nil { return err } } @@ -210,14 +146,14 @@ func CreateIdentityProviderItems(deployContext *DeployContext, cheFlavor string) if len(oauthSecret) < 1 { oauthSecret = util.GeneratePasswd(12) instance.Spec.Auth.OAuthSecret = oauthSecret - if err := UpdateCheCRSpec(deployContext, "oAuthC secret name", oauthSecret); err != nil { + if err := deploy.UpdateCheCRSpec(deployContext, "oAuthC secret name", oauthSecret); err != nil { return err } } keycloakURL := instance.Spec.Auth.IdentityProviderURL keycloakRealm := util.GetValue(instance.Spec.Auth.IdentityProviderRealm, cheFlavor) - oAuthClient := NewOAuthClient(oAuthClientName, oauthSecret, keycloakURL, keycloakRealm, isOpenShift4) + oAuthClient := deploy.NewOAuthClient(oAuthClientName, oauthSecret, keycloakURL, keycloakRealm, isOpenShift4) if err := createNewOauthClient(deployContext, oAuthClient); err != nil { return err } @@ -237,7 +173,7 @@ func CreateIdentityProviderItems(deployContext *DeployContext, cheFlavor string) if err == nil { for { instance.Status.OpenShiftoAuthProvisioned = true - if err := UpdateCheCRStatus(deployContext, "status: provisioned with OpenShift identity provider", "true"); err != nil && + if err := deploy.UpdateCheCRStatus(deployContext, "status: provisioned with OpenShift identity provider", "true"); err != nil && errors.IsConflict(err) { reload(deployContext) @@ -250,7 +186,7 @@ func CreateIdentityProviderItems(deployContext *DeployContext, cheFlavor string) return nil } -func createNewOauthClient(deployContext *DeployContext, oAuthClient *oauth.OAuthClient) error { +func createNewOauthClient(deployContext *deploy.DeployContext, oAuthClient *oauth.OAuthClient) error { oAuthClientFound := &oauth.OAuthClient{} err := deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: oAuthClient.Name, Namespace: oAuthClient.Namespace}, oAuthClientFound) if err != nil && errors.IsNotFound(err) { @@ -269,7 +205,7 @@ func createNewOauthClient(deployContext *DeployContext, oAuthClient *oauth.OAuth return nil } -func reload(deployContext *DeployContext) error { +func reload(deployContext *deploy.DeployContext) error { return deployContext.ClusterAPI.Client.Get( context.TODO(), types.NamespacedName{Name: deployContext.CheCluster.Name, Namespace: deployContext.CheCluster.Namespace}, diff --git a/pkg/deploy/init_test.go b/pkg/deploy/init_test.go new file mode 100644 index 0000000000..22c06f95a5 --- /dev/null +++ b/pkg/deploy/init_test.go @@ -0,0 +1,19 @@ +// +// Copyright (c) 2020-2020 Red Hat, Inc. +// This program and the accompanying materials are made +// available under the terms of the Eclipse Public License 2.0 +// which is available at https://www.eclipse.org/legal/epl-2.0/ +// +// SPDX-License-Identifier: EPL-2.0 +// +// Contributors: +// Red Hat, Inc. - initial API and implementation +// +package deploy + +func init() { + err := InitTestDefaultsFromDeployment("../../deploy/operator.yaml") + if err != nil { + panic(err) + } +} diff --git a/pkg/deploy/oauthclient.go b/pkg/deploy/oauthclient.go index 8df1ea95f1..df43907e5d 100644 --- a/pkg/deploy/oauthclient.go +++ b/pkg/deploy/oauthclient.go @@ -12,25 +12,24 @@ package deploy import ( - "strings" oauth "github.com/openshift/api/oauth/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "strings" ) - func NewOAuthClient(name string, oauthSecret string, keycloakURL string, keycloakRealm string, isOpenShift4 bool) *oauth.OAuthClient { providerName := "openshift-v3" if isOpenShift4 { providerName = "openshift-v4" } - - redirectURLSuffix := "/auth/realms/" + keycloakRealm +"/broker/" + providerName + "/endpoint" + + redirectURLSuffix := "/auth/realms/" + keycloakRealm + "/broker/" + providerName + "/endpoint" redirectURIs := []string{ keycloakURL + redirectURLSuffix, } keycloakURL = strings.NewReplacer("https://", "", "http://", "").Replace(keycloakURL) - if ! strings.Contains(keycloakURL, "://") { + if !strings.Contains(keycloakURL, "://") { redirectURIs = []string{ "http://" + keycloakURL + redirectURLSuffix, "https://" + keycloakURL + redirectURLSuffix, @@ -42,13 +41,13 @@ func NewOAuthClient(name string, oauthSecret string, keycloakURL string, keycloa APIVersion: oauth.SchemeGroupVersion.String(), }, ObjectMeta: metav1.ObjectMeta{ - Name: name, - Labels: map[string]string{"app":"che"}, + Name: name, + Labels: map[string]string{"app": "che"}, }, - Secret: oauthSecret, + Secret: oauthSecret, RedirectURIs: redirectURIs, - GrantMethod: oauth.GrantHandlerPrompt, + GrantMethod: oauth.GrantHandlerPrompt, } } diff --git a/pkg/deploy/plugin-registry/deployment.go b/pkg/deploy/plugin-registry/deployment.go new file mode 100644 index 0000000000..bc0bc493d6 --- /dev/null +++ b/pkg/deploy/plugin-registry/deployment.go @@ -0,0 +1,54 @@ +// +// Copyright (c) 2012-2019 Red Hat, Inc. +// This program and the accompanying materials are made +// available under the terms of the Eclipse Public License 2.0 +// which is available at https://www.eclipse.org/legal/epl-2.0/ +// +// SPDX-License-Identifier: EPL-2.0 +// +// Contributors: +// Red Hat, Inc. - initial API and implementation +// +package plugin_registry + +import ( + "github.com/eclipse/che-operator/pkg/deploy" + "github.com/eclipse/che-operator/pkg/deploy/registry" + "github.com/eclipse/che-operator/pkg/util" + corev1 "k8s.io/api/core/v1" +) + +func SyncPluginRegistryDeploymentToCluster(deployContext *deploy.DeployContext) deploy.DeploymentProvisioningStatus { + registryType := "plugin" + registryImage := util.GetValue(deployContext.CheCluster.Spec.Server.PluginRegistryImage, deploy.DefaultPluginRegistryImage(deployContext.CheCluster)) + registryImagePullPolicy := corev1.PullPolicy(util.GetValue(string(deployContext.CheCluster.Spec.Server.PluginRegistryPullPolicy), deploy.DefaultPullPolicyFromDockerImage(registryImage))) + registryMemoryLimit := util.GetValue(string(deployContext.CheCluster.Spec.Server.PluginRegistryMemoryLimit), deploy.DefaultPluginRegistryMemoryLimit) + registryMemoryRequest := util.GetValue(string(deployContext.CheCluster.Spec.Server.PluginRegistryMemoryRequest), deploy.DefaultPluginRegistryMemoryRequest) + probePath := "/v3/plugins/" + pluginImagesEnv := util.GetEnvByRegExp("^.*plugin_registry_image.*$") + + clusterDeployment, err := deploy.GetClusterDeployment(deploy.PluginRegistry, deployContext.CheCluster.Namespace, deployContext.ClusterAPI.Client) + if err != nil { + return deploy.DeploymentProvisioningStatus{ + ProvisioningStatus: deploy.ProvisioningStatus{Err: err}, + } + } + + specDeployment, err := registry.GetSpecRegistryDeployment( + deployContext, + registryType, + registryImage, + pluginImagesEnv, + registryImagePullPolicy, + registryMemoryLimit, + registryMemoryRequest, + probePath) + + if err != nil { + return deploy.DeploymentProvisioningStatus{ + ProvisioningStatus: deploy.ProvisioningStatus{Err: err}, + } + } + + return deploy.SyncDeploymentToCluster(deployContext, specDeployment, clusterDeployment, nil, nil) +} diff --git a/pkg/deploy/plugin-registry/plugin_registry.go b/pkg/deploy/plugin-registry/plugin_registry.go new file mode 100644 index 0000000000..83b8f81a2e --- /dev/null +++ b/pkg/deploy/plugin-registry/plugin_registry.go @@ -0,0 +1,119 @@ +// +// Copyright (c) 2012-2019 Red Hat, Inc. +// This program and the accompanying materials are made +// available under the terms of the Eclipse Public License 2.0 +// which is available at https://www.eclipse.org/legal/epl-2.0/ +// +// SPDX-License-Identifier: EPL-2.0 +// +// Contributors: +// Red Hat, Inc. - initial API and implementation +// +package plugin_registry + +import ( + "encoding/json" + "fmt" + "github.com/eclipse/che-operator/pkg/deploy" + "github.com/eclipse/che-operator/pkg/deploy/expose" + "github.com/eclipse/che-operator/pkg/util" + "github.com/sirupsen/logrus" + + orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" +) + +type PluginRegistryConfigMap struct { + CheSidecarContainersRegistryURL string `json:"CHE_SIDECAR_CONTAINERS_REGISTRY_URL"` + CheSidecarContainersRegistryOrganization string `json:"CHE_SIDECAR_CONTAINERS_REGISTRY_ORGANIZATION"` +} + +/** + * Create plugin registry resources unless an external registry is used. + */ +func SyncPluginRegistryToCluster(deployContext *deploy.DeployContext, cheHost string) (bool, error) { + pluginRegistryURL := deployContext.CheCluster.Spec.Server.PluginRegistryUrl + if !deployContext.CheCluster.Spec.Server.ExternalPluginRegistry { + additionalLabels := (map[bool]string{true: deployContext.CheCluster.Spec.Server.PluginRegistryRoute.Labels, false: deployContext.CheCluster.Spec.Server.PluginRegistryIngress.Labels})[util.IsOpenShift] + endpoint, done, err := expose.Expose(deployContext, cheHost, deploy.PluginRegistry, additionalLabels) + if !done { + return false, err + } + + if pluginRegistryURL == "" { + if deployContext.CheCluster.Spec.Server.TlsSupport { + pluginRegistryURL = "https://" + endpoint + "/v3" + } else { + pluginRegistryURL = "http://" + endpoint + "/v3" + } + } + + if deployContext.CheCluster.IsAirGapMode() { + configMapData := getPluginRegistryConfigMapData(deployContext.CheCluster) + configMapSpec, err := deploy.GetSpecConfigMap(deployContext, deploy.PluginRegistry, configMapData) + if err != nil { + return false, err + } + + configMap, err := deploy.SyncConfigMapToCluster(deployContext, configMapSpec) + if configMap == nil { + return false, err + } + } + + // Create a new registry service + registryLabels := deploy.GetLabels(deployContext.CheCluster, deploy.PluginRegistry) + serviceStatus := deploy.SyncServiceToCluster(deployContext, deploy.PluginRegistry, []string{"http"}, []int32{8080}, registryLabels) + if !util.IsTestMode() { + if !serviceStatus.Continue { + logrus.Info("Waiting on service '" + deploy.PluginRegistry + "' to be ready") + if serviceStatus.Err != nil { + logrus.Error(serviceStatus.Err) + } + + return false, serviceStatus.Err + } + } + + // Deploy plugin registry + deploymentStatus := SyncPluginRegistryDeploymentToCluster(deployContext) + if !util.IsTestMode() { + if !deploymentStatus.Continue { + logrus.Info("Waiting on deployment '" + deploy.PluginRegistry + "' to be ready") + if deploymentStatus.Err != nil { + logrus.Error(deploymentStatus.Err) + } + + return false, deploymentStatus.Err + } + } + } + + if pluginRegistryURL != deployContext.CheCluster.Status.PluginRegistryURL { + deployContext.CheCluster.Status.PluginRegistryURL = pluginRegistryURL + if err := deploy.UpdateCheCRStatus(deployContext, "status: Plugin Registry URL", pluginRegistryURL); err != nil { + return false, err + } + } + + return true, nil +} + +func getPluginRegistryConfigMapData(cr *orgv1.CheCluster) map[string]string { + pluginRegistryEnv := make(map[string]string) + data := &PluginRegistryConfigMap{ + CheSidecarContainersRegistryURL: cr.Spec.Server.AirGapContainerRegistryHostname, + CheSidecarContainersRegistryOrganization: cr.Spec.Server.AirGapContainerRegistryOrganization, + } + + out, err := json.Marshal(data) + if err != nil { + fmt.Println(err) + } + + err = json.Unmarshal(out, &pluginRegistryEnv) + if err != nil { + fmt.Println(err) + } + + return pluginRegistryEnv +} diff --git a/pkg/deploy/plugin_registry.go b/pkg/deploy/plugin_registry.go deleted file mode 100644 index add18a8d6a..0000000000 --- a/pkg/deploy/plugin_registry.go +++ /dev/null @@ -1,201 +0,0 @@ -// -// Copyright (c) 2012-2019 Red Hat, Inc. -// This program and the accompanying materials are made -// available under the terms of the Eclipse Public License 2.0 -// which is available at https://www.eclipse.org/legal/epl-2.0/ -// -// SPDX-License-Identifier: EPL-2.0 -// -// Contributors: -// Red Hat, Inc. - initial API and implementation -// -package deploy - -import ( - "encoding/json" - "fmt" - - "github.com/eclipse/che-operator/pkg/util" - "github.com/sirupsen/logrus" - - orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" -) - -type PluginRegistryConfigMap struct { - CheSidecarContainersRegistryURL string `json:"CHE_SIDECAR_CONTAINERS_REGISTRY_URL"` - CheSidecarContainersRegistryOrganization string `json:"CHE_SIDECAR_CONTAINERS_REGISTRY_ORGANIZATION"` -} - -const ( - PluginRegistry = "plugin-registry" - pluginRegistryGatewayConfig = "che-gateway-route-plugin-registry" -) - -/** - * Create plugin registry resources unless an external registry is used. - */ -func SyncPluginRegistryToCluster(deployContext *DeployContext, cheHost string) (bool, error) { - pluginRegistryURL := deployContext.CheCluster.Spec.Server.PluginRegistryUrl - if !deployContext.CheCluster.Spec.Server.ExternalPluginRegistry { - var endpoint string - var domain string - exposureStrategy := util.GetServerExposureStrategy(deployContext.CheCluster, DefaultServerExposureStrategy) - singleHostExposureType := GetSingleHostExposureType(deployContext.CheCluster) - useGateway := exposureStrategy == "single-host" && (util.IsOpenShift || singleHostExposureType == "gateway") - - if exposureStrategy == "multi-host" { - // this won't get used on openshift, because there we're intentionally let Openshift decide on the domain name - domain = PluginRegistry + "-" + deployContext.CheCluster.Namespace + "." + deployContext.CheCluster.Spec.K8s.IngressDomain - endpoint = domain - } else { - domain = cheHost - endpoint = domain + "/" + PluginRegistry - } - if !util.IsOpenShift { - if useGateway { - cfg := GetGatewayRouteConfig(deployContext, pluginRegistryGatewayConfig, "/"+PluginRegistry, 10, "http://"+PluginRegistry+":8080", true) - clusterCfg, err := SyncConfigMapToCluster(deployContext, &cfg) - if !util.IsTestMode() { - if clusterCfg == nil { - if err != nil { - logrus.Error(err) - } - return false, err - } - } - if err := DeleteIngressIfExists(PluginRegistry, deployContext); !util.IsTestMode() && err != nil { - logrus.Error(err) - } - } else { - additionalLabels := deployContext.CheCluster.Spec.Server.PluginRegistryIngress.Labels - ingress, err := SyncIngressToCluster(deployContext, PluginRegistry, domain, PluginRegistry, 8080, additionalLabels) - if !util.IsTestMode() { - if ingress == nil { - logrus.Infof("Waiting on ingress '%s' to be ready", PluginRegistry) - if err != nil { - logrus.Error(err) - } - return false, err - } - } - if err := DeleteGatewayRouteConfig(pluginRegistryGatewayConfig, deployContext); !util.IsTestMode() && err != nil { - logrus.Error(err) - } - } - } else { - if useGateway { - cfg := GetGatewayRouteConfig(deployContext, pluginRegistryGatewayConfig, "/"+PluginRegistry, 10, "http://"+PluginRegistry+":8080", true) - clusterCfg, err := SyncConfigMapToCluster(deployContext, &cfg) - if !util.IsTestMode() { - if clusterCfg == nil { - if err != nil { - logrus.Error(err) - } - return false, err - } - } - if err := DeleteRouteIfExists(PluginRegistry, deployContext); !util.IsTestMode() && err != nil { - logrus.Error(err) - } - } else { - // the empty string for a host is intentional here - we let OpenShift decide on the hostname - additionalLabels := deployContext.CheCluster.Spec.Server.PluginRegistryRoute.Labels - route, err := SyncRouteToCluster(deployContext, PluginRegistry, "", PluginRegistry, 8080, additionalLabels) - if !util.IsTestMode() { - if route == nil { - logrus.Infof("Waiting on route '%s' to be ready", PluginRegistry) - if err != nil { - logrus.Error(err) - } - - return false, err - } - } - if err := DeleteGatewayRouteConfig(pluginRegistryGatewayConfig, deployContext); !util.IsTestMode() && err != nil { - logrus.Error(err) - } - - if !util.IsTestMode() { - endpoint = route.Spec.Host - } - } - } - - if pluginRegistryURL == "" { - if deployContext.CheCluster.Spec.Server.TlsSupport { - pluginRegistryURL = "https://" + endpoint + "/v3" - } else { - pluginRegistryURL = "http://" + endpoint + "/v3" - } - } - - if deployContext.CheCluster.IsAirGapMode() { - configMapData := getPluginRegistryConfigMapData(deployContext.CheCluster) - configMapSpec, err := GetSpecConfigMap(deployContext, PluginRegistry, configMapData) - if err != nil { - return false, err - } - - configMap, err := SyncConfigMapToCluster(deployContext, configMapSpec) - if configMap == nil { - return false, err - } - } - - // Create a new registry service - registryLabels := GetLabels(deployContext.CheCluster, PluginRegistry) - serviceStatus := SyncServiceToCluster(deployContext, PluginRegistry, []string{"http"}, []int32{8080}, registryLabels) - if !util.IsTestMode() { - if !serviceStatus.Continue { - logrus.Info("Waiting on service '" + PluginRegistry + "' to be ready") - if serviceStatus.Err != nil { - logrus.Error(serviceStatus.Err) - } - - return false, serviceStatus.Err - } - } - - // Deploy plugin registry - deploymentStatus := SyncPluginRegistryDeploymentToCluster(deployContext) - if !util.IsTestMode() { - if !deploymentStatus.Continue { - logrus.Info("Waiting on deployment '" + PluginRegistry + "' to be ready") - if deploymentStatus.Err != nil { - logrus.Error(deploymentStatus.Err) - } - - return false, deploymentStatus.Err - } - } - } - - if pluginRegistryURL != deployContext.CheCluster.Status.PluginRegistryURL { - deployContext.CheCluster.Status.PluginRegistryURL = pluginRegistryURL - if err := UpdateCheCRStatus(deployContext, "status: Plugin Registry URL", pluginRegistryURL); err != nil { - return false, err - } - } - - return true, nil -} - -func getPluginRegistryConfigMapData(cr *orgv1.CheCluster) map[string]string { - pluginRegistryEnv := make(map[string]string) - data := &PluginRegistryConfigMap{ - CheSidecarContainersRegistryURL: cr.Spec.Server.AirGapContainerRegistryHostname, - CheSidecarContainersRegistryOrganization: cr.Spec.Server.AirGapContainerRegistryOrganization, - } - - out, err := json.Marshal(data) - if err != nil { - fmt.Println(err) - } - - err = json.Unmarshal(out, &pluginRegistryEnv) - if err != nil { - fmt.Println(err) - } - - return pluginRegistryEnv -} diff --git a/pkg/deploy/deployment_postgres.go b/pkg/deploy/postgres/deployment_postgres.go similarity index 81% rename from pkg/deploy/deployment_postgres.go rename to pkg/deploy/postgres/deployment_postgres.go index aa2d7bc4df..3ba8c8a442 100644 --- a/pkg/deploy/deployment_postgres.go +++ b/pkg/deploy/postgres/deployment_postgres.go @@ -9,9 +9,10 @@ // Contributors: // Red Hat, Inc. - initial API and implementation // -package deploy +package postgres import ( + "github.com/eclipse/che-operator/pkg/deploy" "github.com/eclipse/che-operator/pkg/util" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -28,35 +29,35 @@ var ( postgresAdminPassword = util.GeneratePasswd(12) ) -func SyncPostgresDeploymentToCluster(deployContext *DeployContext) DeploymentProvisioningStatus { - clusterDeployment, err := getClusterDeployment(PostgresDeploymentName, deployContext.CheCluster.Namespace, deployContext.ClusterAPI.Client) +func SyncPostgresDeploymentToCluster(deployContext *deploy.DeployContext) deploy.DeploymentProvisioningStatus { + clusterDeployment, err := deploy.GetClusterDeployment(PostgresDeploymentName, deployContext.CheCluster.Namespace, deployContext.ClusterAPI.Client) if err != nil { - return DeploymentProvisioningStatus{ - ProvisioningStatus: ProvisioningStatus{Err: err}, + return deploy.DeploymentProvisioningStatus{ + ProvisioningStatus: deploy.ProvisioningStatus{Err: err}, } } specDeployment, err := getSpecPostgresDeployment(deployContext, clusterDeployment) if err != nil { - return DeploymentProvisioningStatus{ - ProvisioningStatus: ProvisioningStatus{Err: err}, + return deploy.DeploymentProvisioningStatus{ + ProvisioningStatus: deploy.ProvisioningStatus{Err: err}, } } - return SyncDeploymentToCluster(deployContext, specDeployment, clusterDeployment, nil, nil) + return deploy.SyncDeploymentToCluster(deployContext, specDeployment, clusterDeployment, nil, nil) } -func getSpecPostgresDeployment(deployContext *DeployContext, clusterDeployment *appsv1.Deployment) (*appsv1.Deployment, error) { +func getSpecPostgresDeployment(deployContext *deploy.DeployContext, clusterDeployment *appsv1.Deployment) (*appsv1.Deployment, error) { isOpenShift, _, err := util.DetectOpenShift() if err != nil { return nil, err } terminationGracePeriodSeconds := int64(30) - labels := GetLabels(deployContext.CheCluster, PostgresDeploymentName) + labels := deploy.GetLabels(deployContext.CheCluster, PostgresDeploymentName) chePostgresDb := util.GetValue(deployContext.CheCluster.Spec.Database.ChePostgresDb, "dbche") - postgresImage := util.GetValue(deployContext.CheCluster.Spec.Database.PostgresImage, DefaultPostgresImage(deployContext.CheCluster)) - pullPolicy := corev1.PullPolicy(util.GetValue(string(deployContext.CheCluster.Spec.Database.PostgresImagePullPolicy), DefaultPullPolicyFromDockerImage(postgresImage))) + postgresImage := util.GetValue(deployContext.CheCluster.Spec.Database.PostgresImage, deploy.DefaultPostgresImage(deployContext.CheCluster)) + pullPolicy := corev1.PullPolicy(util.GetValue(string(deployContext.CheCluster.Spec.Database.PostgresImagePullPolicy), deploy.DefaultPullPolicyFromDockerImage(postgresImage))) if clusterDeployment != nil { env := clusterDeployment.Spec.Template.Spec.Containers[0].Env @@ -90,10 +91,10 @@ func getSpecPostgresDeployment(deployContext *DeployContext, clusterDeployment * Spec: corev1.PodSpec{ Volumes: []corev1.Volume{ { - Name: DefaultPostgresVolumeClaimName, + Name: deploy.DefaultPostgresVolumeClaimName, VolumeSource: corev1.VolumeSource{ PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ - ClaimName: DefaultPostgresVolumeClaimName, + ClaimName: deploy.DefaultPostgresVolumeClaimName, }, }, }, @@ -120,7 +121,7 @@ func getSpecPostgresDeployment(deployContext *DeployContext, clusterDeployment * }, VolumeMounts: []corev1.VolumeMount{ { - Name: DefaultPostgresVolumeClaimName, + Name: deploy.DefaultPostgresVolumeClaimName, MountPath: "/var/lib/pgsql/data", }, }, diff --git a/pkg/deploy/registry/registry.go b/pkg/deploy/registry/registry.go new file mode 100644 index 0000000000..fa7f7abe1e --- /dev/null +++ b/pkg/deploy/registry/registry.go @@ -0,0 +1,139 @@ +package registry + +import ( + "github.com/eclipse/che-operator/pkg/deploy" + "github.com/eclipse/che-operator/pkg/util" + v12 "k8s.io/api/apps/v1" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + v13 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" +) + +func GetSpecRegistryDeployment( + deployContext *deploy.DeployContext, + registryType string, + registryImage string, + env []v1.EnvVar, + registryImagePullPolicy v1.PullPolicy, + registryMemoryLimit string, + registryMemoryRequest string, + probePath string) (*v12.Deployment, error) { + + terminationGracePeriodSeconds := int64(30) + name := registryType + "-registry" + labels := deploy.GetLabels(deployContext.CheCluster, name) + _25Percent := intstr.FromString("25%") + _1 := int32(1) + _2 := int32(2) + isOptional := true + deployment := &v12.Deployment{ + TypeMeta: v13.TypeMeta{ + Kind: "Deployment", + APIVersion: "apps/v1", + }, + ObjectMeta: v13.ObjectMeta{ + Name: name, + Namespace: deployContext.CheCluster.Namespace, + Labels: labels, + }, + Spec: v12.DeploymentSpec{ + Replicas: &_1, + RevisionHistoryLimit: &_2, + Selector: &v13.LabelSelector{MatchLabels: labels}, + Strategy: v12.DeploymentStrategy{ + Type: v12.RollingUpdateDeploymentStrategyType, + RollingUpdate: &v12.RollingUpdateDeployment{ + MaxSurge: &_25Percent, + MaxUnavailable: &_25Percent, + }, + }, + Template: v1.PodTemplateSpec{ + ObjectMeta: v13.ObjectMeta{ + Labels: labels, + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: "che-" + name, + Image: registryImage, + ImagePullPolicy: registryImagePullPolicy, + Ports: []v1.ContainerPort{ + { + Name: "http", + ContainerPort: 8080, + Protocol: "TCP", + }, + }, + Env: env, + EnvFrom: []v1.EnvFromSource{ + { + ConfigMapRef: &v1.ConfigMapEnvSource{ + Optional: &isOptional, + LocalObjectReference: v1.LocalObjectReference{ + Name: registryType + "-registry", + }, + }, + }, + }, + Resources: v1.ResourceRequirements{ + Requests: v1.ResourceList{ + v1.ResourceMemory: resource.MustParse(registryMemoryRequest), + }, + Limits: v1.ResourceList{ + v1.ResourceMemory: resource.MustParse(registryMemoryLimit), + }, + }, + ReadinessProbe: &v1.Probe{ + Handler: v1.Handler{ + HTTPGet: &v1.HTTPGetAction{ + Path: "/" + registryType + "s/", + Port: intstr.IntOrString{ + Type: intstr.Int, + IntVal: int32(8080), + }, + Scheme: v1.URISchemeHTTP, + }, + }, + InitialDelaySeconds: 3, + FailureThreshold: 10, + TimeoutSeconds: 3, + PeriodSeconds: 10, + SuccessThreshold: 1, + }, + LivenessProbe: &v1.Probe{ + Handler: v1.Handler{ + HTTPGet: &v1.HTTPGetAction{ + Path: "/" + registryType + "s/", + Port: intstr.IntOrString{ + Type: intstr.Int, + IntVal: int32(8080), + }, + Scheme: v1.URISchemeHTTP, + }, + }, + InitialDelaySeconds: 30, + FailureThreshold: 10, + TimeoutSeconds: 3, + SuccessThreshold: 1, + PeriodSeconds: 10, + }, + }, + }, + RestartPolicy: "Always", + TerminationGracePeriodSeconds: &terminationGracePeriodSeconds, + }, + }, + }, + } + + if !util.IsTestMode() { + err := controllerutil.SetControllerReference(deployContext.CheCluster, deployment, deployContext.ClusterAPI.Scheme) + if err != nil { + return nil, err + } + } + + return deployment, nil +} diff --git a/pkg/deploy/che_configmap.go b/pkg/deploy/server/che_configmap.go similarity index 84% rename from pkg/deploy/che_configmap.go rename to pkg/deploy/server/che_configmap.go index 72c14cc4ad..53a9f57f86 100644 --- a/pkg/deploy/che_configmap.go +++ b/pkg/deploy/server/che_configmap.go @@ -9,7 +9,7 @@ // Contributors: // Red Hat, Inc. - initial API and implementation // -package deploy +package server import ( "encoding/json" @@ -17,6 +17,8 @@ import ( "os" "strconv" + "github.com/eclipse/che-operator/pkg/deploy" + "github.com/eclipse/che-operator/pkg/util" "github.com/sirupsen/logrus" corev1 "k8s.io/api/core/v1" @@ -80,29 +82,29 @@ type CheConfigMap struct { SingleHostGatewayConfigMapLabels string `json:"CHE_INFRA_KUBERNETES_SINGLEHOST_GATEWAY_CONFIGMAP__LABELS"` } -func SyncCheConfigMapToCluster(deployContext *DeployContext) (*corev1.ConfigMap, error) { +func SyncCheConfigMapToCluster(deployContext *deploy.DeployContext) (*corev1.ConfigMap, error) { data, err := GetCheConfigMapData(deployContext) if err != nil { return nil, err } - specConfigMap, err := GetSpecConfigMap(deployContext, CheConfigMapName, data) + specConfigMap, err := deploy.GetSpecConfigMap(deployContext, CheConfigMapName, data) if err != nil { return nil, err } - return SyncConfigMapToCluster(deployContext, specConfigMap) + return deploy.SyncConfigMapToCluster(deployContext, specConfigMap) } // GetCheConfigMapData gets env values from CR spec and returns a map with key:value // which is used in CheCluster ConfigMap to configure CheCluster master behavior -func GetCheConfigMapData(deployContext *DeployContext) (cheEnv map[string]string, err error) { +func GetCheConfigMapData(deployContext *deploy.DeployContext) (cheEnv map[string]string, err error) { cheHost := deployContext.CheCluster.Spec.Server.CheHost keycloakURL := deployContext.CheCluster.Spec.Auth.IdentityProviderURL isOpenShift, isOpenshift4, err := util.DetectOpenShift() if err != nil { logrus.Errorf("Failed to get current infra: %s", err) } - cheFlavor := DefaultCheFlavor(deployContext.CheCluster) + cheFlavor := deploy.DefaultCheFlavor(deployContext.CheCluster) infra := "kubernetes" if isOpenShift { infra = "openshift" @@ -139,7 +141,7 @@ func GetCheConfigMapData(deployContext *DeployContext) (cheEnv map[string]string } else { cheWorkspaceNoProxy = cheWorkspaceNoProxy + "," + os.Getenv("KUBERNETES_SERVICE_HOST") } - proxyJavaOpts, err = GenerateProxyJavaOpts(deployContext.Proxy, cheWorkspaceNoProxy) + proxyJavaOpts, err = deploy.GenerateProxyJavaOpts(deployContext.Proxy, cheWorkspaceNoProxy) if err != nil { logrus.Errorf("Failed to generate java proxy options: %v", err) } @@ -150,34 +152,34 @@ func GetCheConfigMapData(deployContext *DeployContext) (cheEnv map[string]string if tlsSupport && tlsSecretName == "" { tlsSecretName = "che-tls" } - securityContextFsGroup := util.GetValue(deployContext.CheCluster.Spec.K8s.SecurityContextFsGroup, DefaultSecurityContextFsGroup) - securityContextRunAsUser := util.GetValue(deployContext.CheCluster.Spec.K8s.SecurityContextRunAsUser, DefaultSecurityContextRunAsUser) - pvcStrategy := util.GetValue(deployContext.CheCluster.Spec.Storage.PvcStrategy, DefaultPvcStrategy) - pvcClaimSize := util.GetValue(deployContext.CheCluster.Spec.Storage.PvcClaimSize, DefaultPvcClaimSize) + securityContextFsGroup := util.GetValue(deployContext.CheCluster.Spec.K8s.SecurityContextFsGroup, deploy.DefaultSecurityContextFsGroup) + securityContextRunAsUser := util.GetValue(deployContext.CheCluster.Spec.K8s.SecurityContextRunAsUser, deploy.DefaultSecurityContextRunAsUser) + pvcStrategy := util.GetValue(deployContext.CheCluster.Spec.Storage.PvcStrategy, deploy.DefaultPvcStrategy) + pvcClaimSize := util.GetValue(deployContext.CheCluster.Spec.Storage.PvcClaimSize, deploy.DefaultPvcClaimSize) workspacePvcStorageClassName := deployContext.CheCluster.Spec.Storage.WorkspacePVCStorageClassName - defaultPVCJobsImage := DefaultPvcJobsImage(deployContext.CheCluster) + defaultPVCJobsImage := deploy.DefaultPvcJobsImage(deployContext.CheCluster) pvcJobsImage := util.GetValue(deployContext.CheCluster.Spec.Storage.PvcJobsImage, defaultPVCJobsImage) preCreateSubPaths := "true" if !deployContext.CheCluster.Spec.Storage.PreCreateSubPaths { preCreateSubPaths = "false" } - chePostgresHostName := util.GetValue(deployContext.CheCluster.Spec.Database.ChePostgresHostName, DefaultChePostgresHostName) - chePostgresPort := util.GetValue(deployContext.CheCluster.Spec.Database.ChePostgresPort, DefaultChePostgresPort) - chePostgresDb := util.GetValue(deployContext.CheCluster.Spec.Database.ChePostgresDb, DefaultChePostgresDb) + chePostgresHostName := util.GetValue(deployContext.CheCluster.Spec.Database.ChePostgresHostName, deploy.DefaultChePostgresHostName) + chePostgresPort := util.GetValue(deployContext.CheCluster.Spec.Database.ChePostgresPort, deploy.DefaultChePostgresPort) + chePostgresDb := util.GetValue(deployContext.CheCluster.Spec.Database.ChePostgresDb, deploy.DefaultChePostgresDb) keycloakRealm := util.GetValue(deployContext.CheCluster.Spec.Auth.IdentityProviderRealm, cheFlavor) keycloakClientId := util.GetValue(deployContext.CheCluster.Spec.Auth.IdentityProviderClientId, cheFlavor+"-public") - ingressStrategy := util.GetServerExposureStrategy(deployContext.CheCluster, DefaultServerExposureStrategy) - ingressClass := util.GetValue(deployContext.CheCluster.Spec.K8s.IngressClass, DefaultIngressClass) + ingressStrategy := util.GetServerExposureStrategy(deployContext.CheCluster, deploy.DefaultServerExposureStrategy) + ingressClass := util.GetValue(deployContext.CheCluster.Spec.K8s.IngressClass, deploy.DefaultIngressClass) devfileRegistryUrl := deployContext.CheCluster.Status.DevfileRegistryURL pluginRegistryUrl := deployContext.CheCluster.Status.PluginRegistryURL - cheLogLevel := util.GetValue(deployContext.CheCluster.Spec.Server.CheLogLevel, DefaultCheLogLevel) - cheDebug := util.GetValue(deployContext.CheCluster.Spec.Server.CheDebug, DefaultCheDebug) + cheLogLevel := util.GetValue(deployContext.CheCluster.Spec.Server.CheLogLevel, deploy.DefaultCheLogLevel) + cheDebug := util.GetValue(deployContext.CheCluster.Spec.Server.CheDebug, deploy.DefaultCheDebug) cheMetrics := strconv.FormatBool(deployContext.CheCluster.Spec.Metrics.Enable) - cheLabels := util.MapToKeyValuePairs(GetLabels(deployContext.CheCluster, DefaultCheFlavor(deployContext.CheCluster))) - cheMultiUser := GetCheMultiUser(deployContext.CheCluster) - workspaceExposure := GetSingleHostExposureType(deployContext.CheCluster) - singleHostGatewayConfigMapLabels := labels.FormatLabels(util.GetMapValue(deployContext.CheCluster.Spec.Server.SingleHostGatewayConfigMapLabels, DefaultSingleHostGatewayConfigMapLabels)) + cheLabels := util.MapToKeyValuePairs(deploy.GetLabels(deployContext.CheCluster, deploy.DefaultCheFlavor(deployContext.CheCluster))) + cheMultiUser := deploy.GetCheMultiUser(deployContext.CheCluster) + workspaceExposure := deploy.GetSingleHostExposureType(deployContext.CheCluster) + singleHostGatewayConfigMapLabels := labels.FormatLabels(util.GetMapValue(deployContext.CheCluster.Spec.Server.SingleHostGatewayConfigMapLabels, deploy.DefaultSingleHostGatewayConfigMapLabels)) data := &CheConfigMap{ CheMultiUser: cheMultiUser, @@ -200,18 +202,18 @@ func GetCheConfigMapData(deployContext *DeployContext) (cheEnv map[string]string K8STrustCerts: tls, CheLogLevel: cheLogLevel, OpenShiftIdentityProvider: openShiftIdentityProviderId, - JavaOpts: DefaultJavaOpts + " " + proxyJavaOpts, - WorkspaceJavaOpts: DefaultWorkspaceJavaOpts + " " + proxyJavaOpts, - WorkspaceMavenOpts: DefaultWorkspaceJavaOpts + " " + proxyJavaOpts, + JavaOpts: deploy.DefaultJavaOpts + " " + proxyJavaOpts, + WorkspaceJavaOpts: deploy.DefaultWorkspaceJavaOpts + " " + proxyJavaOpts, + WorkspaceMavenOpts: deploy.DefaultWorkspaceJavaOpts + " " + proxyJavaOpts, WorkspaceProxyJavaOpts: proxyJavaOpts, WorkspaceHttpProxy: deployContext.Proxy.HttpProxy, WorkspaceHttpsProxy: deployContext.Proxy.HttpsProxy, WorkspaceNoProxy: cheWorkspaceNoProxy, PluginRegistryUrl: pluginRegistryUrl, DevfileRegistryUrl: devfileRegistryUrl, - CheWorkspacePluginBrokerMetadataImage: DefaultCheWorkspacePluginBrokerMetadataImage(deployContext.CheCluster), - CheWorkspacePluginBrokerArtifactsImage: DefaultCheWorkspacePluginBrokerArtifactsImage(deployContext.CheCluster), - CheServerSecureExposerJwtProxyImage: DefaultCheServerSecureExposerJwtProxyImage(deployContext.CheCluster), + CheWorkspacePluginBrokerMetadataImage: deploy.DefaultCheWorkspacePluginBrokerMetadataImage(deployContext.CheCluster), + CheWorkspacePluginBrokerArtifactsImage: deploy.DefaultCheWorkspacePluginBrokerArtifactsImage(deployContext.CheCluster), + CheServerSecureExposerJwtProxyImage: deploy.DefaultCheServerSecureExposerJwtProxyImage(deployContext.CheCluster), CheJGroupsKubernetesLabels: cheLabels, CheMetricsEnabled: cheMetrics, CheTrustedCABundlesConfigMap: deployContext.CheCluster.Spec.Server.ServerTrustStoreConfigMapName, @@ -255,7 +257,7 @@ func GetCheConfigMapData(deployContext *DeployContext) (cheEnv map[string]string if (defaultTargetNamespace != "" && defaultTargetNamespace != deployContext.CheCluster.Namespace) || (k8sDefaultNamespace != "" && k8sDefaultNamespace != deployContext.CheCluster.Namespace) { - cheTLSSecret, err := GetClusterSecret(deployContext.CheCluster.Spec.K8s.TlsSecretName, deployContext.CheCluster.ObjectMeta.Namespace, deployContext.ClusterAPI) + cheTLSSecret, err := deploy.GetClusterSecret(deployContext.CheCluster.Spec.K8s.TlsSecretName, deployContext.CheCluster.ObjectMeta.Namespace, deployContext.ClusterAPI) if err != nil { return nil, err } diff --git a/pkg/deploy/che_configmap_test.go b/pkg/deploy/server/che_configmap_test.go similarity index 82% rename from pkg/deploy/che_configmap_test.go rename to pkg/deploy/server/che_configmap_test.go index b39e8f1f2d..a89716b71c 100644 --- a/pkg/deploy/che_configmap_test.go +++ b/pkg/deploy/server/che_configmap_test.go @@ -9,9 +9,10 @@ // Contributors: // Red Hat, Inc. - initial API and implementation // -package deploy +package server import ( + "github.com/eclipse/che-operator/pkg/deploy" "strings" "testing" @@ -28,13 +29,13 @@ func TestNewCheConfigMap(t *testing.T) { cr.Spec.Server.CheHost = "myhostname.com" cr.Spec.Server.TlsSupport = true cr.Spec.Auth.OpenShiftoAuth = true - deployContext := &DeployContext{ + deployContext := &deploy.DeployContext{ CheCluster: cr, - Proxy: &Proxy{}, - ClusterAPI: ClusterAPI{}, + Proxy: &deploy.Proxy{}, + ClusterAPI: deploy.ClusterAPI{}, } cheEnv, _ := GetCheConfigMapData(deployContext) - testCm, _ := GetSpecConfigMap(deployContext, CheConfigMapName, cheEnv) + testCm, _ := deploy.GetSpecConfigMap(deployContext, CheConfigMapName, cheEnv) identityProvider := testCm.Data["CHE_INFRA_OPENSHIFT_OAUTH__IDENTITY__PROVIDER"] _, isOpenshiftv4, _ := util.DetectOpenShift() protocol := strings.Split(testCm.Data["CHE_API"], "://")[0] @@ -58,13 +59,13 @@ func TestConfigMapOverride(t *testing.T) { "CHE_WORKSPACE_NO_PROXY": "myproxy.myhostname.com", } cr.Spec.Auth.OpenShiftoAuth = true - deployContext := &DeployContext{ + deployContext := &deploy.DeployContext{ CheCluster: cr, - Proxy: &Proxy{}, - ClusterAPI: ClusterAPI{}, + Proxy: &deploy.Proxy{}, + ClusterAPI: deploy.ClusterAPI{}, } cheEnv, _ := GetCheConfigMapData(deployContext) - testCm, _ := GetSpecConfigMap(deployContext, CheConfigMapName, cheEnv) + testCm, _ := deploy.GetSpecConfigMap(deployContext, CheConfigMapName, cheEnv) if testCm.Data["CHE_WORKSPACE_NO_PROXY"] != "myproxy.myhostname.com" { t.Errorf("Test failed. Expected myproxy.myhostname.com but was %s", testCm.Data["CHE_WORKSPACE_NO_PROXY"]) } diff --git a/pkg/deploy/che_service_test.go b/pkg/deploy/server/che_service_test.go similarity index 87% rename from pkg/deploy/che_service_test.go rename to pkg/deploy/server/che_service_test.go index 03e13c7c35..98457ef702 100644 --- a/pkg/deploy/che_service_test.go +++ b/pkg/deploy/server/che_service_test.go @@ -9,10 +9,11 @@ // Contributors: // Red Hat, Inc. - initial API and implementation // -package deploy +package server import ( "fmt" + "github.com/eclipse/che-operator/pkg/deploy" "testing" orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" @@ -39,9 +40,9 @@ func TestCreateCheDefaultService(t *testing.T) { Server: orgv1.CheClusterSpecServer{}, }, } - deployContext := &DeployContext{ + deployContext := &deploy.DeployContext{ CheCluster: cheCluster, - ClusterAPI: ClusterAPI{}, + ClusterAPI: deploy.ClusterAPI{}, } service, err := GetSpecCheService(deployContext) @@ -63,9 +64,9 @@ func TestCreateCheServerDebug(t *testing.T) { }, }, } - deployContext := &DeployContext{ + deployContext := &deploy.DeployContext{ CheCluster: cheCluster, - ClusterAPI: ClusterAPI{}, + ClusterAPI: deploy.ClusterAPI{}, } service, err := GetSpecCheService(deployContext) @@ -90,9 +91,9 @@ func TestCreateCheServiceEnableMetrics(t *testing.T) { }, } - deployContext := &DeployContext{ + deployContext := &deploy.DeployContext{ CheCluster: cheCluster, - ClusterAPI: ClusterAPI{}, + ClusterAPI: deploy.ClusterAPI{}, } service, err := GetSpecCheService(deployContext) @@ -116,9 +117,9 @@ func TestCreateCheServiceDisableMetrics(t *testing.T) { }, } - deployContext := &DeployContext{ + deployContext := &deploy.DeployContext{ CheCluster: cheCluster, - ClusterAPI: ClusterAPI{}, + ClusterAPI: deploy.ClusterAPI{}, } service, err := GetSpecCheService(deployContext) @@ -131,7 +132,7 @@ func TestCreateCheServiceDisableMetrics(t *testing.T) { t.Error("expected 2 ports") } checkPort(ports[0], "http", 8080, t) - checkPort(ports[1], "metrics", DefaultCheMetricsPort, t) + checkPort(ports[1], "metrics", deploy.DefaultCheMetricsPort, t) } func checkPort(actualPort corev1.ServicePort, expectedName string, expectedPort int32, t *testing.T) { diff --git a/pkg/deploy/configmap_cert.go b/pkg/deploy/server/configmap_cert.go similarity index 77% rename from pkg/deploy/configmap_cert.go rename to pkg/deploy/server/configmap_cert.go index 61fc173fea..c9d3f0b050 100644 --- a/pkg/deploy/configmap_cert.go +++ b/pkg/deploy/server/configmap_cert.go @@ -9,10 +9,11 @@ // Contributors: // Red Hat, Inc. - initial API and implementation // -package deploy +package server import ( "context" + "github.com/eclipse/che-operator/pkg/deploy" "github.com/sirupsen/logrus" corev1 "k8s.io/api/core/v1" @@ -22,9 +23,9 @@ const ( injector = "config.openshift.io/inject-trusted-cabundle" ) -func SyncTrustStoreConfigMapToCluster(deployContext *DeployContext) (*corev1.ConfigMap, error) { +func SyncTrustStoreConfigMapToCluster(deployContext *deploy.DeployContext) (*corev1.ConfigMap, error) { name := deployContext.CheCluster.Spec.Server.ServerTrustStoreConfigMapName - specConfigMap, err := GetSpecConfigMap(deployContext, name, map[string]string{}) + specConfigMap, err := deploy.GetSpecConfigMap(deployContext, name, map[string]string{}) if err != nil { return nil, err } @@ -32,7 +33,7 @@ func SyncTrustStoreConfigMapToCluster(deployContext *DeployContext) (*corev1.Con // OpenShift will automatically injects all certs into the configmap specConfigMap.ObjectMeta.Labels[injector] = "true" - clusterConfigMap, err := getClusterConfigMap(specConfigMap.Name, specConfigMap.Namespace, deployContext.ClusterAPI.Client) + clusterConfigMap, err := deploy.GetClusterConfigMap(specConfigMap.Name, specConfigMap.Namespace, deployContext.ClusterAPI.Client) if err != nil { return nil, err } diff --git a/pkg/deploy/deployment_che.go b/pkg/deploy/server/deployment_che.go similarity index 85% rename from pkg/deploy/deployment_che.go rename to pkg/deploy/server/deployment_che.go index 7bb2c8fd4c..7ed4bcd44b 100644 --- a/pkg/deploy/deployment_che.go +++ b/pkg/deploy/server/deployment_che.go @@ -9,12 +9,14 @@ // Contributors: // Red Hat, Inc. - initial API and implementation // -package deploy +package server import ( "strconv" "strings" + "github.com/eclipse/che-operator/pkg/deploy" + orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" "github.com/eclipse/che-operator/pkg/util" appsv1 "k8s.io/api/apps/v1" @@ -25,40 +27,40 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" ) -func SyncCheDeploymentToCluster(deployContext *DeployContext, cmResourceVersion string) DeploymentProvisioningStatus { - clusterDeployment, err := getClusterDeployment(DefaultCheFlavor(deployContext.CheCluster), deployContext.CheCluster.Namespace, deployContext.ClusterAPI.Client) +func SyncCheDeploymentToCluster(deployContext *deploy.DeployContext, cmResourceVersion string) deploy.DeploymentProvisioningStatus { + clusterDeployment, err := deploy.GetClusterDeployment(deploy.DefaultCheFlavor(deployContext.CheCluster), deployContext.CheCluster.Namespace, deployContext.ClusterAPI.Client) if err != nil { - return DeploymentProvisioningStatus{ - ProvisioningStatus: ProvisioningStatus{Err: err}, + return deploy.DeploymentProvisioningStatus{ + ProvisioningStatus: deploy.ProvisioningStatus{Err: err}, } } specDeployment, err := getSpecCheDeployment(deployContext, cmResourceVersion) if err != nil { - return DeploymentProvisioningStatus{ - ProvisioningStatus: ProvisioningStatus{Err: err}, + return deploy.DeploymentProvisioningStatus{ + ProvisioningStatus: deploy.ProvisioningStatus{Err: err}, } } - return SyncDeploymentToCluster(deployContext, specDeployment, clusterDeployment, nil, nil) + return deploy.SyncDeploymentToCluster(deployContext, specDeployment, clusterDeployment, nil, nil) } -func getSpecCheDeployment(deployContext *DeployContext, cmResourceVersion string) (*appsv1.Deployment, error) { +func getSpecCheDeployment(deployContext *deploy.DeployContext, cmResourceVersion string) (*appsv1.Deployment, error) { isOpenShift, _, err := util.DetectOpenShift() if err != nil { return nil, err } - selfSignedCertUsed, err := IsSelfSignedCertificateUsed(deployContext) + selfSignedCertUsed, err := deploy.IsSelfSignedCertificateUsed(deployContext) if err != nil { return nil, err } terminationGracePeriodSeconds := int64(30) - cheFlavor := DefaultCheFlavor(deployContext.CheCluster) - labels := GetLabels(deployContext.CheCluster, cheFlavor) + cheFlavor := deploy.DefaultCheFlavor(deployContext.CheCluster) + labels := deploy.GetLabels(deployContext.CheCluster, cheFlavor) optionalEnv := true - memRequest := util.GetValue(deployContext.CheCluster.Spec.Server.ServerMemoryRequest, DefaultServerMemoryRequest) + memRequest := util.GetValue(deployContext.CheCluster.Spec.Server.ServerMemoryRequest, deploy.DefaultServerMemoryRequest) selfSignedCertEnv := corev1.EnvVar{ Name: "CHE_SELF__SIGNED__CERT", Value: "", @@ -96,7 +98,7 @@ func getSpecCheDeployment(deployContext *DeployContext, cmResourceVersion string SecretKeyRef: &corev1.SecretKeySelector{ Key: "ca.crt", LocalObjectReference: corev1.LocalObjectReference{ - Name: CheTLSSelfSignedCertificateSecretName, + Name: deploy.CheTLSSelfSignedCertificateSecretName, }, Optional: &optionalEnv, }, @@ -183,9 +185,9 @@ func getSpecCheDeployment(deployContext *DeployContext, cmResourceVersion string FieldPath: "metadata.namespace"}}, }) - memLimit := util.GetValue(deployContext.CheCluster.Spec.Server.ServerMemoryLimit, DefaultServerMemoryLimit) + memLimit := util.GetValue(deployContext.CheCluster.Spec.Server.ServerMemoryLimit, deploy.DefaultServerMemoryLimit) cheImageAndTag := GetFullCheServerImageLink(deployContext.CheCluster) - pullPolicy := corev1.PullPolicy(util.GetValue(string(deployContext.CheCluster.Spec.Server.CheImagePullPolicy), DefaultPullPolicyFromDockerImage(cheImageAndTag))) + pullPolicy := corev1.PullPolicy(util.GetValue(string(deployContext.CheCluster.Spec.Server.CheImagePullPolicy), deploy.DefaultPullPolicyFromDockerImage(cheImageAndTag))) deployment := &appsv1.Deployment{ TypeMeta: metav1.TypeMeta{ @@ -262,7 +264,7 @@ func getSpecCheDeployment(deployContext *DeployContext, cmResourceVersion string }, } - cheMultiUser := GetCheMultiUser(deployContext.CheCluster) + cheMultiUser := deploy.GetCheMultiUser(deployContext.CheCluster) if cheMultiUser == "true" { chePostgresSecret := deployContext.CheCluster.Spec.Database.ChePostgresSecret if len(chePostgresSecret) > 0 { @@ -293,22 +295,22 @@ func getSpecCheDeployment(deployContext *DeployContext, cmResourceVersion string deployment.Spec.Strategy.Type = appsv1.RecreateDeploymentStrategyType deployment.Spec.Template.Spec.Volumes = []corev1.Volume{ { - Name: DefaultCheVolumeClaimName, + Name: deploy.DefaultCheVolumeClaimName, VolumeSource: corev1.VolumeSource{ PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ - ClaimName: DefaultCheVolumeClaimName, + ClaimName: deploy.DefaultCheVolumeClaimName, }, }, }} deployment.Spec.Template.Spec.Containers[0].VolumeMounts = []corev1.VolumeMount{ { - MountPath: DefaultCheVolumeMountPath, - Name: DefaultCheVolumeClaimName, + MountPath: deploy.DefaultCheVolumeMountPath, + Name: deploy.DefaultCheVolumeClaimName, }} } // configure probes if debug isn't set - cheDebug := util.GetValue(deployContext.CheCluster.Spec.Server.CheDebug, DefaultCheDebug) + cheDebug := util.GetValue(deployContext.CheCluster.Spec.Server.CheDebug, deploy.DefaultCheDebug) if cheDebug != "true" { deployment.Spec.Template.Spec.Containers[0].ReadinessProbe = &corev1.Probe{ Handler: corev1.Handler{ @@ -350,11 +352,11 @@ func getSpecCheDeployment(deployContext *DeployContext, cmResourceVersion string } if !isOpenShift { - runAsUser, err := strconv.ParseInt(util.GetValue(deployContext.CheCluster.Spec.K8s.SecurityContextRunAsUser, DefaultSecurityContextRunAsUser), 10, 64) + runAsUser, err := strconv.ParseInt(util.GetValue(deployContext.CheCluster.Spec.K8s.SecurityContextRunAsUser, deploy.DefaultSecurityContextRunAsUser), 10, 64) if err != nil { return nil, err } - fsGroup, err := strconv.ParseInt(util.GetValue(deployContext.CheCluster.Spec.K8s.SecurityContextFsGroup, DefaultSecurityContextFsGroup), 10, 64) + fsGroup, err := strconv.ParseInt(util.GetValue(deployContext.CheCluster.Spec.K8s.SecurityContextFsGroup, deploy.DefaultSecurityContextFsGroup), 10, 64) if err != nil { return nil, err } @@ -378,11 +380,11 @@ func getSpecCheDeployment(deployContext *DeployContext, cmResourceVersion string // based on Checluster information and image defaults from env variables func GetFullCheServerImageLink(checluster *orgv1.CheCluster) string { if len(checluster.Spec.Server.CheImage) > 0 { - cheServerImageTag := util.GetValue(checluster.Spec.Server.CheImageTag, DefaultCheVersion()) + cheServerImageTag := util.GetValue(checluster.Spec.Server.CheImageTag, deploy.DefaultCheVersion()) return checluster.Spec.Server.CheImage + ":" + cheServerImageTag } - defaultCheServerImage := DefaultCheServerImage(checluster) + defaultCheServerImage := deploy.DefaultCheServerImage(checluster) if len(checluster.Spec.Server.CheImageTag) == 0 { return defaultCheServerImage } diff --git a/pkg/deploy/server/init_test.go b/pkg/deploy/server/init_test.go new file mode 100644 index 0000000000..e6f7152434 --- /dev/null +++ b/pkg/deploy/server/init_test.go @@ -0,0 +1,21 @@ +// +// Copyright (c) 2020-2020 Red Hat, Inc. +// This program and the accompanying materials are made +// available under the terms of the Eclipse Public License 2.0 +// which is available at https://www.eclipse.org/legal/epl-2.0/ +// +// SPDX-License-Identifier: EPL-2.0 +// +// Contributors: +// Red Hat, Inc. - initial API and implementation +// +package server + +import "github.com/eclipse/che-operator/pkg/deploy" + +func init() { + err := deploy.InitTestDefaultsFromDeployment("../../../deploy/operator.yaml") + if err != nil { + panic(err) + } +} diff --git a/pkg/deploy/server/service.go b/pkg/deploy/server/service.go new file mode 100644 index 0000000000..379431a552 --- /dev/null +++ b/pkg/deploy/server/service.go @@ -0,0 +1,46 @@ +// +// Copyright (c) 2020-2020 Red Hat, Inc. +// This program and the accompanying materials are made +// available under the terms of the Eclipse Public License 2.0 +// which is available at https://www.eclipse.org/legal/epl-2.0/ +// +// SPDX-License-Identifier: EPL-2.0 +// +// Contributors: +// Red Hat, Inc. - initial API and implementation +// +package server + +import ( + "github.com/eclipse/che-operator/pkg/deploy" + v1 "k8s.io/api/core/v1" +) + +func GetSpecCheService(deployContext *deploy.DeployContext) (*v1.Service, error) { + portName := []string{"http"} + portNumber := []int32{8080} + labels := deploy.GetLabels(deployContext.CheCluster, deploy.DefaultCheFlavor(deployContext.CheCluster)) + + if deployContext.CheCluster.Spec.Metrics.Enable { + portName = append(portName, "metrics") + portNumber = append(portNumber, deploy.DefaultCheMetricsPort) + } + + if deployContext.CheCluster.Spec.Server.CheDebug == "true" { + portName = append(portName, "debug") + portNumber = append(portNumber, deploy.DefaultCheDebugPort) + } + + return deploy.GetSpecService(deployContext, deploy.CheServiceName, portName, portNumber, labels) +} + +func SyncCheServiceToCluster(deployContext *deploy.DeployContext) deploy.ServiceProvisioningStatus { + specService, err := GetSpecCheService(deployContext) + if err != nil { + return deploy.ServiceProvisioningStatus{ + ProvisioningStatus: deploy.ProvisioningStatus{Err: err}, + } + } + + return deploy.DoSyncServiceToCluster(deployContext, specService) +} diff --git a/pkg/deploy/service.go b/pkg/deploy/service.go index 8aa3479e81..0318ff68db 100644 --- a/pkg/deploy/service.go +++ b/pkg/deploy/service.go @@ -15,7 +15,6 @@ package deploy import ( "context" "fmt" - "github.com/eclipse/che-operator/pkg/util" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" @@ -40,52 +39,23 @@ var portsDiffOpts = cmp.Options{ cmpopts.IgnoreFields(corev1.ServicePort{}, "TargetPort", "NodePort"), } -func SyncCheServiceToCluster(deployContext *DeployContext) ServiceProvisioningStatus { - specService, err := GetSpecCheService(deployContext) - if err != nil { - return ServiceProvisioningStatus{ - ProvisioningStatus: ProvisioningStatus{Err: err}, - } - } - - return doSyncServiceToCluster(deployContext, specService) -} - -func GetSpecCheService(deployContext *DeployContext) (*corev1.Service, error) { - portName := []string{"http"} - portNumber := []int32{8080} - labels := GetLabels(deployContext.CheCluster, DefaultCheFlavor(deployContext.CheCluster)) - - if deployContext.CheCluster.Spec.Metrics.Enable { - portName = append(portName, "metrics") - portNumber = append(portNumber, DefaultCheMetricsPort) - } - - if deployContext.CheCluster.Spec.Server.CheDebug == "true" { - portName = append(portName, "debug") - portNumber = append(portNumber, DefaultCheDebugPort) - } - - return getSpecService(deployContext, CheServiceName, portName, portNumber, labels) -} - func SyncServiceToCluster( deployContext *DeployContext, name string, portName []string, portNumber []int32, labels map[string]string) ServiceProvisioningStatus { - specService, err := getSpecService(deployContext, name, portName, portNumber, labels) + specService, err := GetSpecService(deployContext, name, portName, portNumber, labels) if err != nil { return ServiceProvisioningStatus{ ProvisioningStatus: ProvisioningStatus{Err: err}, } } - return doSyncServiceToCluster(deployContext, specService) + return DoSyncServiceToCluster(deployContext, specService) } -func doSyncServiceToCluster(deployContext *DeployContext, specService *corev1.Service) ServiceProvisioningStatus { +func DoSyncServiceToCluster(deployContext *DeployContext, specService *corev1.Service) ServiceProvisioningStatus { clusterService, err := getClusterService(specService.Name, specService.Namespace, deployContext.ClusterAPI.Client) if err != nil { @@ -127,7 +97,7 @@ func doSyncServiceToCluster(deployContext *DeployContext, specService *corev1.Se } } -func getSpecService( +func GetSpecService( deployContext *DeployContext, name string, portName []string, diff --git a/pkg/util/k8s_helpers_test.go b/pkg/util/k8s_helpers_test.go index cd26ddf14a..97a1eab27d 100644 --- a/pkg/util/k8s_helpers_test.go +++ b/pkg/util/k8s_helpers_test.go @@ -20,7 +20,7 @@ import ( ) var ( - fakeK8s = fakeClientSet() + fakeK8s = fakeClientSet() namespace = "eclipse-che" ) @@ -59,7 +59,6 @@ func TestGetDeploymentPod(t *testing.T) { logrus.Infof("Test passed. Pod %s found", pod) } - func TestGetEvents(t *testing.T) { // fire up an event with fake-pod as involvedObject @@ -101,4 +100,3 @@ func TestGetEvents(t *testing.T) { logrus.Infof("Test passed. Expected event message: %s. Received event message %s", message, fakePodEventMessage) } } - diff --git a/pkg/util/util.go b/pkg/util/util.go index d5bde78c17..97259ab592 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -182,7 +182,6 @@ func GetServerExposureStrategy(c *orgv1.CheCluster, defaultValue string) string } func IsTestMode() (isTesting bool) { - testMode := os.Getenv("MOCK_API") if len(testMode) == 0 { return false