├── README.md ├── app-resources ├── etherpad │ ├── dev │ │ ├── etherpad_configmap.yaml │ │ ├── etherpad_deployment.yaml │ │ ├── etherpad_route.yaml │ │ ├── etherpad_service.yaml │ │ ├── postgres_deployment.yaml │ │ ├── postgres_secret.yaml │ │ └── postgres_service.yaml │ ├── prd │ │ ├── etherpad_configmap.yaml │ │ ├── etherpad_deployment.yaml │ │ ├── etherpad_route.yaml │ │ ├── etherpad_service.yaml │ │ ├── postgres_deployment.yaml │ │ ├── postgres_secret.yaml │ │ └── postgres_service.yaml │ └── qa │ │ ├── etherpad_configmap.yaml │ │ ├── etherpad_deployment.yaml │ │ ├── etherpad_route.yaml │ │ ├── etherpad_service.yaml │ │ ├── postgres_deployment.yaml │ │ ├── postgres_secret.yaml │ │ └── postgres_service.yaml └── policies │ ├── cert_expiration.yaml │ ├── config_limitrange.yaml │ ├── config_placement_binding.yaml │ ├── config_placement_rule.yaml │ ├── iam.yaml │ └── namespace.yaml ├── imgs ├── Screenshot from 2020-10-03 20-25-48.png ├── Screenshot from 2020-10-03 20-26-16.png ├── Screenshot from 2020-10-03 20-27-14.png ├── Screenshot from 2020-10-03 20-27-39.png └── rhacm-index.png ├── multipleclusters-multiple-envs ├── README.md ├── images │ ├── 2-rhacm-deploy-multiple-clusters.gif │ ├── RH-ACM-2-2-TEKTON.gif │ ├── banner.jpg │ ├── nonprod-cluster.png │ ├── pipeline.png │ ├── prod-and-dr-cluster.png │ └── rhacm-app.png ├── rhacm │ ├── dev │ │ ├── application.yaml │ │ ├── channel.yaml │ │ ├── placement-rule.yaml │ │ └── subscription.yaml │ ├── namespaces.yaml │ ├── prd │ │ ├── application.yaml │ │ ├── channel.yaml │ │ ├── placement-rule.yaml │ │ └── subscription.yaml │ └── qa │ │ ├── application.yaml │ │ ├── channel.yaml │ │ ├── placement-rule.yaml │ │ └── subscription.yaml └── tekton │ ├── README.md │ ├── pipeline-acm.yaml │ ├── pipelinerun.yaml │ ├── prepare │ └── tekton-source-pvc.yaml │ └── tasks │ ├── 01_create_namespaces.yaml │ ├── 02_create_dev_app_using_acm.yaml │ ├── 03_create_qa_app_using_acm.yaml │ └── 04_create_prd_app_using_acm.yaml └── onecluster-multiple-envs ├── README.md ├── images ├── RH-ACM-1.gif ├── image1.png ├── image2.png ├── image3.png ├── image4.png ├── image5.png └── image6.jpg ├── rhacm ├── dev │ ├── application.yaml │ ├── channel.yaml │ ├── placement-rule.yaml │ └── subscription.yaml ├── namespaces.yaml ├── prd │ ├── application.yaml │ ├── channel.yaml │ ├── placement-rule.yaml │ └── subscription.yaml └── qa │ ├── application.yaml │ ├── channel.yaml │ ├── placement-rule.yaml │ └── subscription.yaml └── tekton ├── README.md ├── pipeline-acm.yaml ├── pipelinerun.yaml ├── prepare └── tekton-source-pvc.yaml └── tasks ├── 01_create_namespaces.yaml ├── 02_create_dev_app_using_acm.yaml ├── 03_create_qa_app_using_acm.yaml └── 04_create_prd_app_using_acm.yaml /README.md: -------------------------------------------------------------------------------- 1 | # RED HAT ADVANCED CLUSTER MANAGEMENT LABS 2 | 3 | ## RH ACM DEPLOYMENT 4 | 5 | Reference: https://access.redhat.com/documentation/en-us/red_hat_advanced_cluster_management_for_kubernetes/2.0/html-single/install/index 6 | 7 | Cluster: 8 | 3 Masters - m5.xlarge 9 | 3 Workers - m5.xlarge 10 | 11 | 12 | 1. Create the RH ACM namespace: 13 | 14 | ```shell 15 | oc create namespace rh-acm 16 | ``` 17 | 18 | 2. Swith to the project 19 | 20 | ```shell 21 | oc project rh-acm 22 | ``` 23 | 24 | 3. Use the yaml below to create an operator group: 25 | 26 | ```yaml 27 | apiVersion: operators.coreos.com/v1 28 | kind: OperatorGroup 29 | metadata: 30 | name: rhacm-og 31 | spec: 32 | targetNamespaces: 33 | - rh-acm 34 | ``` 35 | 36 | 4. Create the operator group: 37 | 38 | ```shell 39 | oc apply -f rhacm-og.yaml 40 | ``` 41 | 42 | 5. Use the yaml below to create a subscription: 43 | 44 | ```yaml 45 | apiVersion: operators.coreos.com/v1alpha1 46 | kind: Subscription 47 | metadata: 48 | name: acm-operator-subscription 49 | spec: 50 | sourceNamespace: openshift-marketplace 51 | source: redhat-operators 52 | channel: release-2.0 53 | installPlanApproval: Automatic 54 | name: advanced-cluster-management 55 | ``` 56 | 57 | 6. Apply the subscription: 58 | 59 | ```shell 60 | oc apply -f rhacm-subs.yaml 61 | ``` 62 | 7. Download your pull secret on https://cloud.redhat.com/openshift/install/pull-secret. 63 | 64 | 8. Create a pull secret in the namespace: 65 | 66 | ```shell 67 | oc create secret generic rh-pullsecret -n rh-acm --from-file=.dockerconfigjson=/tmp/pull-secret.txt --type=kubernetes.io/dockerconfigjson 68 | ``` 69 | 70 | 9. Now create the MultiClusterHub using the yaml below: 71 | 72 | ```yaml 73 | apiVersion: operator.open-cluster-management.io/v1 74 | kind: MultiClusterHub 75 | metadata: 76 | name: multiclusterhub 77 | namespace: rh-acm 78 | spec: 79 | imagePullSecret: rh-pullsecret 80 | ``` 81 | 82 | 10. Create the MCB: 83 | 84 | ```shell 85 | oc apply -f multiclusterhub 86 | ``` 87 | 88 | 11. Wait up to 10 minutes until you have all pods Running and Ready: 89 | 90 | ```shell 91 | watch oc get all 92 | > oc get pods 93 | NAME READY STATUS RESTARTS AGE 94 | application-chart-81b08-applicationui-5cdfb97cc7-4hdts 1/1 Running 0 6m39s 95 | application-chart-81b08-applicationui-5cdfb97cc7-9dtc9 1/1 Running 0 9m1s 96 | cert-manager-ba5cb-6499488d89-qvlww 1/1 Running 0 24m 97 | cert-manager-ba5cb-6499488d89-zdvxg 1/1 Running 0 25m 98 | cert-manager-webhook-93dbc-cainjector-7855856c6c-cncxb 1/1 Running 0 27m 99 | cert-manager-webhook-93dbc-cainjector-7855856c6c-t2v76 1/1 Running 0 35m 100 | cert-manager-webhook-b868bcff5-76qz8 1/1 Running 0 9m1s 101 | cert-manager-webhook-b868bcff5-cwvwc 1/1 Running 0 27m 102 | cluster-manager-b48498fd5-6cdgv 1/1 Running 0 24m 103 | cluster-manager-b48498fd5-g6mkl 1/1 Running 0 24m 104 | cluster-manager-b48498fd5-nvsvv 1/1 Running 0 24m 105 | configmap-watcher-ad4ba-6b65c4c6f6-2c8dl 1/1 Running 0 27m 106 | configmap-watcher-ad4ba-6b65c4c6f6-8t7gt 1/1 Running 0 9m1s 107 | console-chart-1d55f-consoleapi-87b495b5c-bh6zn 1/1 Running 0 34m 108 | console-chart-1d55f-consoleapi-87b495b5c-rnz66 1/1 Running 0 34m 109 | console-chart-1d55f-consoleui-69f9885dbb-9xs4h 1/1 Running 0 9m1s 110 | console-chart-1d55f-consoleui-69f9885dbb-h6lf6 1/1 Running 0 9m2s 111 | console-header-9f64755c8-bztc5 1/1 Running 0 14m 112 | console-header-9f64755c8-jvfpw 1/1 Running 0 34m 113 | grc-a7517-grcui-6499d75c6d-b8nzx 1/1 Running 0 9m1s 114 | grc-a7517-grcui-6499d75c6d-gdlhn 1/1 Running 0 9m1s 115 | grc-a7517-grcuiapi-9b7fd8b7c-d7jkt 1/1 Running 0 9m2s 116 | grc-a7517-grcuiapi-9b7fd8b7c-kxk4d 1/1 Running 0 34m 117 | grc-a7517-policy-propagator-865884d469-kskvg 1/1 Running 0 27m 118 | grc-a7517-policy-propagator-865884d469-pwlw5 1/1 Running 0 20m 119 | hive-operator-55f55bdbcd-m4sxf 1/1 Running 0 24m 120 | klusterlet-addon-controller-5b764c4645-7f5xq 1/1 Running 0 25m 121 | klusterlet-addon-controller-5b764c4645-wjzvn 1/1 Running 0 9m1s 122 | kui-web-terminal-b8bd599f5-rgfjp 1/1 Running 0 9m1s 123 | managedcluster-import-controller-579564d45f-jm245 1/1 Running 0 34m 124 | managedcluster-import-controller-579564d45f-t2l5b 1/1 Running 0 9m1s 125 | management-ingress-10d12-779b48c87-48pbr 2/2 Running 0 33m 126 | management-ingress-10d12-779b48c87-j8h9g 2/2 Running 0 9m1s 127 | multicluster-operators-application-66cf666845-r79t6 4/4 Running 0 24m 128 | multicluster-operators-hub-subscription-5587664bfd-rmscv 1/1 Running 0 24m 129 | multicluster-operators-standalone-subscription-5b9c554c49-krdqg 1/1 Running 0 24m 130 | multiclusterhub-operator-5475d87b7f-b6767 1/1 Running 0 24m 131 | multiclusterhub-repo-85984f9cc6-ktlrn 1/1 Running 0 25m 132 | ocm-controller-747f8dcb9f-2gk5z 1/1 Running 0 25m 133 | ocm-controller-747f8dcb9f-bp7b5 1/1 Running 0 24m 134 | ocm-proxyserver-c59bc6c68-468l9 1/1 Running 0 24m 135 | ocm-proxyserver-c59bc6c68-872vf 1/1 Running 0 9m1s 136 | ocm-webhook-5954f77b85-5wsdp 1/1 Running 0 24m 137 | ocm-webhook-5954f77b85-j58kr 1/1 Running 0 25m 138 | search-operator-5d8dcf4944-xz4rq 1/1 Running 0 24m 139 | search-prod-6092c-redisgraph-844c5f7596-xpngc 1/1 Running 0 33m 140 | search-prod-6092c-search-aggregator-65ff9d6cc9-dfsf8 1/1 Running 0 33m 141 | search-prod-6092c-search-api-6c8b5c8b5-khcj2 1/1 Running 0 9m1s 142 | search-prod-6092c-search-api-6c8b5c8b5-rvzp7 1/1 Running 0 6m35s 143 | search-prod-6092c-search-collector-6f5d448cbf-qvjsd 1/1 Running 0 9m1s 144 | topology-fab53-topology-58f4845fc6-cb5sj 1/1 Running 0 9m2s 145 | topology-fab53-topology-58f4845fc6-rkcmt 1/1 Running 0 9m1s 146 | topology-fab53-topologyapi-5fd4bb5fd9-gkbn5 1/1 Running 0 9m1s 147 | topology-fab53-topologyapi-5fd4bb5fd9-rhbn7 1/1 Running 0 9m1s 148 | ``` 149 | 150 | 12. Get the RH ACM route and access it: 151 | 152 | ```shell 153 | > oc get routes 154 | NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD 155 | multicloud-console multicloud-console.apps.acmhub.rhbr-labs.com management-ingress passthrough/Redirect None 156 | ``` 157 | 158 | ![RH ACM Initial Page](imgs/rhacm-index.png) 159 | 160 | # IMPORTING A NEW CLUSTER TO RH ACM 161 | 162 | 163 | ```shell 164 | > oc login -u admin https://api.cluster-93bc.93bc.sandbox1234.opentlc.com:6443 165 | Logged into "https://api.cluster-93bc.93bc.sandbox1234.opentlc.com:6443" as "admin" using existing credentials. 166 | 167 | You have access to 57 projects, the list has been suppressed. You can list all projects with 'oc projects' 168 | 169 | Using project "default". 170 | > [root@gfontana ~]# echo Ci0tLQphcGlWZXJzaW9uOiBhcGlleHRlbnNpb25zLms4cy5pby92MWJldGExCmtpbmQ6IEN1c3RvbVJlc291cmNlRGVmaW5pdGlvbgptZXRhZGF0YToKICBjcmVhdGlvblRpbWVzdGFtcDogbnVsbAogIG5hbWU6IGtsdXN0ZXJsZXRzLm9wZXJhdG9yLm9wZW4tY2x1c3Rlci1tYW5hZ2VtZW50LmlvCnNwZWM6CiAgZ3JvdXA6IG9wZXJhdG9yLm9wZW4tY2x1c3Rlci1tYW5hZ2VtZW50LmlvCiAgbmFtZXM6C ...ommited... MzZmU3MTY1MTNlYWRmNgogIHdvcmtJbWFnZVB1bGxTcGVjOiByZWdpc3RyeS5yZWRoYXQuaW8vcmhhY20yL3dvcmstcmhlbDhAc2hhMjU2OjdiOGVhOTI3YTExNDViYmRhNDdmNTQ5MTQ4MjdkNDk2MTc0ZjcyZDcwOGQ2N2E0OGQzMzQwYWEzZmY1YTY3N2EK | base64 --decode | kubectl apply -f - 171 | customresourcedefinition.apiextensions.k8s.io/klusterlets.operator.open-cluster-management.io created 172 | clusterrole.rbac.authorization.k8s.io/klusterlet unchanged 173 | clusterrole.rbac.authorization.k8s.io/open-cluster-management:klusterlet-admin-aggregate-clusterrole unchanged 174 | clusterrolebinding.rbac.authorization.k8s.io/klusterlet unchanged 175 | namespace/open-cluster-management-agent created 176 | secret/bootstrap-hub-kubeconfig created 177 | secret/open-cluster-management-image-pull-credentials created 178 | serviceaccount/klusterlet created 179 | deployment.apps/klusterlet created 180 | klusterlet.operator.open-cluster-management.io/klusterlet created 181 | 182 | ``` 183 | 184 | # INSTALLING OPENSHIFT PIPELINES 185 | 186 | OpenShift pipelines is installed through an Operator. The step-by-step can be found here: https://github.com/openshift/pipelines-tutorial/blob/master/install-operator.md 187 | 188 | 189 | -------------------------------------------------------------------------------- /app-resources/etherpad/dev/etherpad_configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | creationTimestamp: null 5 | name: etherpad-settings 6 | labels: 7 | app: etherpad 8 | data: 9 | settings.json: | 10 | /* 11 | * This file must be valid JSON. But comments are allowed 12 | * 13 | * Please edit settings.json, not settings.json.template 14 | * 15 | * Please note that starting from Etherpad 1.6.0 you can store DB credentials in 16 | * a separate file (credentials.json). 17 | * 18 | * 19 | * ENVIRONMENT VARIABLE SUBSTITUTION 20 | * ================================= 21 | * 22 | * All the configuration values can be read from environment variables using the 23 | * syntax "${ENV_VAR}" or "${ENV_VAR:default_value}". 24 | * 25 | * This is useful, for example, when running in a Docker container. 26 | * 27 | * EXAMPLE: 28 | * "port": "${PORT:9001}" 29 | * "minify": "${MINIFY}" 30 | * "skinName": "${SKIN_NAME:colibris}" 31 | * 32 | * Would read the configuration values for those items from the environment 33 | * variables PORT, MINIFY and SKIN_NAME. 34 | * 35 | * If PORT and SKIN_NAME variables were not defined, the default values 9001 and 36 | * "colibris" would be used. 37 | * The configuration value "minify", on the other hand, does not have a 38 | * designated default value. Thus, if the environment variable MINIFY were 39 | * undefined, "minify" would be null. 40 | * 41 | * REMARKS: 42 | * 1) please note that variable substitution always needs to be quoted. 43 | * 44 | * "port": 9001, <-- Literal values. When not using 45 | * "minify": false substitution, only strings must be 46 | * "skinName": "colibris" quoted. Booleans and numbers must not. 47 | * 48 | * "port": "${PORT:9001}" <-- CORRECT: if you want to use a variable 49 | * "minify": "${MINIFY:true}" substitution, put quotes around its name, 50 | * "skinName": "${SKIN_NAME}" even if the required value is a number or 51 | * a boolean. 52 | * Etherpad will take care of rewriting it 53 | * to the proper type if necessary. 54 | * 55 | * "port": ${PORT:9001} <-- ERROR: this is not valid json. Quotes 56 | * "minify": ${MINIFY} around variable names are missing. 57 | * "skinName": ${SKIN_NAME} 58 | * 59 | * 2) Beware of undefined variables and default values: nulls and empty strings 60 | * are different! 61 | * 62 | * This is particularly important for user's passwords (see the relevant 63 | * section): 64 | * 65 | * "password": "${PASSW}" // if PASSW is not defined would result in password === null 66 | * "password": "${PASSW:}" // if PASSW is not defined would result in password === '' 67 | * 68 | * If you want to use an empty value (null) as default value for a variable, 69 | * simply do not set it, without putting any colons: "${ABIWORD}". 70 | * 71 | * 3) if you want to use newlines in the default value of a string parameter, 72 | * use "\n" as usual. 73 | * 74 | * "defaultPadText" : "${DEFAULT_PAD_TEXT}Line 1\nLine 2" 75 | */ 76 | { 77 | /* 78 | * Name your instance! 79 | */ 80 | "title": "OpenTLC Etherpad", 81 | 82 | /* 83 | * favicon default name 84 | * alternatively, set up a fully specified Url to your own favicon 85 | */ 86 | "favicon": "favicon.ico", 87 | 88 | /* 89 | * Skin name. 90 | * 91 | * Its value has to be an existing directory under src/static/skins. 92 | * You can write your own, or use one of the included ones: 93 | * 94 | * - "no-skin": an empty skin (default). This yields the unmodified, 95 | * traditional Etherpad theme. 96 | * - "colibris": the new experimental skin (since Etherpad 1.8), candidate to 97 | * become the default in Etherpad 2.0 98 | */ 99 | "skinName": "colibris", 100 | 101 | /* 102 | * Skin Variants 103 | * 104 | * Use the UI skin variants builder at /p/test#skinvariantsbuilder 105 | * 106 | * For the colibris skin only, you can choose how to render the three main 107 | * containers: 108 | * - toolbar (top menu with icons) 109 | * - editor (containing the text of the pad) 110 | * - background (area outside of editor, mostly visible when using page style) 111 | * 112 | * For each of the 3 containers you can choose 4 color combinations: 113 | * super-light, light, dark, super-dark. 114 | * 115 | * For example, to make the toolbar dark, you will include "dark-toolbar" into 116 | * skinVariants. 117 | * 118 | * You can provide multiple skin variants separated by spaces. Default 119 | * skinVariant is "super-light-toolbar super-light-editor light-background". 120 | * 121 | * For the editor container, you can also make it full width by adding 122 | * "full-width-editor" variant (by default editor is rendered as a page, with 123 | * a max-width of 900px). 124 | */ 125 | "skinVariants": "light-toolbar dark-background light-editor full-width-editor", 126 | 127 | /* 128 | * IP and port which Etherpad should bind at. 129 | * 130 | * Binding to a Unix socket is also supported: just use an empty string for 131 | * the ip, and put the full path to the socket in the port parameter. 132 | * 133 | * EXAMPLE USING UNIX SOCKET: 134 | * "ip": "", // <-- has to be an empty string 135 | * "port" : "/somepath/etherpad.socket", // <-- path to a Unix socket 136 | */ 137 | "ip": "0.0.0.0", 138 | "port": 9001, 139 | 140 | /* 141 | * Option to hide/show the settings.json in admin page. 142 | * 143 | * Default option is set to true 144 | */ 145 | "showSettingsInAdminPage": true, 146 | 147 | /* 148 | * Node native SSL support 149 | * 150 | * This is disabled by default. 151 | * Make sure to have the minimum and correct file access permissions set so 152 | * that the Etherpad server can access them 153 | */ 154 | 155 | /* 156 | "ssl" : { 157 | "key" : "/path-to-your/epl-server.key", 158 | "cert" : "/path-to-your/epl-server.crt", 159 | "ca": ["/path-to-your/epl-intermediate-cert1.crt", "/path-to-your/epl-intermediate-cert2.crt"] 160 | }, 161 | */ 162 | 163 | /* 164 | * The type of the database. 165 | * 166 | * You can choose between many DB drivers, for example: dirty, postgres, 167 | * sqlite, mysql. 168 | * 169 | * You shouldn't use "dirty" for for anything else than testing or 170 | * development. 171 | * 172 | * 173 | * Database specific settings are dependent on dbType, and go in dbSettings. 174 | * Remember that since Etherpad 1.6.0 you can also store these informations in 175 | * credentials.json. 176 | * 177 | * For a complete list of the supported drivers, please refer to: 178 | * https://www.npmjs.com/package/ueberdb2 179 | */ 180 | /* 181 | "dbType": "dirty", 182 | "dbSettings": { 183 | "filename": "var/dirty.db" 184 | }, 185 | */ 186 | 187 | /* 188 | * An Example of MySQL Configuration (commented out). 189 | * 190 | * See: https://github.com/ether/etherpad-lite/wiki/How-to-use-Etherpad-Lite-with-MySQL 191 | */ 192 | 193 | /* 194 | "dbType" : "mysql", 195 | "dbSettings" : { 196 | "user": "etherpaduser", 197 | "host": "localhost", 198 | "port": 3306, 199 | "password": "PASSWORD", 200 | "database": "etherpad_lite_db", 201 | "charset": "utf8mb4" 202 | }, 203 | */ 204 | 205 | "dbType" : "DB_TYPE", 206 | "dbSettings" : { 207 | "host" : "DB_HOST", 208 | "port" : "DB_PORT", 209 | "database": "DB_DATABASE", 210 | "user" : "DB_USER", 211 | "password": "DB_PASS" 212 | }, 213 | 214 | /* 215 | * The default text of a pad 216 | */ 217 | "defaultPadText" : "Welcome to the OpenTLC Etherpad!\n\nENVIRONMENT=DEV!\n", 218 | 219 | /* 220 | * Default Pad behavior. 221 | * 222 | * Change them if you want to override. 223 | */ 224 | "padOptions": { 225 | "noColors": false, 226 | "showControls": true, 227 | "showChat": true, 228 | "showLineNumbers": true, 229 | "useMonospaceFont": false, 230 | "userName": false, 231 | "userColor": false, 232 | "rtl": false, 233 | "alwaysShowChat": false, 234 | "chatAndUsers": false, 235 | "lang": "en-us" 236 | }, 237 | 238 | /* 239 | * Pad Shortcut Keys 240 | */ 241 | "padShortcutEnabled" : { 242 | "altF9": true, /* focus on the File Menu and/or editbar */ 243 | "altC": true, /* focus on the Chat window */ 244 | "cmdShift2": true, /* shows a gritter popup showing a line author */ 245 | "delete": true, 246 | "return": true, 247 | "esc": true, /* in mozilla versions 14-19 avoid reconnecting pad */ 248 | "cmdS": true, /* save a revision */ 249 | "tab": true, /* indent */ 250 | "cmdZ": true, /* undo/redo */ 251 | "cmdY": true, /* redo */ 252 | "cmdI": true, /* italic */ 253 | "cmdB": true, /* bold */ 254 | "cmdU": true, /* underline */ 255 | "cmd5": true, /* strike through */ 256 | "cmdShiftL": true, /* unordered list */ 257 | "cmdShiftN": true, /* ordered list */ 258 | "cmdShift1": true, /* ordered list */ 259 | "cmdShiftC": true, /* clear authorship */ 260 | "cmdH": true, /* backspace */ 261 | "ctrlHome": true, /* scroll to top of pad */ 262 | "pageUp": true, 263 | "pageDown": true 264 | }, 265 | 266 | /* 267 | * Should we suppress errors from being visible in the default Pad Text? 268 | */ 269 | "suppressErrorsInPadText": false, 270 | 271 | /* 272 | * If this option is enabled, a user must have a session to access pads. 273 | * This effectively allows only group pads to be accessed. 274 | */ 275 | "requireSession": false, 276 | 277 | /* 278 | * Users may edit pads but not create new ones. 279 | * 280 | * Pad creation is only via the API. 281 | * This applies both to group pads and regular pads. 282 | */ 283 | "editOnly": false, 284 | 285 | /* 286 | * If set to true, those users who have a valid session will automatically be 287 | * granted access to password protected pads. 288 | */ 289 | "sessionNoPassword": false, 290 | 291 | /* 292 | * If true, all css & js will be minified before sending to the client. 293 | * 294 | * This will improve the loading performance massively, but makes it difficult 295 | * to debug the javascript/css 296 | */ 297 | "minify": true, 298 | 299 | /* 300 | * How long may clients use served javascript code (in seconds)? 301 | * 302 | * Not setting this may cause problems during deployment. 303 | * Set to 0 to disable caching. 304 | */ 305 | "maxAge": 21600, // 60 * 60 * 6 = 6 hours 306 | 307 | /* 308 | * Absolute path to the Abiword executable. 309 | * 310 | * Abiword is needed to get advanced import/export features of pads. Setting 311 | * it to null disables Abiword and will only allow plain text and HTML 312 | * import/exports. 313 | */ 314 | "abiword": null, 315 | 316 | /* 317 | * This is the absolute path to the soffice executable. 318 | * 319 | * LibreOffice can be used in lieu of Abiword to export pads. 320 | * Setting it to null disables LibreOffice exporting. 321 | */ 322 | "soffice": null, 323 | 324 | /* 325 | * Path to the Tidy executable. 326 | * 327 | * Tidy is used to improve the quality of exported pads. 328 | * Setting it to null disables Tidy. 329 | */ 330 | "tidyHtml": null, 331 | 332 | /* 333 | * Allow import of file types other than the supported ones: 334 | * txt, doc, docx, rtf, odt, html & htm 335 | */ 336 | "allowUnknownFileEnds": true, 337 | 338 | /* 339 | * This setting is used if you require authentication of all users. 340 | * 341 | * Note: "/admin" always requires authentication. 342 | */ 343 | "requireAuthentication": false, 344 | 345 | /* 346 | * Require authorization by a module, or a user with is_admin set, see below. 347 | */ 348 | "requireAuthorization": false, 349 | 350 | /* 351 | * When you use NGINX or another proxy/load-balancer set this to true. 352 | * 353 | * This is especially necessary when the reverse proxy performs SSL 354 | * termination, otherwise the cookies will not have the "secure" flag. 355 | * 356 | * The other effect will be that the logs will contain the real client's IP, 357 | * instead of the reverse proxy's IP. 358 | */ 359 | "trustProxy": false, 360 | 361 | /* 362 | * Privacy: disable IP logging 363 | */ 364 | "disableIPlogging": false, 365 | 366 | /* 367 | * Time (in seconds) to automatically reconnect pad when a "Force reconnect" 368 | * message is shown to user. 369 | * 370 | * Set to 0 to disable automatic reconnection. 371 | */ 372 | "automaticReconnectionTimeout": 0, 373 | 374 | /* 375 | * By default, when caret is moved out of viewport, it scrolls the minimum 376 | * height needed to make this line visible. 377 | */ 378 | "scrollWhenFocusLineIsOutOfViewport": { 379 | 380 | /* 381 | * Percentage of viewport height to be additionally scrolled. 382 | * 383 | * E.g.: use "percentage.editionAboveViewport": 0.5, to place caret line in 384 | * the middle of viewport, when user edits a line above of the 385 | * viewport 386 | * 387 | * Set to 0 to disable extra scrolling 388 | */ 389 | "percentage": { 390 | "editionAboveViewport": 0, 391 | "editionBelowViewport": 0 392 | }, 393 | 394 | /* 395 | * Time (in milliseconds) used to animate the scroll transition. 396 | * Set to 0 to disable animation 397 | */ 398 | "duration": 0, 399 | 400 | /* 401 | * Flag to control if it should scroll when user places the caret in the 402 | * last line of the viewport 403 | */ 404 | "scrollWhenCaretIsInTheLastLineOfViewport": false, 405 | 406 | /* 407 | * Percentage of viewport height to be additionally scrolled when user 408 | * presses arrow up in the line of the top of the viewport. 409 | * 410 | * Set to 0 to let the scroll to be handled as default by Etherpad 411 | */ 412 | "percentageToScrollWhenUserPressesArrowUp": 0 413 | }, 414 | 415 | /* 416 | * Users for basic authentication. 417 | * 418 | * is_admin = true gives access to /admin. 419 | * If you do not uncomment this, /admin will not be available! 420 | * 421 | * WARNING: passwords should not be stored in plaintext in this file. 422 | * If you want to mitigate this, please install ep_hash_auth and 423 | * follow the section "secure your installation" in README.md 424 | */ 425 | 426 | /* 427 | "users": { 428 | "admin": { 429 | // 1) "password" can be replaced with "hash" if you install ep_hash_auth 430 | // 2) please note that if password is null, the user will not be created 431 | "password": "changeme1", 432 | "is_admin": true 433 | }, 434 | "user": { 435 | // 1) "password" can be replaced with "hash" if you install ep_hash_auth 436 | // 2) please note that if password is null, the user will not be created 437 | "password": "changeme1", 438 | "is_admin": false 439 | } 440 | }, 441 | */ 442 | "users": { 443 | "admin": { 444 | "password": "secret", 445 | "is_admin": true 446 | } 447 | }, 448 | 449 | /* 450 | * Restrict socket.io transport methods 451 | */ 452 | "socketTransportProtocols" : ["xhr-polling", "jsonp-polling", "htmlfile"], 453 | 454 | /* 455 | * Allow Load Testing tools to hit the Etherpad Instance. 456 | * 457 | * WARNING: this will disable security on the instance. 458 | */ 459 | "loadTest": false, 460 | 461 | /* 462 | * Disable indentation on new line when previous line ends with some special 463 | * chars (':', '[', '(', '{') 464 | */ 465 | 466 | /* 467 | "indentationOnNewLine": false, 468 | */ 469 | 470 | /* 471 | * From Etherpad 1.8.3 onwards, import and export of pads is always rate 472 | * limited. 473 | * 474 | * The default is to allow at most 10 requests per IP in a 90 seconds window. 475 | * After that the import/export request is rejected. 476 | * 477 | * See https://github.com/nfriedly/express-rate-limit for more options 478 | */ 479 | "importExportRateLimiting": { 480 | // duration of the rate limit window (milliseconds) 481 | "windowMs": 90000, 482 | 483 | // maximum number of requests per IP to allow during the rate limit window 484 | "max": 10 485 | }, 486 | 487 | /* 488 | * From Etherpad 1.8.3 onwards, the maximum allowed size for a single imported 489 | * file is always bounded. 490 | * 491 | * File size is specified in bytes. Default is 50 MB. 492 | */ 493 | "importMaxFileSize": 52428800, // 50 * 1024 * 1024 494 | 495 | /* 496 | * Toolbar buttons configuration. 497 | * 498 | * Uncomment to customize. 499 | */ 500 | 501 | /* 502 | "toolbar": { 503 | "left": [ 504 | ["bold", "italic", "underline", "strikethrough"], 505 | ["orderedlist", "unorderedlist", "indent", "outdent"], 506 | ["undo", "redo"], 507 | ["clearauthorship"] 508 | ], 509 | "right": [ 510 | ["importexport", "timeslider", "savedrevision"], 511 | ["settings", "embed"], 512 | ["showusers"] 513 | ], 514 | "timeslider": [ 515 | ["timeslider_export", "timeslider_returnToPad"] 516 | ] 517 | }, 518 | */ 519 | 520 | /* 521 | * Expose Etherpad version in the web interface and in the Server http header. 522 | * 523 | * Do not enable on production machines. 524 | */ 525 | "exposeVersion": false, 526 | 527 | /* 528 | * The log level we are using. 529 | * 530 | * Valid values: DEBUG, INFO, WARN, ERROR 531 | */ 532 | "loglevel": "INFO", 533 | 534 | /* 535 | * Logging configuration. See log4js documentation for further information: 536 | * https://github.com/nomiddlename/log4js-node 537 | * 538 | * You can add as many appenders as you want here. 539 | */ 540 | "logconfig" : 541 | { "appenders": [ 542 | { "type": "console" 543 | //, "category": "access"// only logs pad access 544 | } 545 | 546 | /* 547 | , { "type": "file" 548 | , "filename": "your-log-file-here.log" 549 | , "maxLogSize": 1024 550 | , "backups": 3 // how many log files there're gonna be at max 551 | //, "category": "test" // only log a specific category 552 | } 553 | */ 554 | 555 | /* 556 | , { "type": "logLevelFilter" 557 | , "level": "warn" // filters out all log messages that have a lower level than "error" 558 | , "appender": 559 | { Use whatever appender you want here } 560 | } 561 | */ 562 | 563 | /* 564 | , { "type": "logLevelFilter" 565 | , "level": "error" // filters out all log messages that have a lower level than "error" 566 | , "appender": 567 | { "type": "smtp" 568 | , "subject": "An error occurred in your EPL instance!" 569 | , "recipients": "bar@blurdybloop.com, baz@blurdybloop.com" 570 | , "sendInterval": 300 // 60 * 5 = 5 minutes -- will buffer log messages; set to 0 to send a mail for every message 571 | , "transport": "SMTP", "SMTP": { // see https://github.com/andris9/Nodemailer#possible-transport-methods 572 | "host": "smtp.example.com", "port": 465, 573 | "secureConnection": true, 574 | "auth": { 575 | "user": "foo@example.com", 576 | "pass": "bar_foo" 577 | } 578 | } 579 | } 580 | } 581 | */ 582 | 583 | ] 584 | } // logconfig 585 | } -------------------------------------------------------------------------------- /app-resources/etherpad/dev/etherpad_deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | app: etherpad 6 | name: etherpad 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: etherpad 12 | strategy: 13 | rollingUpdate: 14 | maxSurge: 25% 15 | maxUnavailable: 25% 16 | type: RollingUpdate 17 | template: 18 | metadata: 19 | labels: 20 | app: etherpad 21 | spec: 22 | containers: 23 | - env: 24 | - name: DB_TYPE 25 | value: postgres 26 | - name: DB_HOST 27 | value: postgresql 28 | - name: DB_PORT 29 | value: "5432" 30 | - name: DB_DATABASE 31 | value: etherpad 32 | - name: DB_USER 33 | value: ether 34 | - name: DB_PASS 35 | value: ether 36 | - name: NODE_ENV 37 | value: production 38 | image: quay.io/gpte-devops-automation/etherpad:latest 39 | imagePullPolicy: Always 40 | name: etherpad 41 | ports: 42 | - containerPort: 9001 43 | protocol: TCP 44 | resources: {} 45 | terminationMessagePath: /dev/termination-log 46 | terminationMessagePolicy: File 47 | readinessProbe: 48 | failureThreshold: 5 49 | httpGet: 50 | path: / 51 | port: 9001 52 | scheme: HTTP 53 | initialDelaySeconds: 60 54 | periodSeconds: 10 55 | successThreshold: 1 56 | timeoutSeconds: 1 57 | livenessProbe: 58 | failureThreshold: 3 59 | httpGet: 60 | path: / 61 | port: 9001 62 | scheme: HTTP 63 | initialDelaySeconds: 120 64 | periodSeconds: 10 65 | successThreshold: 1 66 | timeoutSeconds: 1 67 | volumeMounts: 68 | - mountPath: /opt/etherpad/config 69 | name: etherpad-settings 70 | dnsPolicy: ClusterFirst 71 | restartPolicy: Always 72 | schedulerName: default-scheduler 73 | securityContext: {} 74 | terminationGracePeriodSeconds: 30 75 | volumes: 76 | - configMap: 77 | defaultMode: 420 78 | name: etherpad-settings 79 | name: etherpad-settings -------------------------------------------------------------------------------- /app-resources/etherpad/dev/etherpad_route.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: route.openshift.io/v1 2 | kind: Route 3 | metadata: 4 | labels: 5 | app: etherpad 6 | name: etherpad-route 7 | spec: 8 | tls: 9 | insecureEdgeTerminationPolicy: Redirect 10 | termination: edge 11 | to: 12 | name: etherpad 13 | port: 14 | targetPort: 9001 -------------------------------------------------------------------------------- /app-resources/etherpad/dev/etherpad_service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | app: etherpad 6 | name: etherpad 7 | spec: 8 | ports: 9 | - name: etherpad 10 | port: 9001 11 | protocol: TCP 12 | selector: 13 | app: etherpad -------------------------------------------------------------------------------- /app-resources/etherpad/dev/postgres_deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: postgresql 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | name: postgresql 10 | strategy: 11 | type: Recreate 12 | template: 13 | metadata: 14 | labels: 15 | name: postgresql 16 | spec: 17 | containers: 18 | - capabilities: {} 19 | env: 20 | - name: POSTGRESQL_USER 21 | valueFrom: 22 | secretKeyRef: 23 | key: database-user 24 | name: ether 25 | - name: POSTGRESQL_PASSWORD 26 | valueFrom: 27 | secretKeyRef: 28 | key: database-password 29 | name: ether 30 | - name: POSTGRESQL_DATABASE 31 | valueFrom: 32 | secretKeyRef: 33 | key: database-name 34 | name: ether 35 | image: registry.redhat.io/rhscl/postgresql-10-rhel7@sha256:5c4f5f52a37718a9a1997ba212ef172694475558c35232b56dac638529c5b569 36 | imagePullPolicy: IfNotPresent 37 | livenessProbe: 38 | exec: 39 | command: 40 | - /usr/libexec/check-container 41 | - --live 42 | initialDelaySeconds: 120 43 | timeoutSeconds: 10 44 | name: postgresql 45 | ports: 46 | - containerPort: 5432 47 | protocol: TCP 48 | readinessProbe: 49 | exec: 50 | command: 51 | - /usr/libexec/check-container 52 | initialDelaySeconds: 5 53 | timeoutSeconds: 1 54 | resources: 55 | limits: 56 | memory: 512Mi 57 | securityContext: 58 | capabilities: {} 59 | privileged: false 60 | terminationMessagePath: /dev/termination-log 61 | volumeMounts: 62 | - mountPath: /var/lib/pgsql/data 63 | name: postgresql-data 64 | dnsPolicy: ClusterFirst 65 | restartPolicy: Always 66 | volumes: 67 | - name: postgresql-data 68 | emptyDir: 69 | medium: "" -------------------------------------------------------------------------------- /app-resources/etherpad/dev/postgres_secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | annotations: 5 | template.openshift.io/expose-database_name: '{.data[''database-name'']}' 6 | template.openshift.io/expose-password: '{.data[''database-password'']}' 7 | template.openshift.io/expose-username: '{.data[''database-user'']}' 8 | labels: 9 | template: postgresql-persistent-template 10 | name: ether 11 | stringData: 12 | database-name: etherpad 13 | database-password: ether 14 | database-user: ether -------------------------------------------------------------------------------- /app-resources/etherpad/dev/postgres_service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: postgresql 5 | spec: 6 | ports: 7 | - name: postgresql 8 | nodePort: 0 9 | port: 5432 10 | protocol: TCP 11 | targetPort: 5432 12 | selector: 13 | name: postgresql 14 | sessionAffinity: None 15 | type: ClusterIP 16 | status: 17 | loadBalancer: {} -------------------------------------------------------------------------------- /app-resources/etherpad/prd/etherpad_configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | creationTimestamp: null 5 | name: etherpad-settings 6 | labels: 7 | app: etherpad 8 | data: 9 | settings.json: | 10 | /* 11 | * This file must be valid JSON. But comments are allowed 12 | * 13 | * Please edit settings.json, not settings.json.template 14 | * 15 | * Please note that starting from Etherpad 1.6.0 you can store DB credentials in 16 | * a separate file (credentials.json). 17 | * 18 | * 19 | * ENVIRONMENT VARIABLE SUBSTITUTION 20 | * ================================= 21 | * 22 | * All the configuration values can be read from environment variables using the 23 | * syntax "${ENV_VAR}" or "${ENV_VAR:default_value}". 24 | * 25 | * This is useful, for example, when running in a Docker container. 26 | * 27 | * EXAMPLE: 28 | * "port": "${PORT:9001}" 29 | * "minify": "${MINIFY}" 30 | * "skinName": "${SKIN_NAME:colibris}" 31 | * 32 | * Would read the configuration values for those items from the environment 33 | * variables PORT, MINIFY and SKIN_NAME. 34 | * 35 | * If PORT and SKIN_NAME variables were not defined, the default values 9001 and 36 | * "colibris" would be used. 37 | * The configuration value "minify", on the other hand, does not have a 38 | * designated default value. Thus, if the environment variable MINIFY were 39 | * undefined, "minify" would be null. 40 | * 41 | * REMARKS: 42 | * 1) please note that variable substitution always needs to be quoted. 43 | * 44 | * "port": 9001, <-- Literal values. When not using 45 | * "minify": false substitution, only strings must be 46 | * "skinName": "colibris" quoted. Booleans and numbers must not. 47 | * 48 | * "port": "${PORT:9001}" <-- CORRECT: if you want to use a variable 49 | * "minify": "${MINIFY:true}" substitution, put quotes around its name, 50 | * "skinName": "${SKIN_NAME}" even if the required value is a number or 51 | * a boolean. 52 | * Etherpad will take care of rewriting it 53 | * to the proper type if necessary. 54 | * 55 | * "port": ${PORT:9001} <-- ERROR: this is not valid json. Quotes 56 | * "minify": ${MINIFY} around variable names are missing. 57 | * "skinName": ${SKIN_NAME} 58 | * 59 | * 2) Beware of undefined variables and default values: nulls and empty strings 60 | * are different! 61 | * 62 | * This is particularly important for user's passwords (see the relevant 63 | * section): 64 | * 65 | * "password": "${PASSW}" // if PASSW is not defined would result in password === null 66 | * "password": "${PASSW:}" // if PASSW is not defined would result in password === '' 67 | * 68 | * If you want to use an empty value (null) as default value for a variable, 69 | * simply do not set it, without putting any colons: "${ABIWORD}". 70 | * 71 | * 3) if you want to use newlines in the default value of a string parameter, 72 | * use "\n" as usual. 73 | * 74 | * "defaultPadText" : "${DEFAULT_PAD_TEXT}Line 1\nLine 2" 75 | */ 76 | { 77 | /* 78 | * Name your instance! 79 | */ 80 | "title": "OpenTLC Etherpad", 81 | 82 | /* 83 | * favicon default name 84 | * alternatively, set up a fully specified Url to your own favicon 85 | */ 86 | "favicon": "favicon.ico", 87 | 88 | /* 89 | * Skin name. 90 | * 91 | * Its value has to be an existing directory under src/static/skins. 92 | * You can write your own, or use one of the included ones: 93 | * 94 | * - "no-skin": an empty skin (default). This yields the unmodified, 95 | * traditional Etherpad theme. 96 | * - "colibris": the new experimental skin (since Etherpad 1.8), candidate to 97 | * become the default in Etherpad 2.0 98 | */ 99 | "skinName": "colibris", 100 | 101 | /* 102 | * Skin Variants 103 | * 104 | * Use the UI skin variants builder at /p/test#skinvariantsbuilder 105 | * 106 | * For the colibris skin only, you can choose how to render the three main 107 | * containers: 108 | * - toolbar (top menu with icons) 109 | * - editor (containing the text of the pad) 110 | * - background (area outside of editor, mostly visible when using page style) 111 | * 112 | * For each of the 3 containers you can choose 4 color combinations: 113 | * super-light, light, dark, super-dark. 114 | * 115 | * For example, to make the toolbar dark, you will include "dark-toolbar" into 116 | * skinVariants. 117 | * 118 | * You can provide multiple skin variants separated by spaces. Default 119 | * skinVariant is "super-light-toolbar super-light-editor light-background". 120 | * 121 | * For the editor container, you can also make it full width by adding 122 | * "full-width-editor" variant (by default editor is rendered as a page, with 123 | * a max-width of 900px). 124 | */ 125 | "skinVariants": "light-toolbar dark-background light-editor full-width-editor", 126 | 127 | /* 128 | * IP and port which Etherpad should bind at. 129 | * 130 | * Binding to a Unix socket is also supported: just use an empty string for 131 | * the ip, and put the full path to the socket in the port parameter. 132 | * 133 | * EXAMPLE USING UNIX SOCKET: 134 | * "ip": "", // <-- has to be an empty string 135 | * "port" : "/somepath/etherpad.socket", // <-- path to a Unix socket 136 | */ 137 | "ip": "0.0.0.0", 138 | "port": 9001, 139 | 140 | /* 141 | * Option to hide/show the settings.json in admin page. 142 | * 143 | * Default option is set to true 144 | */ 145 | "showSettingsInAdminPage": true, 146 | 147 | /* 148 | * Node native SSL support 149 | * 150 | * This is disabled by default. 151 | * Make sure to have the minimum and correct file access permissions set so 152 | * that the Etherpad server can access them 153 | */ 154 | 155 | /* 156 | "ssl" : { 157 | "key" : "/path-to-your/epl-server.key", 158 | "cert" : "/path-to-your/epl-server.crt", 159 | "ca": ["/path-to-your/epl-intermediate-cert1.crt", "/path-to-your/epl-intermediate-cert2.crt"] 160 | }, 161 | */ 162 | 163 | /* 164 | * The type of the database. 165 | * 166 | * You can choose between many DB drivers, for example: dirty, postgres, 167 | * sqlite, mysql. 168 | * 169 | * You shouldn't use "dirty" for for anything else than testing or 170 | * development. 171 | * 172 | * 173 | * Database specific settings are dependent on dbType, and go in dbSettings. 174 | * Remember that since Etherpad 1.6.0 you can also store these informations in 175 | * credentials.json. 176 | * 177 | * For a complete list of the supported drivers, please refer to: 178 | * https://www.npmjs.com/package/ueberdb2 179 | */ 180 | /* 181 | "dbType": "dirty", 182 | "dbSettings": { 183 | "filename": "var/dirty.db" 184 | }, 185 | */ 186 | 187 | /* 188 | * An Example of MySQL Configuration (commented out). 189 | * 190 | * See: https://github.com/ether/etherpad-lite/wiki/How-to-use-Etherpad-Lite-with-MySQL 191 | */ 192 | 193 | /* 194 | "dbType" : "mysql", 195 | "dbSettings" : { 196 | "user": "etherpaduser", 197 | "host": "localhost", 198 | "port": 3306, 199 | "password": "PASSWORD", 200 | "database": "etherpad_lite_db", 201 | "charset": "utf8mb4" 202 | }, 203 | */ 204 | 205 | "dbType" : "DB_TYPE", 206 | "dbSettings" : { 207 | "host" : "DB_HOST", 208 | "port" : "DB_PORT", 209 | "database": "DB_DATABASE", 210 | "user" : "DB_USER", 211 | "password": "DB_PASS" 212 | }, 213 | 214 | /* 215 | * The default text of a pad 216 | */ 217 | "defaultPadText" : "Welcome to the OpenTLC Etherpad!\n\nENVIRONMENT=PRD!\n", 218 | 219 | /* 220 | * Default Pad behavior. 221 | * 222 | * Change them if you want to override. 223 | */ 224 | "padOptions": { 225 | "noColors": false, 226 | "showControls": true, 227 | "showChat": true, 228 | "showLineNumbers": true, 229 | "useMonospaceFont": false, 230 | "userName": false, 231 | "userColor": false, 232 | "rtl": false, 233 | "alwaysShowChat": false, 234 | "chatAndUsers": false, 235 | "lang": "en-us" 236 | }, 237 | 238 | /* 239 | * Pad Shortcut Keys 240 | */ 241 | "padShortcutEnabled" : { 242 | "altF9": true, /* focus on the File Menu and/or editbar */ 243 | "altC": true, /* focus on the Chat window */ 244 | "cmdShift2": true, /* shows a gritter popup showing a line author */ 245 | "delete": true, 246 | "return": true, 247 | "esc": true, /* in mozilla versions 14-19 avoid reconnecting pad */ 248 | "cmdS": true, /* save a revision */ 249 | "tab": true, /* indent */ 250 | "cmdZ": true, /* undo/redo */ 251 | "cmdY": true, /* redo */ 252 | "cmdI": true, /* italic */ 253 | "cmdB": true, /* bold */ 254 | "cmdU": true, /* underline */ 255 | "cmd5": true, /* strike through */ 256 | "cmdShiftL": true, /* unordered list */ 257 | "cmdShiftN": true, /* ordered list */ 258 | "cmdShift1": true, /* ordered list */ 259 | "cmdShiftC": true, /* clear authorship */ 260 | "cmdH": true, /* backspace */ 261 | "ctrlHome": true, /* scroll to top of pad */ 262 | "pageUp": true, 263 | "pageDown": true 264 | }, 265 | 266 | /* 267 | * Should we suppress errors from being visible in the default Pad Text? 268 | */ 269 | "suppressErrorsInPadText": false, 270 | 271 | /* 272 | * If this option is enabled, a user must have a session to access pads. 273 | * This effectively allows only group pads to be accessed. 274 | */ 275 | "requireSession": false, 276 | 277 | /* 278 | * Users may edit pads but not create new ones. 279 | * 280 | * Pad creation is only via the API. 281 | * This applies both to group pads and regular pads. 282 | */ 283 | "editOnly": false, 284 | 285 | /* 286 | * If set to true, those users who have a valid session will automatically be 287 | * granted access to password protected pads. 288 | */ 289 | "sessionNoPassword": false, 290 | 291 | /* 292 | * If true, all css & js will be minified before sending to the client. 293 | * 294 | * This will improve the loading performance massively, but makes it difficult 295 | * to debug the javascript/css 296 | */ 297 | "minify": true, 298 | 299 | /* 300 | * How long may clients use served javascript code (in seconds)? 301 | * 302 | * Not setting this may cause problems during deployment. 303 | * Set to 0 to disable caching. 304 | */ 305 | "maxAge": 21600, // 60 * 60 * 6 = 6 hours 306 | 307 | /* 308 | * Absolute path to the Abiword executable. 309 | * 310 | * Abiword is needed to get advanced import/export features of pads. Setting 311 | * it to null disables Abiword and will only allow plain text and HTML 312 | * import/exports. 313 | */ 314 | "abiword": null, 315 | 316 | /* 317 | * This is the absolute path to the soffice executable. 318 | * 319 | * LibreOffice can be used in lieu of Abiword to export pads. 320 | * Setting it to null disables LibreOffice exporting. 321 | */ 322 | "soffice": null, 323 | 324 | /* 325 | * Path to the Tidy executable. 326 | * 327 | * Tidy is used to improve the quality of exported pads. 328 | * Setting it to null disables Tidy. 329 | */ 330 | "tidyHtml": null, 331 | 332 | /* 333 | * Allow import of file types other than the supported ones: 334 | * txt, doc, docx, rtf, odt, html & htm 335 | */ 336 | "allowUnknownFileEnds": true, 337 | 338 | /* 339 | * This setting is used if you require authentication of all users. 340 | * 341 | * Note: "/admin" always requires authentication. 342 | */ 343 | "requireAuthentication": false, 344 | 345 | /* 346 | * Require authorization by a module, or a user with is_admin set, see below. 347 | */ 348 | "requireAuthorization": false, 349 | 350 | /* 351 | * When you use NGINX or another proxy/load-balancer set this to true. 352 | * 353 | * This is especially necessary when the reverse proxy performs SSL 354 | * termination, otherwise the cookies will not have the "secure" flag. 355 | * 356 | * The other effect will be that the logs will contain the real client's IP, 357 | * instead of the reverse proxy's IP. 358 | */ 359 | "trustProxy": false, 360 | 361 | /* 362 | * Privacy: disable IP logging 363 | */ 364 | "disableIPlogging": false, 365 | 366 | /* 367 | * Time (in seconds) to automatically reconnect pad when a "Force reconnect" 368 | * message is shown to user. 369 | * 370 | * Set to 0 to disable automatic reconnection. 371 | */ 372 | "automaticReconnectionTimeout": 0, 373 | 374 | /* 375 | * By default, when caret is moved out of viewport, it scrolls the minimum 376 | * height needed to make this line visible. 377 | */ 378 | "scrollWhenFocusLineIsOutOfViewport": { 379 | 380 | /* 381 | * Percentage of viewport height to be additionally scrolled. 382 | * 383 | * E.g.: use "percentage.editionAboveViewport": 0.5, to place caret line in 384 | * the middle of viewport, when user edits a line above of the 385 | * viewport 386 | * 387 | * Set to 0 to disable extra scrolling 388 | */ 389 | "percentage": { 390 | "editionAboveViewport": 0, 391 | "editionBelowViewport": 0 392 | }, 393 | 394 | /* 395 | * Time (in milliseconds) used to animate the scroll transition. 396 | * Set to 0 to disable animation 397 | */ 398 | "duration": 0, 399 | 400 | /* 401 | * Flag to control if it should scroll when user places the caret in the 402 | * last line of the viewport 403 | */ 404 | "scrollWhenCaretIsInTheLastLineOfViewport": false, 405 | 406 | /* 407 | * Percentage of viewport height to be additionally scrolled when user 408 | * presses arrow up in the line of the top of the viewport. 409 | * 410 | * Set to 0 to let the scroll to be handled as default by Etherpad 411 | */ 412 | "percentageToScrollWhenUserPressesArrowUp": 0 413 | }, 414 | 415 | /* 416 | * Users for basic authentication. 417 | * 418 | * is_admin = true gives access to /admin. 419 | * If you do not uncomment this, /admin will not be available! 420 | * 421 | * WARNING: passwords should not be stored in plaintext in this file. 422 | * If you want to mitigate this, please install ep_hash_auth and 423 | * follow the section "secure your installation" in README.md 424 | */ 425 | 426 | /* 427 | "users": { 428 | "admin": { 429 | // 1) "password" can be replaced with "hash" if you install ep_hash_auth 430 | // 2) please note that if password is null, the user will not be created 431 | "password": "changeme1", 432 | "is_admin": true 433 | }, 434 | "user": { 435 | // 1) "password" can be replaced with "hash" if you install ep_hash_auth 436 | // 2) please note that if password is null, the user will not be created 437 | "password": "changeme1", 438 | "is_admin": false 439 | } 440 | }, 441 | */ 442 | "users": { 443 | "admin": { 444 | "password": "secret", 445 | "is_admin": true 446 | } 447 | }, 448 | 449 | /* 450 | * Restrict socket.io transport methods 451 | */ 452 | "socketTransportProtocols" : ["xhr-polling", "jsonp-polling", "htmlfile"], 453 | 454 | /* 455 | * Allow Load Testing tools to hit the Etherpad Instance. 456 | * 457 | * WARNING: this will disable security on the instance. 458 | */ 459 | "loadTest": false, 460 | 461 | /* 462 | * Disable indentation on new line when previous line ends with some special 463 | * chars (':', '[', '(', '{') 464 | */ 465 | 466 | /* 467 | "indentationOnNewLine": false, 468 | */ 469 | 470 | /* 471 | * From Etherpad 1.8.3 onwards, import and export of pads is always rate 472 | * limited. 473 | * 474 | * The default is to allow at most 10 requests per IP in a 90 seconds window. 475 | * After that the import/export request is rejected. 476 | * 477 | * See https://github.com/nfriedly/express-rate-limit for more options 478 | */ 479 | "importExportRateLimiting": { 480 | // duration of the rate limit window (milliseconds) 481 | "windowMs": 90000, 482 | 483 | // maximum number of requests per IP to allow during the rate limit window 484 | "max": 10 485 | }, 486 | 487 | /* 488 | * From Etherpad 1.8.3 onwards, the maximum allowed size for a single imported 489 | * file is always bounded. 490 | * 491 | * File size is specified in bytes. Default is 50 MB. 492 | */ 493 | "importMaxFileSize": 52428800, // 50 * 1024 * 1024 494 | 495 | /* 496 | * Toolbar buttons configuration. 497 | * 498 | * Uncomment to customize. 499 | */ 500 | 501 | /* 502 | "toolbar": { 503 | "left": [ 504 | ["bold", "italic", "underline", "strikethrough"], 505 | ["orderedlist", "unorderedlist", "indent", "outdent"], 506 | ["undo", "redo"], 507 | ["clearauthorship"] 508 | ], 509 | "right": [ 510 | ["importexport", "timeslider", "savedrevision"], 511 | ["settings", "embed"], 512 | ["showusers"] 513 | ], 514 | "timeslider": [ 515 | ["timeslider_export", "timeslider_returnToPad"] 516 | ] 517 | }, 518 | */ 519 | 520 | /* 521 | * Expose Etherpad version in the web interface and in the Server http header. 522 | * 523 | * Do not enable on production machines. 524 | */ 525 | "exposeVersion": false, 526 | 527 | /* 528 | * The log level we are using. 529 | * 530 | * Valid values: DEBUG, INFO, WARN, ERROR 531 | */ 532 | "loglevel": "INFO", 533 | 534 | /* 535 | * Logging configuration. See log4js documentation for further information: 536 | * https://github.com/nomiddlename/log4js-node 537 | * 538 | * You can add as many appenders as you want here. 539 | */ 540 | "logconfig" : 541 | { "appenders": [ 542 | { "type": "console" 543 | //, "category": "access"// only logs pad access 544 | } 545 | 546 | /* 547 | , { "type": "file" 548 | , "filename": "your-log-file-here.log" 549 | , "maxLogSize": 1024 550 | , "backups": 3 // how many log files there're gonna be at max 551 | //, "category": "test" // only log a specific category 552 | } 553 | */ 554 | 555 | /* 556 | , { "type": "logLevelFilter" 557 | , "level": "warn" // filters out all log messages that have a lower level than "error" 558 | , "appender": 559 | { Use whatever appender you want here } 560 | } 561 | */ 562 | 563 | /* 564 | , { "type": "logLevelFilter" 565 | , "level": "error" // filters out all log messages that have a lower level than "error" 566 | , "appender": 567 | { "type": "smtp" 568 | , "subject": "An error occurred in your EPL instance!" 569 | , "recipients": "bar@blurdybloop.com, baz@blurdybloop.com" 570 | , "sendInterval": 300 // 60 * 5 = 5 minutes -- will buffer log messages; set to 0 to send a mail for every message 571 | , "transport": "SMTP", "SMTP": { // see https://github.com/andris9/Nodemailer#possible-transport-methods 572 | "host": "smtp.example.com", "port": 465, 573 | "secureConnection": true, 574 | "auth": { 575 | "user": "foo@example.com", 576 | "pass": "bar_foo" 577 | } 578 | } 579 | } 580 | } 581 | */ 582 | 583 | ] 584 | } // logconfig 585 | } -------------------------------------------------------------------------------- /app-resources/etherpad/prd/etherpad_deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | app: etherpad 6 | name: etherpad 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: etherpad 12 | strategy: 13 | rollingUpdate: 14 | maxSurge: 25% 15 | maxUnavailable: 25% 16 | type: RollingUpdate 17 | template: 18 | metadata: 19 | labels: 20 | app: etherpad 21 | spec: 22 | containers: 23 | - env: 24 | - name: DB_TYPE 25 | value: postgres 26 | - name: DB_HOST 27 | value: postgresql 28 | - name: DB_PORT 29 | value: "5432" 30 | - name: DB_DATABASE 31 | value: etherpad 32 | - name: DB_USER 33 | value: ether 34 | - name: DB_PASS 35 | value: ether 36 | - name: NODE_ENV 37 | value: production 38 | image: quay.io/gpte-devops-automation/etherpad:latest 39 | imagePullPolicy: Always 40 | name: etherpad 41 | ports: 42 | - containerPort: 9001 43 | protocol: TCP 44 | resources: {} 45 | terminationMessagePath: /dev/termination-log 46 | terminationMessagePolicy: File 47 | readinessProbe: 48 | failureThreshold: 5 49 | httpGet: 50 | path: / 51 | port: 9001 52 | scheme: HTTP 53 | initialDelaySeconds: 60 54 | periodSeconds: 10 55 | successThreshold: 1 56 | timeoutSeconds: 1 57 | livenessProbe: 58 | failureThreshold: 3 59 | httpGet: 60 | path: / 61 | port: 9001 62 | scheme: HTTP 63 | initialDelaySeconds: 120 64 | periodSeconds: 10 65 | successThreshold: 1 66 | timeoutSeconds: 1 67 | volumeMounts: 68 | - mountPath: /opt/etherpad/config 69 | name: etherpad-settings 70 | dnsPolicy: ClusterFirst 71 | restartPolicy: Always 72 | schedulerName: default-scheduler 73 | securityContext: {} 74 | terminationGracePeriodSeconds: 30 75 | volumes: 76 | - configMap: 77 | defaultMode: 420 78 | name: etherpad-settings 79 | name: etherpad-settings -------------------------------------------------------------------------------- /app-resources/etherpad/prd/etherpad_route.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: route.openshift.io/v1 2 | kind: Route 3 | metadata: 4 | labels: 5 | app: etherpad 6 | name: etherpad-route 7 | spec: 8 | tls: 9 | insecureEdgeTerminationPolicy: Redirect 10 | termination: edge 11 | to: 12 | name: etherpad 13 | port: 14 | targetPort: 9001 -------------------------------------------------------------------------------- /app-resources/etherpad/prd/etherpad_service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | app: etherpad 6 | name: etherpad 7 | spec: 8 | ports: 9 | - name: etherpad 10 | port: 9001 11 | protocol: TCP 12 | selector: 13 | app: etherpad -------------------------------------------------------------------------------- /app-resources/etherpad/prd/postgres_deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: postgresql 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | name: postgresql 10 | strategy: 11 | type: Recreate 12 | template: 13 | metadata: 14 | labels: 15 | name: postgresql 16 | spec: 17 | containers: 18 | - capabilities: {} 19 | env: 20 | - name: POSTGRESQL_USER 21 | valueFrom: 22 | secretKeyRef: 23 | key: database-user 24 | name: ether 25 | - name: POSTGRESQL_PASSWORD 26 | valueFrom: 27 | secretKeyRef: 28 | key: database-password 29 | name: ether 30 | - name: POSTGRESQL_DATABASE 31 | valueFrom: 32 | secretKeyRef: 33 | key: database-name 34 | name: ether 35 | image: registry.redhat.io/rhscl/postgresql-10-rhel7@sha256:5c4f5f52a37718a9a1997ba212ef172694475558c35232b56dac638529c5b569 36 | imagePullPolicy: IfNotPresent 37 | livenessProbe: 38 | exec: 39 | command: 40 | - /usr/libexec/check-container 41 | - --live 42 | initialDelaySeconds: 120 43 | timeoutSeconds: 10 44 | name: postgresql 45 | ports: 46 | - containerPort: 5432 47 | protocol: TCP 48 | readinessProbe: 49 | exec: 50 | command: 51 | - /usr/libexec/check-container 52 | initialDelaySeconds: 5 53 | timeoutSeconds: 1 54 | resources: 55 | limits: 56 | memory: 512Mi 57 | securityContext: 58 | capabilities: {} 59 | privileged: false 60 | terminationMessagePath: /dev/termination-log 61 | volumeMounts: 62 | - mountPath: /var/lib/pgsql/data 63 | name: postgresql-data 64 | dnsPolicy: ClusterFirst 65 | restartPolicy: Always 66 | volumes: 67 | - name: postgresql-data 68 | emptyDir: 69 | medium: "" -------------------------------------------------------------------------------- /app-resources/etherpad/prd/postgres_secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | annotations: 5 | template.openshift.io/expose-database_name: '{.data[''database-name'']}' 6 | template.openshift.io/expose-password: '{.data[''database-password'']}' 7 | template.openshift.io/expose-username: '{.data[''database-user'']}' 8 | labels: 9 | template: postgresql-persistent-template 10 | name: ether 11 | stringData: 12 | database-name: etherpad 13 | database-password: ether 14 | database-user: ether -------------------------------------------------------------------------------- /app-resources/etherpad/prd/postgres_service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: postgresql 5 | spec: 6 | ports: 7 | - name: postgresql 8 | nodePort: 0 9 | port: 5432 10 | protocol: TCP 11 | targetPort: 5432 12 | selector: 13 | name: postgresql 14 | sessionAffinity: None 15 | type: ClusterIP 16 | status: 17 | loadBalancer: {} -------------------------------------------------------------------------------- /app-resources/etherpad/qa/etherpad_configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | creationTimestamp: null 5 | name: etherpad-settings 6 | labels: 7 | app: etherpad 8 | data: 9 | settings.json: | 10 | /* 11 | * This file must be valid JSON. But comments are allowed 12 | * 13 | * Please edit settings.json, not settings.json.template 14 | * 15 | * Please note that starting from Etherpad 1.6.0 you can store DB credentials in 16 | * a separate file (credentials.json). 17 | * 18 | * 19 | * ENVIRONMENT VARIABLE SUBSTITUTION 20 | * ================================= 21 | * 22 | * All the configuration values can be read from environment variables using the 23 | * syntax "${ENV_VAR}" or "${ENV_VAR:default_value}". 24 | * 25 | * This is useful, for example, when running in a Docker container. 26 | * 27 | * EXAMPLE: 28 | * "port": "${PORT:9001}" 29 | * "minify": "${MINIFY}" 30 | * "skinName": "${SKIN_NAME:colibris}" 31 | * 32 | * Would read the configuration values for those items from the environment 33 | * variables PORT, MINIFY and SKIN_NAME. 34 | * 35 | * If PORT and SKIN_NAME variables were not defined, the default values 9001 and 36 | * "colibris" would be used. 37 | * The configuration value "minify", on the other hand, does not have a 38 | * designated default value. Thus, if the environment variable MINIFY were 39 | * undefined, "minify" would be null. 40 | * 41 | * REMARKS: 42 | * 1) please note that variable substitution always needs to be quoted. 43 | * 44 | * "port": 9001, <-- Literal values. When not using 45 | * "minify": false substitution, only strings must be 46 | * "skinName": "colibris" quoted. Booleans and numbers must not. 47 | * 48 | * "port": "${PORT:9001}" <-- CORRECT: if you want to use a variable 49 | * "minify": "${MINIFY:true}" substitution, put quotes around its name, 50 | * "skinName": "${SKIN_NAME}" even if the required value is a number or 51 | * a boolean. 52 | * Etherpad will take care of rewriting it 53 | * to the proper type if necessary. 54 | * 55 | * "port": ${PORT:9001} <-- ERROR: this is not valid json. Quotes 56 | * "minify": ${MINIFY} around variable names are missing. 57 | * "skinName": ${SKIN_NAME} 58 | * 59 | * 2) Beware of undefined variables and default values: nulls and empty strings 60 | * are different! 61 | * 62 | * This is particularly important for user's passwords (see the relevant 63 | * section): 64 | * 65 | * "password": "${PASSW}" // if PASSW is not defined would result in password === null 66 | * "password": "${PASSW:}" // if PASSW is not defined would result in password === '' 67 | * 68 | * If you want to use an empty value (null) as default value for a variable, 69 | * simply do not set it, without putting any colons: "${ABIWORD}". 70 | * 71 | * 3) if you want to use newlines in the default value of a string parameter, 72 | * use "\n" as usual. 73 | * 74 | * "defaultPadText" : "${DEFAULT_PAD_TEXT}Line 1\nLine 2" 75 | */ 76 | { 77 | /* 78 | * Name your instance! 79 | */ 80 | "title": "OpenTLC Etherpad", 81 | 82 | /* 83 | * favicon default name 84 | * alternatively, set up a fully specified Url to your own favicon 85 | */ 86 | "favicon": "favicon.ico", 87 | 88 | /* 89 | * Skin name. 90 | * 91 | * Its value has to be an existing directory under src/static/skins. 92 | * You can write your own, or use one of the included ones: 93 | * 94 | * - "no-skin": an empty skin (default). This yields the unmodified, 95 | * traditional Etherpad theme. 96 | * - "colibris": the new experimental skin (since Etherpad 1.8), candidate to 97 | * become the default in Etherpad 2.0 98 | */ 99 | "skinName": "colibris", 100 | 101 | /* 102 | * Skin Variants 103 | * 104 | * Use the UI skin variants builder at /p/test#skinvariantsbuilder 105 | * 106 | * For the colibris skin only, you can choose how to render the three main 107 | * containers: 108 | * - toolbar (top menu with icons) 109 | * - editor (containing the text of the pad) 110 | * - background (area outside of editor, mostly visible when using page style) 111 | * 112 | * For each of the 3 containers you can choose 4 color combinations: 113 | * super-light, light, dark, super-dark. 114 | * 115 | * For example, to make the toolbar dark, you will include "dark-toolbar" into 116 | * skinVariants. 117 | * 118 | * You can provide multiple skin variants separated by spaces. Default 119 | * skinVariant is "super-light-toolbar super-light-editor light-background". 120 | * 121 | * For the editor container, you can also make it full width by adding 122 | * "full-width-editor" variant (by default editor is rendered as a page, with 123 | * a max-width of 900px). 124 | */ 125 | "skinVariants": "light-toolbar dark-background light-editor full-width-editor", 126 | 127 | /* 128 | * IP and port which Etherpad should bind at. 129 | * 130 | * Binding to a Unix socket is also supported: just use an empty string for 131 | * the ip, and put the full path to the socket in the port parameter. 132 | * 133 | * EXAMPLE USING UNIX SOCKET: 134 | * "ip": "", // <-- has to be an empty string 135 | * "port" : "/somepath/etherpad.socket", // <-- path to a Unix socket 136 | */ 137 | "ip": "0.0.0.0", 138 | "port": 9001, 139 | 140 | /* 141 | * Option to hide/show the settings.json in admin page. 142 | * 143 | * Default option is set to true 144 | */ 145 | "showSettingsInAdminPage": true, 146 | 147 | /* 148 | * Node native SSL support 149 | * 150 | * This is disabled by default. 151 | * Make sure to have the minimum and correct file access permissions set so 152 | * that the Etherpad server can access them 153 | */ 154 | 155 | /* 156 | "ssl" : { 157 | "key" : "/path-to-your/epl-server.key", 158 | "cert" : "/path-to-your/epl-server.crt", 159 | "ca": ["/path-to-your/epl-intermediate-cert1.crt", "/path-to-your/epl-intermediate-cert2.crt"] 160 | }, 161 | */ 162 | 163 | /* 164 | * The type of the database. 165 | * 166 | * You can choose between many DB drivers, for example: dirty, postgres, 167 | * sqlite, mysql. 168 | * 169 | * You shouldn't use "dirty" for for anything else than testing or 170 | * development. 171 | * 172 | * 173 | * Database specific settings are dependent on dbType, and go in dbSettings. 174 | * Remember that since Etherpad 1.6.0 you can also store these informations in 175 | * credentials.json. 176 | * 177 | * For a complete list of the supported drivers, please refer to: 178 | * https://www.npmjs.com/package/ueberdb2 179 | */ 180 | /* 181 | "dbType": "dirty", 182 | "dbSettings": { 183 | "filename": "var/dirty.db" 184 | }, 185 | */ 186 | 187 | /* 188 | * An Example of MySQL Configuration (commented out). 189 | * 190 | * See: https://github.com/ether/etherpad-lite/wiki/How-to-use-Etherpad-Lite-with-MySQL 191 | */ 192 | 193 | /* 194 | "dbType" : "mysql", 195 | "dbSettings" : { 196 | "user": "etherpaduser", 197 | "host": "localhost", 198 | "port": 3306, 199 | "password": "PASSWORD", 200 | "database": "etherpad_lite_db", 201 | "charset": "utf8mb4" 202 | }, 203 | */ 204 | 205 | "dbType" : "DB_TYPE", 206 | "dbSettings" : { 207 | "host" : "DB_HOST", 208 | "port" : "DB_PORT", 209 | "database": "DB_DATABASE", 210 | "user" : "DB_USER", 211 | "password": "DB_PASS" 212 | }, 213 | 214 | /* 215 | * The default text of a pad 216 | */ 217 | "defaultPadText" : "Welcome to the OpenTLC Etherpad!\n\nENVIRONMENT=QA!\n", 218 | 219 | /* 220 | * Default Pad behavior. 221 | * 222 | * Change them if you want to override. 223 | */ 224 | "padOptions": { 225 | "noColors": false, 226 | "showControls": true, 227 | "showChat": true, 228 | "showLineNumbers": true, 229 | "useMonospaceFont": false, 230 | "userName": false, 231 | "userColor": false, 232 | "rtl": false, 233 | "alwaysShowChat": false, 234 | "chatAndUsers": false, 235 | "lang": "en-us" 236 | }, 237 | 238 | /* 239 | * Pad Shortcut Keys 240 | */ 241 | "padShortcutEnabled" : { 242 | "altF9": true, /* focus on the File Menu and/or editbar */ 243 | "altC": true, /* focus on the Chat window */ 244 | "cmdShift2": true, /* shows a gritter popup showing a line author */ 245 | "delete": true, 246 | "return": true, 247 | "esc": true, /* in mozilla versions 14-19 avoid reconnecting pad */ 248 | "cmdS": true, /* save a revision */ 249 | "tab": true, /* indent */ 250 | "cmdZ": true, /* undo/redo */ 251 | "cmdY": true, /* redo */ 252 | "cmdI": true, /* italic */ 253 | "cmdB": true, /* bold */ 254 | "cmdU": true, /* underline */ 255 | "cmd5": true, /* strike through */ 256 | "cmdShiftL": true, /* unordered list */ 257 | "cmdShiftN": true, /* ordered list */ 258 | "cmdShift1": true, /* ordered list */ 259 | "cmdShiftC": true, /* clear authorship */ 260 | "cmdH": true, /* backspace */ 261 | "ctrlHome": true, /* scroll to top of pad */ 262 | "pageUp": true, 263 | "pageDown": true 264 | }, 265 | 266 | /* 267 | * Should we suppress errors from being visible in the default Pad Text? 268 | */ 269 | "suppressErrorsInPadText": false, 270 | 271 | /* 272 | * If this option is enabled, a user must have a session to access pads. 273 | * This effectively allows only group pads to be accessed. 274 | */ 275 | "requireSession": false, 276 | 277 | /* 278 | * Users may edit pads but not create new ones. 279 | * 280 | * Pad creation is only via the API. 281 | * This applies both to group pads and regular pads. 282 | */ 283 | "editOnly": false, 284 | 285 | /* 286 | * If set to true, those users who have a valid session will automatically be 287 | * granted access to password protected pads. 288 | */ 289 | "sessionNoPassword": false, 290 | 291 | /* 292 | * If true, all css & js will be minified before sending to the client. 293 | * 294 | * This will improve the loading performance massively, but makes it difficult 295 | * to debug the javascript/css 296 | */ 297 | "minify": true, 298 | 299 | /* 300 | * How long may clients use served javascript code (in seconds)? 301 | * 302 | * Not setting this may cause problems during deployment. 303 | * Set to 0 to disable caching. 304 | */ 305 | "maxAge": 21600, // 60 * 60 * 6 = 6 hours 306 | 307 | /* 308 | * Absolute path to the Abiword executable. 309 | * 310 | * Abiword is needed to get advanced import/export features of pads. Setting 311 | * it to null disables Abiword and will only allow plain text and HTML 312 | * import/exports. 313 | */ 314 | "abiword": null, 315 | 316 | /* 317 | * This is the absolute path to the soffice executable. 318 | * 319 | * LibreOffice can be used in lieu of Abiword to export pads. 320 | * Setting it to null disables LibreOffice exporting. 321 | */ 322 | "soffice": null, 323 | 324 | /* 325 | * Path to the Tidy executable. 326 | * 327 | * Tidy is used to improve the quality of exported pads. 328 | * Setting it to null disables Tidy. 329 | */ 330 | "tidyHtml": null, 331 | 332 | /* 333 | * Allow import of file types other than the supported ones: 334 | * txt, doc, docx, rtf, odt, html & htm 335 | */ 336 | "allowUnknownFileEnds": true, 337 | 338 | /* 339 | * This setting is used if you require authentication of all users. 340 | * 341 | * Note: "/admin" always requires authentication. 342 | */ 343 | "requireAuthentication": false, 344 | 345 | /* 346 | * Require authorization by a module, or a user with is_admin set, see below. 347 | */ 348 | "requireAuthorization": false, 349 | 350 | /* 351 | * When you use NGINX or another proxy/load-balancer set this to true. 352 | * 353 | * This is especially necessary when the reverse proxy performs SSL 354 | * termination, otherwise the cookies will not have the "secure" flag. 355 | * 356 | * The other effect will be that the logs will contain the real client's IP, 357 | * instead of the reverse proxy's IP. 358 | */ 359 | "trustProxy": false, 360 | 361 | /* 362 | * Privacy: disable IP logging 363 | */ 364 | "disableIPlogging": false, 365 | 366 | /* 367 | * Time (in seconds) to automatically reconnect pad when a "Force reconnect" 368 | * message is shown to user. 369 | * 370 | * Set to 0 to disable automatic reconnection. 371 | */ 372 | "automaticReconnectionTimeout": 0, 373 | 374 | /* 375 | * By default, when caret is moved out of viewport, it scrolls the minimum 376 | * height needed to make this line visible. 377 | */ 378 | "scrollWhenFocusLineIsOutOfViewport": { 379 | 380 | /* 381 | * Percentage of viewport height to be additionally scrolled. 382 | * 383 | * E.g.: use "percentage.editionAboveViewport": 0.5, to place caret line in 384 | * the middle of viewport, when user edits a line above of the 385 | * viewport 386 | * 387 | * Set to 0 to disable extra scrolling 388 | */ 389 | "percentage": { 390 | "editionAboveViewport": 0, 391 | "editionBelowViewport": 0 392 | }, 393 | 394 | /* 395 | * Time (in milliseconds) used to animate the scroll transition. 396 | * Set to 0 to disable animation 397 | */ 398 | "duration": 0, 399 | 400 | /* 401 | * Flag to control if it should scroll when user places the caret in the 402 | * last line of the viewport 403 | */ 404 | "scrollWhenCaretIsInTheLastLineOfViewport": false, 405 | 406 | /* 407 | * Percentage of viewport height to be additionally scrolled when user 408 | * presses arrow up in the line of the top of the viewport. 409 | * 410 | * Set to 0 to let the scroll to be handled as default by Etherpad 411 | */ 412 | "percentageToScrollWhenUserPressesArrowUp": 0 413 | }, 414 | 415 | /* 416 | * Users for basic authentication. 417 | * 418 | * is_admin = true gives access to /admin. 419 | * If you do not uncomment this, /admin will not be available! 420 | * 421 | * WARNING: passwords should not be stored in plaintext in this file. 422 | * If you want to mitigate this, please install ep_hash_auth and 423 | * follow the section "secure your installation" in README.md 424 | */ 425 | 426 | /* 427 | "users": { 428 | "admin": { 429 | // 1) "password" can be replaced with "hash" if you install ep_hash_auth 430 | // 2) please note that if password is null, the user will not be created 431 | "password": "changeme1", 432 | "is_admin": true 433 | }, 434 | "user": { 435 | // 1) "password" can be replaced with "hash" if you install ep_hash_auth 436 | // 2) please note that if password is null, the user will not be created 437 | "password": "changeme1", 438 | "is_admin": false 439 | } 440 | }, 441 | */ 442 | "users": { 443 | "admin": { 444 | "password": "secret", 445 | "is_admin": true 446 | } 447 | }, 448 | 449 | /* 450 | * Restrict socket.io transport methods 451 | */ 452 | "socketTransportProtocols" : ["xhr-polling", "jsonp-polling", "htmlfile"], 453 | 454 | /* 455 | * Allow Load Testing tools to hit the Etherpad Instance. 456 | * 457 | * WARNING: this will disable security on the instance. 458 | */ 459 | "loadTest": false, 460 | 461 | /* 462 | * Disable indentation on new line when previous line ends with some special 463 | * chars (':', '[', '(', '{') 464 | */ 465 | 466 | /* 467 | "indentationOnNewLine": false, 468 | */ 469 | 470 | /* 471 | * From Etherpad 1.8.3 onwards, import and export of pads is always rate 472 | * limited. 473 | * 474 | * The default is to allow at most 10 requests per IP in a 90 seconds window. 475 | * After that the import/export request is rejected. 476 | * 477 | * See https://github.com/nfriedly/express-rate-limit for more options 478 | */ 479 | "importExportRateLimiting": { 480 | // duration of the rate limit window (milliseconds) 481 | "windowMs": 90000, 482 | 483 | // maximum number of requests per IP to allow during the rate limit window 484 | "max": 10 485 | }, 486 | 487 | /* 488 | * From Etherpad 1.8.3 onwards, the maximum allowed size for a single imported 489 | * file is always bounded. 490 | * 491 | * File size is specified in bytes. Default is 50 MB. 492 | */ 493 | "importMaxFileSize": 52428800, // 50 * 1024 * 1024 494 | 495 | /* 496 | * Toolbar buttons configuration. 497 | * 498 | * Uncomment to customize. 499 | */ 500 | 501 | /* 502 | "toolbar": { 503 | "left": [ 504 | ["bold", "italic", "underline", "strikethrough"], 505 | ["orderedlist", "unorderedlist", "indent", "outdent"], 506 | ["undo", "redo"], 507 | ["clearauthorship"] 508 | ], 509 | "right": [ 510 | ["importexport", "timeslider", "savedrevision"], 511 | ["settings", "embed"], 512 | ["showusers"] 513 | ], 514 | "timeslider": [ 515 | ["timeslider_export", "timeslider_returnToPad"] 516 | ] 517 | }, 518 | */ 519 | 520 | /* 521 | * Expose Etherpad version in the web interface and in the Server http header. 522 | * 523 | * Do not enable on production machines. 524 | */ 525 | "exposeVersion": false, 526 | 527 | /* 528 | * The log level we are using. 529 | * 530 | * Valid values: DEBUG, INFO, WARN, ERROR 531 | */ 532 | "loglevel": "INFO", 533 | 534 | /* 535 | * Logging configuration. See log4js documentation for further information: 536 | * https://github.com/nomiddlename/log4js-node 537 | * 538 | * You can add as many appenders as you want here. 539 | */ 540 | "logconfig" : 541 | { "appenders": [ 542 | { "type": "console" 543 | //, "category": "access"// only logs pad access 544 | } 545 | 546 | /* 547 | , { "type": "file" 548 | , "filename": "your-log-file-here.log" 549 | , "maxLogSize": 1024 550 | , "backups": 3 // how many log files there're gonna be at max 551 | //, "category": "test" // only log a specific category 552 | } 553 | */ 554 | 555 | /* 556 | , { "type": "logLevelFilter" 557 | , "level": "warn" // filters out all log messages that have a lower level than "error" 558 | , "appender": 559 | { Use whatever appender you want here } 560 | } 561 | */ 562 | 563 | /* 564 | , { "type": "logLevelFilter" 565 | , "level": "error" // filters out all log messages that have a lower level than "error" 566 | , "appender": 567 | { "type": "smtp" 568 | , "subject": "An error occurred in your EPL instance!" 569 | , "recipients": "bar@blurdybloop.com, baz@blurdybloop.com" 570 | , "sendInterval": 300 // 60 * 5 = 5 minutes -- will buffer log messages; set to 0 to send a mail for every message 571 | , "transport": "SMTP", "SMTP": { // see https://github.com/andris9/Nodemailer#possible-transport-methods 572 | "host": "smtp.example.com", "port": 465, 573 | "secureConnection": true, 574 | "auth": { 575 | "user": "foo@example.com", 576 | "pass": "bar_foo" 577 | } 578 | } 579 | } 580 | } 581 | */ 582 | 583 | ] 584 | } // logconfig 585 | } -------------------------------------------------------------------------------- /app-resources/etherpad/qa/etherpad_deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | app: etherpad 6 | name: etherpad 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: etherpad 12 | strategy: 13 | rollingUpdate: 14 | maxSurge: 25% 15 | maxUnavailable: 25% 16 | type: RollingUpdate 17 | template: 18 | metadata: 19 | labels: 20 | app: etherpad 21 | spec: 22 | containers: 23 | - env: 24 | - name: DB_TYPE 25 | value: postgres 26 | - name: DB_HOST 27 | value: postgresql 28 | - name: DB_PORT 29 | value: "5432" 30 | - name: DB_DATABASE 31 | value: etherpad 32 | - name: DB_USER 33 | value: ether 34 | - name: DB_PASS 35 | value: ether 36 | - name: NODE_ENV 37 | value: production 38 | image: quay.io/gpte-devops-automation/etherpad:latest 39 | imagePullPolicy: Always 40 | name: etherpad 41 | ports: 42 | - containerPort: 9001 43 | protocol: TCP 44 | resources: {} 45 | terminationMessagePath: /dev/termination-log 46 | terminationMessagePolicy: File 47 | readinessProbe: 48 | failureThreshold: 5 49 | httpGet: 50 | path: / 51 | port: 9001 52 | scheme: HTTP 53 | initialDelaySeconds: 60 54 | periodSeconds: 10 55 | successThreshold: 1 56 | timeoutSeconds: 1 57 | livenessProbe: 58 | failureThreshold: 3 59 | httpGet: 60 | path: / 61 | port: 9001 62 | scheme: HTTP 63 | initialDelaySeconds: 120 64 | periodSeconds: 10 65 | successThreshold: 1 66 | timeoutSeconds: 1 67 | volumeMounts: 68 | - mountPath: /opt/etherpad/config 69 | name: etherpad-settings 70 | dnsPolicy: ClusterFirst 71 | restartPolicy: Always 72 | schedulerName: default-scheduler 73 | securityContext: {} 74 | terminationGracePeriodSeconds: 30 75 | volumes: 76 | - configMap: 77 | defaultMode: 420 78 | name: etherpad-settings 79 | name: etherpad-settings -------------------------------------------------------------------------------- /app-resources/etherpad/qa/etherpad_route.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: route.openshift.io/v1 2 | kind: Route 3 | metadata: 4 | labels: 5 | app: etherpad 6 | name: etherpad-route 7 | spec: 8 | tls: 9 | insecureEdgeTerminationPolicy: Redirect 10 | termination: edge 11 | to: 12 | name: etherpad 13 | port: 14 | targetPort: 9001 -------------------------------------------------------------------------------- /app-resources/etherpad/qa/etherpad_service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | app: etherpad 6 | name: etherpad 7 | spec: 8 | ports: 9 | - name: etherpad 10 | port: 9001 11 | protocol: TCP 12 | selector: 13 | app: etherpad -------------------------------------------------------------------------------- /app-resources/etherpad/qa/postgres_deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: postgresql 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | name: postgresql 10 | strategy: 11 | type: Recreate 12 | template: 13 | metadata: 14 | labels: 15 | name: postgresql 16 | spec: 17 | containers: 18 | - capabilities: {} 19 | env: 20 | - name: POSTGRESQL_USER 21 | valueFrom: 22 | secretKeyRef: 23 | key: database-user 24 | name: ether 25 | - name: POSTGRESQL_PASSWORD 26 | valueFrom: 27 | secretKeyRef: 28 | key: database-password 29 | name: ether 30 | - name: POSTGRESQL_DATABASE 31 | valueFrom: 32 | secretKeyRef: 33 | key: database-name 34 | name: ether 35 | image: registry.redhat.io/rhscl/postgresql-10-rhel7@sha256:5c4f5f52a37718a9a1997ba212ef172694475558c35232b56dac638529c5b569 36 | imagePullPolicy: IfNotPresent 37 | livenessProbe: 38 | exec: 39 | command: 40 | - /usr/libexec/check-container 41 | - --live 42 | initialDelaySeconds: 120 43 | timeoutSeconds: 10 44 | name: postgresql 45 | ports: 46 | - containerPort: 5432 47 | protocol: TCP 48 | readinessProbe: 49 | exec: 50 | command: 51 | - /usr/libexec/check-container 52 | initialDelaySeconds: 5 53 | timeoutSeconds: 1 54 | resources: 55 | limits: 56 | memory: 512Mi 57 | securityContext: 58 | capabilities: {} 59 | privileged: false 60 | terminationMessagePath: /dev/termination-log 61 | volumeMounts: 62 | - mountPath: /var/lib/pgsql/data 63 | name: postgresql-data 64 | dnsPolicy: ClusterFirst 65 | restartPolicy: Always 66 | volumes: 67 | - name: postgresql-data 68 | emptyDir: 69 | medium: "" -------------------------------------------------------------------------------- /app-resources/etherpad/qa/postgres_secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | annotations: 5 | template.openshift.io/expose-database_name: '{.data[''database-name'']}' 6 | template.openshift.io/expose-password: '{.data[''database-password'']}' 7 | template.openshift.io/expose-username: '{.data[''database-user'']}' 8 | labels: 9 | template: postgresql-persistent-template 10 | name: ether 11 | stringData: 12 | database-name: etherpad 13 | database-password: ether 14 | database-user: ether -------------------------------------------------------------------------------- /app-resources/etherpad/qa/postgres_service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: postgresql 5 | spec: 6 | ports: 7 | - name: postgresql 8 | nodePort: 0 9 | port: 5432 10 | protocol: TCP 11 | targetPort: 5432 12 | selector: 13 | name: postgresql 14 | sessionAffinity: None 15 | type: ClusterIP 16 | status: 17 | loadBalancer: {} -------------------------------------------------------------------------------- /app-resources/policies/cert_expiration.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: policy.open-cluster-management.io/v1 3 | kind: Policy 4 | metadata: 5 | name: policy-certificate 6 | namespace: rhacm-policies 7 | spec: 8 | remediationAction: inform 9 | disabled: false 10 | policy-templates: 11 | - objectDefinition: 12 | apiVersion: policy.open-cluster-management.io/v1 13 | kind: CertificatePolicy 14 | metadata: 15 | name: policy-certificate-example 16 | spec: 17 | namespaceSelector: 18 | include: 19 | - openshift-ingress 20 | exclude: [] 21 | remediationAction: inform 22 | severity: low 23 | minimumDuration: 2200h 24 | --- 25 | apiVersion: policy.open-cluster-management.io/v1 26 | kind: PlacementBinding 27 | metadata: 28 | name: certificate-placement-binding 29 | namespace: rhacm-policies 30 | placementRef: 31 | name: dev-clusters 32 | kind: PlacementRule 33 | apiGroup: apps.open-cluster-management.io 34 | subjects: 35 | - name: policy-certificate 36 | kind: Policy 37 | apiGroup: policy.open-cluster-management.io 38 | -------------------------------------------------------------------------------- /app-resources/policies/config_limitrange.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy.open-cluster-management.io/v1 2 | kind: Policy 3 | metadata: 4 | name: policy-limitmemory 5 | namespace: rhacm-policies 6 | spec: 7 | remediationAction: enforce 8 | disabled: false 9 | policy-templates: 10 | - objectDefinition: 11 | apiVersion: policy.open-cluster-management.io/v1 12 | kind: ConfigurationPolicy 13 | metadata: 14 | name: policy-limitrange 15 | spec: 16 | severity: medium 17 | namespaceSelector: 18 | exclude: 19 | - kube-* 20 | - openshift-* 21 | - openshift 22 | - open-cluster* 23 | - default 24 | - multicluster-endpoint 25 | include: 26 | - '*' 27 | object-templates: 28 | - complianceType: musthave 29 | objectDefinition: 30 | apiVersion: v1 31 | kind: LimitRange 32 | metadata: 33 | name: default-limit-range 34 | spec: 35 | limits: 36 | - type: Container 37 | default: 38 | cpu: 500m 39 | memory: 512Mi 40 | defaultRequest: 41 | cpu: 50m 42 | memory: 256Mi 43 | max: 44 | cpu: 2 45 | memory: 4Gi 46 | - type: Pod 47 | max: 48 | cpu: 4 49 | memory: 8Gi 50 | -------------------------------------------------------------------------------- /app-resources/policies/config_placement_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy.open-cluster-management.io/v1 2 | kind: PlacementBinding 3 | metadata: 4 | name: binding-policy-limitmemory 5 | namespace: rhacm-policies 6 | placementRef: 7 | name: dev-clusters 8 | kind: PlacementRule 9 | apiGroup: apps.open-cluster-management.io 10 | subjects: 11 | - name: policy-limitmemory 12 | kind: Policy 13 | apiGroup: policy.open-cluster-management.io 14 | -------------------------------------------------------------------------------- /app-resources/policies/config_placement_rule.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.open-cluster-management.io/v1 2 | kind: PlacementRule 3 | metadata: 4 | name: dev-clusters 5 | namespace: rhacm-policies 6 | spec: 7 | clusterConditions: 8 | - type: ManagedClusterConditionAvailable 9 | status: "True" 10 | clusterSelector: 11 | matchExpressions: 12 | - key: environment 13 | operator: In 14 | values: 15 | - "dev" -------------------------------------------------------------------------------- /app-resources/policies/iam.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy.open-cluster-management.io/v1 2 | kind: Policy 3 | metadata: 4 | name: policy-limitclusteradmin 5 | namespace: rhacm-policies 6 | spec: 7 | complianceType: musthave 8 | remediationAction: inform 9 | disabled: false 10 | policy-templates: 11 | - objectDefinition: 12 | apiVersion: policy.open-cluster-management.io/v1 13 | kind: IamPolicy 14 | metadata: 15 | name: policy-limitclusteradmin-example 16 | spec: 17 | severity: medium 18 | namespaceSelector: {} 19 | remediationAction: inform 20 | maxClusterRoleBindingUsers: 5 21 | --- 22 | apiVersion: policy.open-cluster-management.io/v1 23 | kind: PlacementBinding 24 | metadata: 25 | name: binding-policy-iam 26 | namespace: rhacm-policies 27 | placementRef: 28 | name: dev-clusters 29 | kind: PlacementRule 30 | apiGroup: apps.open-cluster-management.io 31 | subjects: 32 | - name: policy-iam 33 | kind: Policy 34 | apiGroup: policy.open-cluster-management.io -------------------------------------------------------------------------------- /app-resources/policies/namespace.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: rhacm-policies -------------------------------------------------------------------------------- /imgs/Screenshot from 2020-10-03 20-25-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giofontana/rhacm-pipelines/d280069c45f2061b333228265518244247e0c653/imgs/Screenshot from 2020-10-03 20-25-48.png -------------------------------------------------------------------------------- /imgs/Screenshot from 2020-10-03 20-26-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giofontana/rhacm-pipelines/d280069c45f2061b333228265518244247e0c653/imgs/Screenshot from 2020-10-03 20-26-16.png -------------------------------------------------------------------------------- /imgs/Screenshot from 2020-10-03 20-27-14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giofontana/rhacm-pipelines/d280069c45f2061b333228265518244247e0c653/imgs/Screenshot from 2020-10-03 20-27-14.png -------------------------------------------------------------------------------- /imgs/Screenshot from 2020-10-03 20-27-39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giofontana/rhacm-pipelines/d280069c45f2061b333228265518244247e0c653/imgs/Screenshot from 2020-10-03 20-27-39.png -------------------------------------------------------------------------------- /imgs/rhacm-index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giofontana/rhacm-pipelines/d280069c45f2061b333228265518244247e0c653/imgs/rhacm-index.png -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/README.md: -------------------------------------------------------------------------------- 1 | # GitOps Using Red Hat OpenShift Pipelines (Tekton) and Red Hat Advanced Cluster Management to Deploy on Multiple Clusters 2 | ### October 13th, 2020 | by Giovanni Fontana 3 | 4 | 5 | Recently, Red Hat launched the Advanced Cluster Management tool, which aims to help organizations overcome the challenges of having applications deployed in multiple clusters and clouds. Red Hat is also actively collaborating with the Tekton project as the solution that will enable teams to build Kubernetes-style delivery pipelines that can fully control and own the complete life cycle of their microservices without having to rely on central teams to maintain and manage a CI server, plugins, and its configurations. 6 | 7 | In the last article (see here) we saw how to use Tekton and Red Hat Advanced Cluster Management to deploy an application on multiple namespaces, one for each lifecycle environment (Dev, QA and Prod), using a **single** OpenShift managed cluster. In this article we are going to expand our use case to deploy that same application using **three different clusters**, one for **Non-Production** workloads, another for **Production** and a last one representing a **DR** (Disaster Recovery) cluster. 8 | 9 | Therefore, our **Non-Production** cluster will have the Dev and QA projects: 10 | 11 | ![Non-Production Cluster](images/nonprod-cluster.png) 12 | 13 | On other hand, in our **Production** and **DR** clusters we are going to have exactly the same workload, which is the application production version - in this step we will see how to use the PlacementRule to deploy an application on multiple clusters at once! 14 | 15 | ![Prod and DR Clusters](images/prod-and-dr-cluster.png) 16 | 17 | In the last article we explored the different RH ACM object types: **Application, Channel, PlacementRule and Subscription**. We also deployed all **three stages on a single cluster**, therefore the PlacementRule is equal for all of them. At this time we will change them to be able to deploy the application on different clusters. Let’s check them: 18 | 19 | **PlacementRule for Dev and QA:** 20 | 21 | ```yaml 22 | --- 23 | apiVersion: apps.open-cluster-management.io/v1 24 | kind: PlacementRule 25 | metadata: 26 | name: nonprod-cluster 27 | namespace: etherpad-acm-dev 28 | spec: 29 | clusterConditions: 30 | - type: ManagedClusterConditionAvailable 31 | status: "True" 32 | clusterSelector: 33 | matchLabels: 34 | environment: nonprod 35 | ``` 36 | 37 | **PlacementRule for Prod and DR:** 38 | ```yaml 39 | --- 40 | apiVersion: apps.open-cluster-management.io/v1 41 | kind: PlacementRule 42 | metadata: 43 | name: prd-and-dr-cluster 44 | namespace: etherpad-acm-prd 45 | spec: 46 | clusterConditions: 47 | - type: ManagedClusterConditionAvailable 48 | status: "True" 49 | clusterSelector: 50 | matchExpressions: 51 | - key: environment 52 | operator: In 53 | values: 54 | - prod 55 | - dr 56 | ``` 57 | 58 | NOTE: My clusters have been tagged with the following labels during their import to RH ACM: 59 | 60 | * Non Production Cluster: environment=nonprod 61 | * Production Cluster: environment=prod 62 | * DR Cluster: environment=dr 63 | 64 | Let’s run it? The yaml files are in this github repo: https://github.com/giofontana/rhacm-pipelines/tree/master/multipleclusters-multiple-envs 65 | 66 | ![RH ACM Multiple Clusters Deployment](images/2-rhacm-deploy-multiple-clusters.gif) 67 | 68 | Note that when you create the subscription for prod environment, RH ACM starts the deployment of the etherpad application on two clusters at the same time (Prod and DR). 69 | 70 | ![RH ACM Multiple Clusters Deployment](images/rhacm-app.png) 71 | 72 | Therefore, we already addressed how to deploy an application on multiple namespaces in multiple clusters using RH ACM. Now we need to inject what we already have on a Tekton pipeline. 73 | 74 | Our pipeline now will cover the following process: 75 | 76 | ![Multiple Clusters Deployment Pipeline](images/pipeline.png) 77 | 78 | 1. **[TEKTON - TASK creating-namespaces]** Create the namespaces on the OpenShift Hub Cluster (where RH ACM is deployed); 79 | 2. **[TEKTON - TASK etherpad-dev-deployment]** Create Application, Channel, PlacementRule for NON-PRODUCTION and Subscription; 80 | 3. **[RH ACM - DEV DEPLOYMENT]** Deploy etherpad application on etherpad-dev namespace in NON-PRODUCTION cluster 81 | 4. **[TEKTON - TASK etherpad-qa-deployment]** Create Application, Channel, PlacementRule for NON-PRODUCTION and Subscription; 82 | 5. **[RH ACM - QA DEPLOYMENT]** Deploy etherpad application on etherpad-qa namespace in NON-PRODUCTION cluster 83 | 6. **[TEKTON - TASK etherpad-prd-deployment]** Create Application, Channel, PlacementRule for PRODUCTION + DR and Subscription; 84 | 7. **[RH ACM - PROD + DR DEPLOYMENT]** Deploy etherpad application on etherpad-prod namespace in PRODUCTION and DR cluster. 85 | 86 | Here we can notice something that in my perspective is really valuable about using **RH ACM** as your deployment tool: You don’t need to change anything in your pipeline because now you need to deploy your application in more clusters - **you just need to change the PlacementRule object** of the environment you need to change. In the last article we deployed the Dev, QA and Prod application in a single cluster, we are now deploying this same application using three different clusters and what have we changed? Only the PlacementRule object! Very nice right? 87 | 88 | To finish our article, let’s see our pipeline in action! 89 | 90 | ![Multiple Clusters Deployment Pipeline](images/RH-ACM-2-2-TEKTON.gif) 91 | 92 | # Conclusion 93 | 94 | In this article, we improved the application deployment to simulate a more real world scenario using RH ACM and Tekton: Deploy of Dev and QA version of an application in a NON-PRODUCTION cluster and deploy of the Production version in two different clusters (PROD and DR) at the same time. We also saw that, by using RH ACM, we “decouple” the deployment logic from the pipeline and we were able to change the deployment targets by only changing the PlacementRule objects and no changes were needed on the Tekton side. 95 | 96 | What did you think? Interesting, right? If you are interested in knowing more about OpenShift Pipelines and Red Hat Advanced Cluster Management for Kubernetes talk to a Red Hatter by filling [this form](https://www.redhat.com/en/technologies/management/advanced-cluster-management#contact-form) or talking to your Red Hat representative. You can also see more about it on the [Red Hat Videos YouTube channel](https://www.youtube.com/watch?v=gKw-bJGYTQw). 97 | -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/images/2-rhacm-deploy-multiple-clusters.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giofontana/rhacm-pipelines/d280069c45f2061b333228265518244247e0c653/multipleclusters-multiple-envs/images/2-rhacm-deploy-multiple-clusters.gif -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/images/RH-ACM-2-2-TEKTON.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giofontana/rhacm-pipelines/d280069c45f2061b333228265518244247e0c653/multipleclusters-multiple-envs/images/RH-ACM-2-2-TEKTON.gif -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/images/banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giofontana/rhacm-pipelines/d280069c45f2061b333228265518244247e0c653/multipleclusters-multiple-envs/images/banner.jpg -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/images/nonprod-cluster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giofontana/rhacm-pipelines/d280069c45f2061b333228265518244247e0c653/multipleclusters-multiple-envs/images/nonprod-cluster.png -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/images/pipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giofontana/rhacm-pipelines/d280069c45f2061b333228265518244247e0c653/multipleclusters-multiple-envs/images/pipeline.png -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/images/prod-and-dr-cluster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giofontana/rhacm-pipelines/d280069c45f2061b333228265518244247e0c653/multipleclusters-multiple-envs/images/prod-and-dr-cluster.png -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/images/rhacm-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giofontana/rhacm-pipelines/d280069c45f2061b333228265518244247e0c653/multipleclusters-multiple-envs/images/rhacm-app.png -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/rhacm/dev/application.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: app.k8s.io/v1beta1 4 | kind: Application 5 | metadata: 6 | name: etherpad-acm-dev 7 | namespace: etherpad-acm-dev 8 | spec: 9 | componentKinds: 10 | - group: apps.open-cluster-management.io 11 | kind: Subscription 12 | descriptor: {} 13 | selector: 14 | matchExpressions: 15 | - key: app 16 | operator: In 17 | values: 18 | - etherpad-acm-dev -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/rhacm/dev/channel.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apps.open-cluster-management.io/v1 4 | kind: Channel 5 | metadata: 6 | name: etherpad-app-latest 7 | namespace: etherpad-acm-dev 8 | spec: 9 | type: GitHub 10 | pathname: https://github.com/giofontana/rhacm-pipelines.git -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/rhacm/dev/placement-rule.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apps.open-cluster-management.io/v1 4 | kind: PlacementRule 5 | metadata: 6 | name: nonprod-cluster 7 | namespace: etherpad-acm-dev 8 | spec: 9 | clusterConditions: 10 | - type: ManagedClusterConditionAvailable 11 | status: "True" 12 | clusterSelector: 13 | matchLabels: 14 | environment: nonprod -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/rhacm/dev/subscription.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apps.open-cluster-management.io/v1 4 | kind: Subscription 5 | metadata: 6 | name: etherpad-acm-dev 7 | namespace: etherpad-acm-dev 8 | labels: 9 | app: etherpad-acm-dev 10 | annotations: 11 | apps.open-cluster-management.io/github-path: app-resources/etherpad/dev 12 | spec: 13 | channel: etherpad-acm-dev/etherpad-app-latest 14 | placement: 15 | placementRef: 16 | kind: PlacementRule 17 | name: nonprod-cluster 18 | 19 | -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/rhacm/namespaces.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: etherpad-acm-dev 6 | --- 7 | apiVersion: v1 8 | kind: Namespace 9 | metadata: 10 | name: etherpad-acm-qa 11 | --- 12 | apiVersion: v1 13 | kind: Namespace 14 | metadata: 15 | name: etherpad-acm-prd -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/rhacm/prd/application.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: app.k8s.io/v1beta1 4 | kind: Application 5 | metadata: 6 | name: etherpad-acm-prd 7 | namespace: etherpad-acm-prd 8 | spec: 9 | componentKinds: 10 | - group: apps.open-cluster-management.io 11 | kind: Subscription 12 | descriptor: {} 13 | selector: 14 | matchExpressions: 15 | - key: app 16 | operator: In 17 | values: 18 | - etherpad-acm-prd -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/rhacm/prd/channel.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apps.open-cluster-management.io/v1 4 | kind: Channel 5 | metadata: 6 | name: etherpad-app-latest 7 | namespace: etherpad-acm-prd 8 | spec: 9 | type: GitHub 10 | pathname: https://github.com/giofontana/rhacm-pipelines.git -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/rhacm/prd/placement-rule.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apps.open-cluster-management.io/v1 4 | kind: PlacementRule 5 | metadata: 6 | name: prd-and-dr-cluster 7 | namespace: etherpad-acm-prd 8 | spec: 9 | clusterConditions: 10 | - type: ManagedClusterConditionAvailable 11 | status: "True" 12 | clusterSelector: 13 | matchExpressions: 14 | - key: environment 15 | operator: In 16 | values: 17 | - prod 18 | - dr -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/rhacm/prd/subscription.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apps.open-cluster-management.io/v1 4 | kind: Subscription 5 | metadata: 6 | name: etherpad-acm-prd 7 | namespace: etherpad-acm-prd 8 | labels: 9 | app: etherpad-acm-prd 10 | annotations: 11 | apps.open-cluster-management.io/github-path: app-resources/etherpad/prd 12 | spec: 13 | channel: etherpad-acm-prd/etherpad-app-latest 14 | placement: 15 | placementRef: 16 | kind: PlacementRule 17 | name: prd-and-dr-cluster 18 | 19 | -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/rhacm/qa/application.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: app.k8s.io/v1beta1 4 | kind: Application 5 | metadata: 6 | name: etherpad-acm-qa 7 | namespace: etherpad-acm-qa 8 | spec: 9 | componentKinds: 10 | - group: apps.open-cluster-management.io 11 | kind: Subscription 12 | descriptor: {} 13 | selector: 14 | matchExpressions: 15 | - key: app 16 | operator: In 17 | values: 18 | - etherpad-acm-qa -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/rhacm/qa/channel.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apps.open-cluster-management.io/v1 4 | kind: Channel 5 | metadata: 6 | name: etherpad-app-latest 7 | namespace: etherpad-acm-qa 8 | spec: 9 | type: GitHub 10 | pathname: https://github.com/giofontana/rhacm-pipelines.git -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/rhacm/qa/placement-rule.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apps.open-cluster-management.io/v1 4 | kind: PlacementRule 5 | metadata: 6 | name: nonprod-cluster 7 | namespace: etherpad-acm-qa 8 | spec: 9 | clusterConditions: 10 | - type: ManagedClusterConditionAvailable 11 | status: "True" 12 | clusterSelector: 13 | matchLabels: 14 | environment: nonprod -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/rhacm/qa/subscription.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apps.open-cluster-management.io/v1 4 | kind: Subscription 5 | metadata: 6 | name: etherpad-acm-qa 7 | namespace: etherpad-acm-qa 8 | labels: 9 | app: etherpad-acm-qa 10 | annotations: 11 | apps.open-cluster-management.io/github-path: app-resources/etherpad/qa 12 | spec: 13 | channel: etherpad-acm-qa/etherpad-app-latest 14 | placement: 15 | placementRef: 16 | kind: PlacementRule 17 | name: nonprod-cluster 18 | 19 | -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/tekton/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Create CD workflow on RH ACM using Tekton 3 | 4 | Procedure: 5 | 6 | ```console 7 | > oc new-project etherpad-cicd 8 | 9 | Now using project "etherpad-cicd" on server "https://api.acmhub.rhbr-labs.com:6443". 10 | 11 | You can add applications to this project with the 'new-app' command. For example, try: 12 | 13 | oc new-app ruby~https://github.com/sclorg/ruby-ex.git 14 | 15 | to build a new example application in Python. Or use kubectl to deploy a simple Kubernetes application: 16 | 17 | kubectl create deployment hello-node --image=gcr.io/hello-minikube-zero-install/hello-node 18 | 19 | > oc get serviceaccount pipeline 20 | NAME SECRETS AGE 21 | pipeline 2 29s 22 | 23 | > cd onecluster-multiple-envs/tekton 24 | 25 | > oc create -f tasks/01_create_namespaces.yaml 26 | task.tekton.dev/create-namespaces created 27 | 28 | > oc create -f tasks/02_create_dev_app_using_acm.yaml 29 | task.tekton.dev/etherpad-dev-deployment created 30 | 31 | > oc apply -f tasks/03_create_qa_app_using_acm.yaml 32 | task.tekton.dev/etherpad-qa-deployment created 33 | 34 | > oc apply -f tasks/04_create_prd_app_using_acm.yaml 35 | task.tekton.dev/etherpad-prd-deployment created 36 | 37 | > oc adm policy add-cluster-role-to-user cluster-admin system:serviceaccount:etherpad-cicd:pipeline 38 | clusterrole.rbac.authorization.k8s.io/cluster-admin added: "system:serviceaccount:etherpad-cicd:pipeline" 39 | 40 | > oc apply -f pipeline-acm.yaml 41 | pipeline.tekton.dev/deploy-using-acm created 42 | 43 | > oc apply -f prepare/tekton-source-pvc.yaml 44 | persistentvolumeclaim/source-pvc created 45 | 46 | > oc apply -f pipelinerun.yaml 47 | pipelinerun.tekton.dev/deploy-using-acm-run-1 created 48 | 49 | > tkn pipelinerun logs deploy-using-acm-run-1 -f 50 | [fetch-repository : clone] + CHECKOUT_DIR=/workspace/output/ 51 | [fetch-repository : clone] + '[[' true '==' true ]] 52 | [fetch-repository : clone] + cleandir 53 | [fetch-repository : clone] + '[[' -d /workspace/output/ ]] 54 | [fetch-repository : clone] + rm -rf /workspace/output//onecluster-multiple-envs 55 | [fetch-repository : clone] + rm -rf /workspace/output//.git 56 | [fetch-repository : clone] + rm -rf '/workspace/output//..?*' 57 | [fetch-repository : clone] + test -z 58 | [fetch-repository : clone] + test -z 59 | [fetch-repository : clone] + test -z 60 | [fetch-repository : clone] + /ko-app/git-init -url https://github.com/giofontana/rhacm-pipelines.git -revision master -refspec -path /workspace/output/ '-sslVerify=true' '-submodules=true' -depth 1 61 | [fetch-repository : clone] {"level":"info","ts":1597794549.2025642,"caller":"git/git.go:136","msg":"Successfully cloned https://github.com/giofontana/rhacm-pipelines.git @ f111d89c17e5647d3cd4dedca6968f20b73cfb0d (grafted, HEAD, origin/master) in path /workspace/output/"} 62 | [fetch-repository : clone] {"level":"info","ts":1597794549.240191,"caller":"git/git.go:177","msg":"Successfully initialized and updated submodules in path /workspace/output/"} 63 | [fetch-repository : clone] + cd /workspace/output/ 64 | [fetch-repository : clone] + git rev-parse HEAD 65 | [fetch-repository : clone] + tr -d '\n' 66 | [fetch-repository : clone] + RESULT_SHA=f111d89c17e5647d3cd4dedca6968f20b73cfb0d 67 | [fetch-repository : clone] + EXIT_CODE=0 68 | [fetch-repository : clone] + '[' 0 '!=' 0 ] 69 | [fetch-repository : clone] + echo -n f111d89c17e5647d3cd4dedca6968f20b73cfb0d 70 | 71 | [create-namespaces : creating-namespaces] **** Creating namespaces **** 72 | [create-namespaces : creating-namespaces] namespace/etherpad-acm-dev unchanged 73 | [create-namespaces : creating-namespaces] namespace/etherpad-acm-qa unchanged 74 | [create-namespaces : creating-namespaces] namespace/etherpad-acm-prd unchanged 75 | 76 | [etherpad-dev-deployment : etherpad-dev-deployment] **** DEV ENVIRONMENT: Creating application on RH ACM **** 77 | [etherpad-dev-deployment : etherpad-dev-deployment] application.app.k8s.io/etherpad-acm-dev unchanged 78 | [etherpad-dev-deployment : etherpad-dev-deployment] **** DEV ENVIRONMENT: Creating channel on RH ACM **** 79 | [etherpad-dev-deployment : etherpad-dev-deployment] channel.apps.open-cluster-management.io/etherpad-app-latest unchanged 80 | [etherpad-dev-deployment : etherpad-dev-deployment] **** DEV ENVIRONMENT: Creating placementrule on RH ACM **** 81 | [etherpad-dev-deployment : etherpad-dev-deployment] placementrule.apps.open-cluster-management.io/dev-cluster unchanged 82 | [etherpad-dev-deployment : etherpad-dev-deployment] **** DEV ENVIRONMENT: Creating subscription on RH ACM **** 83 | [etherpad-dev-deployment : etherpad-dev-deployment] subscription.apps.open-cluster-management.io/etherpad-acm-dev unchanged 84 | 85 | [etherpad-qa-deployment : etherpad-qa-deployment] **** QA ENVIRONMENT: Creating application on RH ACM **** 86 | [etherpad-qa-deployment : etherpad-qa-deployment] application.app.k8s.io/etherpad-acm-qa unchanged 87 | [etherpad-qa-deployment : etherpad-qa-deployment] **** QA ENVIRONMENT: Creating channel on RH ACM **** 88 | [etherpad-qa-deployment : etherpad-qa-deployment] channel.apps.open-cluster-management.io/etherpad-app-latest unchanged 89 | [etherpad-qa-deployment : etherpad-qa-deployment] **** QA ENVIRONMENT: Creating placementrule on RH ACM **** 90 | [etherpad-qa-deployment : etherpad-qa-deployment] placementrule.apps.open-cluster-management.io/qa-cluster unchanged 91 | [etherpad-qa-deployment : etherpad-qa-deployment] **** QA ENVIRONMENT: Creating subscription on RH ACM **** 92 | [etherpad-qa-deployment : etherpad-qa-deployment] subscription.apps.open-cluster-management.io/etherpad-acm-qa unchanged 93 | 94 | [etherpad-prd-deployment : etherpad-qa-deployment] **** PRD ENVIRONMENT: Creating application on RH ACM **** 95 | [etherpad-prd-deployment : etherpad-qa-deployment] application.app.k8s.io/etherpad-acm-prd unchanged 96 | [etherpad-prd-deployment : etherpad-qa-deployment] **** PRD ENVIRONMENT: Creating channel on RH ACM **** 97 | [etherpad-prd-deployment : etherpad-qa-deployment] channel.apps.open-cluster-management.io/etherpad-app-latest unchanged 98 | [etherpad-prd-deployment : etherpad-qa-deployment] **** PRD ENVIRONMENT: Creating placementrule on RH ACM **** 99 | [etherpad-prd-deployment : etherpad-qa-deployment] placementrule.apps.open-cluster-management.io/prd-cluster unchanged 100 | [etherpad-prd-deployment : etherpad-qa-deployment] **** PRD ENVIRONMENT: Creating subscription on RH ACM **** 101 | [etherpad-prd-deployment : etherpad-qa-deployment] subscription.apps.open-cluster-management.io/etherpad-acm-prd unchanged 102 | 103 | ``` 104 | 105 | -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/tekton/pipeline-acm.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: tekton.dev/v1beta1 4 | kind: Pipeline 5 | metadata: 6 | name: deploy-using-acm 7 | spec: 8 | workspaces: 9 | - name: shared-workspace 10 | params: 11 | - name: deployment-name 12 | type: string 13 | description: name of the deployment to be patched 14 | - name: git-url 15 | type: string 16 | description: url of the git repo for the code of deployment 17 | default: "https://github.com/giofontana/rhacm-pipelines.git" 18 | - name: git-revision 19 | type: string 20 | description: revision to be used from repo of the code for deployment 21 | default: "master" 22 | tasks: 23 | - name: fetch-repository 24 | taskRef: 25 | name: git-clone 26 | kind: ClusterTask 27 | workspaces: 28 | - name: output 29 | workspace: shared-workspace 30 | params: 31 | - name: url 32 | value: $(params.git-url) 33 | - name: subdirectory 34 | value: "" 35 | - name: deleteExisting 36 | value: "true" 37 | - name: revision 38 | value: $(params.git-revision) 39 | 40 | - name: create-namespaces 41 | taskRef: 42 | kind: Task 43 | name: create-namespaces 44 | workspaces: 45 | - name: source 46 | workspace: shared-workspace 47 | runAfter: 48 | - fetch-repository 49 | 50 | - name: etherpad-dev-deployment 51 | taskRef: 52 | kind: Task 53 | name: etherpad-dev-deployment 54 | workspaces: 55 | - name: source 56 | workspace: shared-workspace 57 | runAfter: 58 | - create-namespaces 59 | 60 | - name: etherpad-qa-deployment 61 | taskRef: 62 | kind: Task 63 | name: etherpad-qa-deployment 64 | workspaces: 65 | - name: source 66 | workspace: shared-workspace 67 | runAfter: 68 | - etherpad-dev-deployment 69 | 70 | - name: etherpad-prd-deployment 71 | taskRef: 72 | kind: Task 73 | name: etherpad-prd-deployment 74 | workspaces: 75 | - name: source 76 | workspace: shared-workspace 77 | runAfter: 78 | - etherpad-qa-deployment -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/tekton/pipelinerun.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: tekton.dev/v1beta1 4 | kind: PipelineRun 5 | metadata: 6 | name: deploy-using-acm-run-1 7 | namespace: etherpad-cicd 8 | labels: 9 | tekton.dev/pipeline: deploy-using-acm 10 | spec: 11 | params: 12 | - name: deployment-name 13 | value: teste-1 14 | - name: git-url 15 | value: 'https://github.com/giofontana/rhacm-pipelines.git' 16 | - name: git-revision 17 | value: master 18 | pipelineRef: 19 | name: deploy-using-acm 20 | serviceAccountName: pipeline 21 | timeout: 1h0m0s 22 | workspaces: 23 | - name: shared-workspace 24 | persistentvolumeclaim: 25 | claimName: source-pvc 26 | -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/tekton/prepare/tekton-source-pvc.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: v1 4 | kind: PersistentVolumeClaim 5 | metadata: 6 | name: source-pvc 7 | spec: 8 | accessModes: 9 | - ReadWriteOnce 10 | resources: 11 | requests: 12 | storage: 500Mi -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/tekton/tasks/01_create_namespaces.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: tekton.dev/v1beta1 4 | kind: Task 5 | metadata: 6 | name: create-namespaces 7 | spec: 8 | workspaces: 9 | - name: source 10 | steps: 11 | - name: creating-namespaces 12 | image: quay.io/openshift/origin-cli:latest 13 | workingDir: /workspace/source 14 | command: ["/bin/bash", "-c"] 15 | args: 16 | - |- 17 | echo "**** Creating namespaces ****" 18 | oc apply -f "multipleclusters-multiple-envs/rhacm/namespaces.yaml" -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/tekton/tasks/02_create_dev_app_using_acm.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: tekton.dev/v1beta1 4 | kind: Task 5 | metadata: 6 | name: etherpad-dev-deployment 7 | spec: 8 | workspaces: 9 | - name: source 10 | steps: 11 | - name: etherpad-dev-deployment 12 | image: quay.io/openshift/origin-cli:latest 13 | workingDir: /workspace/source 14 | command: ["/bin/bash", "-c"] 15 | args: 16 | - |- 17 | echo "**** DEV ENVIRONMENT: Creating application on RH ACM ****" 18 | oc apply -f multipleclusters-multiple-envs/rhacm/dev/application.yaml 19 | 20 | echo "**** DEV ENVIRONMENT: Creating channel on RH ACM ****" 21 | oc apply -f multipleclusters-multiple-envs/rhacm/dev/channel.yaml 22 | 23 | echo "**** DEV ENVIRONMENT: Creating placementrule on RH ACM ****" 24 | oc apply -f multipleclusters-multiple-envs/rhacm/dev/placement-rule.yaml 25 | 26 | echo "**** DEV ENVIRONMENT: Creating subscription on RH ACM ****" 27 | oc apply -f multipleclusters-multiple-envs/rhacm/dev/subscription.yaml -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/tekton/tasks/03_create_qa_app_using_acm.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: tekton.dev/v1beta1 4 | kind: Task 5 | metadata: 6 | name: etherpad-qa-deployment 7 | spec: 8 | workspaces: 9 | - name: source 10 | steps: 11 | - name: etherpad-qa-deployment 12 | image: quay.io/openshift/origin-cli:latest 13 | workingDir: /workspace/source 14 | command: ["/bin/bash", "-c"] 15 | args: 16 | - |- 17 | echo "**** QA ENVIRONMENT: Creating application on RH ACM ****" 18 | oc apply -f multipleclusters-multiple-envs/rhacm/qa/application.yaml 19 | 20 | echo "**** QA ENVIRONMENT: Creating channel on RH ACM ****" 21 | oc apply -f multipleclusters-multiple-envs/rhacm/qa/channel.yaml 22 | 23 | echo "**** QA ENVIRONMENT: Creating placementrule on RH ACM ****" 24 | oc apply -f multipleclusters-multiple-envs/rhacm/qa/placement-rule.yaml 25 | 26 | echo "**** QA ENVIRONMENT: Creating subscription on RH ACM ****" 27 | oc apply -f multipleclusters-multiple-envs/rhacm/qa/subscription.yaml -------------------------------------------------------------------------------- /multipleclusters-multiple-envs/tekton/tasks/04_create_prd_app_using_acm.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: tekton.dev/v1beta1 4 | kind: Task 5 | metadata: 6 | name: etherpad-prd-deployment 7 | spec: 8 | workspaces: 9 | - name: source 10 | steps: 11 | - name: etherpad-prd-deployment 12 | image: quay.io/openshift/origin-cli:latest 13 | workingDir: /workspace/source 14 | command: ["/bin/bash", "-c"] 15 | args: 16 | - |- 17 | echo "**** PRD ENVIRONMENT: Creating application on RH ACM ****" 18 | oc apply -f multipleclusters-multiple-envs/rhacm/prd/application.yaml 19 | 20 | echo "**** PRD ENVIRONMENT: Creating channel on RH ACM ****" 21 | oc apply -f multipleclusters-multiple-envs/rhacm/prd/channel.yaml 22 | 23 | echo "**** PRD ENVIRONMENT: Creating placementrule on RH ACM ****" 24 | oc apply -f multipleclusters-multiple-envs/rhacm/prd/placement-rule.yaml 25 | 26 | echo "**** PRD ENVIRONMENT: Creating subscription on RH ACM ****" 27 | oc apply -f multipleclusters-multiple-envs/rhacm/prd/subscription.yaml -------------------------------------------------------------------------------- /onecluster-multiple-envs/README.md: -------------------------------------------------------------------------------- 1 |
2 | Automation 4 |
5 | 6 | # GitOps using Red Hat OpenShift Pipelines (Tekton) and Red Hat Advanced Cluster Management 7 | #### August 28th, 2020 | by Giovanni Fontana 8 | 9 | Recently, Red Hat launched the Advanced Cluster Management tool, which aims to help organizations overcome the challenges of having applications deployed in multiple clusters and clouds. Red Hat is also actively collaborating with the Tekton project as the solution that will enable teams to build Kubernetes-style delivery pipelines that can fully control and own the complete lifecycle of their microservices without having to rely on central teams to maintain and manage a CI server, plugins, and its configurations. 10 | 11 | In this article, we will use both worlds together to build a CI/CD pipeline which will deploy an application in multiple environments and multiple clusters. If this is the first time you see RH ACM, I recommend you start by reading [this article](https://www.openshift.com/blog/understanding-gitops-with-red-hat-advanced-cluster-management). 12 | 13 | Use Cases: 14 | 15 | In general, each organization defines its application lifecycle strategy differently based on its own business requirements. Having that in mind, I will try to reproduce some general use cases, from simpler ones to more complex use cases. 16 | 17 | 1. **One single cluster**: multiple environments using different namespaces. 18 | 2. **Two clusters**: one for non-production workloads and another one for production. 19 | 3. **Three or more clusters**: one for non-production workloads and two or more clusters for production workloads (e.g.: Production and DR cluster). 20 | 21 | Also, we will simulate first a simpler scenario where we will focus only on the deployment of an image (essentially the CD stage) and finally a more complete pipeline including the building phase (entire CI/CD workflow). 22 | 23 | In this article, I am going to show only the first use case. Use cases 2 and 3 will be covered in the next posts. 24 | 25 | ## Preparation: 26 | 27 | I will not cover the installation of RH ACM and OpenShift Pipelines. The deployment is very straightforward using Operators and you can find the instructions in the official documentation: 28 | 29 | * [Installing OpenShift Pipelines | Pipelines | OpenShift Container Platform 4.5](https://docs.openshift.com/container-platform/4.5/pipelines/installing-pipelines.html) 30 | * [Install Red Hat Advanced Cluster Management for Kubernetes 2.0](https://access.redhat.com/documentation/en-us/red_hat_advanced_cluster_management_for_kubernetes/2.0/html/install/index) 31 | 32 | Both tools have been installed in a dedicated OpenShift cluster, which RH ACM names as “hub cluster”. Also, the managed-cluster has been imported in RH ACM with name “prd”: 33 | 34 | ![Managed Cluster on RH ACM](images/image4.png) 35 | 36 | ## GitOps in a single OpenShift cluster using Red Hat OpenShift Pipelines (Tekton) and Red Hat Advanced Cluster Management 37 | 38 | In this use case, I will be using the etherpad, a sample application from [rhacm-labs](https://github.com/redhat-gpte-devopsautomation/rhacm-labs). 39 | 40 | ### Resources: 41 | 42 | Basically we have three types of resources we will need to handle: 43 | 44 | 1. **Application resources**: YAML files that describe the k8s application, such as the application deployment, route, services, and so on. 45 | 46 | ![Application resources](images/image1.png) 47 | 48 | 2. **RH ACM resources**: Files that will create the objects that RH ACM uses to manage an application. The following objects will be used: 49 | 50 | * **Channels** (channel.apps.open-cluster-management.io): define the source repositories that a cluster can subscribe to with a subscription, and can be the following types: GitHub repositories, Helm release registries, object stores, and resource template (deployable) namespaces on the hub cluster. In our case, we are using a GitHub channel. 51 | * **Subscriptions** (subscription.apps.open-cluster-management.io): allow clusters to subscribe to a source repository (channel). Subscriptions can be applied locally to the hub or to managed-clusters. 52 | * **Placement rules** (placementrule.apps.open-cluster-management.io): define the target clusters where subscriptions deploy and maintain the Kubernetes resources. You can use placement rules to help you facilitate the multi-cluster deployment. Placement rules can be shared across subscriptions. 53 | * **Applications** (application.app.k8s.io): Used in Red Hat Advanced Cluster Management for Kubernetes for grouping Kubernetes resources that make up an application. 54 | 55 | ![RH ACM resources](images/image3.png) 56 | 57 | 3. **Tekton resources**: Files that will create the tasks and pipeline to deploy the application using RH ACM in three different stages: Development, QA, and Production. 58 | 59 | ![Tekton resources](images/image5.png) 60 | 61 | All source code used in this demo is in this git repository: https://github.com/giofontana/rhacm-pipelines/tree/master/onecluster-multiple-envs 62 | 63 | ### Deploying an application using RH ACM 64 | 65 | To begin our process let’s look first on how to deploy the sample application using RH ACM. The first thing we will need to do is to create namespaces on the hub cluster that will manage the application. 66 | 67 | ```yaml 68 | --- 69 | apiVersion: v1 70 | kind: Namespace 71 | metadata: 72 | name: etherpad-acm-dev 73 | --- 74 | apiVersion: v1 75 | kind: Namespace 76 | metadata: 77 | name: etherpad-acm-qa 78 | --- 79 | apiVersion: v1 80 | kind: Namespace 81 | metadata: 82 | name: etherpad-acm-prd 83 | ``` 84 | 85 | We are creating a project for each stage of our application lifecycle (DEV/QA/PRD). This is a sample, in a real-world scenario probably you should use some annotations and labels in your namespaces also. 86 | 87 | We also will have an application, channel, placement-rule, and subscription YAML file for each stage: 88 | 89 | Example for **dev**: 90 | 91 | ```yaml 92 | --- 93 | apiVersion: app.k8s.io/v1beta1 94 | kind: Application 95 | metadata: 96 | name: etherpad-acm-dev 97 | namespace: etherpad-acm-dev 98 | spec: 99 | componentKinds: 100 | - group: apps.open-cluster-management.io 101 | kind: Subscription 102 | descriptor: {} 103 | selector: 104 | matchExpressions: 105 | - key: app 106 | operator: In 107 | values: 108 | - etherpad-acm-dev 109 | --- 110 | apiVersion: apps.open-cluster-management.io/v1 111 | kind: Channel 112 | metadata: 113 | name: etherpad-app-latest 114 | namespace: etherpad-acm-dev 115 | spec: 116 | type: GitHub 117 | pathname: https://github.com/giofontana/rhacm-pipelines.git 118 | --- 119 | apiVersion: apps.open-cluster-management.io/v1 120 | kind: PlacementRule 121 | metadata: 122 | name: dev-cluster 123 | namespace: etherpad-acm-dev 124 | spec: 125 | clusterConditions: 126 | - type: ManagedClusterConditionAvailable 127 | status: "True" 128 | clusterSelector: 129 | matchLabels: 130 | environment: prd 131 | --- 132 | apiVersion: apps.open-cluster-management.io/v1 133 | kind: Subscription 134 | metadata: 135 | name: etherpad-acm-dev 136 | namespace: etherpad-acm-dev 137 | labels: 138 | app: etherpad-acm-dev 139 | annotations: 140 | apps.open-cluster-management.io/github-path: onecluster-multiple-envs/app-resources/etherpad/dev 141 | spec: 142 | channel: etherpad-acm-dev/etherpad-app-latest 143 | placement: 144 | placementRef: 145 | kind: PlacementRule 146 | name: dev-cluster 147 | ``` 148 | 149 | **Note**: You will notice that the clusterSelector for all stages are equal, this is because for while we are using one single managed-cluster. You can switch it according to as many clusters as you need. 150 | 151 | This is the folder structure we will have in the end: 152 | 153 | ```console 154 | onecluster-multiple-envs/rhacm 155 | ├── namespaces.yaml 156 | ├── dev 157 | │ ├── application.yaml 158 | │ ├── channel.yaml 159 | │ ├── placement-rule.yaml 160 | │ └── subscription.yaml 161 | ├── prd 162 | │ ├── application.yaml 163 | │ ├── channel.yaml 164 | │ ├── placement-rule.yaml 165 | │ └── subscription.yaml 166 | └── qa 167 | ├── application.yaml 168 | ├── channel.yaml 169 | ├── placement-rule.yaml 170 | └── subscription.yaml 171 | ``` 172 | 173 | Now, let’s test it? To deploy this structure you just need to run each YAML file against the RH ACM hub cluster. 174 | 175 | ![App deployment using RH ACM](images/RH-ACM-1.gif) 176 | 177 | On the right side, you will see the managed cluster. Note that as soon as the subscription is created on the hub cluster, the deployment starts on the managed cluster - first DEV, then QA, and finally PRD. 178 | 179 | ### Creating a pipeline using RH ACM resources 180 | 181 | Now that we already have our 3 projects for each stage (DEV/QA/PRD) being deployed and managed using RH ACM, we will create a pipeline to create the RH ACM resources automatically using Tekton. 182 | 183 | To do that we have the following tasks in Tekton: 184 | 185 | * create_namespaces: Create the namespaces needed in the hub cluster. 186 | * etherpad-dev-deployment: Deployment of DEV stage of etherpad. 187 | * etherpad-qa-deployment: Deployment of QA stage of etherpad. 188 | * etherpad-prd-deployment: Deployment of PRD stage of etherpad. 189 | 190 | Also, we created a pipeline with the following structure: 191 | 192 | ```yaml 193 | apiVersion: tekton.dev/v1beta1 194 | kind: Pipeline 195 | metadata: 196 | name: deploy-using-acm 197 | spec: 198 | workspaces: 199 | - name: shared-workspace 200 | params: 201 | - name: deployment-name 202 | type: string 203 | description: name of the deployment to be patched 204 | - name: git-url 205 | type: string 206 | description: url of the git repo for the code of deployment 207 | default: "https://github.com/giofontana/rhacm-pipelines.git" 208 | - name: git-revision 209 | type: string 210 | description: revision to be used from repo of the code for deployment 211 | default: "master" 212 | tasks: 213 | - name: fetch-repository 214 | taskRef: 215 | name: git-clone 216 | kind: ClusterTask 217 | workspaces: 218 | - name: output 219 | workspace: shared-workspace 220 | params: 221 | - name: url 222 | value: $(params.git-url) 223 | - name: subdirectory 224 | value: "" 225 | - name: deleteExisting 226 | value: "true" 227 | - name: revision 228 | value: $(params.git-revision) 229 | 230 | - name: create-namespaces 231 | taskRef: 232 | kind: Task 233 | name: create-namespaces 234 | workspaces: 235 | - name: source 236 | workspace: shared-workspace 237 | runAfter: 238 | - fetch-repository 239 | 240 | - name: etherpad-dev-deployment 241 | taskRef: 242 | kind: Task 243 | name: etherpad-dev-deployment 244 | workspaces: 245 | - name: source 246 | workspace: shared-workspace 247 | runAfter: 248 | - create-namespaces 249 | 250 | - name: etherpad-qa-deployment 251 | taskRef: 252 | kind: Task 253 | name: etherpad-qa-deployment 254 | workspaces: 255 | - name: source 256 | workspace: shared-workspace 257 | runAfter: 258 | - etherpad-dev-deployment 259 | 260 | - name: etherpad-prd-deployment 261 | taskRef: 262 | kind: Task 263 | name: etherpad-prd-deployment 264 | workspaces: 265 | - name: source 266 | workspace: shared-workspace 267 | runAfter: 268 | - etherpad-qa-deployment 269 | ``` 270 | 271 | We can now deploy the Tekton objects: 272 | 273 | ```console 274 | > oc new-project etherpad-cicd 275 | 276 | Now using project "etherpad-cicd" on server "https://api.acmhub.rhbr-labs.com:6443". 277 | 278 | You can add applications to this project with the 'new-app' command. For example, try: 279 | 280 | oc new-app ruby~https://github.com/sclorg/ruby-ex.git 281 | 282 | to build a new example application in Python. Or use kubectl to deploy a simple Kubernetes application: 283 | 284 | kubectl create deployment hello-node --image=gcr.io/hello-minikube-zero-install/hello-node 285 | 286 | > oc get serviceaccount pipeline 287 | NAME SECRETS AGE 288 | pipeline 2 29s 289 | 290 | > cd onecluster-multiple-envs/tekton 291 | 292 | > oc create -f tasks/01_create_namespaces.yaml 293 | task.tekton.dev/create-namespaces created 294 | 295 | > oc create -f tasks/02_create_dev_app_using_acm.yaml 296 | task.tekton.dev/etherpad-dev-deployment created 297 | 298 | > oc apply -f tasks/03_create_qa_app_using_acm.yaml 299 | task.tekton.dev/etherpad-qa-deployment created 300 | 301 | > oc apply -f tasks/04_create_prd_app_using_acm.yaml 302 | task.tekton.dev/etherpad-prd-deployment created 303 | 304 | > oc adm policy add-cluster-role-to-user cluster-admin system:serviceaccount:etherpad-cicd:pipeline 305 | clusterrole.rbac.authorization.k8s.io/cluster-admin added: "system:serviceaccount:etherpad-cicd:pipeline" 306 | 307 | > oc apply -f pipeline-acm.yaml 308 | pipeline.tekton.dev/deploy-using-acm created 309 | 310 | > oc apply -f prepare/tekton-source-pvc.yaml 311 | persistentvolumeclaim/source-pvc created 312 | ``` 313 | 314 | And run our pipeline: 315 | 316 | ```console 317 | > oc apply -f pipelinerun.yaml 318 | pipelinerun.tekton.dev/deploy-using-acm-run-1 created 319 | 320 | > tkn pipelinerun logs deploy-using-acm-run-1 -f 321 | [fetch-repository : clone] + CHECKOUT_DIR=/workspace/output/ 322 | [fetch-repository : clone] + '[[' true '==' true ]] 323 | [fetch-repository : clone] + cleandir 324 | [fetch-repository : clone] + '[[' -d /workspace/output/ ]] 325 | [fetch-repository : clone] + rm -rf /workspace/output//onecluster-multiple-envs 326 | [fetch-repository : clone] + rm -rf /workspace/output//.git 327 | [fetch-repository : clone] + rm -rf '/workspace/output//..?*' 328 | [fetch-repository : clone] + test -z 329 | [fetch-repository : clone] + test -z 330 | [fetch-repository : clone] + test -z 331 | [fetch-repository : clone] + /ko-app/git-init -url https://github.com/giofontana/rhacm-pipelines.git -revision master -refspec -path /workspace/output/ '-sslVerify=true' '-submodules=true' -depth 1 332 | [fetch-repository : clone] {"level":"info","ts":1597794549.2025642,"caller":"git/git.go:136","msg":"Successfully cloned https://github.com/giofontana/rhacm-pipelines.git @ f111d89c17e5647d3cd4dedca6968f20b73cfb0d (grafted, HEAD, origin/master) in path /workspace/output/"} 333 | [fetch-repository : clone] {"level":"info","ts":1597794549.240191,"caller":"git/git.go:177","msg":"Successfully initialized and updated submodules in path /workspace/output/"} 334 | [fetch-repository : clone] + cd /workspace/output/ 335 | [fetch-repository : clone] + git rev-parse HEAD 336 | [fetch-repository : clone] + tr -d '\n' 337 | [fetch-repository : clone] + RESULT_SHA=f111d89c17e5647d3cd4dedca6968f20b73cfb0d 338 | [fetch-repository : clone] + EXIT_CODE=0 339 | [fetch-repository : clone] + '[' 0 '!=' 0 ] 340 | [fetch-repository : clone] + echo -n f111d89c17e5647d3cd4dedca6968f20b73cfb0d 341 | 342 | [create-namespaces : creating-namespaces] **** Creating namespaces **** 343 | [create-namespaces : creating-namespaces] namespace/etherpad-acm-dev unchanged 344 | [create-namespaces : creating-namespaces] namespace/etherpad-acm-qa unchanged 345 | [create-namespaces : creating-namespaces] namespace/etherpad-acm-prd unchanged 346 | 347 | [etherpad-dev-deployment : etherpad-dev-deployment] **** DEV ENVIRONMENT: Creating application on RH ACM **** 348 | [etherpad-dev-deployment : etherpad-dev-deployment] application.app.k8s.io/etherpad-acm-dev unchanged 349 | [etherpad-dev-deployment : etherpad-dev-deployment] **** DEV ENVIRONMENT: Creating channel on RH ACM **** 350 | [etherpad-dev-deployment : etherpad-dev-deployment] channel.apps.open-cluster-management.io/etherpad-app-latest unchanged 351 | [etherpad-dev-deployment : etherpad-dev-deployment] **** DEV ENVIRONMENT: Creating placementrule on RH ACM **** 352 | [etherpad-dev-deployment : etherpad-dev-deployment] placementrule.apps.open-cluster-management.io/dev-cluster unchanged 353 | [etherpad-dev-deployment : etherpad-dev-deployment] **** DEV ENVIRONMENT: Creating subscription on RH ACM **** 354 | [etherpad-dev-deployment : etherpad-dev-deployment] subscription.apps.open-cluster-management.io/etherpad-acm-dev unchanged 355 | 356 | [etherpad-qa-deployment : etherpad-qa-deployment] **** QA ENVIRONMENT: Creating application on RH ACM **** 357 | [etherpad-qa-deployment : etherpad-qa-deployment] application.app.k8s.io/etherpad-acm-qa unchanged 358 | [etherpad-qa-deployment : etherpad-qa-deployment] **** QA ENVIRONMENT: Creating channel on RH ACM **** 359 | [etherpad-qa-deployment : etherpad-qa-deployment] channel.apps.open-cluster-management.io/etherpad-app-latest unchanged 360 | [etherpad-qa-deployment : etherpad-qa-deployment] **** QA ENVIRONMENT: Creating placementrule on RH ACM **** 361 | [etherpad-qa-deployment : etherpad-qa-deployment] placementrule.apps.open-cluster-management.io/qa-cluster unchanged 362 | [etherpad-qa-deployment : etherpad-qa-deployment] **** QA ENVIRONMENT: Creating subscription on RH ACM **** 363 | [etherpad-qa-deployment : etherpad-qa-deployment] subscription.apps.open-cluster-management.io/etherpad-acm-qa unchanged 364 | 365 | [etherpad-prd-deployment : etherpad-qa-deployment] **** PRD ENVIRONMENT: Creating application on RH ACM **** 366 | [etherpad-prd-deployment : etherpad-qa-deployment] application.app.k8s.io/etherpad-acm-prd unchanged 367 | [etherpad-prd-deployment : etherpad-qa-deployment] **** PRD ENVIRONMENT: Creating channel on RH ACM **** 368 | [etherpad-prd-deployment : etherpad-qa-deployment] channel.apps.open-cluster-management.io/etherpad-app-latest unchanged 369 | [etherpad-prd-deployment : etherpad-qa-deployment] **** PRD ENVIRONMENT: Creating placementrule on RH ACM **** 370 | [etherpad-prd-deployment : etherpad-qa-deployment] placementrule.apps.open-cluster-management.io/prd-cluster unchanged 371 | [etherpad-prd-deployment : etherpad-qa-deployment] **** PRD ENVIRONMENT: Creating subscription on RH ACM **** 372 | [etherpad-prd-deployment : etherpad-qa-deployment] subscription.apps.open-cluster-management.io/etherpad-acm-prd unchanged 373 | ``` 374 | 375 | Note that the tasks have “unchanged” results because we already have our application deployed. 376 | 377 | Here is how we see this pipeline in the web console: 378 | 379 | ![Tekton on OCP Web Console](images/image2.png) 380 | 381 | ### Conclusion 382 | 383 | In this article, we saw how to create three applications on RH ACM in your hub cluster to deploy a sample application for each stage of its lifecycle: Development, QA, and production. We also learned how to create a pipeline using Tekton to make those deployments automatically. 384 | 385 | In the next article we are going to explore how to have a similar case, but deploying the application in more than one cluster (use cases 2 and 3). In a final article, I am planning to share an entire CI/CD pipeline, including the build phase that we are not mentioning yet. 386 | 387 | I encourage you to try out Red Hat Advanced Cluster Management for Kubernetes if you are looking for a solution for multi-cluster, see [here](https://www.redhat.com/en/technologies/management/advanced-cluster-management) how to try it. Combining it with Red Hat OpenShift Pipelines (Tekton) will give you a powerful native Kubernetes solution for GitOps, you can find more information about it in the [OpenShift documentation page](https://docs.openshift.com/container-platform/4.5/pipelines/understanding-openshift-pipelines.html). 388 | -------------------------------------------------------------------------------- /onecluster-multiple-envs/images/RH-ACM-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giofontana/rhacm-pipelines/d280069c45f2061b333228265518244247e0c653/onecluster-multiple-envs/images/RH-ACM-1.gif -------------------------------------------------------------------------------- /onecluster-multiple-envs/images/image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giofontana/rhacm-pipelines/d280069c45f2061b333228265518244247e0c653/onecluster-multiple-envs/images/image1.png -------------------------------------------------------------------------------- /onecluster-multiple-envs/images/image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giofontana/rhacm-pipelines/d280069c45f2061b333228265518244247e0c653/onecluster-multiple-envs/images/image2.png -------------------------------------------------------------------------------- /onecluster-multiple-envs/images/image3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giofontana/rhacm-pipelines/d280069c45f2061b333228265518244247e0c653/onecluster-multiple-envs/images/image3.png -------------------------------------------------------------------------------- /onecluster-multiple-envs/images/image4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giofontana/rhacm-pipelines/d280069c45f2061b333228265518244247e0c653/onecluster-multiple-envs/images/image4.png -------------------------------------------------------------------------------- /onecluster-multiple-envs/images/image5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giofontana/rhacm-pipelines/d280069c45f2061b333228265518244247e0c653/onecluster-multiple-envs/images/image5.png -------------------------------------------------------------------------------- /onecluster-multiple-envs/images/image6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giofontana/rhacm-pipelines/d280069c45f2061b333228265518244247e0c653/onecluster-multiple-envs/images/image6.jpg -------------------------------------------------------------------------------- /onecluster-multiple-envs/rhacm/dev/application.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: app.k8s.io/v1beta1 4 | kind: Application 5 | metadata: 6 | name: etherpad-acm-dev 7 | namespace: etherpad-acm-dev 8 | spec: 9 | componentKinds: 10 | - group: apps.open-cluster-management.io 11 | kind: Subscription 12 | descriptor: {} 13 | selector: 14 | matchExpressions: 15 | - key: app 16 | operator: In 17 | values: 18 | - etherpad-acm-dev -------------------------------------------------------------------------------- /onecluster-multiple-envs/rhacm/dev/channel.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apps.open-cluster-management.io/v1 4 | kind: Channel 5 | metadata: 6 | name: etherpad-app-latest 7 | namespace: etherpad-acm-dev 8 | spec: 9 | type: GitHub 10 | pathname: https://github.com/giofontana/rhacm-pipelines.git -------------------------------------------------------------------------------- /onecluster-multiple-envs/rhacm/dev/placement-rule.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apps.open-cluster-management.io/v1 4 | kind: PlacementRule 5 | metadata: 6 | name: dev-cluster 7 | namespace: etherpad-acm-dev 8 | spec: 9 | clusterConditions: 10 | - type: ManagedClusterConditionAvailable 11 | status: "True" 12 | clusterSelector: 13 | matchLabels: 14 | environment: prd -------------------------------------------------------------------------------- /onecluster-multiple-envs/rhacm/dev/subscription.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apps.open-cluster-management.io/v1 4 | kind: Subscription 5 | metadata: 6 | name: etherpad-acm-dev 7 | namespace: etherpad-acm-dev 8 | labels: 9 | app: etherpad-acm-dev 10 | annotations: 11 | apps.open-cluster-management.io/github-path: app-resources/etherpad/dev 12 | spec: 13 | channel: etherpad-acm-dev/etherpad-app-latest 14 | placement: 15 | placementRef: 16 | kind: PlacementRule 17 | name: dev-cluster 18 | 19 | -------------------------------------------------------------------------------- /onecluster-multiple-envs/rhacm/namespaces.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: etherpad-acm-dev 6 | --- 7 | apiVersion: v1 8 | kind: Namespace 9 | metadata: 10 | name: etherpad-acm-qa 11 | --- 12 | apiVersion: v1 13 | kind: Namespace 14 | metadata: 15 | name: etherpad-acm-prd -------------------------------------------------------------------------------- /onecluster-multiple-envs/rhacm/prd/application.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: app.k8s.io/v1beta1 4 | kind: Application 5 | metadata: 6 | name: etherpad-acm-prd 7 | namespace: etherpad-acm-prd 8 | spec: 9 | componentKinds: 10 | - group: apps.open-cluster-management.io 11 | kind: Subscription 12 | descriptor: {} 13 | selector: 14 | matchExpressions: 15 | - key: app 16 | operator: In 17 | values: 18 | - etherpad-acm-prd -------------------------------------------------------------------------------- /onecluster-multiple-envs/rhacm/prd/channel.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apps.open-cluster-management.io/v1 4 | kind: Channel 5 | metadata: 6 | name: etherpad-app-latest 7 | namespace: etherpad-acm-prd 8 | spec: 9 | type: GitHub 10 | pathname: https://github.com/giofontana/rhacm-pipelines.git -------------------------------------------------------------------------------- /onecluster-multiple-envs/rhacm/prd/placement-rule.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apps.open-cluster-management.io/v1 4 | kind: PlacementRule 5 | metadata: 6 | name: prd-cluster 7 | namespace: etherpad-acm-prd 8 | spec: 9 | clusterConditions: 10 | - type: ManagedClusterConditionAvailable 11 | status: "True" 12 | clusterSelector: 13 | matchLabels: 14 | environment: prd -------------------------------------------------------------------------------- /onecluster-multiple-envs/rhacm/prd/subscription.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apps.open-cluster-management.io/v1 4 | kind: Subscription 5 | metadata: 6 | name: etherpad-acm-prd 7 | namespace: etherpad-acm-prd 8 | labels: 9 | app: etherpad-acm-prd 10 | annotations: 11 | apps.open-cluster-management.io/github-path: app-resources/etherpad/prd 12 | spec: 13 | channel: etherpad-acm-prd/etherpad-app-latest 14 | placement: 15 | placementRef: 16 | kind: PlacementRule 17 | name: prd-cluster 18 | 19 | -------------------------------------------------------------------------------- /onecluster-multiple-envs/rhacm/qa/application.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: app.k8s.io/v1beta1 4 | kind: Application 5 | metadata: 6 | name: etherpad-acm-qa 7 | namespace: etherpad-acm-qa 8 | spec: 9 | componentKinds: 10 | - group: apps.open-cluster-management.io 11 | kind: Subscription 12 | descriptor: {} 13 | selector: 14 | matchExpressions: 15 | - key: app 16 | operator: In 17 | values: 18 | - etherpad-acm-qa -------------------------------------------------------------------------------- /onecluster-multiple-envs/rhacm/qa/channel.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apps.open-cluster-management.io/v1 4 | kind: Channel 5 | metadata: 6 | name: etherpad-app-latest 7 | namespace: etherpad-acm-qa 8 | spec: 9 | type: GitHub 10 | pathname: https://github.com/giofontana/rhacm-pipelines.git -------------------------------------------------------------------------------- /onecluster-multiple-envs/rhacm/qa/placement-rule.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apps.open-cluster-management.io/v1 4 | kind: PlacementRule 5 | metadata: 6 | name: qa-cluster 7 | namespace: etherpad-acm-qa 8 | spec: 9 | clusterConditions: 10 | - type: ManagedClusterConditionAvailable 11 | status: "True" 12 | clusterSelector: 13 | matchLabels: 14 | environment: prd -------------------------------------------------------------------------------- /onecluster-multiple-envs/rhacm/qa/subscription.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apps.open-cluster-management.io/v1 4 | kind: Subscription 5 | metadata: 6 | name: etherpad-acm-qa 7 | namespace: etherpad-acm-qa 8 | labels: 9 | app: etherpad-acm-qa 10 | annotations: 11 | apps.open-cluster-management.io/github-path: app-resources/etherpad/qa 12 | spec: 13 | channel: etherpad-acm-qa/etherpad-app-latest 14 | placement: 15 | placementRef: 16 | kind: PlacementRule 17 | name: qa-cluster 18 | 19 | -------------------------------------------------------------------------------- /onecluster-multiple-envs/tekton/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Create CD workflow on RH ACM using Tekton 3 | 4 | Procedure: 5 | 6 | ```console 7 | > oc new-project etherpad-cicd 8 | 9 | Now using project "etherpad-cicd" on server "https://api.acmhub.rhbr-labs.com:6443". 10 | 11 | You can add applications to this project with the 'new-app' command. For example, try: 12 | 13 | oc new-app ruby~https://github.com/sclorg/ruby-ex.git 14 | 15 | to build a new example application in Python. Or use kubectl to deploy a simple Kubernetes application: 16 | 17 | kubectl create deployment hello-node --image=gcr.io/hello-minikube-zero-install/hello-node 18 | 19 | > oc get serviceaccount pipeline 20 | NAME SECRETS AGE 21 | pipeline 2 29s 22 | 23 | > cd onecluster-multiple-envs/tekton 24 | 25 | > oc create -f tasks/01_create_namespaces.yaml 26 | task.tekton.dev/create-namespaces created 27 | 28 | > oc create -f tasks/02_create_dev_app_using_acm.yaml 29 | task.tekton.dev/etherpad-dev-deployment created 30 | 31 | > oc apply -f tasks/03_create_qa_app_using_acm.yaml 32 | task.tekton.dev/etherpad-qa-deployment created 33 | 34 | > oc apply -f tasks/04_create_prd_app_using_acm.yaml 35 | task.tekton.dev/etherpad-prd-deployment created 36 | 37 | > oc adm policy add-cluster-role-to-user cluster-admin system:serviceaccount:etherpad-cicd:pipeline 38 | clusterrole.rbac.authorization.k8s.io/cluster-admin added: "system:serviceaccount:etherpad-cicd:pipeline" 39 | 40 | > oc apply -f pipeline-acm.yaml 41 | pipeline.tekton.dev/deploy-using-acm created 42 | 43 | > oc apply -f prepare/tekton-source-pvc.yaml 44 | persistentvolumeclaim/source-pvc created 45 | 46 | > oc apply -f pipelinerun.yaml 47 | pipelinerun.tekton.dev/deploy-using-acm-run-1 created 48 | 49 | > tkn pipelinerun logs deploy-using-acm-run-1 -f 50 | [fetch-repository : clone] + CHECKOUT_DIR=/workspace/output/ 51 | [fetch-repository : clone] + '[[' true '==' true ]] 52 | [fetch-repository : clone] + cleandir 53 | [fetch-repository : clone] + '[[' -d /workspace/output/ ]] 54 | [fetch-repository : clone] + rm -rf /workspace/output//onecluster-multiple-envs 55 | [fetch-repository : clone] + rm -rf /workspace/output//.git 56 | [fetch-repository : clone] + rm -rf '/workspace/output//..?*' 57 | [fetch-repository : clone] + test -z 58 | [fetch-repository : clone] + test -z 59 | [fetch-repository : clone] + test -z 60 | [fetch-repository : clone] + /ko-app/git-init -url https://github.com/giofontana/rhacm-pipelines.git -revision master -refspec -path /workspace/output/ '-sslVerify=true' '-submodules=true' -depth 1 61 | [fetch-repository : clone] {"level":"info","ts":1597794549.2025642,"caller":"git/git.go:136","msg":"Successfully cloned https://github.com/giofontana/rhacm-pipelines.git @ f111d89c17e5647d3cd4dedca6968f20b73cfb0d (grafted, HEAD, origin/master) in path /workspace/output/"} 62 | [fetch-repository : clone] {"level":"info","ts":1597794549.240191,"caller":"git/git.go:177","msg":"Successfully initialized and updated submodules in path /workspace/output/"} 63 | [fetch-repository : clone] + cd /workspace/output/ 64 | [fetch-repository : clone] + git rev-parse HEAD 65 | [fetch-repository : clone] + tr -d '\n' 66 | [fetch-repository : clone] + RESULT_SHA=f111d89c17e5647d3cd4dedca6968f20b73cfb0d 67 | [fetch-repository : clone] + EXIT_CODE=0 68 | [fetch-repository : clone] + '[' 0 '!=' 0 ] 69 | [fetch-repository : clone] + echo -n f111d89c17e5647d3cd4dedca6968f20b73cfb0d 70 | 71 | [create-namespaces : creating-namespaces] **** Creating namespaces **** 72 | [create-namespaces : creating-namespaces] namespace/etherpad-acm-dev unchanged 73 | [create-namespaces : creating-namespaces] namespace/etherpad-acm-qa unchanged 74 | [create-namespaces : creating-namespaces] namespace/etherpad-acm-prd unchanged 75 | 76 | [etherpad-dev-deployment : etherpad-dev-deployment] **** DEV ENVIRONMENT: Creating application on RH ACM **** 77 | [etherpad-dev-deployment : etherpad-dev-deployment] application.app.k8s.io/etherpad-acm-dev unchanged 78 | [etherpad-dev-deployment : etherpad-dev-deployment] **** DEV ENVIRONMENT: Creating channel on RH ACM **** 79 | [etherpad-dev-deployment : etherpad-dev-deployment] channel.apps.open-cluster-management.io/etherpad-app-latest unchanged 80 | [etherpad-dev-deployment : etherpad-dev-deployment] **** DEV ENVIRONMENT: Creating placementrule on RH ACM **** 81 | [etherpad-dev-deployment : etherpad-dev-deployment] placementrule.apps.open-cluster-management.io/dev-cluster unchanged 82 | [etherpad-dev-deployment : etherpad-dev-deployment] **** DEV ENVIRONMENT: Creating subscription on RH ACM **** 83 | [etherpad-dev-deployment : etherpad-dev-deployment] subscription.apps.open-cluster-management.io/etherpad-acm-dev unchanged 84 | 85 | [etherpad-qa-deployment : etherpad-qa-deployment] **** QA ENVIRONMENT: Creating application on RH ACM **** 86 | [etherpad-qa-deployment : etherpad-qa-deployment] application.app.k8s.io/etherpad-acm-qa unchanged 87 | [etherpad-qa-deployment : etherpad-qa-deployment] **** QA ENVIRONMENT: Creating channel on RH ACM **** 88 | [etherpad-qa-deployment : etherpad-qa-deployment] channel.apps.open-cluster-management.io/etherpad-app-latest unchanged 89 | [etherpad-qa-deployment : etherpad-qa-deployment] **** QA ENVIRONMENT: Creating placementrule on RH ACM **** 90 | [etherpad-qa-deployment : etherpad-qa-deployment] placementrule.apps.open-cluster-management.io/qa-cluster unchanged 91 | [etherpad-qa-deployment : etherpad-qa-deployment] **** QA ENVIRONMENT: Creating subscription on RH ACM **** 92 | [etherpad-qa-deployment : etherpad-qa-deployment] subscription.apps.open-cluster-management.io/etherpad-acm-qa unchanged 93 | 94 | [etherpad-prd-deployment : etherpad-qa-deployment] **** PRD ENVIRONMENT: Creating application on RH ACM **** 95 | [etherpad-prd-deployment : etherpad-qa-deployment] application.app.k8s.io/etherpad-acm-prd unchanged 96 | [etherpad-prd-deployment : etherpad-qa-deployment] **** PRD ENVIRONMENT: Creating channel on RH ACM **** 97 | [etherpad-prd-deployment : etherpad-qa-deployment] channel.apps.open-cluster-management.io/etherpad-app-latest unchanged 98 | [etherpad-prd-deployment : etherpad-qa-deployment] **** PRD ENVIRONMENT: Creating placementrule on RH ACM **** 99 | [etherpad-prd-deployment : etherpad-qa-deployment] placementrule.apps.open-cluster-management.io/prd-cluster unchanged 100 | [etherpad-prd-deployment : etherpad-qa-deployment] **** PRD ENVIRONMENT: Creating subscription on RH ACM **** 101 | [etherpad-prd-deployment : etherpad-qa-deployment] subscription.apps.open-cluster-management.io/etherpad-acm-prd unchanged 102 | 103 | ``` 104 | 105 | -------------------------------------------------------------------------------- /onecluster-multiple-envs/tekton/pipeline-acm.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Pipeline 3 | metadata: 4 | name: deploy-using-acm 5 | spec: 6 | workspaces: 7 | - name: shared-workspace 8 | params: 9 | - name: deployment-name 10 | type: string 11 | description: name of the deployment to be patched 12 | - name: git-url 13 | type: string 14 | description: url of the git repo for the code of deployment 15 | default: "https://github.com/giofontana/rhacm-pipelines.git" 16 | - name: git-revision 17 | type: string 18 | description: revision to be used from repo of the code for deployment 19 | default: "master" 20 | tasks: 21 | - name: fetch-repository 22 | taskRef: 23 | name: git-clone 24 | kind: ClusterTask 25 | workspaces: 26 | - name: output 27 | workspace: shared-workspace 28 | params: 29 | - name: url 30 | value: $(params.git-url) 31 | - name: subdirectory 32 | value: "" 33 | - name: deleteExisting 34 | value: "true" 35 | - name: revision 36 | value: $(params.git-revision) 37 | 38 | - name: create-namespaces 39 | taskRef: 40 | kind: Task 41 | name: create-namespaces 42 | workspaces: 43 | - name: source 44 | workspace: shared-workspace 45 | runAfter: 46 | - fetch-repository 47 | 48 | - name: etherpad-dev-deployment 49 | taskRef: 50 | kind: Task 51 | name: etherpad-dev-deployment 52 | workspaces: 53 | - name: source 54 | workspace: shared-workspace 55 | runAfter: 56 | - create-namespaces 57 | 58 | - name: etherpad-qa-deployment 59 | taskRef: 60 | kind: Task 61 | name: etherpad-qa-deployment 62 | workspaces: 63 | - name: source 64 | workspace: shared-workspace 65 | runAfter: 66 | - etherpad-dev-deployment 67 | 68 | - name: etherpad-prd-deployment 69 | taskRef: 70 | kind: Task 71 | name: etherpad-prd-deployment 72 | workspaces: 73 | - name: source 74 | workspace: shared-workspace 75 | runAfter: 76 | - etherpad-qa-deployment -------------------------------------------------------------------------------- /onecluster-multiple-envs/tekton/pipelinerun.yaml: -------------------------------------------------------------------------------- 1 | 2 | apiVersion: tekton.dev/v1beta1 3 | kind: PipelineRun 4 | metadata: 5 | name: deploy-using-acm-run-1 6 | namespace: etherpad-cicd 7 | labels: 8 | tekton.dev/pipeline: deploy-using-acm 9 | spec: 10 | params: 11 | - name: deployment-name 12 | value: teste-1 13 | - name: git-url 14 | value: 'https://github.com/giofontana/rhacm-pipelines.git' 15 | - name: git-revision 16 | value: master 17 | pipelineRef: 18 | name: deploy-using-acm 19 | serviceAccountName: pipeline 20 | timeout: 1h0m0s 21 | workspaces: 22 | - name: shared-workspace 23 | persistentvolumeclaim: 24 | claimName: source-pvc 25 | -------------------------------------------------------------------------------- /onecluster-multiple-envs/tekton/prepare/tekton-source-pvc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: source-pvc 5 | spec: 6 | accessModes: 7 | - ReadWriteOnce 8 | resources: 9 | requests: 10 | storage: 500Mi -------------------------------------------------------------------------------- /onecluster-multiple-envs/tekton/tasks/01_create_namespaces.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | name: create-namespaces 5 | spec: 6 | workspaces: 7 | - name: source 8 | steps: 9 | - name: creating-namespaces 10 | image: quay.io/openshift/origin-cli:latest 11 | workingDir: /workspace/source 12 | command: ["/bin/bash", "-c"] 13 | args: 14 | - |- 15 | echo "**** Creating namespaces ****" 16 | oc apply -f onecluster-multiple-envs/rhacm/namespaces.yaml -------------------------------------------------------------------------------- /onecluster-multiple-envs/tekton/tasks/02_create_dev_app_using_acm.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | name: etherpad-dev-deployment 5 | spec: 6 | workspaces: 7 | - name: source 8 | steps: 9 | - name: etherpad-dev-deployment 10 | image: quay.io/openshift/origin-cli:latest 11 | workingDir: /workspace/source 12 | command: ["/bin/bash", "-c"] 13 | args: 14 | - |- 15 | echo "**** DEV ENVIRONMENT: Creating application on RH ACM ****" 16 | oc apply -f onecluster-multiple-envs/rhacm/dev/application.yaml 17 | 18 | echo "**** DEV ENVIRONMENT: Creating channel on RH ACM ****" 19 | oc apply -f onecluster-multiple-envs/rhacm/dev/channel.yaml 20 | 21 | echo "**** DEV ENVIRONMENT: Creating placementrule on RH ACM ****" 22 | oc apply -f onecluster-multiple-envs/rhacm/dev/placement-rule.yaml 23 | 24 | echo "**** DEV ENVIRONMENT: Creating subscription on RH ACM ****" 25 | oc apply -f onecluster-multiple-envs/rhacm/dev/subscription.yaml -------------------------------------------------------------------------------- /onecluster-multiple-envs/tekton/tasks/03_create_qa_app_using_acm.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | name: etherpad-qa-deployment 5 | spec: 6 | workspaces: 7 | - name: source 8 | steps: 9 | - name: etherpad-qa-deployment 10 | image: quay.io/openshift/origin-cli:latest 11 | workingDir: /workspace/source 12 | command: ["/bin/bash", "-c"] 13 | args: 14 | - |- 15 | echo "**** QA ENVIRONMENT: Creating application on RH ACM ****" 16 | oc apply -f onecluster-multiple-envs/rhacm/qa/application.yaml 17 | 18 | echo "**** QA ENVIRONMENT: Creating channel on RH ACM ****" 19 | oc apply -f onecluster-multiple-envs/rhacm/qa/channel.yaml 20 | 21 | echo "**** QA ENVIRONMENT: Creating placementrule on RH ACM ****" 22 | oc apply -f onecluster-multiple-envs/rhacm/qa/placement-rule.yaml 23 | 24 | echo "**** QA ENVIRONMENT: Creating subscription on RH ACM ****" 25 | oc apply -f onecluster-multiple-envs/rhacm/qa/subscription.yaml -------------------------------------------------------------------------------- /onecluster-multiple-envs/tekton/tasks/04_create_prd_app_using_acm.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | name: etherpad-prd-deployment 5 | spec: 6 | workspaces: 7 | - name: source 8 | steps: 9 | - name: etherpad-prd-deployment 10 | image: quay.io/openshift/origin-cli:latest 11 | workingDir: /workspace/source 12 | command: ["/bin/bash", "-c"] 13 | args: 14 | - |- 15 | echo "**** PRD ENVIRONMENT: Creating application on RH ACM ****" 16 | oc apply -f onecluster-multiple-envs/rhacm/prd/application.yaml 17 | 18 | echo "**** PRD ENVIRONMENT: Creating channel on RH ACM ****" 19 | oc apply -f onecluster-multiple-envs/rhacm/prd/channel.yaml 20 | 21 | echo "**** PRD ENVIRONMENT: Creating placementrule on RH ACM ****" 22 | oc apply -f onecluster-multiple-envs/rhacm/prd/placement-rule.yaml 23 | 24 | echo "**** PRD ENVIRONMENT: Creating subscription on RH ACM ****" 25 | oc apply -f onecluster-multiple-envs/rhacm/prd/subscription.yaml --------------------------------------------------------------------------------