Refactor deploy package (#474)

* Move exposure logic to one place & Group deploy classes

Signed-off-by: Anatolii Bazko <abazko@redhat.com>
pull/485/head
Serhii Leshchenko 2020-10-05 17:34:43 +03:00 committed by GitHub
parent aa8fb587d3
commit cc93735274
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 1043 additions and 1046 deletions

View File

@ -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{},

View File

@ -13,7 +13,6 @@ package main
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func deleteNamespace() (err error) {

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -34,5 +34,3 @@ func VerifyCheRunning(status string) (deployed bool, err error) {
}
}
}

View File

@ -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
}

View File

@ -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

View File

@ -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
}

View File

@ -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")

View File

@ -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,

9
pkg/deploy/const.go Normal file
View File

@ -0,0 +1,9 @@
package deploy
const (
DevfileRegistry = "devfile-registry"
)
const (
PluginRegistry = "plugin-registry"
)

View File

@ -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
}

View File

@ -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
}

View File

@ -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 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
}
}
}
InitDefaultsFromEnv()
}
func TestDefaultFromEnv(t *testing.T) {
cheVersionTest := os.Getenv("CHE_VERSION")
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"))
if DefaultCheVersion() != cheVersionTest {
t.Errorf("Expected %s but was %s", cheVersionTest, DefaultCheVersion())
}

View File

@ -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,

View File

@ -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
}

View File

@ -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)
}

View File

@ -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
}

View File

@ -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
}

120
pkg/deploy/expose/expose.go Normal file
View File

@ -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
}

View File

@ -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{

View File

@ -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 {

View File

@ -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}"

View File

@ -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},

19
pkg/deploy/init_test.go Normal file
View File

@ -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)
}
}

View File

@ -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,
}
}

View File

@ -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)
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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",
},
},

View File

@ -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
}

View File

@ -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
}

View File

@ -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"])
}

View File

@ -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) {

View File

@ -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
}

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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)
}

View File

@ -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,

View File

@ -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)
}
}

View File

@ -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