Code clean up 3 (#753)
* Code clean up part 3 Signed-off-by: Anatolii Bazko <abazko@redhat.com>pull/758/head
parent
92d317caf5
commit
fa39d6f79e
|
|
@ -1,35 +0,0 @@
|
|||
#
|
||||
# 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
|
||||
name: Minishift
|
||||
on: pull_request
|
||||
jobs:
|
||||
minishift-e2e:
|
||||
name: e2e tests
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Provision Minishift cluster
|
||||
run: |
|
||||
brew install minishift
|
||||
export MINISHIFT_GITHUB_API_TOKEN=${{ secrets.GITHUB_TOKEN }}
|
||||
minishift start --memory=5500 --vm-driver=virtualbox
|
||||
- name: Replace Minishift default certificates
|
||||
run: /bin/bash .github/bin/minishift/certs.sh
|
||||
- name: Run tests
|
||||
run: |
|
||||
eval $(minishift oc-env)
|
||||
oc apply -f deploy/crds/org_v1_che_crd.yaml
|
||||
go mod tidy
|
||||
go run e2e/*.go
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: minishift-e2e-artifacts
|
||||
path: /tmp/artifacts-che
|
||||
|
|
@ -26,10 +26,8 @@ oc apply -f ${BASE_DIR}/deploy/crds/org_v1_che_crd.yaml -n $NAMESPACE
|
|||
# sometimes the operator cannot get CRD right away
|
||||
sleep 2
|
||||
|
||||
# uncomment if you need Login with OpenShift
|
||||
#oc new-app -f ${BASE_DIR}/deploy/role_binding_oauth.yaml -p NAMESPACE=$1 -n=$1
|
||||
#oc apply -f ${BASE_DIR}/deploy/cluster_role.yaml -n $NAMESPACE
|
||||
#oc apply -f ${BASE_DIR}/deploy/cluster_role_binding.yaml -n $NAMESPACE
|
||||
oc apply -f ${BASE_DIR}/deploy/cluster_role.yaml -n $NAMESPACE
|
||||
oc apply -f ${BASE_DIR}/deploy/cluster_role_binding.yaml -n $NAMESPACE
|
||||
|
||||
oc apply -f ${BASE_DIR}/deploy/operator.yaml -n $NAMESPACE
|
||||
oc apply -f ${BASE_DIR}/deploy/crds/org_v1_che_cr.yaml -n $NAMESPACE
|
||||
|
|
|
|||
|
|
@ -1,36 +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
|
||||
kind: Template
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: che-operator
|
||||
labels:
|
||||
app.kubernetes.io/name: che
|
||||
app.kubernetes.io/instance: che
|
||||
app.kubernetes.io/component: che-operator
|
||||
objects:
|
||||
- kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: che-operator
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: che-operator
|
||||
namespace: ${NAMESPACE}
|
||||
roleRef:
|
||||
kind: ClusterRole
|
||||
name: che-operator
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
parameters:
|
||||
- name: NAMESPACE
|
||||
displayName: Namespace
|
||||
description: Namespace
|
||||
required: true
|
||||
145
e2e/config.go
145
e2e/config.go
|
|
@ -1,145 +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 main
|
||||
|
||||
import (
|
||||
orgv1 "github.com/eclipse-che/che-operator/pkg/apis/org/v1"
|
||||
oauth "github.com/openshift/api/oauth/v1"
|
||||
"github.com/sirupsen/logrus"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/config"
|
||||
)
|
||||
|
||||
var (
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
clientSet, err = getClientSet()
|
||||
oauthClientSet, _ = getOAuthClientSet()
|
||||
client = GetK8Config()
|
||||
SchemeGroupVersion = schema.GroupVersion{Group: groupName, Version: orgv1.SchemeGroupVersion.Version}
|
||||
)
|
||||
|
||||
type k8s struct {
|
||||
clientset kubernetes.Interface
|
||||
}
|
||||
|
||||
type CRClient struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
type OauthClient struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func GetK8Config() *k8s {
|
||||
cfg, err := config.GetConfig()
|
||||
if err != nil {
|
||||
logrus.Errorf(err.Error())
|
||||
}
|
||||
client := k8s{}
|
||||
client.clientset, err = kubernetes.NewForConfig(cfg)
|
||||
|
||||
if err != nil {
|
||||
logrus.Errorf(err.Error())
|
||||
}
|
||||
return &client
|
||||
}
|
||||
|
||||
func getClientSet() (clientSet *CRClient, err error) {
|
||||
cfg, err := config.GetConfig()
|
||||
if err != nil {
|
||||
logrus.Errorf(err.Error())
|
||||
}
|
||||
client := k8s{}
|
||||
client.clientset, err = kubernetes.NewForConfig(cfg)
|
||||
clientSet, err = newForConfig(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return clientSet, nil
|
||||
}
|
||||
|
||||
func getOAuthClientSet() (clientSet *OauthClient, err error) {
|
||||
cfg, err := config.GetConfig()
|
||||
if err != nil {
|
||||
logrus.Errorf(err.Error())
|
||||
}
|
||||
client := k8s{}
|
||||
client.clientset, err = kubernetes.NewForConfig(cfg)
|
||||
clientSet, err = newOAuthConfig(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return clientSet, nil
|
||||
}
|
||||
|
||||
func getCR() (*orgv1.CheCluster, error) {
|
||||
|
||||
result := orgv1.CheCluster{}
|
||||
opts := metav1.ListOptions{}
|
||||
err = clientSet.restClient.
|
||||
Get().
|
||||
Namespace(namespace).
|
||||
Resource(kind).
|
||||
Name(crName).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(&result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func newForConfig(c *rest.Config) (*CRClient, error) {
|
||||
config := *c
|
||||
config.ContentConfig.GroupVersion = &schema.GroupVersion{Group: groupName, Version: orgv1.SchemeGroupVersion.Version}
|
||||
//config.ContentConfig.GroupVersion = &schema.GroupVersion{Group: oauth.GroupName, Version: oauth.SchemeGroupVersion.Version}
|
||||
config.APIPath = "/apis"
|
||||
config.NegotiatedSerializer = serializer.WithoutConversionCodecFactory{CodecFactory: scheme.Codecs}
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &CRClient{restClient: client}, nil
|
||||
}
|
||||
|
||||
func newOAuthConfig(c *rest.Config) (*OauthClient, error) {
|
||||
config := *c
|
||||
config.ContentConfig.GroupVersion = &schema.GroupVersion{Group: oauth.GroupName, Version: oauth.SchemeGroupVersion.Version}
|
||||
config.APIPath = "/apis"
|
||||
config.NegotiatedSerializer = serializer.WithoutConversionCodecFactory{CodecFactory: scheme.Codecs}
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &OauthClient{restClient: client}, nil
|
||||
}
|
||||
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&orgv1.CheCluster{},
|
||||
&orgv1.CheClusterList{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
}
|
||||
149
e2e/create.go
149
e2e/create.go
|
|
@ -1,149 +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 main
|
||||
|
||||
import (
|
||||
orgv1 "github.com/eclipse-che/che-operator/pkg/apis/org/v1"
|
||||
"github.com/eclipse-che/che-operator/pkg/util"
|
||||
"github.com/sirupsen/logrus"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
rbac "k8s.io/api/rbac/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func createOperatorServiceAccount(operatorServiceAccount *corev1.ServiceAccount) (err error) {
|
||||
|
||||
operatorServiceAccount, err = client.clientset.CoreV1().ServiceAccounts(namespace).Create(operatorServiceAccount)
|
||||
if err != nil {
|
||||
logrus.Fatalf("Failed to create service account %s: %s", operatorServiceAccount.Name, err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func createOperatorServiceAccountRole(operatorServiceAccountRole *rbac.Role) (err error) {
|
||||
|
||||
operatorServiceAccountRole, err = client.clientset.RbacV1().Roles(namespace).Create(operatorServiceAccountRole)
|
||||
if err != nil {
|
||||
logrus.Fatalf("Failed to create role %s: %s", operatorServiceAccountRole.Name, err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func createOperatorServiceAccountClusterRole(operatorServiceAccountClusterRole *rbac.ClusterRole) (err error) {
|
||||
|
||||
operatorServiceAccountClusterRole, err = client.clientset.RbacV1().ClusterRoles().Create(operatorServiceAccountClusterRole)
|
||||
if err != nil && !errors.IsAlreadyExists(err) {
|
||||
logrus.Fatalf("Failed to create role %s: %s", operatorServiceAccountClusterRole.Name, err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func createOperatorServiceAccountRoleBinding(operatorServiceAccountRoleBinding *rbac.RoleBinding) (err error) {
|
||||
|
||||
operatorServiceAccountRoleBinding, err = client.clientset.RbacV1().RoleBindings(namespace).Create(operatorServiceAccountRoleBinding)
|
||||
if err != nil {
|
||||
logrus.Fatalf("Failed to create role %s: %s", operatorServiceAccountRoleBinding.Name, err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func createOperatorServiceAccountClusterRoleBinding(operatorServiceAccountClusterRoleBinding *rbac.ClusterRoleBinding) (err error) {
|
||||
|
||||
operatorServiceAccountClusterRoleBinding, err = client.clientset.RbacV1().ClusterRoleBindings().Create(operatorServiceAccountClusterRoleBinding)
|
||||
if err != nil && !errors.IsAlreadyExists(err) {
|
||||
logrus.Fatalf("Failed to create role %s: %s", operatorServiceAccountClusterRoleBinding.Name, err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func deployOperator(deployment *appsv1.Deployment) (err error) {
|
||||
|
||||
deployment, err = client.clientset.AppsV1().Deployments(namespace).Create(deployment)
|
||||
if err != nil {
|
||||
logrus.Fatalf("Failed to create deployment %s: %s", deployment.Name, err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func newNamespace() (ns *corev1.Namespace) {
|
||||
|
||||
return &corev1.Namespace{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Namespace",
|
||||
APIVersion: corev1.SchemeGroupVersion.Version,
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: namespace,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func createNamespace(ns *corev1.Namespace) (err error) {
|
||||
|
||||
ns, err = client.clientset.CoreV1().Namespaces().Create(ns)
|
||||
if err != nil {
|
||||
logrus.Warn(err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func newCheCluster() (cr *orgv1.CheCluster) {
|
||||
cr = &orgv1.CheCluster{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: crName,
|
||||
},
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: kind,
|
||||
},
|
||||
Spec: orgv1.CheClusterSpec{
|
||||
Server: orgv1.CheClusterSpecServer{
|
||||
UseInternalClusterSVCNames: true,
|
||||
},
|
||||
Auth: orgv1.CheClusterSpecAuth{
|
||||
OpenShiftoAuth: util.NewBoolPointer(true),
|
||||
},
|
||||
},
|
||||
}
|
||||
return cr
|
||||
}
|
||||
|
||||
func createCR() (err error) {
|
||||
result := orgv1.CheCluster{}
|
||||
cheCluster := newCheCluster()
|
||||
err = clientSet.restClient.
|
||||
Post().
|
||||
Namespace(namespace).
|
||||
Resource(kind).
|
||||
Name(crName).
|
||||
Body(cheCluster).
|
||||
Do().
|
||||
Into(&result)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1,23 +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 main
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func deleteNamespace() (err error) {
|
||||
if err := client.clientset.CoreV1().Namespaces().Delete(namespace, &metav1.DeleteOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1,142 +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 main
|
||||
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"io/ioutil"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
rbac "k8s.io/api/rbac/v1"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func deserializeOperatorDeployment() (operatorDeployment *appsv1.Deployment, err error) {
|
||||
fileLocation, err := filepath.Abs("deploy/operator.yaml")
|
||||
if err != nil {
|
||||
logrus.Fatalf("Failed to locate operator deployment yaml, %s", err)
|
||||
}
|
||||
file, err := ioutil.ReadFile(fileLocation)
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to locate operator deployment yaml, %s", err)
|
||||
}
|
||||
deployment := string(file)
|
||||
decode := scheme.Codecs.UniversalDeserializer().Decode
|
||||
object, _, err := decode([]byte(deployment), nil, nil)
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to deserialize yaml %s", err)
|
||||
return nil, err
|
||||
}
|
||||
operatorDeployment = object.(*appsv1.Deployment)
|
||||
return operatorDeployment, nil
|
||||
}
|
||||
|
||||
func deserializeOperatorServiceAccount() (operatorServiceAccount *corev1.ServiceAccount, err error) {
|
||||
fileLocation, err := filepath.Abs("deploy/service_account.yaml")
|
||||
if err != nil {
|
||||
logrus.Fatalf("Failed to locate operator service account yaml, %s", err)
|
||||
}
|
||||
file, err := ioutil.ReadFile(fileLocation)
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to locate operator service account yaml, %s", err)
|
||||
}
|
||||
sa := string(file)
|
||||
decode := scheme.Codecs.UniversalDeserializer().Decode
|
||||
object, _, err := decode([]byte(sa), nil, nil)
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to deserialize yaml %s", err)
|
||||
return nil, err
|
||||
}
|
||||
operatorServiceAccount = object.(*corev1.ServiceAccount)
|
||||
return operatorServiceAccount, nil
|
||||
}
|
||||
|
||||
func deserializeOperatorRole() (operatorServiceAccountRole *rbac.Role, err error) {
|
||||
fileLocation, err := filepath.Abs("deploy/role.yaml")
|
||||
if err != nil {
|
||||
logrus.Fatalf("Failed to locate operator service account role yaml, %s", err)
|
||||
}
|
||||
file, err := ioutil.ReadFile(fileLocation)
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to locate operator service account role yaml, %s", err)
|
||||
}
|
||||
role := string(file)
|
||||
decode := scheme.Codecs.UniversalDeserializer().Decode
|
||||
object, _, err := decode([]byte(role), nil, nil)
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to deserialize yaml %s", err)
|
||||
return nil, err
|
||||
}
|
||||
operatorServiceAccountRole = object.(*rbac.Role)
|
||||
return operatorServiceAccountRole, nil
|
||||
}
|
||||
|
||||
func deserializeOperatorClusterRole() (operatorServiceAccountClusterRole *rbac.ClusterRole, err error) {
|
||||
fileLocation, err := filepath.Abs("deploy/cluster_role.yaml")
|
||||
if err != nil {
|
||||
logrus.Fatalf("Failed to locate operator service account cluster role yaml, %s", err)
|
||||
}
|
||||
file, err := ioutil.ReadFile(fileLocation)
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to locate operator service account cluster role yaml, %s", err)
|
||||
}
|
||||
role := string(file)
|
||||
decode := scheme.Codecs.UniversalDeserializer().Decode
|
||||
object, _, err := decode([]byte(role), nil, nil)
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to deserialize yaml %s", err)
|
||||
return nil, err
|
||||
}
|
||||
operatorServiceAccountClusterRole = object.(*rbac.ClusterRole)
|
||||
return operatorServiceAccountClusterRole, nil
|
||||
}
|
||||
|
||||
func deserializeOperatorRoleBinding() (operatorServiceAccountRoleBinding *rbac.RoleBinding, err error) {
|
||||
fileLocation, err := filepath.Abs("deploy/role_binding.yaml")
|
||||
if err != nil {
|
||||
logrus.Fatalf("Failed to locate operator service account role binding yaml, %s", err)
|
||||
}
|
||||
file, err := ioutil.ReadFile(fileLocation)
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to locate operator service account role binding yaml, %s", err)
|
||||
}
|
||||
roleBinding := string(file)
|
||||
decode := scheme.Codecs.UniversalDeserializer().Decode
|
||||
object, _, err := decode([]byte(roleBinding), nil, nil)
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to deserialize yaml %s", err)
|
||||
return nil, err
|
||||
}
|
||||
operatorServiceAccountRoleBinding = object.(*rbac.RoleBinding)
|
||||
return operatorServiceAccountRoleBinding, nil
|
||||
}
|
||||
|
||||
func deserializeOperatorClusterRoleBinding() (operatorServiceAccountClusterRoleBinding *rbac.ClusterRoleBinding, err error) {
|
||||
fileLocation, err := filepath.Abs("deploy/cluster_role_binding.yaml")
|
||||
if err != nil {
|
||||
logrus.Fatalf("Failed to locate operator service account role binding yaml, %s", err)
|
||||
}
|
||||
file, err := ioutil.ReadFile(fileLocation)
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to locate operator service account role binding yaml, %s", err)
|
||||
}
|
||||
roleBinding := string(file)
|
||||
decode := scheme.Codecs.UniversalDeserializer().Decode
|
||||
object, _, err := decode([]byte(roleBinding), nil, nil)
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to deserialize yaml %s", err)
|
||||
return nil, err
|
||||
}
|
||||
operatorServiceAccountClusterRoleBinding = object.(*rbac.ClusterRoleBinding)
|
||||
return operatorServiceAccountClusterRoleBinding, nil
|
||||
}
|
||||
38
e2e/get.go
38
e2e/get.go
|
|
@ -1,38 +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 main
|
||||
|
||||
import (
|
||||
oauth "github.com/openshift/api/oauth/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func getConfigMap(cmName string) (cm *corev1.ConfigMap, err error) {
|
||||
|
||||
cm, err = client.clientset.CoreV1().ConfigMaps(namespace).Get(cmName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cm, nil
|
||||
|
||||
}
|
||||
45
e2e/patch.go
45
e2e/patch.go
|
|
@ -1,45 +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 main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/sirupsen/logrus"
|
||||
api "k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
func patchCustomResource(path string, value bool) (err error) {
|
||||
|
||||
type PatchSpec struct {
|
||||
Operation string `json:"op"`
|
||||
Path string `json:"path"`
|
||||
Value bool `json:"value"`
|
||||
}
|
||||
|
||||
fields := make([]PatchSpec, 1)
|
||||
fields[0].Operation = "replace"
|
||||
fields[0].Path = path
|
||||
fields[0].Value = value
|
||||
patchBytes, err := json.Marshal(fields)
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to marchall fields %s", err)
|
||||
return err
|
||||
}
|
||||
_, err = clientSet.restClient.Patch(api.JSONPatchType).Name(crName).Namespace(namespace).Resource(kind).Body(patchBytes).Do().Get()
|
||||
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to patch CR: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# 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
|
||||
|
||||
# Exit on error
|
||||
set -e
|
||||
|
||||
trap 'Catch_Finish $?' EXIT SIGINT
|
||||
|
||||
source ../.ci/util/ci_common.sh
|
||||
|
||||
Catch_Finish() {
|
||||
rm -rf ${OPERATOR_REPO}/tmp
|
||||
}
|
||||
|
||||
#TODO! Move this utilities to another folder
|
||||
printInfo() {
|
||||
green=`tput setaf 2`
|
||||
reset=`tput sgr0`
|
||||
echo "${green}[INFO]: ${1} ${reset}"
|
||||
}
|
||||
|
||||
printError() {
|
||||
red=`tput setaf 1`
|
||||
reset=`tput sgr0`
|
||||
echo "${red}[ERROR]: ${1} ${reset}"
|
||||
}
|
||||
|
||||
init() {
|
||||
MSFT_RELEASE="1.34.2"
|
||||
GO_TOOLSET_VERSION="1.11.5-3"
|
||||
SCRIPT=$(readlink -f "$0") # this script's absolute path
|
||||
SCRIPTPATH=$(dirname "$SCRIPT") # /path/to/e2e/ folder
|
||||
if [[ ${WORKSPACE} ]] && [[ -d ${WORKSPACE} ]]; then OPERATOR_REPO=${WORKSPACE}; else OPERATOR_REPO=$(dirname "$SCRIPTPATH"); fi
|
||||
}
|
||||
|
||||
eval_minishift_env() {
|
||||
if ! [ -x "$(command -v minsishift)" ]; then
|
||||
printError 'Minishift is not installed.Please install minishift following the instructions: https://docs.okd.io/latest/minishift/getting-started/installing.html' >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! $(ps axf | grep minishift | grep -v grep) ]]; then
|
||||
printError "Minishift is not running. Please start minishift to be available to run e2e tests!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
eval $(minishift oc-env)
|
||||
oc login -u system:admin
|
||||
oc adm policy add-cluster-role-to-user cluster-admin developer && oc login -u developer -p developer
|
||||
}
|
||||
|
||||
oc_tls_mode() {
|
||||
# generate self signed cert
|
||||
printInfo "Generate self signed certificate"
|
||||
cd $OPERATOR_REPO/tmp && generate_self_signed_certs # replace default router cert
|
||||
printInfo "Update OpenShift router tls secret"
|
||||
oc project default
|
||||
oc secrets new router-certs tls.crt=ca.crt tls.key=key.pem -o json --type='kubernetes.io/tls' --confirm | oc replace -f -
|
||||
printInfo "Initiate a new router deployment"
|
||||
sleep 20
|
||||
oc rollout latest dc/router -n=default || true
|
||||
}
|
||||
|
||||
run_tests() {
|
||||
if [ ! -d "$OPERATOR_REPO/tmp" ]; then mkdir -p "$OPERATOR_REPO/tmp" && chmod 777 "$OPERATOR_REPO/tmp"; fi
|
||||
eval_minishift_env
|
||||
printInfo "Register a custom resource definition"
|
||||
oc apply -f ${OPERATOR_REPO}/deploy/crds/org_v1_che_crd.yaml
|
||||
|
||||
oc_tls_mode
|
||||
|
||||
printInfo "Compile tests binary"
|
||||
docker run -t \
|
||||
-v ${OPERATOR_REPO}/tmp:/operator \
|
||||
-v ${OPERATOR_REPO}:/opt/app-root/src/go/src/github.com/eclipse-che/che-operator registry.access.redhat.com/devtools/go-toolset-rhel7:${GO_TOOLSET_VERSION} \
|
||||
sh -c "OOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o /operator/run-tests /opt/app-root/src/go/src/github.com/eclipse-che/che-operator/e2e/*.go"
|
||||
|
||||
printInfo "Build operator docker image and load in to minishift VM..."
|
||||
cd ${OPERATOR_REPO} && docker build -t che/operator -f Dockerfile . && docker save che/operator > operator.tar
|
||||
eval $(minishift docker-env) && docker load -i operator.tar && rm operator.tar
|
||||
|
||||
printInfo "Run tests..."
|
||||
${OPERATOR_REPO}/tmp/run-tests
|
||||
}
|
||||
|
||||
init
|
||||
run_tests
|
||||
#TODO avoid the use of cd on shell...
|
||||
173
e2e/tests.go
173
e2e/tests.go
|
|
@ -1,173 +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 main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
orgv1 "github.com/eclipse-che/che-operator/pkg/apis/org/v1"
|
||||
"github.com/eclipse-che/che-operator/pkg/controller/che"
|
||||
"github.com/sirupsen/logrus"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/tools/clientcmd/api"
|
||||
)
|
||||
|
||||
var (
|
||||
crName = "eclipse-che"
|
||||
kind = "checlusters"
|
||||
groupName = "org.eclipse.che"
|
||||
namespace = "che"
|
||||
)
|
||||
|
||||
func main() {
|
||||
logrus.Info("Starting CHE/CRW operator e2e tests")
|
||||
logrus.Info("A running OCP instance and cluster-admin login are required")
|
||||
logrus.Info("Adding CRD to schema")
|
||||
if err := orgv1.SchemeBuilder.AddToScheme(scheme.Scheme); err != nil {
|
||||
logrus.Fatalf("Failed to add CRD to scheme")
|
||||
}
|
||||
apiScheme := runtime.NewScheme()
|
||||
if err := api.AddToScheme(apiScheme); err != nil {
|
||||
logrus.Fatalf("Failed to add CRD to scheme")
|
||||
}
|
||||
logrus.Info("CRD successfully added to schema")
|
||||
|
||||
logrus.Infof("Creating a new namespace: %s", namespace)
|
||||
ns := newNamespace()
|
||||
if err := createNamespace(ns); err != nil {
|
||||
logrus.Warn(err)
|
||||
}
|
||||
|
||||
logrus.Info("Creating a new CR")
|
||||
err = createCR()
|
||||
if err != nil {
|
||||
logrus.Fatalf("Failed to create %s CR: %s", crName, err)
|
||||
}
|
||||
logrus.Info("CR has been successfully created")
|
||||
|
||||
logrus.Infof("Getting CR %s to verify it has been successfully created", crName)
|
||||
cheCluster, err := getCR()
|
||||
if err != nil {
|
||||
logrus.Fatalf("An error occurred: %s", err)
|
||||
}
|
||||
logrus.Infof("CR found: name: %s", cheCluster.Name)
|
||||
|
||||
logrus.Info("Creating a service account for operator deployment")
|
||||
|
||||
operatorServiceAccount, err := deserializeOperatorServiceAccount()
|
||||
if err := createOperatorServiceAccount(operatorServiceAccount); err != nil {
|
||||
logrus.Fatalf("Failed to create Operator service account: %s", err)
|
||||
}
|
||||
|
||||
logrus.Info("Creating role for operator service account")
|
||||
|
||||
operatorServiceAccountRole, err := deserializeOperatorRole()
|
||||
if err := createOperatorServiceAccountRole(operatorServiceAccountRole); err != nil {
|
||||
logrus.Fatalf("Failed to create Operator service account role: %s", err)
|
||||
|
||||
}
|
||||
|
||||
logrus.Info("Creating RoleBinding")
|
||||
operatorServiceAccountRoleBinding, err := deserializeOperatorRoleBinding()
|
||||
if err := createOperatorServiceAccountRoleBinding(operatorServiceAccountRoleBinding); err != nil {
|
||||
logrus.Fatalf("Failed to create Operator service account role binding: %s", err)
|
||||
|
||||
}
|
||||
|
||||
logrus.Info("Deploying operator")
|
||||
operatorDeployment, err := deserializeOperatorDeployment()
|
||||
if err := deployOperator(operatorDeployment); err != nil {
|
||||
logrus.Fatalf("Failed to create Operator deployment: %s", err)
|
||||
}
|
||||
|
||||
logrus.Info("Waiting for CR Available status. Timeout 15 min")
|
||||
deployed, err := VerifyCheRunning(che.AvailableStatus)
|
||||
if deployed {
|
||||
logrus.Info("Installation succeeded")
|
||||
}
|
||||
|
||||
// create clusterRole and clusterRoleBinding to let operator service account create oAuthclients
|
||||
logrus.Info("Creating cluster role for operator service account")
|
||||
|
||||
operatorServiceAccountClusterRole, err := deserializeOperatorClusterRole()
|
||||
if err := createOperatorServiceAccountClusterRole(operatorServiceAccountClusterRole); err != nil {
|
||||
logrus.Fatalf("Failed to create Operator service account cluster role: %s", err)
|
||||
|
||||
}
|
||||
|
||||
logrus.Info("Creating RoleBinding")
|
||||
operatorServiceAccountClusterRoleBinding, err := deserializeOperatorClusterRoleBinding()
|
||||
if err := createOperatorServiceAccountClusterRoleBinding(operatorServiceAccountClusterRoleBinding); err != nil {
|
||||
logrus.Fatalf("Failed to create Operator service account cluster role binding: %s", err)
|
||||
|
||||
}
|
||||
|
||||
// reconfigure CR to enable login with OpenShift
|
||||
logrus.Info("Patching CR with oAuth enabled. This should cause a new Che deployment")
|
||||
patchPath := "/spec/auth/openShiftoAuth"
|
||||
if err := patchCustomResource(patchPath, true); err != nil {
|
||||
logrus.Fatalf("An error occurred while patching CR %s", err)
|
||||
}
|
||||
|
||||
// check if a CR status has changed to Rolling update in progress
|
||||
redeployed, err := VerifyCheRunning(che.RollingUpdateInProgressStatus)
|
||||
if redeployed {
|
||||
logrus.Info("New deployment triggered")
|
||||
}
|
||||
|
||||
// wait for Available status
|
||||
logrus.Info("Waiting for CR Available status. Timeout 15 min")
|
||||
deployed, err = VerifyCheRunning(che.AvailableStatus)
|
||||
if deployed {
|
||||
logrus.Info("Installation succeeded")
|
||||
}
|
||||
|
||||
// check if oAuthClient has been created
|
||||
cr, err := getCR()
|
||||
if err != nil {
|
||||
logrus.Fatalf("Failed to get CR: %s", err)
|
||||
}
|
||||
oAuthClientName := cr.Spec.Auth.OAuthClientName
|
||||
_, err = getOauthClient(oAuthClientName)
|
||||
if err != nil {
|
||||
logrus.Fatalf("oAuthclient %s not found", oAuthClientName)
|
||||
}
|
||||
logrus.Infof("Checking if oauthclient %s has been created", oAuthClientName)
|
||||
|
||||
// verify oAuthClient name is set in che ConfigMap
|
||||
cm, err := getConfigMap("che")
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to get ConfigMap: %s", err)
|
||||
}
|
||||
expectedIdentityProvider := "openshift-v3"
|
||||
actualIdentityProvider := cm.Data["CHE_INFRA_OPENSHIFT_OAUTH__IDENTITY__PROVIDER"]
|
||||
expectedWorkspaceProject := ""
|
||||
actualWorkspaceProject := cm.Data["CHE_INFRA_OPENSHIFT_PROJECT"]
|
||||
|
||||
logrus.Info("Checking if identity provider is added to configmap")
|
||||
|
||||
if expectedIdentityProvider != actualIdentityProvider {
|
||||
logrus.Fatalf("Test failed. Expecting identity provider: %s, got: %s", expectedIdentityProvider, actualIdentityProvider)
|
||||
}
|
||||
|
||||
logrus.Info("Checking if workspace project is empty in CM")
|
||||
if expectedWorkspaceProject != actualWorkspaceProject {
|
||||
logrus.Fatalf("Test failed. Expecting identity provider: %s, got: %s", expectedWorkspaceProject, actualWorkspaceProject)
|
||||
}
|
||||
|
||||
// cleanup
|
||||
logrus.Infof("Tests passed. Deleting namespace %s", namespace)
|
||||
if err := deleteNamespace(); err != nil {
|
||||
logrus.Errorf("Failed to delete namespace %s: %s", namespace, err)
|
||||
}
|
||||
}
|
||||
36
e2e/watch.go
36
e2e/watch.go
|
|
@ -1,36 +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 main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
func VerifyCheRunning(status string) (deployed bool, err error) {
|
||||
|
||||
timeout := time.After(15 * time.Minute)
|
||||
tick := time.Tick(10 * time.Second)
|
||||
for {
|
||||
select {
|
||||
case <-timeout:
|
||||
return false, errors.New("timed out")
|
||||
case <-tick:
|
||||
customResource, _ := getCR()
|
||||
if customResource.Status.CheClusterRunning != status {
|
||||
|
||||
} else {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -409,8 +409,9 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e
|
|||
}
|
||||
|
||||
if instance.Spec.Auth.InitialOpenShiftOAuthUser == nil && instance.Status.OpenShiftOAuthUserCredentialsSecret != "" {
|
||||
secret, err := deploy.GetSecret(deployContext, openShiftOAuthUserCredentialsSecret, instance.Namespace)
|
||||
if secret == nil {
|
||||
secret := &corev1.Secret{}
|
||||
exists, err := deploy.GetNamespacedObject(deployContext, openShiftOAuthUserCredentialsSecret, secret)
|
||||
if !exists {
|
||||
if err == nil {
|
||||
instance.Status.OpenShiftOAuthUserCredentialsSecret = ""
|
||||
if err := r.UpdateCheCRStatus(instance, "openShiftOAuthUserCredentialsSecret", ""); err != nil {
|
||||
|
|
@ -604,15 +605,12 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e
|
|||
// Create service account "che" for che-server component.
|
||||
// "che" is the one which token is used to create workspace objects.
|
||||
// Notice: Also we have on more "che-workspace" SA used by plugins like exec, terminal, metrics with limited privileges.
|
||||
cheSA, err := deploy.SyncServiceAccountToCluster(deployContext, CheServiceAccountName)
|
||||
if cheSA == nil {
|
||||
logrus.Info("Waiting on service account 'che' to be created")
|
||||
done, err = deploy.SyncServiceAccountToCluster(deployContext, CheServiceAccountName)
|
||||
if !done {
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
if !tests {
|
||||
return reconcile.Result{RequeueAfter: time.Second}, err
|
||||
}
|
||||
return reconcile.Result{RequeueAfter: time.Second}, err
|
||||
}
|
||||
|
||||
if !util.IsOAuthEnabled(instance) && !util.IsWorkspaceInSameNamespaceWithChe(instance) {
|
||||
|
|
@ -711,14 +709,6 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e
|
|||
}
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
done, err = deploy.DeleteNamespacedObject(deployContext, deploy.DefaultPostgresVolumeClaimName, &corev1.PersistentVolumeClaim{})
|
||||
if !done {
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
} else {
|
||||
done, err := deploy.DeleteNamespacedObject(deployContext, deploy.DefaultCheVolumeClaimName, &corev1.PersistentVolumeClaim{})
|
||||
if !done {
|
||||
|
|
@ -729,96 +719,13 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e
|
|||
}
|
||||
}
|
||||
|
||||
// Create Postgres resources and provisioning unless an external DB is used
|
||||
externalDB := instance.Spec.Database.ExternalDb
|
||||
if !externalDB {
|
||||
if cheMultiUser == "false" {
|
||||
done, err := deploy.Delete(deployContext, types.NamespacedName{Name: deploy.PostgresName, Namespace: instance.Namespace}, &appsv1.Deployment{})
|
||||
if !tests {
|
||||
if !done {
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Create a new postgres service
|
||||
serviceStatus := deploy.SyncServiceToCluster(deployContext, deploy.PostgresName, []string{deploy.PostgresName}, []int32{5432}, deploy.PostgresName)
|
||||
if !tests {
|
||||
if !serviceStatus.Continue {
|
||||
logrus.Info("Waiting on service 'postgres' to be ready")
|
||||
if serviceStatus.Err != nil {
|
||||
logrus.Error(serviceStatus.Err)
|
||||
}
|
||||
|
||||
return reconcile.Result{Requeue: serviceStatus.Requeue}, serviceStatus.Err
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new Postgres PVC object
|
||||
done, err := deploy.SyncPVCToCluster(deployContext, deploy.DefaultPostgresVolumeClaimName, "1Gi", deploy.PostgresName)
|
||||
if !tests {
|
||||
if !done {
|
||||
logrus.Infof("Waiting on pvc '%s' to be bound. Sometimes PVC can be bound only when the first consumer is created.", deploy.DefaultPostgresVolumeClaimName)
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new Postgres deployment
|
||||
provisioned, err := postgres.SyncPostgresDeploymentToCluster(deployContext)
|
||||
if !tests {
|
||||
if !provisioned {
|
||||
logrus.Infof("Waiting on deployment '%s' to be ready", deploy.PostgresName)
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
}
|
||||
|
||||
if !tests {
|
||||
identityProviderPostgresPassword := instance.Spec.Auth.IdentityProviderPostgresPassword
|
||||
identityProviderPostgresSecret := instance.Spec.Auth.IdentityProviderPostgresSecret
|
||||
if len(identityProviderPostgresSecret) > 0 {
|
||||
_, password, err := util.K8sclient.ReadSecret(identityProviderPostgresSecret, instance.Namespace)
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to read '%s' secret: %s", identityProviderPostgresSecret, err)
|
||||
return reconcile.Result{Requeue: true, RequeueAfter: time.Second * 5}, err
|
||||
}
|
||||
identityProviderPostgresPassword = password
|
||||
}
|
||||
dbStatus := instance.Status.DbProvisoned
|
||||
// provision Db and users for Che and Keycloak servers
|
||||
if !dbStatus {
|
||||
_, err := util.K8sclient.ExecIntoPod(
|
||||
instance,
|
||||
deploy.PostgresName,
|
||||
func(cr *orgv1.CheCluster) (string, error) {
|
||||
return identity_provider.GetPostgresProvisionCommand(identityProviderPostgresPassword), nil
|
||||
},
|
||||
"create Keycloak DB, user, privileges")
|
||||
if err == nil {
|
||||
for {
|
||||
instance.Status.DbProvisoned = true
|
||||
if err := r.UpdateCheCRStatus(instance, "status: provisioned with DB and user", "true"); err != nil &&
|
||||
errors.IsConflict(err) {
|
||||
instance, _ = r.GetCR(request)
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
} else {
|
||||
return reconcile.Result{Requeue: true, RequeueAfter: time.Second * 5}, err
|
||||
}
|
||||
}
|
||||
}
|
||||
postgres := postgres.NewPostgres(deployContext)
|
||||
done, err = postgres.Sync()
|
||||
if !done {
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
tlsSupport := instance.Spec.Server.TlsSupport
|
||||
|
|
@ -828,16 +735,13 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e
|
|||
}
|
||||
|
||||
// create Che service and route
|
||||
serviceStatus := server.SyncCheServiceToCluster(deployContext)
|
||||
if !tests {
|
||||
if !serviceStatus.Continue {
|
||||
logrus.Infof("Waiting on service '%s' to be ready", deploy.CheServiceName)
|
||||
if serviceStatus.Err != nil {
|
||||
logrus.Error(serviceStatus.Err)
|
||||
}
|
||||
|
||||
return reconcile.Result{Requeue: serviceStatus.Requeue}, serviceStatus.Err
|
||||
done, err = server.SyncCheServiceToCluster(deployContext)
|
||||
if !done {
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
deployContext.InternalService.CheHost = fmt.Sprintf("http://%s.%s.svc:8080", deploy.CheServiceName, deployContext.CheCluster.Namespace)
|
||||
|
|
@ -878,7 +782,7 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e
|
|||
customHost = ""
|
||||
}
|
||||
|
||||
route, err := deploy.SyncRouteToCluster(
|
||||
done, err := deploy.SyncRouteToCluster(
|
||||
deployContext,
|
||||
cheFlavor,
|
||||
customHost,
|
||||
|
|
@ -886,13 +790,20 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e
|
|||
8080,
|
||||
deployContext.CheCluster.Spec.Server.CheServerRoute,
|
||||
cheFlavor)
|
||||
if route == nil {
|
||||
logrus.Infof("Waiting on route '%s' to be ready", cheFlavor)
|
||||
if !done {
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
return reconcile.Result{RequeueAfter: time.Second * 1}, err
|
||||
route := &routev1.Route{}
|
||||
exists, err := deploy.GetNamespacedObject(deployContext, cheFlavor, route)
|
||||
if !exists {
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
cheHost = route.Spec.Host
|
||||
if customHost == "" {
|
||||
|
|
@ -1055,7 +966,7 @@ func EvaluateCheServerVersion(cr *orgv1.CheCluster) string {
|
|||
|
||||
func getDefaultCheHost(deployContext *deploy.DeployContext) (string, error) {
|
||||
cheFlavor := deploy.DefaultCheFlavor(deployContext.CheCluster)
|
||||
route, err := deploy.SyncRouteToCluster(
|
||||
done, err := deploy.SyncRouteToCluster(
|
||||
deployContext,
|
||||
cheFlavor,
|
||||
"",
|
||||
|
|
@ -1063,13 +974,22 @@ func getDefaultCheHost(deployContext *deploy.DeployContext) (string, error) {
|
|||
8080,
|
||||
deployContext.CheCluster.Spec.Server.CheServerRoute,
|
||||
cheFlavor)
|
||||
if route == nil {
|
||||
logrus.Infof("Waiting on route '%s' to be ready", cheFlavor)
|
||||
if !done {
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
|
||||
route := &routev1.Route{}
|
||||
exists, err := deploy.GetNamespacedObject(deployContext, cheFlavor, route)
|
||||
if !exists {
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
|
||||
return route.Spec.Host, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ func (r *ReconcileChe) GenerateAndSaveFields(deployContext *deploy.DeployContext
|
|||
if len(deployContext.CheCluster.Spec.Database.ChePostgresSecret) < 1 {
|
||||
if len(deployContext.CheCluster.Spec.Database.ChePostgresUser) < 1 || len(deployContext.CheCluster.Spec.Database.ChePostgresPassword) < 1 {
|
||||
chePostgresSecret := deploy.DefaultChePostgresSecret()
|
||||
_, err := deploy.SyncSecret(deployContext, chePostgresSecret, cheNamespace, map[string][]byte{"user": []byte(deploy.DefaultChePostgresUser), "password": []byte(util.GeneratePasswd(12))})
|
||||
_, err := deploy.SyncSecretToCluster(deployContext, chePostgresSecret, cheNamespace, map[string][]byte{"user": []byte(deploy.DefaultChePostgresUser), "password": []byte(util.GeneratePasswd(12))})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -70,7 +70,7 @@ func (r *ReconcileChe) GenerateAndSaveFields(deployContext *deploy.DeployContext
|
|||
|
||||
if len(deployContext.CheCluster.Spec.Auth.IdentityProviderPostgresPassword) < 1 {
|
||||
identityPostgresSecret := deploy.DefaultCheIdentityPostgresSecret()
|
||||
_, err := deploy.SyncSecret(deployContext, identityPostgresSecret, cheNamespace, map[string][]byte{"password": []byte(keycloakPostgresPassword)})
|
||||
_, err := deploy.SyncSecretToCluster(deployContext, identityPostgresSecret, cheNamespace, map[string][]byte{"password": []byte(keycloakPostgresPassword)})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -94,7 +94,7 @@ func (r *ReconcileChe) GenerateAndSaveFields(deployContext *deploy.DeployContext
|
|||
|
||||
if len(deployContext.CheCluster.Spec.Auth.IdentityProviderAdminUserName) < 1 || len(deployContext.CheCluster.Spec.Auth.IdentityProviderPassword) < 1 {
|
||||
identityProviderSecret := deploy.DefaultCheIdentitySecret()
|
||||
_, err = deploy.SyncSecret(deployContext, identityProviderSecret, cheNamespace, map[string][]byte{"user": []byte(keycloakAdminUserName), "password": []byte(keycloakAdminPassword)})
|
||||
_, err = deploy.SyncSecretToCluster(deployContext, identityProviderSecret, cheNamespace, map[string][]byte{"user": []byte(keycloakAdminUserName), "password": []byte(keycloakAdminPassword)})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
oauthv1 "github.com/openshift/api/config/v1"
|
||||
userv1 "github.com/openshift/api/user/v1"
|
||||
"github.com/sirupsen/logrus"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
|
|
@ -79,8 +80,14 @@ func (iuh *OpenShiftOAuthUserOperatorHandler) SyncOAuthInitialUser(openshiftOAut
|
|||
}
|
||||
|
||||
initialUserSecretData := map[string][]byte{"user": []byte(userName), "password": []byte(password)}
|
||||
credentionalSecret, err := deploy.SyncSecret(deployContext, openShiftOAuthUserCredentialsSecret, cr.Namespace, initialUserSecretData)
|
||||
if credentionalSecret == nil {
|
||||
done, err := deploy.SyncSecretToCluster(deployContext, openShiftOAuthUserCredentialsSecret, cr.Namespace, initialUserSecretData)
|
||||
if !done {
|
||||
return false, err
|
||||
}
|
||||
|
||||
credentionalSecret := &corev1.Secret{}
|
||||
exists, err := deploy.GetNamespacedObject(deployContext, openShiftOAuthUserCredentialsSecret, credentionalSecret)
|
||||
if !exists {
|
||||
return false, err
|
||||
}
|
||||
|
||||
|
|
@ -93,8 +100,8 @@ func (iuh *OpenShiftOAuthUserOperatorHandler) SyncOAuthInitialUser(openshiftOAut
|
|||
}
|
||||
|
||||
htpasswdFileSecretData := map[string][]byte{"htpasswd": []byte(htpasswdFileContent)}
|
||||
secret, err := deploy.SyncSecret(deployContext, htpasswdSecretName, ocConfigNamespace, htpasswdFileSecretData)
|
||||
if secret == nil {
|
||||
done, err = deploy.SyncSecretToCluster(deployContext, htpasswdSecretName, ocConfigNamespace, htpasswdFileSecretData)
|
||||
if !done {
|
||||
return false, err
|
||||
}
|
||||
|
||||
|
|
@ -127,11 +134,13 @@ func (iuh *OpenShiftOAuthUserOperatorHandler) DeleteOAuthInitialUser(deployConte
|
|||
return err
|
||||
}
|
||||
|
||||
if err := deploy.DeleteSecret(htpasswdSecretName, ocConfigNamespace, iuh.runtimeClient); err != nil {
|
||||
_, err = deploy.Delete(deployContext, types.NamespacedName{Name: htpasswdSecretName, Namespace: ocConfigNamespace}, &corev1.Secret{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := deploy.DeleteSecret(openShiftOAuthUserCredentialsSecret, cr.Namespace, iuh.runtimeClient); err != nil {
|
||||
_, err = deploy.DeleteNamespacedObject(deployContext, openShiftOAuthUserCredentialsSecret, &corev1.Secret{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,8 +47,8 @@ const (
|
|||
func (r *ReconcileChe) delegateWorkspacePermissionsInTheSameNamespaceWithChe(deployContext *deploy.DeployContext) (reconcile.Result, error) {
|
||||
// Create "che-workspace" service account.
|
||||
// Che workspace components use this service account.
|
||||
cheWorkspaceSA, err := deploy.SyncServiceAccountToCluster(deployContext, CheWorkspacesServiceAccount)
|
||||
if cheWorkspaceSA == nil {
|
||||
done, err := deploy.SyncServiceAccountToCluster(deployContext, CheWorkspacesServiceAccount)
|
||||
if !done {
|
||||
logrus.Infof("Waiting on service account '%s' to be created", CheWorkspacesServiceAccount)
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
|
|
@ -58,7 +58,7 @@ func (r *ReconcileChe) delegateWorkspacePermissionsInTheSameNamespaceWithChe(dep
|
|||
|
||||
// Create view role for "che-workspace" service account.
|
||||
// This role used by exec terminals, tasks, metric che-theia plugin and so on.
|
||||
done, err := deploy.SyncViewRoleToCluster(deployContext)
|
||||
done, err = deploy.SyncViewRoleToCluster(deployContext)
|
||||
if !done {
|
||||
logrus.Infof("Waiting on role '%s' to be created", deploy.ViewRoleName)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -63,3 +63,7 @@ type Proxy struct {
|
|||
NoProxy string
|
||||
TrustedCAMapName string
|
||||
}
|
||||
|
||||
type Syncable interface {
|
||||
Sync() (bool, error)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,10 +125,11 @@ func MountSecrets(specDeployment *appsv1.Deployment, deployContext *DeployContex
|
|||
container.VolumeMounts = append(container.VolumeMounts, volumeMount)
|
||||
|
||||
case "env":
|
||||
secret, err := GetSecret(deployContext, secretObj.Name, deployContext.CheCluster.Namespace)
|
||||
secret := &corev1.Secret{}
|
||||
exists, err := GetNamespacedObject(deployContext, secretObj.Name, secret)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if secret == nil {
|
||||
} else if !exists {
|
||||
return fmt.Errorf("Secret '%s' not found", secretObj.Name)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,15 +60,13 @@ func SyncDevfileRegistryToCluster(deployContext *deploy.DeployContext, cheHost s
|
|||
}
|
||||
|
||||
// Create a new registry service
|
||||
serviceStatus := deploy.SyncServiceToCluster(deployContext, deploy.DevfileRegistryName, []string{"http"}, []int32{8080}, deploy.DevfileRegistryName)
|
||||
done, err = deploy.SyncServiceToCluster(deployContext, deploy.DevfileRegistryName, []string{"http"}, []int32{8080}, deploy.DevfileRegistryName)
|
||||
if !util.IsTestMode() {
|
||||
if !serviceStatus.Continue {
|
||||
logrus.Info("Waiting on service '" + deploy.DevfileRegistryName + "' to be ready")
|
||||
if serviceStatus.Err != nil {
|
||||
logrus.Error(serviceStatus.Err)
|
||||
if !done {
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
|
||||
return false, serviceStatus.Err
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/eclipse-che/che-operator/pkg/deploy"
|
||||
"github.com/eclipse-che/che-operator/pkg/deploy/gateway"
|
||||
"github.com/eclipse-che/che-operator/pkg/util"
|
||||
routev1 "github.com/openshift/api/route/v1"
|
||||
"github.com/sirupsen/logrus"
|
||||
extentionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
)
|
||||
|
|
@ -96,14 +97,15 @@ func Expose(
|
|||
}
|
||||
return "", false, err
|
||||
}
|
||||
if err := deploy.DeleteRouteIfExists(endpointName, deployContext); !util.IsTestMode() && err != nil {
|
||||
|
||||
_, err = deploy.DeleteNamespacedObject(deployContext, endpointName, &routev1.Route{})
|
||||
if 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, routeCustomSettings, component)
|
||||
if route == nil {
|
||||
logrus.Infof("Waiting on route '%s' to be ready", endpointName)
|
||||
done, err := deploy.SyncRouteToCluster(deployContext, endpointName, "", endpointName, 8080, routeCustomSettings, component)
|
||||
if !done {
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
|
|
@ -114,6 +116,15 @@ func Expose(
|
|||
logrus.Error(err)
|
||||
}
|
||||
|
||||
route := &routev1.Route{}
|
||||
exists, err := deploy.GetNamespacedObject(deployContext, endpointName, route)
|
||||
if !exists {
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
return "", false, err
|
||||
}
|
||||
|
||||
endpoint = route.Spec.Host
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,14 +64,12 @@ func SyncIdentityProviderToCluster(deployContext *deploy.DeployContext) (bool, e
|
|||
}
|
||||
|
||||
func syncService(deployContext *deploy.DeployContext) (bool, error) {
|
||||
serviceStatus := deploy.SyncServiceToCluster(
|
||||
return deploy.SyncServiceToCluster(
|
||||
deployContext,
|
||||
deploy.IdentityProviderName,
|
||||
[]string{"http"},
|
||||
[]int32{8080},
|
||||
deploy.IdentityProviderName)
|
||||
|
||||
return serviceStatus.Continue, serviceStatus.Err
|
||||
}
|
||||
|
||||
func syncExposure(deployContext *deploy.DeployContext) (bool, error) {
|
||||
|
|
@ -165,7 +163,7 @@ func SyncOpenShiftIdentityProviderItems(deployContext *deploy.DeployContext) (bo
|
|||
keycloakURL := cr.Spec.Auth.IdentityProviderURL
|
||||
cheFlavor := deploy.DefaultCheFlavor(cr)
|
||||
keycloakRealm := util.GetValue(cr.Spec.Auth.IdentityProviderRealm, cheFlavor)
|
||||
oAuthClient := deploy.NewOAuthClient(oAuthClientName, oauthSecret, keycloakURL, keycloakRealm, util.IsOpenShift4)
|
||||
oAuthClient := deploy.GetOAuthClientSpec(oAuthClientName, oauthSecret, keycloakURL, keycloakRealm, util.IsOpenShift4)
|
||||
provisioned, err := deploy.Sync(deployContext, oAuthClient, oAuthClientDiffOpts)
|
||||
if !provisioned {
|
||||
return false, err
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ const (
|
|||
OAuthFinalizerName = "oauthclients.finalizers.che.eclipse.org"
|
||||
)
|
||||
|
||||
func NewOAuthClient(name string, oauthSecret string, keycloakURL string, keycloakRealm string, isOpenShift4 bool) *oauth.OAuthClient {
|
||||
func GetOAuthClientSpec(name string, oauthSecret string, keycloakURL string, keycloakRealm string, isOpenShift4 bool) *oauth.OAuthClient {
|
||||
providerName := "openshift-v3"
|
||||
if isOpenShift4 {
|
||||
providerName = "openshift-v4"
|
||||
|
|
|
|||
|
|
@ -62,16 +62,12 @@ func SyncPluginRegistryToCluster(deployContext *deploy.DeployContext, cheHost st
|
|||
}
|
||||
|
||||
// Create a new registry service
|
||||
serviceStatus := deploy.SyncServiceToCluster(deployContext, deploy.PluginRegistryName, []string{"http"}, []int32{8080}, deploy.PluginRegistryName)
|
||||
if !util.IsTestMode() {
|
||||
if !serviceStatus.Continue {
|
||||
logrus.Info("Waiting on service '" + deploy.PluginRegistryName + "' to be ready")
|
||||
if serviceStatus.Err != nil {
|
||||
logrus.Error(serviceStatus.Err)
|
||||
}
|
||||
|
||||
return false, serviceStatus.Err
|
||||
done, err = deploy.SyncServiceToCluster(deployContext, deploy.PluginRegistryName, []string{"http"}, []int32{8080}, deploy.PluginRegistryName)
|
||||
if !done {
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
deployContext.InternalService.PluginRegistryHost = fmt.Sprintf("http://%s.%s.svc:8080/v3", deploy.PluginRegistryName, deployContext.CheCluster.Namespace)
|
||||
|
|
|
|||
|
|
@ -12,8 +12,13 @@
|
|||
package postgres
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
orgv1 "github.com/eclipse-che/che-operator/pkg/apis/org/v1"
|
||||
"github.com/eclipse-che/che-operator/pkg/deploy"
|
||||
identity_provider "github.com/eclipse-che/che-operator/pkg/deploy/identity-provider"
|
||||
"github.com/eclipse-che/che-operator/pkg/util"
|
||||
"github.com/sirupsen/logrus"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
|
@ -24,9 +29,76 @@ var (
|
|||
postgresAdminPassword = util.GeneratePasswd(12)
|
||||
)
|
||||
|
||||
func SyncPostgresDeploymentToCluster(deployContext *deploy.DeployContext) (bool, error) {
|
||||
type Postgres struct {
|
||||
deployContext *deploy.DeployContext
|
||||
isMultiUser bool
|
||||
}
|
||||
|
||||
func NewPostgres(deployContext *deploy.DeployContext) *Postgres {
|
||||
return &Postgres{
|
||||
deployContext: deployContext,
|
||||
isMultiUser: deploy.GetCheMultiUser(deployContext.CheCluster) == "true",
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Postgres) Sync() (bool, error) {
|
||||
if p.deployContext.CheCluster.Spec.Database.ExternalDb {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
done, err := p.syncService()
|
||||
if !done {
|
||||
return false, err
|
||||
}
|
||||
|
||||
done, err = p.syncPVC()
|
||||
if !done {
|
||||
return false, err
|
||||
}
|
||||
|
||||
done, err = p.syncDeployment()
|
||||
if !done {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if !p.deployContext.CheCluster.Status.DbProvisoned {
|
||||
if !util.IsTestMode() { // ignore in tests
|
||||
done, err = p.provisionDB()
|
||||
if !done {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (p *Postgres) syncService() (bool, error) {
|
||||
if !p.isMultiUser {
|
||||
return deploy.DeleteNamespacedObject(p.deployContext, deploy.PostgresName, &corev1.Service{})
|
||||
}
|
||||
return deploy.SyncServiceToCluster(p.deployContext, deploy.PostgresName, []string{deploy.PostgresName}, []int32{5432}, deploy.PostgresName)
|
||||
}
|
||||
|
||||
func (p *Postgres) syncPVC() (bool, error) {
|
||||
if !p.isMultiUser {
|
||||
return deploy.DeleteNamespacedObject(p.deployContext, deploy.DefaultPostgresVolumeClaimName, &corev1.PersistentVolumeClaim{})
|
||||
}
|
||||
|
||||
done, err := deploy.SyncPVCToCluster(p.deployContext, deploy.DefaultPostgresVolumeClaimName, "1Gi", deploy.PostgresName)
|
||||
if !done {
|
||||
logrus.Infof("Waiting on pvc '%s' to be bound. Sometimes PVC can be bound only when the first consumer is created.", deploy.DefaultPostgresVolumeClaimName)
|
||||
}
|
||||
return done, err
|
||||
}
|
||||
|
||||
func (p *Postgres) syncDeployment() (bool, error) {
|
||||
if !p.isMultiUser {
|
||||
return deploy.DeleteNamespacedObject(p.deployContext, deploy.PostgresName, &appsv1.Deployment{})
|
||||
}
|
||||
|
||||
clusterDeployment := &appsv1.Deployment{}
|
||||
exists, err := deploy.GetNamespacedObject(deployContext, deploy.PostgresName, clusterDeployment)
|
||||
exists, err := deploy.GetNamespacedObject(p.deployContext, deploy.PostgresName, clusterDeployment)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
|
@ -35,25 +107,54 @@ func SyncPostgresDeploymentToCluster(deployContext *deploy.DeployContext) (bool,
|
|||
clusterDeployment = nil
|
||||
}
|
||||
|
||||
specDeployment, err := GetSpecPostgresDeployment(deployContext, clusterDeployment)
|
||||
specDeployment, err := p.getDeploymentSpec(clusterDeployment)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return deploy.SyncDeploymentSpecToCluster(deployContext, specDeployment, deploy.DefaultDeploymentDiffOpts)
|
||||
return deploy.SyncDeploymentSpecToCluster(p.deployContext, specDeployment, deploy.DefaultDeploymentDiffOpts)
|
||||
}
|
||||
|
||||
func GetSpecPostgresDeployment(deployContext *deploy.DeployContext, clusterDeployment *appsv1.Deployment) (*appsv1.Deployment, error) {
|
||||
isOpenShift, _, err := util.DetectOpenShift()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func (p *Postgres) provisionDB() (bool, error) {
|
||||
identityProviderPostgresPassword := p.deployContext.CheCluster.Spec.Auth.IdentityProviderPostgresPassword
|
||||
identityProviderPostgresSecret := p.deployContext.CheCluster.Spec.Auth.IdentityProviderPostgresSecret
|
||||
if identityProviderPostgresSecret != "" {
|
||||
secret := &corev1.Secret{}
|
||||
exists, err := deploy.GetNamespacedObject(p.deployContext, identityProviderPostgresSecret, secret)
|
||||
if err != nil {
|
||||
return false, err
|
||||
} else if !exists {
|
||||
return false, fmt.Errorf("Secret '%s' not found", identityProviderPostgresSecret)
|
||||
}
|
||||
identityProviderPostgresPassword = string(secret.Data["password"])
|
||||
}
|
||||
|
||||
_, err := util.K8sclient.ExecIntoPod(
|
||||
p.deployContext.CheCluster,
|
||||
deploy.PostgresName,
|
||||
func(cr *orgv1.CheCluster) (string, error) {
|
||||
return identity_provider.GetPostgresProvisionCommand(identityProviderPostgresPassword), nil
|
||||
},
|
||||
"create Keycloak DB, user, privileges")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
p.deployContext.CheCluster.Status.DbProvisoned = true
|
||||
err = deploy.UpdateCheCRStatus(p.deployContext, "status: provisioned with DB and user", "true")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (p *Postgres) getDeploymentSpec(clusterDeployment *appsv1.Deployment) (*appsv1.Deployment, error) {
|
||||
terminationGracePeriodSeconds := int64(30)
|
||||
labels, labelSelector := deploy.GetLabelsAndSelector(deployContext.CheCluster, deploy.PostgresName)
|
||||
chePostgresDb := util.GetValue(deployContext.CheCluster.Spec.Database.ChePostgresDb, "dbche")
|
||||
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)))
|
||||
labels, labelSelector := deploy.GetLabelsAndSelector(p.deployContext.CheCluster, deploy.PostgresName)
|
||||
chePostgresDb := util.GetValue(p.deployContext.CheCluster.Spec.Database.ChePostgresDb, "dbche")
|
||||
postgresImage := util.GetValue(p.deployContext.CheCluster.Spec.Database.PostgresImage, deploy.DefaultPostgresImage(p.deployContext.CheCluster))
|
||||
pullPolicy := corev1.PullPolicy(util.GetValue(string(p.deployContext.CheCluster.Spec.Database.PostgresImagePullPolicy), deploy.DefaultPullPolicyFromDockerImage(postgresImage)))
|
||||
|
||||
if clusterDeployment != nil {
|
||||
clusterContainer := &clusterDeployment.Spec.Template.Spec.Containers[0]
|
||||
|
|
@ -70,7 +171,7 @@ func GetSpecPostgresDeployment(deployContext *deploy.DeployContext, clusterDeplo
|
|||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: deploy.PostgresName,
|
||||
Namespace: deployContext.CheCluster.Namespace,
|
||||
Namespace: p.deployContext.CheCluster.Namespace,
|
||||
Labels: labels,
|
||||
},
|
||||
Spec: appsv1.DeploymentSpec{
|
||||
|
|
@ -108,18 +209,18 @@ func GetSpecPostgresDeployment(deployContext *deploy.DeployContext, clusterDeplo
|
|||
Resources: corev1.ResourceRequirements{
|
||||
Requests: corev1.ResourceList{
|
||||
corev1.ResourceMemory: util.GetResourceQuantity(
|
||||
deployContext.CheCluster.Spec.Database.ChePostgresContainerResources.Requests.Memory,
|
||||
p.deployContext.CheCluster.Spec.Database.ChePostgresContainerResources.Requests.Memory,
|
||||
deploy.DefaultPostgresMemoryRequest),
|
||||
corev1.ResourceCPU: util.GetResourceQuantity(
|
||||
deployContext.CheCluster.Spec.Database.ChePostgresContainerResources.Requests.Cpu,
|
||||
p.deployContext.CheCluster.Spec.Database.ChePostgresContainerResources.Requests.Cpu,
|
||||
deploy.DefaultPostgresCpuRequest),
|
||||
},
|
||||
Limits: corev1.ResourceList{
|
||||
corev1.ResourceMemory: util.GetResourceQuantity(
|
||||
deployContext.CheCluster.Spec.Database.ChePostgresContainerResources.Limits.Memory,
|
||||
p.deployContext.CheCluster.Spec.Database.ChePostgresContainerResources.Limits.Memory,
|
||||
deploy.DefaultPostgresMemoryLimit),
|
||||
corev1.ResourceCPU: util.GetResourceQuantity(
|
||||
deployContext.CheCluster.Spec.Database.ChePostgresContainerResources.Limits.Cpu,
|
||||
p.deployContext.CheCluster.Spec.Database.ChePostgresContainerResources.Limits.Cpu,
|
||||
deploy.DefaultPostgresCpuLimit),
|
||||
},
|
||||
},
|
||||
|
|
@ -183,7 +284,7 @@ func GetSpecPostgresDeployment(deployContext *deploy.DeployContext, clusterDeplo
|
|||
|
||||
container := &deployment.Spec.Template.Spec.Containers[0]
|
||||
|
||||
chePostgresSecret := deployContext.CheCluster.Spec.Database.ChePostgresSecret
|
||||
chePostgresSecret := p.deployContext.CheCluster.Spec.Database.ChePostgresSecret
|
||||
if len(chePostgresSecret) > 0 {
|
||||
container.Env = append(container.Env,
|
||||
corev1.EnvVar{
|
||||
|
|
@ -211,14 +312,14 @@ func GetSpecPostgresDeployment(deployContext *deploy.DeployContext, clusterDeplo
|
|||
container.Env = append(container.Env,
|
||||
corev1.EnvVar{
|
||||
Name: "POSTGRESQL_USER",
|
||||
Value: deployContext.CheCluster.Spec.Database.ChePostgresUser,
|
||||
Value: p.deployContext.CheCluster.Spec.Database.ChePostgresUser,
|
||||
}, corev1.EnvVar{
|
||||
Name: "POSTGRESQL_PASSWORD",
|
||||
Value: deployContext.CheCluster.Spec.Database.ChePostgresPassword,
|
||||
Value: p.deployContext.CheCluster.Spec.Database.ChePostgresPassword,
|
||||
})
|
||||
}
|
||||
|
||||
if !isOpenShift {
|
||||
if !util.IsOpenShift {
|
||||
var runAsUser int64 = 26
|
||||
deployment.Spec.Template.Spec.SecurityContext = &corev1.PodSecurityContext{
|
||||
RunAsUser: &runAsUser,
|
||||
|
|
@ -12,15 +12,19 @@
|
|||
package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
|
||||
"github.com/eclipse-che/che-operator/pkg/util"
|
||||
|
||||
"github.com/eclipse-che/che-operator/pkg/deploy"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
|
||||
orgv1 "github.com/eclipse-che/che-operator/pkg/apis/org/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log/zap"
|
||||
|
|
@ -99,7 +103,8 @@ func TestDeployment(t *testing.T) {
|
|||
Proxy: &deploy.Proxy{},
|
||||
}
|
||||
|
||||
deployment, err := GetSpecPostgresDeployment(deployContext, nil)
|
||||
postgres := NewPostgres(deployContext)
|
||||
deployment, err := postgres.getDeploymentSpec(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating deployment: %v", err)
|
||||
}
|
||||
|
|
@ -117,3 +122,46 @@ func TestDeployment(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncPostgresToCluster(t *testing.T) {
|
||||
orgv1.SchemeBuilder.AddToScheme(scheme.Scheme)
|
||||
corev1.SchemeBuilder.AddToScheme(scheme.Scheme)
|
||||
cli := fake.NewFakeClientWithScheme(scheme.Scheme)
|
||||
deployContext := &deploy.DeployContext{
|
||||
CheCluster: &orgv1.CheCluster{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "eclipse-che",
|
||||
Name: "eclipse-che",
|
||||
},
|
||||
},
|
||||
ClusterAPI: deploy.ClusterAPI{
|
||||
Client: cli,
|
||||
NonCachedClient: cli,
|
||||
Scheme: scheme.Scheme,
|
||||
},
|
||||
}
|
||||
|
||||
postgres := NewPostgres(deployContext)
|
||||
done, err := postgres.Sync()
|
||||
if !done || err != nil {
|
||||
t.Fatalf("Failed to sync PostgreSQL: %v", err)
|
||||
}
|
||||
|
||||
service := &corev1.Service{}
|
||||
err = cli.Get(context.TODO(), types.NamespacedName{Name: deploy.PostgresName, Namespace: "eclipse-che"}, service)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get service: %v", err)
|
||||
}
|
||||
|
||||
pvc := &corev1.PersistentVolumeClaim{}
|
||||
err = cli.Get(context.TODO(), types.NamespacedName{Name: deploy.DefaultPostgresVolumeClaimName, Namespace: "eclipse-che"}, pvc)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get pvc: %v", err)
|
||||
}
|
||||
|
||||
deployment := &appsv1.Deployment{}
|
||||
err = cli.Get(context.TODO(), types.NamespacedName{Name: deploy.PostgresName, Namespace: "eclipse-che"}, deployment)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get deployment: %v", err)
|
||||
}
|
||||
}
|
||||
|
|
@ -20,14 +20,10 @@ import (
|
|||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
routev1 "github.com/openshift/api/route/v1"
|
||||
"github.com/sirupsen/logrus"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
runtimeClient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -57,82 +53,21 @@ func SyncRouteToCluster(
|
|||
serviceName string,
|
||||
servicePort int32,
|
||||
routeCustomSettings orgv1.RouteCustomSettings,
|
||||
component string) (*routev1.Route, error) {
|
||||
component string) (bool, error) {
|
||||
|
||||
specRoute, err := GetSpecRoute(deployContext, name, host, serviceName, servicePort, routeCustomSettings, component)
|
||||
routeSpec, err := GetRouteSpec(deployContext, name, host, serviceName, servicePort, routeCustomSettings, component)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return false, err
|
||||
}
|
||||
|
||||
clusterRoute, err := GetClusterRoute(specRoute.Name, specRoute.Namespace, deployContext.ClusterAPI.Client)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if clusterRoute == nil {
|
||||
logrus.Infof("Creating a new object: %s, name %s", specRoute.Kind, specRoute.Name)
|
||||
err := deployContext.ClusterAPI.Client.Create(context.TODO(), specRoute)
|
||||
if !errors.IsAlreadyExists(err) {
|
||||
return nil, err
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
diffOpts := routeDiffOpts
|
||||
if host != "" {
|
||||
diffOpts = routeWithHostDiffOpts
|
||||
return Sync(deployContext, routeSpec, routeWithHostDiffOpts)
|
||||
}
|
||||
diff := cmp.Diff(clusterRoute, specRoute, diffOpts)
|
||||
if len(diff) > 0 {
|
||||
logrus.Infof("Deleting existed object: %s, name: %s", clusterRoute.Kind, clusterRoute.Name)
|
||||
fmt.Printf("Difference:\n%s", diff)
|
||||
|
||||
err := deployContext.ClusterAPI.Client.Delete(context.TODO(), clusterRoute)
|
||||
if !errors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return clusterRoute, nil
|
||||
return Sync(deployContext, routeSpec, routeDiffOpts)
|
||||
}
|
||||
|
||||
func DeleteRouteIfExists(name string, deployContext *DeployContext) error {
|
||||
ingress, err := GetClusterRoute(name, deployContext.CheCluster.Namespace, deployContext.ClusterAPI.Client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ingress != nil {
|
||||
err = deployContext.ClusterAPI.Client.Delete(context.TODO(), ingress)
|
||||
if !errors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetClusterRoute returns existing route.
|
||||
func GetClusterRoute(name string, namespace string, client runtimeClient.Client) (*routev1.Route, error) {
|
||||
route := &routev1.Route{}
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
}
|
||||
err := client.Get(context.TODO(), namespacedName, route)
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return route, nil
|
||||
}
|
||||
|
||||
// GetSpecRoute returns default configuration of a route in Che namespace.
|
||||
func GetSpecRoute(
|
||||
// GetRouteSpec returns default configuration of a route in Che namespace.
|
||||
func GetRouteSpec(
|
||||
deployContext *DeployContext,
|
||||
name string,
|
||||
host string,
|
||||
|
|
@ -201,10 +136,5 @@ func GetSpecRoute(
|
|||
}
|
||||
}
|
||||
|
||||
err := controllerutil.SetControllerReference(deployContext.CheCluster, route, deployContext.ClusterAPI.Scheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return route, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
package deploy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"reflect"
|
||||
|
||||
|
|
@ -19,9 +20,9 @@ import (
|
|||
routev1 "github.com/openshift/api/route/v1"
|
||||
|
||||
orgv1 "github.com/eclipse-che/che-operator/pkg/apis/org/v1"
|
||||
"github.com/eclipse-che/che-operator/pkg/util"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
|
|
@ -75,14 +76,6 @@ func TestRouteSpec(t *testing.T) {
|
|||
"app.kubernetes.io/managed-by": DefaultCheFlavor(cheCluster) + "-operator",
|
||||
"app.kubernetes.io/name": DefaultCheFlavor(cheCluster),
|
||||
},
|
||||
OwnerReferences: []metav1.OwnerReference{
|
||||
{
|
||||
APIVersion: "org.eclipse.che/v1",
|
||||
Kind: "CheCluster",
|
||||
Controller: util.NewBoolPointer(true),
|
||||
BlockOwnerDeletion: util.NewBoolPointer(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Route",
|
||||
|
|
@ -126,14 +119,6 @@ func TestRouteSpec(t *testing.T) {
|
|||
"app.kubernetes.io/managed-by": DefaultCheFlavor(cheCluster) + "-operator",
|
||||
"app.kubernetes.io/name": DefaultCheFlavor(cheCluster),
|
||||
},
|
||||
OwnerReferences: []metav1.OwnerReference{
|
||||
{
|
||||
APIVersion: "org.eclipse.che/v1",
|
||||
Kind: "CheCluster",
|
||||
Controller: util.NewBoolPointer(true),
|
||||
BlockOwnerDeletion: util.NewBoolPointer(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Route",
|
||||
|
|
@ -172,7 +157,7 @@ func TestRouteSpec(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
actualRoute, err := GetSpecRoute(deployContext,
|
||||
actualRoute, err := GetRouteSpec(deployContext,
|
||||
testCase.routeName,
|
||||
testCase.routeHost,
|
||||
testCase.serviceName,
|
||||
|
|
@ -190,3 +175,60 @@ func TestRouteSpec(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncRouteToCluster(t *testing.T) {
|
||||
orgv1.SchemeBuilder.AddToScheme(scheme.Scheme)
|
||||
routev1.AddToScheme(scheme.Scheme)
|
||||
cli := fake.NewFakeClientWithScheme(scheme.Scheme)
|
||||
deployContext := &DeployContext{
|
||||
CheCluster: &orgv1.CheCluster{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "eclipse-che",
|
||||
Name: "eclipse-che",
|
||||
},
|
||||
},
|
||||
ClusterAPI: ClusterAPI{
|
||||
Client: cli,
|
||||
NonCachedClient: cli,
|
||||
Scheme: scheme.Scheme,
|
||||
},
|
||||
}
|
||||
|
||||
done, err := SyncRouteToCluster(deployContext, "test", "", "service", 80, orgv1.RouteCustomSettings{}, "test")
|
||||
if !done || err != nil {
|
||||
t.Fatalf("Failed to sync route: %v", err)
|
||||
}
|
||||
|
||||
// sync another route
|
||||
done, err = SyncRouteToCluster(deployContext, "test", "", "service", 90, orgv1.RouteCustomSettings{}, "test")
|
||||
if !done || err != nil {
|
||||
t.Fatalf("Failed to sync route: %v", err)
|
||||
}
|
||||
|
||||
actual := &routev1.Route{}
|
||||
err = cli.Get(context.TODO(), types.NamespacedName{Name: "test"}, actual)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get route: %v", err)
|
||||
}
|
||||
if actual.Spec.Port.TargetPort.IntVal != 90 {
|
||||
t.Fatalf("Failed to sync route: %v", err)
|
||||
}
|
||||
|
||||
// sync route with labels & domain
|
||||
done, err = SyncRouteToCluster(deployContext, "test", "", "service", 90, orgv1.RouteCustomSettings{Labels: "a=b", Domain: "domain"}, "test")
|
||||
if !done || err != nil {
|
||||
t.Fatalf("Failed to sync route: %v", err)
|
||||
}
|
||||
|
||||
actual = &routev1.Route{}
|
||||
err = cli.Get(context.TODO(), types.NamespacedName{Name: "test"}, actual)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get route: %v", err)
|
||||
}
|
||||
if actual.ObjectMeta.Labels["a"] != "b" {
|
||||
t.Fatalf("Failed to sync route")
|
||||
}
|
||||
if actual.Spec.Host != "test-eclipse-che.domain" {
|
||||
t.Fatalf("Failed to sync route")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,10 +13,8 @@ package deploy
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
|
|
@ -34,69 +32,14 @@ var secretDiffOpts = cmp.Options{
|
|||
}
|
||||
|
||||
// SyncSecret applies secret into cluster or external namespace
|
||||
func SyncSecret(
|
||||
func SyncSecretToCluster(
|
||||
deployContext *DeployContext,
|
||||
name string,
|
||||
namespace string,
|
||||
data map[string][]byte) (*corev1.Secret, error) {
|
||||
data map[string][]byte) (bool, error) {
|
||||
|
||||
specSecret, err := GetSpecSecret(deployContext, name, namespace, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
clusterSecret, err := GetSecret(deployContext, specSecret.Name, specSecret.Namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if clusterSecret == nil {
|
||||
logrus.Infof("Creating a new object: %s, name %s", specSecret.Kind, specSecret.Name)
|
||||
err := deployContext.ClusterAPI.Client.Create(context.TODO(), specSecret)
|
||||
return specSecret, err
|
||||
}
|
||||
|
||||
diff := cmp.Diff(clusterSecret, specSecret, secretDiffOpts)
|
||||
if len(diff) > 0 {
|
||||
logrus.Infof("Updating existed object: %s, name: %s", clusterSecret.Kind, clusterSecret.Name)
|
||||
fmt.Printf("Difference:\n%s", diff)
|
||||
|
||||
err := deployContext.ClusterAPI.Client.Delete(context.TODO(), clusterSecret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = deployContext.ClusterAPI.Client.Create(context.TODO(), specSecret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return clusterSecret, nil
|
||||
}
|
||||
|
||||
// GetSecret retrieves given secret from cluster
|
||||
func GetSecret(deployContext *DeployContext, name string, namespace string) (*corev1.Secret, error) {
|
||||
secret := &corev1.Secret{}
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
}
|
||||
|
||||
var err error
|
||||
if namespace == deployContext.CheCluster.ObjectMeta.Namespace {
|
||||
err = deployContext.ClusterAPI.Client.Get(context.TODO(), namespacedName, secret)
|
||||
} else {
|
||||
err = deployContext.ClusterAPI.NonCachedClient.Get(context.TODO(), namespacedName, secret)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return secret, nil
|
||||
secretSpec := GetSecretSpec(deployContext, name, namespace, data)
|
||||
return Sync(deployContext, secretSpec, secretDiffOpts)
|
||||
}
|
||||
|
||||
// Get all secrets by labels and annotations
|
||||
|
|
@ -139,8 +82,8 @@ func GetSecrets(deployContext *DeployContext, labels map[string]string, annotati
|
|||
return secrets, nil
|
||||
}
|
||||
|
||||
// GetSpecSecret return default secret config for given data
|
||||
func GetSpecSecret(deployContext *DeployContext, name string, namespace string, data map[string][]byte) (*corev1.Secret, error) {
|
||||
// GetSecretSpec return default secret config for given data
|
||||
func GetSecretSpec(deployContext *DeployContext, name string, namespace string, data map[string][]byte) *corev1.Secret {
|
||||
labels := GetLabels(deployContext.CheCluster, DefaultCheFlavor(deployContext.CheCluster))
|
||||
secret := &corev1.Secret{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
|
|
@ -155,14 +98,7 @@ func GetSpecSecret(deployContext *DeployContext, name string, namespace string,
|
|||
Data: data,
|
||||
}
|
||||
|
||||
if deployContext.CheCluster.Namespace == namespace {
|
||||
err := controllerutil.SetControllerReference(deployContext.CheCluster, secret, deployContext.ClusterAPI.Scheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return secret, nil
|
||||
return secret
|
||||
}
|
||||
|
||||
// CreateTLSSecretFromEndpoint creates TLS secret with given name which contains certificates obtained from the given url.
|
||||
|
|
@ -177,7 +113,7 @@ func CreateTLSSecretFromEndpoint(deployContext *DeployContext, url string, name
|
|||
return err
|
||||
}
|
||||
|
||||
secret, err = SyncSecret(deployContext, name, deployContext.CheCluster.Namespace, map[string][]byte{"ca.crt": crtBytes})
|
||||
_, err = SyncSecretToCluster(deployContext, name, deployContext.CheCluster.Namespace, map[string][]byte{"ca.crt": crtBytes})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -185,24 +121,3 @@ func CreateTLSSecretFromEndpoint(deployContext *DeployContext, url string, name
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteSecret - delete secret by name and namespace
|
||||
func DeleteSecret(secretName string, namespace string, runtimeClient client.Client) error {
|
||||
logrus.Infof("Delete secret: %s in the namespace: %s", secretName, namespace)
|
||||
|
||||
secret := &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: secretName,
|
||||
Namespace: namespace,
|
||||
},
|
||||
}
|
||||
|
||||
if err := runtimeClient.Delete(context.TODO(), secret); err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,12 +12,14 @@
|
|||
package deploy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
|
||||
orgv1 "github.com/eclipse-che/che-operator/pkg/apis/org/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log/zap"
|
||||
|
|
@ -163,3 +165,45 @@ func TestGetSecrets(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncSecretToCluster(t *testing.T) {
|
||||
orgv1.SchemeBuilder.AddToScheme(scheme.Scheme)
|
||||
cli := fake.NewFakeClientWithScheme(scheme.Scheme)
|
||||
deployContext := &DeployContext{
|
||||
CheCluster: &orgv1.CheCluster{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "eclipse-che",
|
||||
Name: "eclipse-che",
|
||||
},
|
||||
},
|
||||
ClusterAPI: ClusterAPI{
|
||||
Client: cli,
|
||||
NonCachedClient: cli,
|
||||
Scheme: scheme.Scheme,
|
||||
},
|
||||
}
|
||||
|
||||
done, err := SyncSecretToCluster(deployContext, "test", "eclipse-che", map[string][]byte{"A": []byte("AAAA")})
|
||||
if !done || err != nil {
|
||||
t.Fatalf("Failed to sync secret: %v", err)
|
||||
}
|
||||
|
||||
// sync another secret
|
||||
done, err = SyncSecretToCluster(deployContext, "test", "eclipse-che", map[string][]byte{"B": []byte("BBBB")})
|
||||
if !done || err != nil {
|
||||
t.Fatalf("Failed to sync secret: %v", err)
|
||||
}
|
||||
|
||||
actual := &corev1.Secret{}
|
||||
err = cli.Get(context.TODO(), types.NamespacedName{Name: "test"}, actual)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get secret: %v", err)
|
||||
}
|
||||
|
||||
if len(actual.Data) != 1 {
|
||||
t.Fatalf("Failed to sync secret: %v", err)
|
||||
}
|
||||
if string(actual.Data["B"]) != "BBBB" {
|
||||
t.Fatalf("Failed to sync secret: %v", err)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -294,11 +294,12 @@ func GetCheConfigMapData(deployContext *deploy.DeployContext) (cheEnv map[string
|
|||
// than Che server namespace, from where the Che TLS secret is not accessable
|
||||
if !util.IsWorkspaceInSameNamespaceWithChe(deployContext.CheCluster) {
|
||||
if deployContext.CheCluster.Spec.K8s.TlsSecretName != "" {
|
||||
cheTLSSecret, err := deploy.GetSecret(deployContext, deployContext.CheCluster.Spec.K8s.TlsSecretName, deployContext.CheCluster.ObjectMeta.Namespace)
|
||||
cheTLSSecret := &corev1.Secret{}
|
||||
exists, err := deploy.GetNamespacedObject(deployContext, deployContext.CheCluster.Spec.K8s.TlsSecretName, cheTLSSecret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if cheTLSSecret == nil {
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("%s secret not found", deployContext.CheCluster.Spec.K8s.TlsSecretName)
|
||||
} else {
|
||||
if _, exists := cheTLSSecret.Data["tls.key"]; !exists {
|
||||
|
|
|
|||
|
|
@ -13,9 +13,10 @@ package server
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/eclipse-che/che-operator/pkg/deploy"
|
||||
"testing"
|
||||
|
||||
"github.com/eclipse-che/che-operator/pkg/deploy"
|
||||
|
||||
orgv1 "github.com/eclipse-che/che-operator/pkg/apis/org/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
|
@ -44,11 +45,7 @@ func TestCreateCheDefaultService(t *testing.T) {
|
|||
CheCluster: cheCluster,
|
||||
ClusterAPI: deploy.ClusterAPI{},
|
||||
}
|
||||
service, err := GetSpecCheService(deployContext)
|
||||
|
||||
if service == nil || err != nil {
|
||||
t.Error("service should be created witn no error")
|
||||
}
|
||||
service := GetSpecCheService(deployContext)
|
||||
ports := service.Spec.Ports
|
||||
if len(ports) != 1 {
|
||||
t.Error("expected 1 default port")
|
||||
|
|
@ -69,11 +66,7 @@ func TestCreateCheServerDebug(t *testing.T) {
|
|||
ClusterAPI: deploy.ClusterAPI{},
|
||||
}
|
||||
|
||||
service, err := GetSpecCheService(deployContext)
|
||||
|
||||
if service == nil || err != nil {
|
||||
t.Error("service should be created without error")
|
||||
}
|
||||
service := GetSpecCheService(deployContext)
|
||||
ports := service.Spec.Ports
|
||||
if len(ports) != 2 {
|
||||
t.Error("expected 2 default port")
|
||||
|
|
@ -96,11 +89,7 @@ func TestCreateCheServiceEnableMetrics(t *testing.T) {
|
|||
ClusterAPI: deploy.ClusterAPI{},
|
||||
}
|
||||
|
||||
service, err := GetSpecCheService(deployContext)
|
||||
|
||||
if service == nil || err != nil {
|
||||
t.Error("service should be created witn no error")
|
||||
}
|
||||
service := GetSpecCheService(deployContext)
|
||||
ports := service.Spec.Ports
|
||||
if len(ports) != 1 {
|
||||
t.Error("expected 1 default port")
|
||||
|
|
@ -122,11 +111,7 @@ func TestCreateCheServiceDisableMetrics(t *testing.T) {
|
|||
ClusterAPI: deploy.ClusterAPI{},
|
||||
}
|
||||
|
||||
service, err := GetSpecCheService(deployContext)
|
||||
|
||||
if service == nil || err != nil {
|
||||
t.Error("service should be created witn no error")
|
||||
}
|
||||
service := GetSpecCheService(deployContext)
|
||||
ports := service.Spec.Ports
|
||||
if len(ports) != 2 {
|
||||
t.Error("expected 2 ports")
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import (
|
|||
v1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
func GetSpecCheService(deployContext *deploy.DeployContext) (*v1.Service, error) {
|
||||
func GetSpecCheService(deployContext *deploy.DeployContext) *v1.Service {
|
||||
portName := []string{"http"}
|
||||
portNumber := []int32{8080}
|
||||
|
||||
|
|
@ -30,16 +30,10 @@ func GetSpecCheService(deployContext *deploy.DeployContext) (*v1.Service, error)
|
|||
portNumber = append(portNumber, deploy.DefaultCheDebugPort)
|
||||
}
|
||||
|
||||
return deploy.GetSpecService(deployContext, deploy.CheServiceName, portName, portNumber, deploy.DefaultCheFlavor(deployContext.CheCluster))
|
||||
return deploy.GetServiceSpec(deployContext, deploy.CheServiceName, portName, portNumber, deploy.DefaultCheFlavor(deployContext.CheCluster))
|
||||
}
|
||||
|
||||
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)
|
||||
func SyncCheServiceToCluster(deployContext *deploy.DeployContext) (bool, error) {
|
||||
specService := GetSpecCheService(deployContext)
|
||||
return deploy.SyncServiceSpecToCluster(deployContext, specService)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,31 +13,24 @@
|
|||
package deploy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/eclipse-che/che-operator/pkg/util"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
"github.com/sirupsen/logrus"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
runtimeClient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
)
|
||||
|
||||
type ServiceProvisioningStatus struct {
|
||||
ProvisioningStatus
|
||||
}
|
||||
|
||||
const (
|
||||
CheServiceName = "che-host"
|
||||
)
|
||||
|
||||
var portsDiffOpts = cmp.Options{
|
||||
cmpopts.IgnoreFields(corev1.ServicePort{}, "TargetPort", "NodePort"),
|
||||
var serviceDiffOpts = cmp.Options{
|
||||
cmpopts.IgnoreFields(corev1.Service{}, "TypeMeta", "ObjectMeta"),
|
||||
cmp.Comparer(func(x, y corev1.ServiceSpec) bool {
|
||||
return cmp.Equal(x.Ports, y.Ports, cmpopts.IgnoreFields(corev1.ServicePort{}, "TargetPort", "NodePort")) &&
|
||||
reflect.DeepEqual(x.Selector, y.Selector)
|
||||
}),
|
||||
}
|
||||
|
||||
func SyncServiceToCluster(
|
||||
|
|
@ -45,65 +38,22 @@ func SyncServiceToCluster(
|
|||
name string,
|
||||
portName []string,
|
||||
portNumber []int32,
|
||||
component string) ServiceProvisioningStatus {
|
||||
specService, err := GetSpecService(deployContext, name, portName, portNumber, component)
|
||||
if err != nil {
|
||||
return ServiceProvisioningStatus{
|
||||
ProvisioningStatus: ProvisioningStatus{Err: err},
|
||||
}
|
||||
}
|
||||
component string) (bool, error) {
|
||||
|
||||
return DoSyncServiceToCluster(deployContext, specService)
|
||||
serviceSpec := GetServiceSpec(deployContext, name, portName, portNumber, component)
|
||||
return SyncServiceSpecToCluster(deployContext, serviceSpec)
|
||||
}
|
||||
|
||||
func DoSyncServiceToCluster(deployContext *DeployContext, specService *corev1.Service) ServiceProvisioningStatus {
|
||||
|
||||
clusterService, err := getClusterService(specService.Name, specService.Namespace, deployContext.ClusterAPI.Client)
|
||||
if err != nil {
|
||||
return ServiceProvisioningStatus{
|
||||
ProvisioningStatus: ProvisioningStatus{Err: err},
|
||||
}
|
||||
}
|
||||
|
||||
if clusterService == nil {
|
||||
logrus.Infof("Creating a new object: %s, name %s", specService.Kind, specService.Name)
|
||||
err := deployContext.ClusterAPI.Client.Create(context.TODO(), specService)
|
||||
return ServiceProvisioningStatus{
|
||||
ProvisioningStatus: ProvisioningStatus{Requeue: true, Err: err},
|
||||
}
|
||||
}
|
||||
|
||||
diffPorts := cmp.Diff(clusterService.Spec.Ports, specService.Spec.Ports, portsDiffOpts)
|
||||
diffSelectors := cmp.Diff(clusterService.Spec.Selector, specService.Spec.Selector)
|
||||
if len(diffPorts) > 0 || len(diffSelectors) > 0 {
|
||||
logrus.Infof("Updating existed object: %s, name: %s", specService.Kind, specService.Name)
|
||||
fmt.Printf("Ports difference:\n%s", diffPorts)
|
||||
fmt.Printf("Selectors difference:\n%s", diffSelectors)
|
||||
|
||||
err := deployContext.ClusterAPI.Client.Delete(context.TODO(), clusterService)
|
||||
if err != nil {
|
||||
return ServiceProvisioningStatus{
|
||||
ProvisioningStatus: ProvisioningStatus{Requeue: true, Err: err},
|
||||
}
|
||||
}
|
||||
|
||||
err = deployContext.ClusterAPI.Client.Create(context.TODO(), specService)
|
||||
return ServiceProvisioningStatus{
|
||||
ProvisioningStatus: ProvisioningStatus{Requeue: true, Err: err},
|
||||
}
|
||||
}
|
||||
|
||||
return ServiceProvisioningStatus{
|
||||
ProvisioningStatus: ProvisioningStatus{Continue: true},
|
||||
}
|
||||
func SyncServiceSpecToCluster(deployContext *DeployContext, serviceSpec *corev1.Service) (bool, error) {
|
||||
return Sync(deployContext, serviceSpec, serviceDiffOpts)
|
||||
}
|
||||
|
||||
func GetSpecService(
|
||||
func GetServiceSpec(
|
||||
deployContext *DeployContext,
|
||||
name string,
|
||||
portName []string,
|
||||
portNumber []int32,
|
||||
component string) (*corev1.Service, error) {
|
||||
component string) *corev1.Service {
|
||||
|
||||
labels := GetLabels(deployContext.CheCluster, component)
|
||||
ports := []corev1.ServicePort{}
|
||||
|
|
@ -132,28 +82,5 @@ func GetSpecService(
|
|||
},
|
||||
}
|
||||
|
||||
if !util.IsTestMode() {
|
||||
err := controllerutil.SetControllerReference(deployContext.CheCluster, service, deployContext.ClusterAPI.Scheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return service, nil
|
||||
}
|
||||
|
||||
func getClusterService(name string, namespace string, client runtimeClient.Client) (*corev1.Service, error) {
|
||||
service := &corev1.Service{}
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
}
|
||||
err := client.Get(context.TODO(), namespacedName, service)
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return service, nil
|
||||
return service
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,54 +12,16 @@
|
|||
package deploy
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
runtimeClient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
)
|
||||
|
||||
func SyncServiceAccountToCluster(deployContext *DeployContext, name string) (*corev1.ServiceAccount, error) {
|
||||
specSA, err := getSpecServiceAccount(deployContext, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
clusterSA, err := getClusterServiceAccount(specSA.Name, specSA.Namespace, deployContext.ClusterAPI.Client)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if clusterSA == nil {
|
||||
logrus.Infof("Creating a new object: %s, name %s", specSA.Kind, specSA.Name)
|
||||
err := deployContext.ClusterAPI.Client.Create(context.TODO(), specSA)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return clusterSA, nil
|
||||
func SyncServiceAccountToCluster(deployContext *DeployContext, name string) (bool, error) {
|
||||
saSpec := getServiceAccountSpec(deployContext, name)
|
||||
return CreateIfNotExists(deployContext, saSpec)
|
||||
}
|
||||
|
||||
func getClusterServiceAccount(name string, namespace string, client runtimeClient.Client) (*corev1.ServiceAccount, error) {
|
||||
serviceAccount := &corev1.ServiceAccount{}
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
}
|
||||
err := client.Get(context.TODO(), namespacedName, serviceAccount)
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return serviceAccount, nil
|
||||
}
|
||||
|
||||
func getSpecServiceAccount(deployContext *DeployContext, name string) (*corev1.ServiceAccount, error) {
|
||||
func getServiceAccountSpec(deployContext *DeployContext, name string) *corev1.ServiceAccount {
|
||||
labels := GetLabels(deployContext.CheCluster, DefaultCheFlavor(deployContext.CheCluster))
|
||||
serviceAccount := &corev1.ServiceAccount{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
|
|
@ -73,10 +35,5 @@ func getSpecServiceAccount(deployContext *DeployContext, name string) (*corev1.S
|
|||
},
|
||||
}
|
||||
|
||||
err := controllerutil.SetControllerReference(deployContext.CheCluster, serviceAccount, deployContext.ClusterAPI.Scheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return serviceAccount, nil
|
||||
return serviceAccount
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
//
|
||||
// Copyright (c) 2021 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 (
|
||||
"context"
|
||||
|
||||
orgv1 "github.com/eclipse-che/che-operator/pkg/apis/org/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestServiceToCluster(t *testing.T) {
|
||||
orgv1.SchemeBuilder.AddToScheme(scheme.Scheme)
|
||||
cli := fake.NewFakeClientWithScheme(scheme.Scheme)
|
||||
deployContext := &DeployContext{
|
||||
CheCluster: &orgv1.CheCluster{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "eclipse-che",
|
||||
Name: "eclipse-che",
|
||||
},
|
||||
},
|
||||
ClusterAPI: ClusterAPI{
|
||||
Client: cli,
|
||||
NonCachedClient: cli,
|
||||
Scheme: scheme.Scheme,
|
||||
},
|
||||
}
|
||||
|
||||
done, err := SyncServiceToCluster(deployContext, "test", []string{"port"}, []int32{8080}, "test")
|
||||
if !done || err != nil {
|
||||
t.Fatalf("Failed to sync service: %v", err)
|
||||
}
|
||||
|
||||
// sync another service
|
||||
done, err = SyncServiceToCluster(deployContext, "test", []string{"port"}, []int32{9090}, "test")
|
||||
if !done || err != nil {
|
||||
t.Fatalf("Failed to sync service: %v", err)
|
||||
}
|
||||
|
||||
actual := &corev1.Service{}
|
||||
err = cli.Get(context.TODO(), types.NamespacedName{Name: "test"}, actual)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get service: %v", err)
|
||||
}
|
||||
|
||||
if actual.Spec.Ports[0].Port != 9090 {
|
||||
t.Fatalf("Failed to sync service.")
|
||||
}
|
||||
}
|
||||
|
|
@ -315,7 +315,7 @@ func doGet(client client.Client, key client.ObjectKey, object runtime.Object) (b
|
|||
}
|
||||
|
||||
func isUpdateUsingDeleteCreate(kind string) bool {
|
||||
return "Service" == kind || "Ingress" == kind || "Route" == kind || "Job" == kind
|
||||
return "Service" == kind || "Ingress" == kind || "Route" == kind || "Job" == kind || "Secret" == kind
|
||||
}
|
||||
|
||||
func setOwnerReferenceIfNeeded(deployContext *DeployContext, blueprint metav1.Object) error {
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ func GetEndpointTLSCrtChain(deployContext *DeployContext, endpointURL string) ([
|
|||
if util.IsOpenShift {
|
||||
// Create test route to get certificates chain.
|
||||
// Note, it is not possible to use SyncRouteToCluster here as it may cause infinite reconcile loop.
|
||||
routeSpec, err := GetSpecRoute(
|
||||
routeSpec, err := GetRouteSpec(
|
||||
deployContext,
|
||||
"test",
|
||||
"",
|
||||
|
|
@ -164,14 +164,15 @@ func GetEndpointTLSCrtChain(deployContext *DeployContext, endpointURL string) ([
|
|||
}()
|
||||
|
||||
// Wait till the route is ready
|
||||
var route *routev1.Route
|
||||
for wait := true; wait; {
|
||||
route := &routev1.Route{}
|
||||
for {
|
||||
time.Sleep(time.Duration(1) * time.Second)
|
||||
route, err = GetClusterRoute(routeSpec.Name, routeSpec.Namespace, deployContext.ClusterAPI.Client)
|
||||
exists, err := GetNamespacedObject(deployContext, routeSpec.Name, route)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if exists {
|
||||
break
|
||||
}
|
||||
wait = len(route.Spec.Host) == 0
|
||||
}
|
||||
|
||||
requestURL = "https://" + route.Spec.Host
|
||||
|
|
@ -204,16 +205,15 @@ func GetEndpointTLSCrtChain(deployContext *DeployContext, endpointURL string) ([
|
|||
}()
|
||||
|
||||
// Wait till the ingress is ready
|
||||
var ingress *v1beta1.Ingress
|
||||
for wait := true; wait; {
|
||||
ingress := &v1beta1.Ingress{}
|
||||
for {
|
||||
time.Sleep(time.Duration(1) * time.Second)
|
||||
|
||||
ingress := &v1beta1.Ingress{}
|
||||
exists, err := GetNamespacedObject(deployContext, ingressSpec.Name, ingress)
|
||||
if !exists {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if exists {
|
||||
break
|
||||
}
|
||||
wait = len(ingress.Spec.Rules[0].Host) == 0
|
||||
}
|
||||
|
||||
requestURL = "https://" + ingress.Spec.Rules[0].Host
|
||||
|
|
@ -322,12 +322,12 @@ func K8sHandleCheTLSSecrets(deployContext *DeployContext) (reconcile.Result, err
|
|||
}
|
||||
|
||||
// Prepare permissions for the certificate generation job
|
||||
sa, err := SyncServiceAccountToCluster(deployContext, CheTLSJobServiceAccountName)
|
||||
if sa == nil {
|
||||
done, err := SyncServiceAccountToCluster(deployContext, CheTLSJobServiceAccountName)
|
||||
if !done {
|
||||
return reconcile.Result{RequeueAfter: time.Second}, err
|
||||
}
|
||||
|
||||
done, err := SyncTLSRoleToCluster(deployContext)
|
||||
done, err = SyncTLSRoleToCluster(deployContext)
|
||||
if !done {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue