diff --git a/.gitignore b/.gitignore index 485dee6..5c3bdbb 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -.idea +*bundle.yaml diff --git a/README.md b/README.md index d0c411d..cc99c4f 100644 --- a/README.md +++ b/README.md @@ -32,9 +32,9 @@ High level architecture and overview of the solution can be found [HERE](https:/ The following are the images and tags for this release: | Component | k8s | Openshift | | --- | --- | --- | -| Redis Enterprise | `redislabs/redis:6.2.10-107` | `redislabs/redis:6.2.10-107.rhel8-openshift` | -| Operator | `redislabs/operator:6.2.10-34` | `redislabs/operator:6.2.10-34` | -| Services Rigger | `redislabs/k8s-controller:6.2.10-34` | `redislabs/k8s-controller:6.2.10-34` | +| Redis Enterprise | `redislabs/redis:6.2.10-129` | `redislabs/redis:6.2.10-129.rhel8-openshift` | +| Operator | `redislabs/operator:6.2.10-45` | `redislabs/operator:6.2.10-45` | +| Services Rigger | `redislabs/k8s-controller:6.2.10-45` | `redislabs/k8s-controller:6.2.10-45` | > * RedHat certified images are available on [Redhat Catalog](https://access.redhat.com/containers/#/product/71f6d1bb3408bd0d)
@@ -220,8 +220,6 @@ The "OpenShift" installation deploys the operator from the current release with This is the fastest way to get up and running with a new cluster on OpenShift 3.x. For OpenShift 4.x, you may choose to use OLM deployment from within your OpenShift cluster or follow the steps below. Other custom configurations are referenced in this repository. -If you are running on OpenShift 3.x, use the `bundle.yaml` file located under `openshift_3_x` folder (see comment in step 4). -That folder also contains the custom resource definitions compatible with OpenShift 3.x. > Note: you will need to replace `` with your project name. 1. Create a new project: @@ -252,7 +250,6 @@ That folder also contains the custom resource definitions compatible with OpenSh ```bash oc apply -f openshift.bundle.yaml ``` - > Note: If you are running on OpenShift 3.x, use the `bundle.yaml` file located under `openshift_3_x` folder. 5. Redis Enterprise Cluster custom resource - `RedisEnterpriseCluster` > Note: Define a `storageClassName` setting in `openshift/rec_rhel.yaml` as required (it's set to `gp2` by default). @@ -379,7 +376,7 @@ The operator deploys a `RedisEnterpriseCluster` with default configurations valu redisEnterpriseImageSpec: imagePullPolicy: IfNotPresent repository: redislabs/redis - versionTag: 6.2.10-107 + versionTag: 6.2.10-129 ``` * Persistence @@ -481,21 +478,21 @@ For example: redisEnterpriseImageSpec: imagePullPolicy: IfNotPresent repository: harbor.corp.local/redisenterprise/redis - versionTag: 6.2.10-107 + versionTag: 6.2.10-129 ``` ```yaml redisEnterpriseServicesRiggerImageSpec: imagePullPolicy: IfNotPresent repository: harbor.corp.local/redisenterprise/k8s-controller - versionTag: 6.2.10-34 + versionTag: 6.2.10-45 ``` ```yaml bootstrapperImageSpec: imagePullPolicy: IfNotPresent repository: harbor.corp.local/redisenterprise/operator - versionTag: 6.2.10-34 + versionTag: 6.2.10-45 ``` In Operator Deployment spec (operator.yaml): @@ -507,7 +504,7 @@ spec: spec: containers: - name: redis-enterprise-operator - image: harbor.corp.local/redisenterprise/operator:6.2.10-34 + image: harbor.corp.local/redisenterprise/operator:6.2.10-45 ``` Image specification follow the [K8s Container schema](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.10/#container-v1-core). @@ -630,7 +627,7 @@ Note: in the examples above the Redis Enterprise Cluster name is: 'rec' and the The Operator automates and simplifies the upgrade process. The Redis Enterprise Cluster Software, and the Redis Enterprise Operator for Kubernetes versions are tightly coupled and should be upgraded together. It is recommended to use the bundle.yaml to upgrade, as it loads all the relevant CRD documents for this version. If the updated CRDs are not loaded, the operator might fail. -There are two ways to upgrade - either set 'autoUpgradeRedisEnterprise' within the Redis Enterprise Cluster Spec to instruct the operator to automatically upgrade to the compatible version, or specify the correct Redis Enterprise image manually using the versionTag attribute. The Redis Enterprise Version compatible with this release is 6.2.10-107 +There are two ways to upgrade - either set 'autoUpgradeRedisEnterprise' within the Redis Enterprise Cluster Spec to instruct the operator to automatically upgrade to the compatible version, or specify the correct Redis Enterprise image manually using the versionTag attribute. The Redis Enterprise Version compatible with this release is 6.2.10-129 ```yaml autoUpgradeRedisEnterprise: true @@ -639,7 +636,7 @@ There are two ways to upgrade - either set 'autoUpgradeRedisEnterprise' within t Alternatively: ```yaml RedisEnterpriseImageSpec: - versionTag: redislabs/redis:6.2.10-107 + versionTag: redislabs/redis:6.2.10-129 ``` ## Supported K8S Distributions @@ -647,33 +644,29 @@ Each release of the Redis Enterprise Operator deployment is thoroughly tested ag Supported versions (platforms/versions that are not listed are not supported): | Distribution | Support Status | |---------------------------------|----------------| -| OpenShift 4.6 (K8s 1.19) | deprecated | -| OpenShift 4.7 (K8s 1.20) | supported | -| OpenShift 4.8 (K8s 1.21) | supported | +| OpenShift 4.7 (K8s 1.20) | deprecated | +| OpenShift 4.8 (K8s 1.21) | deprecated | | OpenShift 4.9 (K8s 1.22) | supported | | OpenShift 4.10 (K8s 1.23) | supported | -| KOPS vanilla 1.18 | deprecated | -| KOPS vanilla 1.19 | deprecated | -| KOPS vanilla 1.20 | supported | +| KOPS vanilla 1.20 | deprecated | | KOPS vanilla 1.21 | supported | | KOPS vanilla 1.22 | supported | | KOPS vanilla 1.23 | supported | -| GKE 1.19 | deprecated | +| KOPS vanilla 1.24 | supported | | GKE 1.20 | supported | | GKE 1.21 | supported | | GKE 1.22 | supported | -| Rancher 2.6 (K8s 1.18) | deprecated | -| Rancher 2.6 (K8s 1.19) | supported | -| Rancher 2.6 (K8s 1.20) | supported | +| GKE 1.23 | supported | +| Rancher 2.6 (K8s 1.19) | deprecated | +| Rancher 2.6 (K8s 1.20) | deprecated | | Rancher 2.6 (K8s 1.21) | supported | -| VMWare TKGIE** 1.10 (K8s 1.19) | supported | -| VMWare TKGIE 1.11 (K8s 1.20) | supported | -| AKS 1.20 | deprecated | -| AKS 1.21 | deprecated | +| Rancher 2.6 (K8s 1.22) | supported | +| VMWare TKGIE** 1.10 (K8s 1.19) | deprecated | +| VMWare TKGIE** 1.11 (K8s 1.20) | deprecated | +| VMWare TKGIE** 1.12 (K8s 1.21) | supported | +| VMWare TKGIE** 1.13 (K8s 1.22) | supported | | AKS 1.22 | supported | | AKS 1.23 | supported | -| EKS 1.18 | deprecated | -| EKS 1.19 | deprecated | | EKS 1.20 | supported | | EKS 1.21 | supported | | EKS 1.22 | supported | diff --git a/bundle.yaml b/bundle.yaml index b337172..14c0ef6 100644 --- a/bundle.yaml +++ b/bundle.yaml @@ -8,10 +8,11 @@ rules: resources: ["roles", "serviceaccounts", "rolebindings"] verbs: ["bind", "escalate", "impersonate", "userextras", "create", "get", "list", "watch", "update", "patch", "delete", "deletecollection"] - - apiGroups: - - app.redislabs.com + - apiGroups: ["app.redislabs.com"] resources: ["redisenterpriseclusters", "redisenterpriseclusters/status", "redisenterpriseclusters/finalizers", - "redisenterprisedatabases", "redisenterprisedatabases/status", "redisenterprisedatabases/finalizers"] + "redisenterprisedatabases", "redisenterprisedatabases/status", "redisenterprisedatabases/finalizers", + "redisenterpriseremoteclusters", "redisenterpriseremoteclusters/status", + "redisenterpriseremoteclusters/finalizers"] verbs: ["delete", "deletecollection", "get", "list", "patch", "create", "update", "watch"] - apiGroups: [""] resources: ["secrets"] @@ -35,8 +36,6 @@ rules: - apiGroups: [""] resources: ["persistentvolumeclaims"] verbs: ["create", "delete", "get" , "update", "list", "watch"] - - # needed rbac rules for services controller - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list", "update", "patch", "delete"] @@ -45,18 +44,15 @@ rules: verbs: ["get", "watch", "list", "update", "patch", "create", "delete"] - apiGroups: ["policy"] resources: ["podsecuritypolicies"] - resourceNames: - - redis-enterprise-psp - verbs: - - use - - apiGroups: ["extensions"] - resources: ["ingresses"] - verbs: ["create", "patch", "replace", "delete", "deletecollection", "read", "list", "listallnamespaces", - "watch", "watchlist", "watchlistallnamespaces", "patchstatus", "readstatus", "replacestatus", "update"] + resourceNames: ["redis-enterprise-psp"] + verbs: ["use"] - apiGroups: ["networking.k8s.io"] resources: ["ingresses"] verbs: ["create", "patch", "replace", "delete", "deletecollection", "read", "list", "listallnamespaces", "watch", "watchlist", "watchlistallnamespaces", "patchstatus", "readstatus", "replacestatus", "update"] + - apiGroups: ["networking.istio.io"] + resources: ["gateways", "virtualservices"] + verbs: ["get", "watch", "list", "update", "patch", "create", "delete"] --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 @@ -762,8 +758,6 @@ spec: lastBackupTime: description: Time of last successful backup type: string - required: - - backupHistory type: object specStatus: description: Whether the desired specification is valid @@ -816,7 +810,7 @@ spec: serviceAccountName: redis-enterprise-operator containers: - name: redis-enterprise-operator - image: redislabs/operator:6.2.10-34 + image: redislabs/operator:6.2.10-45 command: - redis-enterprise-operator imagePullPolicy: Always @@ -858,7 +852,7 @@ spec: port: 8080 scheme: HTTP - name: admission - image: redislabs/operator:6.2.10-34 + image: redislabs/operator:6.2.10-45 command: - /usr/local/bin/admission imagePullPolicy: Always @@ -1035,7 +1029,9 @@ spec: description: RedisEnterpriseClusterSpec defines the desired state of RedisEnterpriseCluster properties: activeActive: - description: Specification for ActiveActive setup + description: Specification for ActiveActive setup. At most one of + ingressOrRouteSpec or activeActive fields can be set at the same + time. properties: apiIngressUrl: description: RS API URL @@ -1081,6 +1077,10 @@ spec: type: string versionTag: type: string + digestHash: + description: 'The digest hash of the image to pull. Version tag must be also specified with the corresponding version, will use the digest hash to pull the image if exists. + Note: This is currently supported only for OLM.' + type: string type: object bootstrapperResources: description: Compute resource requirements for bootstrapper containers @@ -1203,6 +1203,42 @@ spec: type: string type: object type: array + ingressOrRouteSpec: + description: Access configurations for the Redis Enterprise Cluster + and Databases. Note - this feature is currently in preview. For + this feature to take effect, set a boolean environment variable + with the name "ENABLE_ALPHA_FEATURES" to True. This variable can + be set via the redis-enterprise-operator pod spec, or through the + operator-environment-config Config Map. At most one of ingressOrRouteSpec + or activeActive fields can be set at the same time. + properties: + apiFqdnUrl: + description: RS API URL + type: string + dbFqdnSuffix: + description: DB ENDPOINT SUFFIX - will be used to set the db host + ingress . Creates a host name so it + should be unique if more than one db is created on the cluster + with the same name + type: string + ingressAnnotations: + additionalProperties: + type: string + description: Additional annotations to set on ingress resources + created by the operator + type: object + method: + description: Used to distinguish between different platforms implementation. + enum: + - openShiftRoute + - ingress + - istio + type: string + required: + - apiFqdnUrl + - dbFqdnSuffix + - method + type: object license: description: Redis Enterprise License type: string @@ -3868,6 +3904,10 @@ spec: type: string versionTag: type: string + digestHash: + description: 'The digest hash of the image to pull. Version tag must be also specified with the corresponding version, will use the digest hash to pull the image if exists. + Note: This is currently supported only for OLM.' + type: string type: object redisEnterpriseNodeResources: description: Compute resource requirements for Redis Enterprise containers @@ -7886,7 +7926,9 @@ spec: description: RedisEnterpriseClusterSpec defines the desired state of RedisEnterpriseCluster properties: activeActive: - description: Specification for ActiveActive setup + description: Specification for ActiveActive setup. At most one of + ingressOrRouteSpec or activeActive fields can be set at the same + time. properties: apiIngressUrl: description: RS API URL @@ -7908,6 +7950,7 @@ spec: enum: - openShiftRoute - ingress + - istio type: string required: - apiIngressUrl @@ -8053,6 +8096,42 @@ spec: type: string type: object type: array + ingressOrRouteSpec: + description: Access configurations for the Redis Enterprise Cluster + and Databases. Note - this feature is currently in preview. For + this feature to take effect, set a boolean environment variable + with the name "ENABLE_ALPHA_FEATURES" to True. This variable can + be set via the redis-enterprise-operator pod spec, or through the + operator-environment-config Config Map. At most one of ingressOrRouteSpec + or activeActive fields can be set at the same time. + properties: + apiFqdnUrl: + description: RS API URL + type: string + dbFqdnSuffix: + description: DB ENDPOINT SUFFIX - will be used to set the db host + ingress . Creates a host name so it + should be unique if more than one db is created on the cluster + with the same name + type: string + ingressAnnotations: + additionalProperties: + type: string + description: Additional annotations to set on ingress resources + created by the operator + type: object + method: + description: Used to distinguish between different platforms implementation. + enum: + - openShiftRoute + - ingress + - istio + type: string + required: + - apiFqdnUrl + - dbFqdnSuffix + - method + type: object license: description: Redis Enterprise License type: string @@ -10719,6 +10798,10 @@ spec: type: string versionTag: type: string + digestHash: + description: 'The digest hash of the image to pull. Version tag must be also specified with the corresponding version, will use the digest hash to pull the image if exists. + Note: This is currently supported only for OLM.' + type: string type: object redisEnterpriseNodeResources: description: Compute resource requirements for Redis Enterprise containers @@ -10840,6 +10923,10 @@ spec: type: string versionTag: type: string + digestHash: + description: 'The digest hash of the image to pull. Version tag must be also specified with the corresponding version, will use the digest hash to pull the image if exists. + Note: This is currently supported only for OLM.' + type: string type: object redisEnterpriseServicesRiggerResources: description: Compute resource requirements for Services Rigger pod diff --git a/crds/rec_crd.yaml b/crds/rec_crd.yaml index 07f06f3..ad4dcac 100644 --- a/crds/rec_crd.yaml +++ b/crds/rec_crd.yaml @@ -133,7 +133,9 @@ spec: description: RedisEnterpriseClusterSpec defines the desired state of RedisEnterpriseCluster properties: activeActive: - description: Specification for ActiveActive setup + description: Specification for ActiveActive setup. At most one of + ingressOrRouteSpec or activeActive fields can be set at the same + time. properties: apiIngressUrl: description: RS API URL @@ -179,6 +181,10 @@ spec: type: string versionTag: type: string + digestHash: + description: 'The digest hash of the image to pull. Version tag must be also specified with the corresponding version, will use the digest hash to pull the image if exists. + Note: This is currently supported only for OLM.' + type: string type: object bootstrapperResources: description: Compute resource requirements for bootstrapper containers @@ -301,6 +307,42 @@ spec: type: string type: object type: array + ingressOrRouteSpec: + description: Access configurations for the Redis Enterprise Cluster + and Databases. Note - this feature is currently in preview. For + this feature to take effect, set a boolean environment variable + with the name "ENABLE_ALPHA_FEATURES" to True. This variable can + be set via the redis-enterprise-operator pod spec, or through the + operator-environment-config Config Map. At most one of ingressOrRouteSpec + or activeActive fields can be set at the same time. + properties: + apiFqdnUrl: + description: RS API URL + type: string + dbFqdnSuffix: + description: DB ENDPOINT SUFFIX - will be used to set the db host + ingress . Creates a host name so it + should be unique if more than one db is created on the cluster + with the same name + type: string + ingressAnnotations: + additionalProperties: + type: string + description: Additional annotations to set on ingress resources + created by the operator + type: object + method: + description: Used to distinguish between different platforms implementation. + enum: + - openShiftRoute + - ingress + - istio + type: string + required: + - apiFqdnUrl + - dbFqdnSuffix + - method + type: object license: description: Redis Enterprise License type: string @@ -2966,6 +3008,10 @@ spec: type: string versionTag: type: string + digestHash: + description: 'The digest hash of the image to pull. Version tag must be also specified with the corresponding version, will use the digest hash to pull the image if exists. + Note: This is currently supported only for OLM.' + type: string type: object redisEnterpriseNodeResources: description: Compute resource requirements for Redis Enterprise containers @@ -6984,7 +7030,9 @@ spec: description: RedisEnterpriseClusterSpec defines the desired state of RedisEnterpriseCluster properties: activeActive: - description: Specification for ActiveActive setup + description: Specification for ActiveActive setup. At most one of + ingressOrRouteSpec or activeActive fields can be set at the same + time. properties: apiIngressUrl: description: RS API URL @@ -7006,6 +7054,7 @@ spec: enum: - openShiftRoute - ingress + - istio type: string required: - apiIngressUrl @@ -7151,6 +7200,42 @@ spec: type: string type: object type: array + ingressOrRouteSpec: + description: Access configurations for the Redis Enterprise Cluster + and Databases. Note - this feature is currently in preview. For + this feature to take effect, set a boolean environment variable + with the name "ENABLE_ALPHA_FEATURES" to True. This variable can + be set via the redis-enterprise-operator pod spec, or through the + operator-environment-config Config Map. At most one of ingressOrRouteSpec + or activeActive fields can be set at the same time. + properties: + apiFqdnUrl: + description: RS API URL + type: string + dbFqdnSuffix: + description: DB ENDPOINT SUFFIX - will be used to set the db host + ingress . Creates a host name so it + should be unique if more than one db is created on the cluster + with the same name + type: string + ingressAnnotations: + additionalProperties: + type: string + description: Additional annotations to set on ingress resources + created by the operator + type: object + method: + description: Used to distinguish between different platforms implementation. + enum: + - openShiftRoute + - ingress + - istio + type: string + required: + - apiFqdnUrl + - dbFqdnSuffix + - method + type: object license: description: Redis Enterprise License type: string @@ -9817,6 +9902,10 @@ spec: type: string versionTag: type: string + digestHash: + description: 'The digest hash of the image to pull. Version tag must be also specified with the corresponding version, will use the digest hash to pull the image if exists. + Note: This is currently supported only for OLM.' + type: string type: object redisEnterpriseNodeResources: description: Compute resource requirements for Redis Enterprise containers @@ -9938,6 +10027,10 @@ spec: type: string versionTag: type: string + digestHash: + description: 'The digest hash of the image to pull. Version tag must be also specified with the corresponding version, will use the digest hash to pull the image if exists. + Note: This is currently supported only for OLM.' + type: string type: object redisEnterpriseServicesRiggerResources: description: Compute resource requirements for Services Rigger pod diff --git a/crds/redb_crd.yaml b/crds/redb_crd.yaml index 0defc00..5a53195 100644 --- a/crds/redb_crd.yaml +++ b/crds/redb_crd.yaml @@ -685,8 +685,6 @@ spec: lastBackupTime: description: Time of last successful backup type: string - required: - - backupHistory type: object specStatus: description: Whether the desired specification is valid diff --git a/google_private_cloud/README.md b/google_private_cloud/README.md new file mode 100644 index 0000000..cdba418 --- /dev/null +++ b/google_private_cloud/README.md @@ -0,0 +1,100 @@ + +# Deploying Redis Enterprise on Google Private Cloud + +This page describes how to deploy Redis Enterprise on Google Private Cloud Kubernetes solution using the Redis Enterprise Operator. + +### Prerequisites + +- A Kubernetes cluster version of 1.20 or higher, with a minimum of 3 worker nodes. +- A Kubernetes client (kubectl) with a matching version. +- Access to DockerHub, Harbor or a private repository that can serve the required images. + + + +The following are the images and tags for this release: + +| Component | k8s | +| --- | --- | +| Redis Enterprise | `redislabs/redis:6.2.10-129` | +| Operator | `redislabs/operator:6.2.10-45` | +| Services Rigger | `redislabs/k8s-controller:6.2.10-45` | + + +### Installation +The "Basic" installation deploys the operator (from the current release) from DockerHub and default settings. +This is the fastest way to get up and running with a new Redis Enterprise on Kubernetes. + +1. We will need to clone the yamls from [github](https://github.com/RedisLabs/redis-enterprise-k8s-docs/releases) to your local directory. + +2. Create a new namespace: + > Note: + For the purpose of this doc, we'll use the name "demo" for our cluster's namespace. + + ```bash + kubectl create namespace demo + ``` + + Switch context to the newly created namespace: + + ```bash + kubectl config set-context --current --namespace=demo + ``` +*** +For deploying the bundle and the Redis Enterprise Cluster custom resource we will use the [Kustomize](https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/). +3. Customize the operator deployment - + + Before deploying the bundle.yaml we will need to customize it . + edit the `bundle\kustomize_bundle.yaml` file : + > Note: + Replace the [User Private repo] with your private images repository location. + +4. Deploy the operator bundle + + with `kubectl`, the following command will deploy a bundle of all the yaml declarations required for the operator: + + ```bash + kubectl apply -k bundle + ``` + + Run `kubectl get deployment` and verify redis-enterprise-operator deployment is running. + + A typical response may look like this: + + ```bash + NAME READY UP-TO-DATE AVAILABLE AGE + redis-enterprise-operator 1/1 1 1 2m + ``` + +5. Customize the Redis Enterprise Cluster custom resource - + + Before deploying the rec.yaml we will need to customize it . + edit the `rec\kustomize_rec.yaml` file : + > Note: + Replace the [User Private repo] with your private images repository location. + + The kustomize_rec.yaml configure the Redis Enterprise Cluster custom resource with the default configuration, + which is suitable for development type deployments and works in typical scenarios. + The full list of attributes supported through the Redis Enterprise Cluster (REC) API can be found [HERE](redis_enterprise_cluster_api.md). + + +6. Redis Enterprise Cluster custom resource - `RedisEnterpriseCluster` + + Create a `RedisEnterpriseCluster`(REC) using the kustomize capability, + + ```bash + kubectl apply -k rec + ``` + + > Note: + The Operator can only manage one Redis Enterprise Cluster custom resource in a namespace. To deploy another Enterprise Clusters in the same Kubernetes cluster, deploy an Operator in an additional namespace for each additional Enterprise Cluster required. Note that each Enterprise Cluster can effectively host hundreds of Redis Database instances. Deploying multiple clusters is typically used for scenarios where complete operational isolation is required at the cluster level. + +7. Run ```kubectl get rec``` and verify creation was successful. `rec` is a shortcut for RedisEnterpriseCluster. The cluster takes around 5-10 minutes to come up. + A typical response may look like this: + ``` + NAME AGE + rec 5m + ``` + > Note: Once the cluster is up, the cluster GUI and API could be used to configure databases. It is recommended to use the K8s REDB API that is configured through the following steps. To configure the cluster using the cluster GUI/API, use the ui service created by the operator and the default credentials as set in a secret. The secret name is the same as the cluster name within the namespace. + + +*** For advanced configuration and more info you can visit our formal documentation [here](https://github.com/RedisLabs/redis-enterprise-k8s-docs/blob/master/README.md). \ No newline at end of file diff --git a/google_private_cloud/bundle/kustomization.yaml b/google_private_cloud/bundle/kustomization.yaml new file mode 100644 index 0000000..d0304c1 --- /dev/null +++ b/google_private_cloud/bundle/kustomization.yaml @@ -0,0 +1,4 @@ +resources: +- bundle.yaml +patchesStrategicMerge: +- kustomize_bundle.yaml \ No newline at end of file diff --git a/google_private_cloud/rec/kustomization.yaml b/google_private_cloud/rec/kustomization.yaml new file mode 100644 index 0000000..619df3f --- /dev/null +++ b/google_private_cloud/rec/kustomization.yaml @@ -0,0 +1,4 @@ +resources: +- rec.yaml +patchesStrategicMerge: +- kustomize_rec.yaml \ No newline at end of file diff --git a/google_private_cloud/rec/kustomize_rec.yaml b/google_private_cloud/rec/kustomize_rec.yaml new file mode 100644 index 0000000..db0f689 --- /dev/null +++ b/google_private_cloud/rec/kustomize_rec.yaml @@ -0,0 +1,17 @@ +apiVersion: app.redislabs.com/v1alpha1 +kind: RedisEnterpriseCluster +metadata: + name: rec +spec: + persistentSpec: + storageClassName: standard + volumeSize: 20Gi + redisEnterpriseImageSpec: + repository: [User redis Private repo] + versionTag: 6.2.10-129 + redisEnterpriseServicesRiggerImageSpec: + repository: [User service rigger Private repo] + versionTag: 6.2.10-45 + bootstrapperImageSpec: + repository: [User operator Private repo] + versionTag: 6.2.10-45 \ No newline at end of file diff --git a/google_private_cloud/rec/rec.yaml b/google_private_cloud/rec/rec.yaml new file mode 100644 index 0000000..2480955 --- /dev/null +++ b/google_private_cloud/rec/rec.yaml @@ -0,0 +1,7 @@ +apiVersion: app.redislabs.com/v1 +kind: RedisEnterpriseCluster +metadata: + name: rec +spec: + # Add fields here + nodes: 3 diff --git a/log_collector/log_collector.py b/log_collector/log_collector.py index 1abc38f..bce8f22 100755 --- a/log_collector/log_collector.py +++ b/log_collector/log_collector.py @@ -5,7 +5,6 @@ several API objects and for pods logs unless pass a -n parameter will run on current namespace. Run with -h to see options """ - import argparse import json import logging @@ -23,24 +22,27 @@ RLEC_CONTAINER_NAME = "redis-enterprise-node" RS_LOG_FOLDER_PATH = "/var/opt/redislabs/log" -# pylint: disable=locally-disabled, invalid-name -logger = logging.getLogger("log collector") +logger = logging.getLogger(__name__) TIME_FORMAT = time.strftime("%Y%m%d-%H%M%S") KUBCTL_DESCRIBE_RETRIES = 3 KUBCTL_GET_YAML_RETRIES = 3 -timeout = 180 +TIMEOUT = 180 + +DEFAULT_K8S_CLI = "kubectl" +OC_K8S_CLI = "oc" API_RESOURCES = [ "RedisEnterpriseCluster", "RedisEnterpriseDatabase", + "RedisEnterpriseRemoteCluster", "StatefulSet", "Deployment", "Service", "ConfigMap", - "Routes", + "Route", "Ingress", "Role", "RoleBinding", @@ -61,8 +63,8 @@ "ClusterRoleBinding", "ClusterServiceVersion", "Subscription", - "Installplan", - "CatalogSource" + "InstallPlan", + "CatalogSource", "PodSecurityPolicy", "ReplicaSet", "StorageClass", @@ -82,26 +84,27 @@ def make_dir(directory): sys.exit() -def _filter_non_existing_namespaces(namespaces): +def _filter_non_existing_namespaces(namespaces, k8s_cli): """ Filter non-existing namespaces from user's input """ - return_code, out = run_shell_command("kubectl get ns -o=custom-columns='DATA:metadata.name' --no-headers=true") + return_code, out = run_shell_command( + "{} get ns -o=custom-columns='DATA:metadata.name' --no-headers=true".format(k8s_cli)) if return_code: return [] res = [] existing_namespaces = set(out.split()) - for ns in namespaces: - if ns in existing_namespaces: - res.append(ns) + for namespace in namespaces: + if namespace in existing_namespaces: + res.append(namespace) else: - logger.warning("Namespace %s doesn't exist - Skipping", ns) + logger.warning("Namespace %s doesn't exist - Skipping", namespace) return res -def _get_namespaces_to_run_on(namespace): +def _get_namespaces_to_run_on(namespace, k8s_cli): def _get_namespace_from_config(): - config_namespace = get_namespace_from_config() + config_namespace = get_namespace_from_config(k8s_cli) if not config_namespace: return ["default"] return [config_namespace] @@ -110,7 +113,8 @@ def _get_namespace_from_config(): return _get_namespace_from_config() if namespace == 'all': - return_code, out = run_shell_command("kubectl get ns -o=custom-columns='DATA:metadata.name' --no-headers=true") + return_code, out = run_shell_command( + "{} get ns -o=custom-columns='DATA:metadata.name' --no-headers=true".format(k8s_cli)) if return_code: logger.warning("Failed to parse namespace list - will use namespace from config: %s", out) return _get_namespace_from_config() @@ -118,35 +122,69 @@ def _get_namespace_from_config(): # comma separated string namespaces = namespace.split(',') - existing_namespaces = _filter_non_existing_namespaces(namespaces) + existing_namespaces = _filter_non_existing_namespaces(namespaces, k8s_cli) if not existing_namespaces: logger.warning("Input doesn't contain an existing namespace - will use namespace from config") return _get_namespace_from_config() return existing_namespaces -def collect_from_ns(namespace, output_dir, logs_from_all_pods=False): +def collect_from_ns(namespace, output_dir, logs_from_all_pods=False, k8s_cli_input=""): "Collect the context of a specific namespace. Typically runs in parallel processes." + k8s_cli = detect_k8s_cli(k8s_cli_input) logger.info("Started collecting from namespace '%s'", namespace) ns_output_dir = os.path.join(output_dir, namespace) make_dir(ns_output_dir) - collect_connectivity_check(namespace, ns_output_dir) - get_redis_enterprise_debug_info(namespace, ns_output_dir) - collect_pod_rs_logs(namespace, ns_output_dir) - collect_resources_list(namespace, ns_output_dir) - collect_events(namespace, ns_output_dir) - collect_api_resources(namespace, ns_output_dir) - collect_api_resources_description(namespace, ns_output_dir) - collect_pods_logs(namespace, ns_output_dir, logs_from_all_pods) - + collect_connectivity_check(namespace, ns_output_dir, k8s_cli) + get_redis_enterprise_debug_info(namespace, ns_output_dir, k8s_cli) + collect_pod_rs_logs(namespace, ns_output_dir, k8s_cli) + collect_resources_list(namespace, ns_output_dir, k8s_cli) + collect_events(namespace, ns_output_dir, k8s_cli) + collect_api_resources(namespace, ns_output_dir, k8s_cli) + collect_api_resources_description(namespace, ns_output_dir, k8s_cli) + collect_pods_logs(namespace, ns_output_dir, k8s_cli, logs_from_all_pods) + + +def detect_k8s_cli(k8s_cli_input=""): + "Check whether the kubernetes is openshift and use oc as needed" + if k8s_cli_input and k8s_cli_input != "auto-detect": + logger.info("Using cli-client %s", k8s_cli_input) + return k8s_cli_input + + # auto detect mode + get_nodes_cmd = "{} get nodes -o json".format(DEFAULT_K8S_CLI) + return_code, output = run_shell_command(get_nodes_cmd) + if return_code: + logger.info("Failed to run cmd %s", get_nodes_cmd) + return DEFAULT_K8S_CLI -def run(namespace_input, output_dir, logs_from_all_pods=False): + if output: + try: + parsed = json.loads("".join(output)) + if "items" in parsed and len(parsed["items"]) and \ + ("machine.openshift.io/machine" in parsed["items"][0]["metadata"]["annotations"] or + "node.openshift.io/os_id" in parsed["items"][0]["metadata"]["labels"]): + # this is an openshift + logger.info( + "Auto detected OpenShift, will use oc as cli tool " + "(this can be overriden using the --k8s_cli argument)") + return OC_K8S_CLI + except json.JSONDecodeError: + logger.exception( + "Failed to detect the relevant client for Kubernetes " + "(failed to parse kubectl command) will keep the default") + return DEFAULT_K8S_CLI + return DEFAULT_K8S_CLI + + +def run(namespace_input, output_dir, logs_from_all_pods=False, k8s_cli_input=""): """ Collect logs """ start_time = time.time() - namespaces = _get_namespaces_to_run_on(namespace_input) + k8s_cli = detect_k8s_cli(k8s_cli_input) + namespaces = _get_namespaces_to_run_on(namespace_input, k8s_cli) output_file_name = "redis_enterprise_k8s_debug_info_{}".format(TIME_FORMAT) if not output_dir: @@ -154,28 +192,44 @@ def run(namespace_input, output_dir, logs_from_all_pods=False): output_dir = os.getcwd() output_dir = os.path.join(output_dir, output_file_name) make_dir(output_dir) - collect_cluster_info(output_dir) + collect_cluster_info(output_dir, k8s_cli) processes = [] for namespace in namespaces: - p = Process(target=collect_from_ns, args=[namespace, output_dir, logs_from_all_pods]) - p.start() - processes.append(p) + proc = Process(target=collect_from_ns, args=[namespace, output_dir, logs_from_all_pods, k8s_cli_input]) + proc.start() + processes.append(proc) + + for proc in processes: + proc.join() - for p in processes: - p.join() + create_collection_report(output_dir, output_file_name, k8s_cli, namespaces, start_time) archive_files(output_dir, output_file_name) logger.info("Finished Redis Enterprise log collector") logger.info("--- Run time: %d minutes ---", round(((time.time() - start_time) / 60), 3)) -def get_non_ready_rs_pod_names(namespace): +def create_collection_report(output_dir, output_file_name, k8s_cli, namespaces, start_time): + """ + create a file with some data about the collection + """ + + with open(os.path.join(output_dir, 'collection_report.json'), "w") as output_fh: + json.dump({ + "output_file_name": output_file_name, + "k8s_cli": k8s_cli, + "namespaces": namespaces, + "start_time": start_time + }, output_fh) + + +def get_non_ready_rs_pod_names(namespace, k8s_cli): """ get names of rs pods that are not ready """ pod_names = [] - rs_pods = get_pods(namespace, selector='redis.io/role=node') + rs_pods = get_pods(namespace, k8s_cli, selector='redis.io/role=node') if not rs_pods: logger.info("Namespace '%s': cannot find redis enterprise pods", namespace) return [] @@ -192,12 +246,12 @@ def get_non_ready_rs_pod_names(namespace): return pod_names -def collect_pod_rs_logs(namespace, output_dir): +def collect_pod_rs_logs(namespace, output_dir, k8s_cli): """ get logs from rs pods that are not ready """ rs_pod_logs_dir = os.path.join(output_dir, "rs_pod_logs") - rs_pod_names = get_pod_names(namespace=namespace, selector='redis.io/role=node') + rs_pod_names = get_pod_names(namespace=namespace, k8s_cli=k8s_cli, selector='redis.io/role=node') if not rs_pod_names: logger.warning("Namespace '%s' Could not get rs pods list - " "skipping rs pods logs collection", namespace) @@ -207,11 +261,12 @@ def collect_pod_rs_logs(namespace, output_dir): for rs_pod_name in rs_pod_names: pod_log_dir = os.path.join(rs_pod_logs_dir, rs_pod_name) make_dir(pod_log_dir) - cmd = "cd \"{}\" && kubectl -n {} cp {}:{} ./ -c {}".format(pod_log_dir, - namespace, - rs_pod_name, - RS_LOG_FOLDER_PATH, - RLEC_CONTAINER_NAME) + cmd = "cd \"{}\" && {} -n {} cp {}:{} ./ -c {}".format(pod_log_dir, + k8s_cli, + namespace, + rs_pod_name, + RS_LOG_FOLDER_PATH, + RLEC_CONTAINER_NAME) return_code, out = run_shell_command(cmd) if return_code: logger.warning("Failed to copy rs logs from pod " @@ -223,11 +278,12 @@ def collect_pod_rs_logs(namespace, output_dir): pod_config_dir = os.path.join(pod_log_dir, "config") make_dir(pod_config_dir) - cmd = "cd \"{}\" && kubectl -n {} cp {}:{} ./ -c {}".format(pod_config_dir, - namespace, - rs_pod_name, - "/opt/redislabs/config", - RLEC_CONTAINER_NAME) + cmd = "cd \"{}\" && {} -n {} cp {}:{} ./ -c {}".format(pod_config_dir, + k8s_cli, + namespace, + rs_pod_name, + "/opt/redislabs/config", + RLEC_CONTAINER_NAME) return_code, out = run_shell_command(cmd) if return_code: logger.warning("Failed to copy rs config from pod " @@ -237,14 +293,14 @@ def collect_pod_rs_logs(namespace, output_dir): logger.info("Collected rs config from pod marked as not ready, pod name: %s", rs_pod_name) -def debuginfo_attempt_on_pod(namespace, output_dir, pod_name, attempt): +def debuginfo_attempt_on_pod(namespace, output_dir, pod_name, attempt, k8s_cli): """ Execute the rladmin command to get debug info on a specific pod Returns: true on success, false on failure """ prog = "/opt/redislabs/bin/rladmin" - cmd = "kubectl -n {} exec {} -c {} {} cluster debug_info path /tmp" \ - .format(namespace, pod_name, RLEC_CONTAINER_NAME, prog) + cmd = "{} -n {} exec {} -c {} {} cluster debug_info path /tmp" \ + .format(k8s_cli, namespace, pod_name, RLEC_CONTAINER_NAME, prog) return_code, out = run_shell_command(cmd) if "Downloading complete" not in out: logger.warning("Failed running rladmin command in pod: %s (attempt %d)", @@ -265,11 +321,12 @@ def debuginfo_attempt_on_pod(namespace, output_dir, pod_name, attempt): return False # copy package from RS pod - cmd = "cd \"{}\" && kubectl -n {} cp {}:{} ./{}".format(output_dir, - namespace, - pod_name, - debug_file_path, - debug_file_name) + cmd = "cd \"{}\" && {} -n {} cp {}:{} ./{}".format(output_dir, + k8s_cli, + namespace, + pod_name, + debug_file_path, + debug_file_name) return_code, out = run_shell_command(cmd) if return_code: logger.warning("Failed to copy debug info from pod " @@ -281,12 +338,12 @@ def debuginfo_attempt_on_pod(namespace, output_dir, pod_name, attempt): return True -def get_redis_enterprise_debug_info(namespace, output_dir): +def get_redis_enterprise_debug_info(namespace, output_dir, k8s_cli): """ Connects to an RS cluster node, creates and copies debug info package from a pod, preferably one that passes readiness probe """ - rs_pods = get_pods(namespace, selector='redis.io/role=node') + rs_pods = get_pods(namespace, k8s_cli, selector='redis.io/role=node') if not rs_pods: logger.info("Namespace '%s': Cannot find redis enterprise pod", namespace) return @@ -308,31 +365,32 @@ def get_redis_enterprise_debug_info(namespace, output_dir): if debuginfo_attempt_on_pod(namespace, output_dir, pod_name, - attempt + 1): + attempt + 1, + k8s_cli): logger.info("Namespace '%s': Collected Redis Enterprise cluster debug package", namespace) return -def collect_resources_list(namespace, output_dir): +def collect_resources_list(namespace, output_dir, k8s_cli): """ Prints the output of kubectl get all to a file """ collect_helper(output_dir, - cmd="kubectl get all -o wide -n {}".format(namespace), + cmd="{} get all -o wide -n {}".format(k8s_cli, namespace), file_name="resources_list", resource_name="resources list", namespace=namespace) -def collect_cluster_info(output_dir): +def collect_cluster_info(output_dir, k8s_cli): """ Prints the output of kubectl cluster-info to a file """ - collect_helper(output_dir, cmd="kubectl cluster-info", + collect_helper(output_dir, cmd="{} cluster-info".format(k8s_cli), file_name="cluster_info", resource_name="cluster-info") -def collect_events(namespace, output_dir): +def collect_events(namespace, output_dir, k8s_cli): """ Prints the output of kubectl cluster-info to a file """ @@ -341,12 +399,12 @@ def collect_events(namespace, output_dir): logger.warning("Cannot collect events without namespace - " "skipping events collection") return - cmd = "kubectl get events -n {} -o wide".format(namespace) + cmd = "{} get events -n {} -o wide".format(k8s_cli, namespace) collect_helper(output_dir, cmd=cmd, file_name="events", resource_name="events", namespace=namespace) -def collect_api_resources(namespace, output_dir): +def collect_api_resources(namespace, output_dir, k8s_cli): """ Creates file for each of the API resources with the output of kubectl get -o yaml @@ -354,7 +412,7 @@ def collect_api_resources(namespace, output_dir): logger.info("Namespace '%s': Collecting API resources", namespace) resources_out = OrderedDict() for resource in API_RESOURCES: - output = run_kubectl_get_yaml(namespace, resource) + output = run_get_resource_yaml(namespace, resource, k8s_cli) if output: resources_out[resource] = output logger.info("Namespace '%s': + Collected %s", namespace, resource) @@ -364,7 +422,7 @@ def collect_api_resources(namespace, output_dir): file_handle.write(out) -def collect_api_resources_description(namespace, output_dir): +def collect_api_resources_description(namespace, output_dir, k8s_cli): """ Creates file for each of the API resources with the output of kubectl describe @@ -372,7 +430,7 @@ def collect_api_resources_description(namespace, output_dir): logger.info("Namespace '%s': Collecting API resources description", namespace) resources_out = OrderedDict() for resource in API_RESOURCES: - output = run_kubectl_describe(namespace, resource) + output = describe_resource(namespace, resource, k8s_cli) if output: resources_out[resource] = output logger.info("Namespace: '%s' + Collected %s", namespace, resource) @@ -383,7 +441,7 @@ def collect_api_resources_description(namespace, output_dir): file_handle.write(out) -def collect_pods_logs(namespace, output_dir, logs_from_all_pods=False): +def collect_pods_logs(namespace, output_dir, k8s_cli, logs_from_all_pods=False): """ Collects all the pods logs from given namespace """ @@ -391,11 +449,11 @@ def collect_pods_logs(namespace, output_dir, logs_from_all_pods=False): logs_dir = os.path.join(output_dir, "pods") if logs_from_all_pods: - pods = get_pod_names(namespace) + pods = get_pod_names(namespace, k8s_cli) else: pods = [] for selector in ["app=redis-enterprise", "name=redis-enterprise-operator"]: - pods.extend(get_pod_names(namespace, selector)) + pods.extend(get_pod_names(namespace, k8s_cli, selector)) if not pods: logger.warning("Namespace '%s' Could not get pods list - " @@ -405,25 +463,27 @@ def collect_pods_logs(namespace, output_dir, logs_from_all_pods=False): make_dir(logs_dir) for pod in pods: - collect_logs_from_pod(namespace, pod, logs_dir) + collect_logs_from_pod(namespace, pod, logs_dir, k8s_cli) -def collect_connectivity_check(namespace, output_dir): +def collect_connectivity_check(namespace, output_dir, k8s_cli): """ Collect connectivity checks to files (using certain ns). """ # Verify with curl. if sys.platform != 'win32': - collect_helper(output_dir, - cmd="APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}') \ - && curl -k -v ${APISERVER}/api/", - file_name="connectivity_check_via_curl", - resource_name="connectivity check via curl") + cmd = "{} config view --minify -o ".format(k8s_cli) + "jsonpath='{.clusters[0].cluster.server}'" + _, api_server = run_shell_command(cmd) + if api_server: + collect_helper(output_dir, + cmd="curl -k -v {}/api/".format(api_server), + file_name="connectivity_check_via_curl", + resource_name="connectivity check via curl") # Verify with kubectl. collect_helper(output_dir, - cmd="kubectl get all -v=6 -n {}".format(namespace), - file_name="connectivity_check_via_kubectl", - resource_name="connectivity check via kubectl", + cmd="{} get all -v=6 -n {}".format(k8s_cli, namespace), + file_name="connectivity_check_via_k8s_cli", + resource_name="connectivity check via k8s cli", namespace=namespace) @@ -444,13 +504,13 @@ def archive_files(output_dir, output_dir_name): logger.warning("Failed to delete directory after archiving: %s", ex) -def get_pods(namespace, selector=""): +def get_pods(namespace, k8s_cli, selector=""): """ Returns list of pods """ if selector: selector = '--selector="{}"'.format(selector) - cmd = 'kubectl get pod -n {} {} -o json '.format(namespace, selector) + cmd = '{} get pod -n {} {} -o json '.format(k8s_cli, namespace, selector) return_code, out = run_shell_command(cmd) if return_code: logger.warning("Failed to get pods: %s", out) @@ -458,11 +518,11 @@ def get_pods(namespace, selector=""): return json.loads(out)['items'] -def get_list_of_containers_from_pod(namespace, pod_name): +def get_list_of_containers_from_pod(namespace, pod_name, k8s_cli): """ Returns list of containers from a given pod """ - cmd = f"kubectl get pod {pod_name} -o jsonpath='{{.spec.containers[*].name}}' -n {namespace}" + cmd = "{} get pod {} -o jsonpath='{{.spec.containers[*].name}}' -n {}".format(k8s_cli, pod_name, namespace) return_code, out = run_shell_command(cmd) if return_code: logger.warning("Failed to get containers from pod: %s", out) @@ -470,11 +530,11 @@ def get_list_of_containers_from_pod(namespace, pod_name): return out.replace("'", "").split() -def get_list_of_init_containers_from_pod(namespace, pod_name): +def get_list_of_init_containers_from_pod(namespace, pod_name, k8s_cli): """ Returns a list of init containers from a given pod. """ - cmd = f"kubectl get pod {pod_name} -o jsonpath='{{.spec.initContainers[*].name}}' -n {namespace}" + cmd = "{} get pod {} -o jsonpath='{{.spec.initContainers[*].name}}' -n {}".format(k8s_cli, pod_name, namespace) return_code, out = run_shell_command(cmd) if return_code: logger.warning("Failed to get init containers from pod: %s", out) @@ -482,32 +542,32 @@ def get_list_of_init_containers_from_pod(namespace, pod_name): return out.replace("'", "").split() -def collect_logs_from_pod(namespace, pod, logs_dir): +def collect_logs_from_pod(namespace, pod, logs_dir, k8s_cli): """ Helper function getting logs of a pod """ - containers = get_list_of_containers_from_pod(namespace, pod) - init_containers = get_list_of_init_containers_from_pod(namespace, pod) + containers = get_list_of_containers_from_pod(namespace, pod, k8s_cli) + init_containers = get_list_of_init_containers_from_pod(namespace, pod, k8s_cli) containers.extend(init_containers) if containers is None: logger.warning("Namespace '%s' Could not get containers for pod: %s list - " "skipping pods logs collection", namespace, pod) return for container in containers: - cmd = "kubectl logs -c {} -n {} {}" \ - .format(container, namespace, pod) - with open(os.path.join(logs_dir, "{}.log".format(f'{pod}-{container}')), + cmd = "{} logs -c {} -n {} {}" \ + .format(k8s_cli, container, namespace, pod) + with open(os.path.join(logs_dir, "{}-{}.log".format(pod, container)), "w+") as file_handle: _, output = run_shell_command(cmd) file_handle.write(output) # operator and admission containers restart after changing the operator-environment-configmap # getting the logs of the containers before the restart can help us with debugging potential bugs - get_logs_before_restart_cmd = "kubectl logs -c {} -n {} {} -p" \ - .format(container, namespace, pod) + get_logs_before_restart_cmd = "{} logs -c {} -n {} {} -p" \ + .format(k8s_cli, container, namespace, pod) err_code, output = run_shell_command(get_logs_before_restart_cmd) container_log_before_restart_file = os.path.join(logs_dir, - "{}.log".format(f'{pod}-{container}-instance-before-restart')) + '{}-{}-instance-before-restart.log'.format(pod, container)) if err_code == 0: # Previous container instance found; did restart. with open(container_log_before_restart_file, "w+") as file_handle: file_handle.write(output) @@ -515,23 +575,23 @@ def collect_logs_from_pod(namespace, pod, logs_dir): logger.info("Namespace '%s': + %s-%s", namespace, pod, container) -def get_pod_names(namespace, selector=""): +def get_pod_names(namespace, k8s_cli, selector=""): """ Returns list of pod names """ - pods = get_pods(namespace, selector) + pods = get_pods(namespace, k8s_cli, selector) if not pods: logger.info("Namespace '%s': Cannot find pods", namespace) return None return [pod['metadata']['name'] for pod in pods] -def get_namespace_from_config(): +def get_namespace_from_config(k8s_cli): """ Returns the namespace from current context if one is set OW None """ # find namespace from config file - cmd = "kubectl config view -o json" + cmd = "{} config view -o json".format(k8s_cli) return_code, out = run_shell_command(cmd) if return_code: return None @@ -572,16 +632,30 @@ def native_string(input_var): return input_var.decode('utf-8', 'replace') -def run_kubectl_get_yaml(namespace, resource_type): +def run_get_resource_yaml(namespace, resource_type, k8s_cli): """ Runs kubectl get command with yaml format """ - cmd = "kubectl get -n {} {} -o yaml".format(namespace, resource_type) - for _ in range(KUBCTL_GET_YAML_RETRIES): + cmd = "{} get -n {} {} -o yaml".format(k8s_cli, namespace, resource_type) + error_template = "Namespace '{}': Failed to get {} resource: {{}}.".format(namespace, resource_type) + return run_shell_command_with_retries(cmd, KUBCTL_GET_YAML_RETRIES, error_template) + + +def run_shell_command_with_retries(cmd, retries, error_template): + """ + Run a shell command, retrying up to attempts. + When the command fails with a non-zero exit code, the output is printed + using the provided string ('{}'-style template). + Repeated error messages are supressed. + """ + prev_out = None + for _ in range(retries): return_code, out = run_shell_command(cmd) if return_code == 0: return out - logger.warning("Namespace '%s': Failed to get %s resource %s.", namespace, resource_type, out.rstrip()) + if out is not None and out != prev_out: + logger.warning(error_template.format(out.rstrip())) + prev_out = out return None @@ -591,7 +665,7 @@ def run_shell_command(args): """ # to allow timeouts to work in windows, # would need to find another mechanism that signal.alarm based - if sys.platform == 'win32' or timeout == 0: + if sys.platform == 'win32' or TIMEOUT == 0: return run_shell_command_regular(args) return run_shell_command_timeout(args) @@ -644,9 +718,9 @@ def alarm_handler(_, __): stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=env) - if timeout != 0: + if TIMEOUT != 0: signal.signal(signal.SIGALRM, alarm_handler) - signal.alarm(timeout) + signal.alarm(TIMEOUT) try: output, _ = piped_process.communicate() # disable alarm after process returns @@ -667,17 +741,13 @@ def alarm_handler(_, __): return piped_process.returncode, native_string(output) -def run_kubectl_describe(namespace, resource_type): +def describe_resource(namespace, resource_type, k8s_cli): """ Runs kubectl describe command """ - cmd = "kubectl describe -n {} {}".format(namespace, resource_type) - for _ in range(KUBCTL_DESCRIBE_RETRIES): - return_code, out = run_shell_command(cmd) - if return_code == 0: - return out - logger.warning("Namespace: '%s': Failed to describe %s resource: %s", namespace, resource_type, out) - return None + cmd = "{} describe -n {} {}".format(k8s_cli, namespace, resource_type) + error_template = "Namespace '{}': Failed to describe {} resource: {{}}.".format(namespace, resource_type) + return run_shell_command_with_retries(cmd, KUBCTL_DESCRIBE_RETRIES, error_template) if __name__ == "__main__": @@ -695,20 +765,24 @@ def run_kubectl_describe(namespace, resource_type): parser.add_argument('-a', '--logs_from_all_pods', action="store_true", help="collect logs from all pods, not only the operator and pods run by the operator") parser.add_argument('-t', '--timeout', action="store", - type=int, default=timeout, + type=int, default=TIMEOUT, help="time to wait for external commands to " "finish execution " "(default: 180s, specify 0 to not timeout) " "(Linux only)") + parser.add_argument('--k8s_cli', action="store", type=str, + help="Which K8s cli client to use (kubectl/oc/auto-detect). " + "Defaults to auto-detect (chooses between \"kubectl\" and \"oc\"). " + "Full paths can also be used.") # pylint: disable=locally-disabled, invalid-name results = parser.parse_args() # pylint: disable=locally-disabled, invalid-name - timeout = results.timeout - if timeout < 0: + TIMEOUT = results.timeout + if TIMEOUT < 0: logger.error("timeout can't be less than 0") sys.exit(1) logger.info("Started Redis Enterprise k8s log collector") - run(results.namespace, results.output_dir, results.logs_from_all_pods) + run(results.namespace, results.output_dir, results.logs_from_all_pods, results.k8s_cli) diff --git a/multi-namespace-redb/operator.yaml b/multi-namespace-redb/operator.yaml index d859a7b..690013c 100644 --- a/multi-namespace-redb/operator.yaml +++ b/multi-namespace-redb/operator.yaml @@ -15,7 +15,7 @@ spec: serviceAccountName: redis-enterprise-operator containers: - name: redis-enterprise-operator - image: redislabs/operator:6.2.10-34 + image: redislabs/operator:6.2.10-45 command: - redis-enterprise-operator imagePullPolicy: Always @@ -57,7 +57,7 @@ spec: port: 8080 scheme: HTTP - name: admission - image: redislabs/operator:6.2.10-34 + image: redislabs/operator:6.2.10-45 command: - /usr/local/bin/admission imagePullPolicy: Always diff --git a/openshift.bundle.yaml b/openshift.bundle.yaml index f07a78c..3ec7c33 100644 --- a/openshift.bundle.yaml +++ b/openshift.bundle.yaml @@ -32,10 +32,11 @@ rules: resources: ["roles", "serviceaccounts", "rolebindings"] verbs: ["bind", "escalate", "impersonate", "userextras", "create", "get", "list", "watch", "update", "patch", "delete", "deletecollection"] - - apiGroups: - - app.redislabs.com + - apiGroups: ["app.redislabs.com"] resources: ["redisenterpriseclusters", "redisenterpriseclusters/status", "redisenterpriseclusters/finalizers", - "redisenterprisedatabases", "redisenterprisedatabases/status", "redisenterprisedatabases/finalizers"] + "redisenterprisedatabases", "redisenterprisedatabases/status", "redisenterprisedatabases/finalizers", + "redisenterpriseremoteclusters", "redisenterpriseremoteclusters/status", + "redisenterpriseremoteclusters/finalizers"] verbs: ["delete", "deletecollection", "get", "list", "patch", "create", "update", "watch"] - apiGroups: [""] resources: ["secrets"] @@ -59,8 +60,6 @@ rules: - apiGroups: [""] resources: ["persistentvolumeclaims"] verbs: ["create", "delete", "get" , "update", "list", "watch"] - - # needed rbac rules for services controller - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list", "update", "patch", "delete"] @@ -69,20 +68,16 @@ rules: verbs: ["get", "watch", "list", "update", "patch", "create", "delete"] - apiGroups: ["policy"] resources: ["podsecuritypolicies"] - resourceNames: - - redis-enterprise-psp - verbs: - - use - - apiGroups: ["extensions"] - resources: ["ingresses"] - verbs: ["create", "patch", "replace", "delete", "deletecollection", "read", "list", "listallnamespaces", - "watch", "watchlist", "watchlistallnamespaces", "patchstatus", "readstatus", "replacestatus", "update"] + resourceNames: ["redis-enterprise-psp"] + verbs: ["use"] - apiGroups: ["networking.k8s.io"] resources: ["ingresses"] verbs: ["create", "patch", "replace", "delete", "deletecollection", "read", "list", "listallnamespaces", "watch", "watchlist", "watchlistallnamespaces", "patchstatus", "readstatus", "replacestatus", "update"] - - apiGroups: - - route.openshift.io + - apiGroups: [ "networking.istio.io" ] + resources: [ "gateways", "virtualservices" ] + verbs: [ "get", "watch", "list", "update", "patch", "create", "delete" ] + - apiGroups: ["route.openshift.io"] resources: ["routes", "routes/custom-host"] verbs: ["create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"] @@ -791,8 +786,6 @@ spec: lastBackupTime: description: Time of last successful backup type: string - required: - - backupHistory type: object specStatus: description: Whether the desired specification is valid @@ -845,7 +838,7 @@ spec: serviceAccountName: redis-enterprise-operator containers: - name: redis-enterprise-operator - image: registry.connect.redhat.com/redislabs/redis-enterprise-operator:6.2.10-34 + image: registry.connect.redhat.com/redislabs/redis-enterprise-operator:6.2.10-45 securityContext: runAsUser: 1001 command: @@ -891,7 +884,7 @@ spec: port: 8080 scheme: HTTP - name: admission - image: registry.connect.redhat.com/redislabs/redis-enterprise-operator:6.2.10-34 + image: registry.connect.redhat.com/redislabs/redis-enterprise-operator:6.2.10-45 command: - /usr/local/bin/admission imagePullPolicy: Always @@ -1068,7 +1061,9 @@ spec: description: RedisEnterpriseClusterSpec defines the desired state of RedisEnterpriseCluster properties: activeActive: - description: Specification for ActiveActive setup + description: Specification for ActiveActive setup. At most one of + ingressOrRouteSpec or activeActive fields can be set at the same + time. properties: apiIngressUrl: description: RS API URL @@ -1114,6 +1109,10 @@ spec: type: string versionTag: type: string + digestHash: + description: 'The digest hash of the image to pull. Version tag must be also specified with the corresponding version, will use the digest hash to pull the image if exists. + Note: This is currently supported only for OLM.' + type: string type: object bootstrapperResources: description: Compute resource requirements for bootstrapper containers @@ -1236,6 +1235,42 @@ spec: type: string type: object type: array + ingressOrRouteSpec: + description: Access configurations for the Redis Enterprise Cluster + and Databases. Note - this feature is currently in preview. For + this feature to take effect, set a boolean environment variable + with the name "ENABLE_ALPHA_FEATURES" to True. This variable can + be set via the redis-enterprise-operator pod spec, or through the + operator-environment-config Config Map. At most one of ingressOrRouteSpec + or activeActive fields can be set at the same time. + properties: + apiFqdnUrl: + description: RS API URL + type: string + dbFqdnSuffix: + description: DB ENDPOINT SUFFIX - will be used to set the db host + ingress . Creates a host name so it + should be unique if more than one db is created on the cluster + with the same name + type: string + ingressAnnotations: + additionalProperties: + type: string + description: Additional annotations to set on ingress resources + created by the operator + type: object + method: + description: Used to distinguish between different platforms implementation. + enum: + - openShiftRoute + - ingress + - istio + type: string + required: + - apiFqdnUrl + - dbFqdnSuffix + - method + type: object license: description: Redis Enterprise License type: string @@ -3901,6 +3936,10 @@ spec: type: string versionTag: type: string + digestHash: + description: 'The digest hash of the image to pull. Version tag must be also specified with the corresponding version, will use the digest hash to pull the image if exists. + Note: This is currently supported only for OLM.' + type: string type: object redisEnterpriseNodeResources: description: Compute resource requirements for Redis Enterprise containers @@ -7919,7 +7958,9 @@ spec: description: RedisEnterpriseClusterSpec defines the desired state of RedisEnterpriseCluster properties: activeActive: - description: Specification for ActiveActive setup + description: Specification for ActiveActive setup. At most one of + ingressOrRouteSpec or activeActive fields can be set at the same + time. properties: apiIngressUrl: description: RS API URL @@ -7941,6 +7982,7 @@ spec: enum: - openShiftRoute - ingress + - istio type: string required: - apiIngressUrl @@ -8086,6 +8128,42 @@ spec: type: string type: object type: array + ingressOrRouteSpec: + description: Access configurations for the Redis Enterprise Cluster + and Databases. Note - this feature is currently in preview. For + this feature to take effect, set a boolean environment variable + with the name "ENABLE_ALPHA_FEATURES" to True. This variable can + be set via the redis-enterprise-operator pod spec, or through the + operator-environment-config Config Map. At most one of ingressOrRouteSpec + or activeActive fields can be set at the same time. + properties: + apiFqdnUrl: + description: RS API URL + type: string + dbFqdnSuffix: + description: DB ENDPOINT SUFFIX - will be used to set the db host + ingress . Creates a host name so it + should be unique if more than one db is created on the cluster + with the same name + type: string + ingressAnnotations: + additionalProperties: + type: string + description: Additional annotations to set on ingress resources + created by the operator + type: object + method: + description: Used to distinguish between different platforms implementation. + enum: + - openShiftRoute + - ingress + - istio + type: string + required: + - apiFqdnUrl + - dbFqdnSuffix + - method + type: object license: description: Redis Enterprise License type: string @@ -10752,6 +10830,10 @@ spec: type: string versionTag: type: string + digestHash: + description: 'The digest hash of the image to pull. Version tag must be also specified with the corresponding version, will use the digest hash to pull the image if exists. + Note: This is currently supported only for OLM.' + type: string type: object redisEnterpriseNodeResources: description: Compute resource requirements for Redis Enterprise containers @@ -10873,6 +10955,10 @@ spec: type: string versionTag: type: string + digestHash: + description: 'The digest hash of the image to pull. Version tag must be also specified with the corresponding version, will use the digest hash to pull the image if exists. + Note: This is currently supported only for OLM.' + type: string type: object redisEnterpriseServicesRiggerResources: description: Compute resource requirements for Services Rigger pod diff --git a/openshift/operator_rhel.yaml b/openshift/operator_rhel.yaml index 1b51708..5a5a1d1 100644 --- a/openshift/operator_rhel.yaml +++ b/openshift/operator_rhel.yaml @@ -15,7 +15,7 @@ spec: serviceAccountName: redis-enterprise-operator containers: - name: redis-enterprise-operator - image: registry.connect.redhat.com/redislabs/redis-enterprise-operator:6.2.10-34 + image: registry.connect.redhat.com/redislabs/redis-enterprise-operator:6.2.10-45 securityContext: runAsUser: 1001 command: @@ -61,7 +61,7 @@ spec: port: 8080 scheme: HTTP - name: admission - image: registry.connect.redhat.com/redislabs/redis-enterprise-operator:6.2.10-34 + image: registry.connect.redhat.com/redislabs/redis-enterprise-operator:6.2.10-45 command: - /usr/local/bin/admission imagePullPolicy: Always diff --git a/openshift/rec_rhel.yaml b/openshift/rec_rhel.yaml index 5bf0d25..7827a3b 100644 --- a/openshift/rec_rhel.yaml +++ b/openshift/rec_rhel.yaml @@ -7,7 +7,7 @@ spec: nodes: 3 redisEnterpriseImageSpec: repository: registry.connect.redhat.com/redislabs/redis-enterprise - versionTag: 6.2.10-107.rhel8-openshift + versionTag: 6.2.10-129.rhel8-openshift redisEnterpriseServicesRiggerImageSpec: repository: registry.connect.redhat.com/redislabs/services-manager bootstrapperImageSpec: diff --git a/openshift/role.yaml b/openshift/role.yaml index 6576d2e..146ec4d 100644 --- a/openshift/role.yaml +++ b/openshift/role.yaml @@ -7,10 +7,11 @@ rules: resources: ["roles", "serviceaccounts", "rolebindings"] verbs: ["bind", "escalate", "impersonate", "userextras", "create", "get", "list", "watch", "update", "patch", "delete", "deletecollection"] - - apiGroups: - - app.redislabs.com + - apiGroups: ["app.redislabs.com"] resources: ["redisenterpriseclusters", "redisenterpriseclusters/status", "redisenterpriseclusters/finalizers", - "redisenterprisedatabases", "redisenterprisedatabases/status", "redisenterprisedatabases/finalizers"] + "redisenterprisedatabases", "redisenterprisedatabases/status", "redisenterprisedatabases/finalizers", + "redisenterpriseremoteclusters", "redisenterpriseremoteclusters/status", + "redisenterpriseremoteclusters/finalizers"] verbs: ["delete", "deletecollection", "get", "list", "patch", "create", "update", "watch"] - apiGroups: [""] resources: ["secrets"] @@ -34,8 +35,6 @@ rules: - apiGroups: [""] resources: ["persistentvolumeclaims"] verbs: ["create", "delete", "get" , "update", "list", "watch"] - - # needed rbac rules for services controller - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list", "update", "patch", "delete"] @@ -44,20 +43,16 @@ rules: verbs: ["get", "watch", "list", "update", "patch", "create", "delete"] - apiGroups: ["policy"] resources: ["podsecuritypolicies"] - resourceNames: - - redis-enterprise-psp - verbs: - - use - - apiGroups: ["extensions"] - resources: ["ingresses"] - verbs: ["create", "patch", "replace", "delete", "deletecollection", "read", "list", "listallnamespaces", - "watch", "watchlist", "watchlistallnamespaces", "patchstatus", "readstatus", "replacestatus", "update"] + resourceNames: ["redis-enterprise-psp"] + verbs: ["use"] - apiGroups: ["networking.k8s.io"] resources: ["ingresses"] verbs: ["create", "patch", "replace", "delete", "deletecollection", "read", "list", "listallnamespaces", "watch", "watchlist", "watchlistallnamespaces", "patchstatus", "readstatus", "replacestatus", "update"] - - apiGroups: - - route.openshift.io + - apiGroups: [ "networking.istio.io" ] + resources: [ "gateways", "virtualservices" ] + verbs: [ "get", "watch", "list", "update", "patch", "create", "delete" ] + - apiGroups: ["route.openshift.io"] resources: ["routes", "routes/custom-host"] verbs: ["create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"] diff --git a/operator.yaml b/operator.yaml index d859a7b..690013c 100644 --- a/operator.yaml +++ b/operator.yaml @@ -15,7 +15,7 @@ spec: serviceAccountName: redis-enterprise-operator containers: - name: redis-enterprise-operator - image: redislabs/operator:6.2.10-34 + image: redislabs/operator:6.2.10-45 command: - redis-enterprise-operator imagePullPolicy: Always @@ -57,7 +57,7 @@ spec: port: 8080 scheme: HTTP - name: admission - image: redislabs/operator:6.2.10-34 + image: redislabs/operator:6.2.10-45 command: - /usr/local/bin/admission imagePullPolicy: Always diff --git a/redis_enterprise_cluster_api.md b/redis_enterprise_cluster_api.md index 4f68561..e849bcb 100644 --- a/redis_enterprise_cluster_api.md +++ b/redis_enterprise_cluster_api.md @@ -12,6 +12,7 @@ This document describes the parameters for the Redis Enterprise Cluster custom r * [CrdbCoordinator](#crdbcoordinator) * [CrdbWorker](#crdbworker) * [ImageSpec](#imagespec) + * [IngressOrRouteSpec](#ingressorroutespec) * [LicenseStatus](#licensestatus) * [MdnsServer](#mdnsserver) * [Module](#module) @@ -34,9 +35,8 @@ This document describes the parameters for the Redis Enterprise Cluster custom r * [StatsArchiver](#statsarchiver) * [UpgradeSpec](#upgradespec) * [Enums](#enums) - * [ActiveActiveMethod](#activeactivemethod) - * [ClusterEventReason](#clustereventreason) * [ClusterState](#clusterstate) + * [IngressMethod](#ingressmethod) * [OperatingMode](#operatingmode) * [RedisOnFlashsStorageEngine](#redisonflashsstorageengine) * [SpecStatusName](#specstatusname) @@ -47,7 +47,7 @@ This document describes the parameters for the Redis Enterprise Cluster custom r | Field | Description | Scheme | Default Value | Required | | ----- | ----------- | ------ | -------- | -------- | -| method | Used to distinguish between different platforms implementation | [ActiveActiveMethod](#activeactivemethod) | | true | +| method | Used to distinguish between different platforms implementation | [IngressMethod](#ingressmethod) | | true | | apiIngressUrl | RS API URL | string | | true | | dbIngressSuffix | DB ENDPOINT SUFFIX - will be used to set the db host ingress . Creates a host name so it should be unique if more than one db is created on the cluster with the same name | string | | true | | ingressAnnotations | Used for ingress controllers such as ha-proxy or nginx in GKE | map[string]string | | false | @@ -119,9 +119,21 @@ Image specification | ----- | ----------- | ------ | -------- | -------- | | repository | Repository | string | | true | | versionTag | | string | | true | +| digestHash | The digest hash of the image to pull. Version tag must be also specified with the corresponding version, will use the digest hash to pull the image if exists. Note: This is currently supported only for OLM. | string | | false | | imagePullPolicy | | v1.PullPolicy | | true | [Back to Table of Contents](#table-of-contents) +### IngressOrRouteSpec + + +| Field | Description | Scheme | Default Value | Required | +| ----- | ----------- | ------ | -------- | -------- | +| method | Used to distinguish between different platforms implementation. | [IngressMethod](#ingressmethod) | | true | +| apiFqdnUrl | RS API URL | string | | true | +| dbFqdnSuffix | DB ENDPOINT SUFFIX - will be used to set the db host ingress . Creates a host name so it should be unique if more than one db is created on the cluster with the same name | string | | true | +| ingressAnnotations | Additional annotations to set on ingress resources created by the operator | map[string]string | | false | +[Back to Table of Contents](#table-of-contents) + ### LicenseStatus @@ -260,7 +272,7 @@ RedisEnterpriseClusterSpec defines the desired state of RedisEnterpriseCluster | extraLabels | Labels that the user defines for their convenience. Note that Persistent Volume Claims would only be labeled with the extra labels specified during the cluster's creation (modifying this field when the cluster is running won't affect the Persistent Volume | map[string]string | empty | false | | podAntiAffinity | Override for the default anti-affinity rules of the Redis Enterprise pods | *v1.PodAntiAffinity | | false | | antiAffinityAdditionalTopologyKeys | Additional antiAffinity terms in order to support installation on different zones/vcenters | []string | | false | -| activeActive | Specification for ActiveActive setup | *[ActiveActive](#activeactive) | | false | +| activeActive | Specification for ActiveActive setup. At most one of ingressOrRouteSpec or activeActive fields can be set at the same time. | *[ActiveActive](#activeactive) | | false | | upgradeSpec | Specification for upgrades of Redis Enterprise | *[UpgradeSpec](#upgradespec) | | false | | podSecurityPolicyName | Name of pod security policy to use on pods See https://kubernetes.io/docs/concepts/policy/pod-security-policy/ | string | empty | false | | enforceIPv4 | Sets ENFORCE_IPV4 environment variable | *bool | False | false | @@ -282,10 +294,11 @@ RedisEnterpriseClusterSpec defines the desired state of RedisEnterpriseCluster | certificates | RS Cluster Certificates. Used to modify the certificates used by the cluster. See the \"RSClusterCertificates\" struct described above to see the supported certificates. | *[RSClusterCertificates](#rsclustercertificates) | | false | | podStartingPolicy | Mitigation setting for STS pods stuck in \"ContainerCreating\" | *[StartingPolicy](#startingpolicy) | | false | | redisEnterpriseTerminationGracePeriodSeconds | The TerminationGracePeriodSeconds value for the (STS created) REC pods. Note that pods should not be taken down intentionally by force. Because clean pod shutdown is essential to prevent data loss, the default value is intentionally large (1 year). When data loss is acceptable (such as pure caching configurations), a value of a few minutes may be acceptable. | *int64 | 31536000 | false | -| redisOnFlashSpec | Stores configurations specific to redis on flash. If provided, the cluster will be capable of creating redis on flash databases. Note - This is an ALPHA Feature. For this feature to take effect, set a boolean environment variable with the name "ENABLE_ALPHA_FEATURES" to True. This variable can be set via the redis-enterprise-operator pod spec, or through the operator-environment-config Config Map. | *[RedisOnFlashSpec](#redisonflashspec) | | false | +| redisOnFlashSpec | Stores configurations specific to redis on flash. If provided, the cluster will be capable of creating redis on flash databases. Note - This is an ALPHA Feature. For this feature to take effect, set a boolean environment variable with the name \"ENABLE_ALPHA_FEATURES\" to True. This variable can be set via the redis-enterprise-operator pod spec, or through the operator-environment-config Config Map. | *[RedisOnFlashSpec](#redisonflashspec) | | false | | ocspConfiguration | An API object that represents the cluster's OCSP configuration. To enable OCSP, the cluster's proxy certificate should contain the OCSP responder URL. Note - This is an ALPHA Feature. For this feature to take effect, set a boolean environment variable with the name \"ENABLE_ALPHA_FEATURES\" to True. This variable can be set via the redis-enterprise-operator pod spec, or through the operator-environment-config Config Map. | *[OcspConfiguration](#ocspconfiguration) | | false | | encryptPkeys | Private key encryption - in order to enable, first need to mount ${ephemeralconfdir}/secrets/pem/passphrase and add the passphrase and then set fields value to 'true' Possible values: true/false Note: This is an ALPHA Feature. For this feature to take effect, set a boolean environment variable with the name \"ENABLE_ALPHA_FEATURES\" to True. This variable can be set via the redis-enterprise-operator pod spec, or through the operator-environment-config Config Map. | *bool | | false | | containerTimezone | Container timezone configuration. While the default timezone on all containers is UTC, this setting can be used to set the timezone on services rigger/bootstrapper/RS containers. Currently the only supported value is to propagate the host timezone to all containers. | *[ContainerTimezoneSpec](#containertimezonespec) | | false | +| ingressOrRouteSpec | Access configurations for the Redis Enterprise Cluster and Databases. Note - this feature is currently in preview. For this feature to take effect, set a boolean environment variable with the name \"ENABLE_ALPHA_FEATURES\" to True. This variable can be set via the redis-enterprise-operator pod spec, or through the operator-environment-config Config Map. At most one of ingressOrRouteSpec or activeActive fields can be set at the same time. | *[IngressOrRouteSpec](#ingressorroutespec) | | false | [Back to Table of Contents](#table-of-contents) ### RedisEnterpriseClusterStatus @@ -379,24 +392,6 @@ Specification for upgrades of Redis Enterprise [Back to Table of Contents](#table-of-contents) ## Enums -### ActiveActiveMethod -Method of ingress from another cluster in Active-Active configuration - -| Value | Description | -| ----- | ----------- | -| "openShiftRoute" | Routes are only usable in OpenShift | -| "ingress" | See https://kubernetes.io/docs/concepts/services-networking/ingress/ | -[Back to Table of Contents](#table-of-contents) - -### ClusterEventReason -Reason for cluster event - -| Value | Description | -| ----- | ----------- | -| "InvalidConfiguration" | Invalid Configuration | -| "StatusChange" | Status Change | -[Back to Table of Contents](#table-of-contents) - ### ClusterState State of the Redis Enterprise Cluster @@ -416,6 +411,16 @@ State of the Redis Enterprise Cluster | "ClusterRecreating" | ClusterRecreating - similar to ClusterRecoveryReset - delete all pods before recreation of the cluster. | [Back to Table of Contents](#table-of-contents) +### IngressMethod +Used to distinguish between different platforms implementation + +| Value | Description | +| ----- | ----------- | +| "openShiftRoute" | Routes are only usable in OpenShift | +| "ingress" | See https://kubernetes.io/docs/concepts/services-networking/ingress/ | +| "istio" | Ingress implemented via Istio | +[Back to Table of Contents](#table-of-contents) + ### OperatingMode | Value | Description | diff --git a/redis_enterprise_database_api.md b/redis_enterprise_database_api.md index 0a56f8e..b238bb0 100644 --- a/redis_enterprise_database_api.md +++ b/redis_enterprise_database_api.md @@ -47,13 +47,13 @@ This document describes the parameters for the Redis Enterprise Database custom | Field | Description | Scheme | Default Value | Required | | ----- | ----------- | ------ | -------- | -------- | -| backupFailureReason | Reason of last failed backup process | string | | false | -| backupHistory | Backup history retention policy (number of days, 0 is forever) | int | | true | -| backupInterval | Interval in seconds in which automatic backup will be initiated | int | | false | -| backupIntervalOffset | Offset (in seconds) from round backup interval when automatic backup will be initiated (should be less than backup_interval) | int | | false | -| backupProgressPercentage | Database scheduled periodic backup progress (percentage) | int | | false | -| backupStatus | Status of scheduled periodic backup process | string | | false | -| lastBackupTime | Time of last successful backup | string | | false | +| backupFailureReason | Reason of last failed backup process | *string | | false | +| backupHistory | Backup history retention policy (number of days, 0 is forever) | *int | | false | +| backupInterval | Interval in seconds in which automatic backup will be initiated | *int | | false | +| backupIntervalOffset | Offset (in seconds) from round backup interval when automatic backup will be initiated (should be less than backup_interval) | *int | | false | +| backupProgressPercentage | Database scheduled periodic backup progress (percentage) | *int | | false | +| backupStatus | Status of scheduled periodic backup process | *string | | false | +| lastBackupTime | Time of last successful backup | *string | | false | [Back to Table of Contents](#table-of-contents) ### BackupSpec diff --git a/role.yaml b/role.yaml index 3e13085..be676ef 100644 --- a/role.yaml +++ b/role.yaml @@ -7,10 +7,11 @@ rules: resources: ["roles", "serviceaccounts", "rolebindings"] verbs: ["bind", "escalate", "impersonate", "userextras", "create", "get", "list", "watch", "update", "patch", "delete", "deletecollection"] - - apiGroups: - - app.redislabs.com + - apiGroups: ["app.redislabs.com"] resources: ["redisenterpriseclusters", "redisenterpriseclusters/status", "redisenterpriseclusters/finalizers", - "redisenterprisedatabases", "redisenterprisedatabases/status", "redisenterprisedatabases/finalizers"] + "redisenterprisedatabases", "redisenterprisedatabases/status", "redisenterprisedatabases/finalizers", + "redisenterpriseremoteclusters", "redisenterpriseremoteclusters/status", + "redisenterpriseremoteclusters/finalizers"] verbs: ["delete", "deletecollection", "get", "list", "patch", "create", "update", "watch"] - apiGroups: [""] resources: ["secrets"] @@ -34,8 +35,6 @@ rules: - apiGroups: [""] resources: ["persistentvolumeclaims"] verbs: ["create", "delete", "get" , "update", "list", "watch"] - - # needed rbac rules for services controller - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list", "update", "patch", "delete"] @@ -44,15 +43,12 @@ rules: verbs: ["get", "watch", "list", "update", "patch", "create", "delete"] - apiGroups: ["policy"] resources: ["podsecuritypolicies"] - resourceNames: - - redis-enterprise-psp - verbs: - - use - - apiGroups: ["extensions"] - resources: ["ingresses"] - verbs: ["create", "patch", "replace", "delete", "deletecollection", "read", "list", "listallnamespaces", - "watch", "watchlist", "watchlistallnamespaces", "patchstatus", "readstatus", "replacestatus", "update"] + resourceNames: ["redis-enterprise-psp"] + verbs: ["use"] - apiGroups: ["networking.k8s.io"] resources: ["ingresses"] verbs: ["create", "patch", "replace", "delete", "deletecollection", "read", "list", "listallnamespaces", "watch", "watchlist", "watchlistallnamespaces", "patchstatus", "readstatus", "replacestatus", "update"] + - apiGroups: ["networking.istio.io"] + resources: ["gateways", "virtualservices"] + verbs: ["get", "watch", "list", "update", "patch", "create", "delete"]