diff --git a/.catalog-onboard-pipeline.yaml b/.catalog-onboard-pipeline.yaml
new file mode 100644
index 0000000..f15b649
--- /dev/null
+++ b/.catalog-onboard-pipeline.yaml
@@ -0,0 +1,13 @@
+---
+apiVersion: v1
+offerings:
+ - name: deploy-arch-ibm-slz-was-operator
+ kind: solution
+ catalog_id: 7df1e4ca-d54c-4fd0-82ce-3d13247308cd
+ offering_id: 70e68cb4-7026-4329-9faa-8a1e56444aba
+ variations:
+ - name: standard
+ mark_ready: false
+ install_type: extension
+ pre_validation: "tests/scripts/pre-validation-slz-roks.sh"
+ post_validation: "tests/scripts/post-validation-slz-roks.sh"
diff --git a/.github/settings.yml b/.github/settings.yml
index f97a943..fbbda70 100644
--- a/.github/settings.yml
+++ b/.github/settings.yml
@@ -22,7 +22,7 @@ repository:
# Uncomment this description property
# and update the description to the current repo description.
- # description: ""
+ description: "This module installs a WebSphere® Liberty operator and create an instance of WebSphere Liberty operator on IBM Cloud Red Hat OpenShift cluster on VPC Gen2."
# Use a comma-separated list of topics to set on the repo (ensure not to use any caps in the topic string).
topics: terraform, ibm-cloud, terraform-module
diff --git a/.gitignore b/.gitignore
index a7550ad..ee8c557 100644
--- a/.gitignore
+++ b/.gitignore
@@ -51,3 +51,4 @@ terraform.rc
# Visual Studio Code
.vscode/
+*.code-workspace
diff --git a/.releaserc b/.releaserc
index 708916f..0085925 100644
--- a/.releaserc
+++ b/.releaserc
@@ -10,6 +10,9 @@
}],
["@semantic-release/exec", {
"successCmd": "echo \"SEMVER_VERSION=${nextRelease.version}\" >> $GITHUB_ENV"
+ }],
+ ["@semantic-release/exec",{
+ "publishCmd": "./ci/trigger-catalog-onboarding-pipeline.sh --version=v${nextRelease.version}"
}]
]
}
diff --git a/README.md b/README.md
index ff003c2..a3ac53c 100644
--- a/README.md
+++ b/README.md
@@ -1,27 +1,27 @@
-# Terraform Modules Template Project
+# WebSphere Liberty operator on Red Hat OpenShift VPC cluster module
-[![Incubating (Not yet consumable)](https://img.shields.io/badge/status-Incubating%20(Not%20yet%20consumable)-red)](https://terraform-ibm-modules.github.io/documentation/#/badge-status)
+[![Implemented (No quality checks)](https://img.shields.io/badge/Status-Implemented%20(No%20quality%20checks)-yellowgreen)](https://terraform-ibm-modules.github.io/documentation/#/badge-status)
[![latest release](https://img.shields.io/github/v/release/terraform-ibm-modules/terraform-ibm-websphere-liberty-operator?logo=GitHub&sort=semver)](https://github.com/terraform-ibm-modules/terraform-ibm-websphere-liberty-operator/releases/latest)
[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit)
[![Renovate enabled](https://img.shields.io/badge/renovate-enabled-brightgreen.svg)](https://renovatebot.com/)
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
-TODO: Replace me with description of the module(s) in this repo
+Use this module to install a WebSphere® Liberty operator and create an instance of WebSphere Liberty operator on IBM Cloud Red Hat OpenShift cluster on VPC Gen2.
+For more information about the WebSphere Liberty operator refer to the official documentation avaiable [here](https://www.ibm.com/docs/en/was-liberty/core?topic=container-running-websphere-liberty-operator)
## Overview
* [terraform-ibm-websphere-liberty-operator](#terraform-ibm-websphere-liberty-operator)
* [Examples](./examples)
- * [Basic example](./examples/basic)
* [Complete example](./examples/complete)
* [Contributing](#contributing)
@@ -89,6 +89,12 @@ statement instead the previous block.
| Name | Version |
|------|---------|
| [terraform](#requirement\_terraform) | >= 1.3.0, <1.6.0 |
+| [external](#requirement\_external) | >=2.2.3, <3.0.0 |
+| [helm](#requirement\_helm) | >= 2.8.0, <3.0.0 |
+| [ibm](#requirement\_ibm) | >= 1.59.0, < 2.0.0 |
+| [kubernetes](#requirement\_kubernetes) | >= 2.16.1, <3.0.0 |
+| [null](#requirement\_null) | >= 3.2.1, < 4.0.0 |
+| [time](#requirement\_time) | >= 0.9.1, < 1.0.0 |
### Modules
@@ -96,15 +102,46 @@ No modules.
### Resources
-No resources.
+| Name | Type |
+|------|------|
+| [helm_release.ibm_operator_catalog](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource |
+| [helm_release.websphere_liberty_operator](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource |
+| [helm_release.websphere_liberty_operator_group](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource |
+| [helm_release.websphere_liberty_operator_sampleapp](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource |
+| [kubernetes_namespace.helm_release_operator_namespace](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/namespace) | resource |
+| [kubernetes_namespace.websphere_liberty_operator_namespace](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/namespace) | resource |
+| [kubernetes_namespace.websphere_liberty_sampleapp_namespace](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/namespace) | resource |
+| [null_resource.confirm_websphere_liberty_operator_operational](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
+| [time_sleep.wait_catalog](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep) | resource |
+| [time_sleep.wait_sampleapp](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep) | resource |
+| [time_sleep.wait_websphere_liberty_operator](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep) | resource |
+| [external_external.websphere_liberty_operator_sampleapp_url](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external) | data source |
+| [ibm_container_cluster_config.cluster_config](https://registry.terraform.io/providers/ibm-cloud/ibm/latest/docs/data-sources/container_cluster_config) | data source |
### Inputs
-No inputs.
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [add\_ibm\_operator\_catalog](#input\_add\_ibm\_operator\_catalog) | Flag to configure the IBM Operator Catalog in the cluster before installing the WebSphere Liberty Operator. Default is true | `bool` | `true` | no |
+| [cluster\_config\_endpoint\_type](#input\_cluster\_config\_endpoint\_type) | Specify which type of endpoint to use for for cluster config access: 'default', 'private', 'vpe', 'link'. 'default' value will use the default endpoint of the cluster. | `string` | `"default"` | no |
+| [cluster\_id](#input\_cluster\_id) | Id of the target IBM Cloud OpenShift Cluster | `string` | n/a | yes |
+| [create\_ws\_liberty\_operator\_namespace](#input\_create\_ws\_liberty\_operator\_namespace) | Flag to create the namespace where to deploy the WebSphere Liberty Operator. Default to false | `bool` | `false` | no |
+| [ibmcloud\_api\_key](#input\_ibmcloud\_api\_key) | APIkey that's associated with the account to use | `string` | `null` | no |
+| [install\_wslo\_sampleapp](#input\_install\_wslo\_sampleapp) | Flag to deploy the WebSphere Liberty sample application. Default to false | `bool` | `false` | no |
+| [operator\_helm\_release\_namespace](#input\_operator\_helm\_release\_namespace) | Namespace to deploy the helm releases. Default to liberty-operator-helm-release | `string` | `"liberty-operator"` | no |
+| [region](#input\_region) | Cluster region | `string` | n/a | yes |
+| [ws\_liberty\_operator\_namespace](#input\_ws\_liberty\_operator\_namespace) | Namespace to install the WebSphere Liberty Operator. Default to openshift-operators | `string` | `"openshift-operators"` | no |
+| [ws\_liberty\_operator\_target\_namespace](#input\_ws\_liberty\_operator\_target\_namespace) | Namespace to be watched by the WebSphere Liberty Operator. Default to null (operator to watch all namespaces) | `string` | `null` | no |
+| [wslo\_sampleapp\_name](#input\_wslo\_sampleapp\_name) | Application name to use for the WebSphere Liberty sample application | `string` | `"websphereliberty-app-sample"` | no |
+| [wslo\_sampleapp\_namespace](#input\_wslo\_sampleapp\_namespace) | Namespace to deploy the WebSphere Liberty sample application | `string` | `"samplelibertyapp"` | no |
### Outputs
-No outputs.
+| Name | Description |
+|------|-------------|
+| [websphere\_liberty\_operator\_sampleapp\_url](#output\_websphere\_liberty\_operator\_sampleapp\_url) | WebSphere Liberty sample application URL |
+| [ws\_liberty\_operator\_namespace](#output\_ws\_liberty\_operator\_namespace) | Namespace where the WebSphere Liberty operator is installed |
+| [ws\_liberty\_operator\_target\_namespace](#output\_ws\_liberty\_operator\_target\_namespace) | Namespace watched by the WebSphere Liberty operator |
diff --git a/chart/ibm-operator-catalog/.helmignore b/chart/ibm-operator-catalog/.helmignore
new file mode 100644
index 0000000..0e8a0eb
--- /dev/null
+++ b/chart/ibm-operator-catalog/.helmignore
@@ -0,0 +1,23 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*.orig
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/chart/ibm-operator-catalog/Chart.yaml b/chart/ibm-operator-catalog/Chart.yaml
new file mode 100644
index 0000000..2ec4e9e
--- /dev/null
+++ b/chart/ibm-operator-catalog/Chart.yaml
@@ -0,0 +1,15 @@
+apiVersion: v2
+name: ibm-websphere-liberty-operator
+description: A Helm chart to configure the Operator Catalog source for the IBM operator catalog
+type: application
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+# Versions are expected to follow Semantic Versioning (https://semver.org/)
+version: 0.0.1
+
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application. Versions are not expected to
+# follow Semantic Versioning. They should reflect the version the application is using.
+# It is recommended to use it with quotes.
+appVersion: "1.0.0"
diff --git a/chart/ibm-operator-catalog/templates/ibm-operator-catalog-source.yaml b/chart/ibm-operator-catalog/templates/ibm-operator-catalog-source.yaml
new file mode 100644
index 0000000..6e83822
--- /dev/null
+++ b/chart/ibm-operator-catalog/templates/ibm-operator-catalog-source.yaml
@@ -0,0 +1,13 @@
+apiVersion: operators.coreos.com/v1alpha1
+kind: CatalogSource
+metadata:
+ name: ibm-operator-catalog
+ namespace: openshift-marketplace
+spec:
+ displayName: IBM Operator Catalog
+ publisher: IBM
+ sourceType: grpc
+ image: '{{ .Values.image.path }}:{{ required "IBM Operator catalog version must be provided" .Values.image.version }}'
+ updateStrategy:
+ registryPoll:
+ interval: 45m
diff --git a/chart/ibm-operator-catalog/values.yaml b/chart/ibm-operator-catalog/values.yaml
new file mode 100755
index 0000000..f499b50
--- /dev/null
+++ b/chart/ibm-operator-catalog/values.yaml
@@ -0,0 +1,5 @@
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+image:
+ path: "icr.io/cpopen/ibm-operator-catalog"
+ version: "v1.25-20240202.161709-9DAF3E648@sha256:92e28be4af60f68c656f52b2445aafcc052fcd0390479b868c5b0ba2d465a25a"
diff --git a/chart/websphere-liberty-operator-group/.helmignore b/chart/websphere-liberty-operator-group/.helmignore
new file mode 100644
index 0000000..0e8a0eb
--- /dev/null
+++ b/chart/websphere-liberty-operator-group/.helmignore
@@ -0,0 +1,23 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*.orig
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/chart/websphere-liberty-operator-group/Chart.yaml b/chart/websphere-liberty-operator-group/Chart.yaml
new file mode 100644
index 0000000..3b3c66c
--- /dev/null
+++ b/chart/websphere-liberty-operator-group/Chart.yaml
@@ -0,0 +1,15 @@
+apiVersion: v2
+name: ibm-websphere-liberty-operator
+description: A Helm chart to configure the Operator Group for the IBM WebSphere Liberty Operator
+type: application
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+# Versions are expected to follow Semantic Versioning (https://semver.org/)
+version: 0.0.1
+
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application. Versions are not expected to
+# follow Semantic Versioning. They should reflect the version the application is using.
+# It is recommended to use it with quotes.
+appVersion: "1.0.0"
diff --git a/chart/websphere-liberty-operator-group/templates/ibm-websphere-liberty-operator-group.yaml b/chart/websphere-liberty-operator-group/templates/ibm-websphere-liberty-operator-group.yaml
new file mode 100644
index 0000000..868946a
--- /dev/null
+++ b/chart/websphere-liberty-operator-group/templates/ibm-websphere-liberty-operator-group.yaml
@@ -0,0 +1,8 @@
+apiVersion: operators.coreos.com/v1alpha2
+kind: OperatorGroup
+metadata:
+ name: ibm-websphere-liberty
+ namespace: {{ .Values.operatornamespace }}
+spec:
+ targetNamespaces:
+ - {{ .Values.operatortargetnamespace }}
diff --git a/chart/websphere-liberty-operator-group/values.yaml b/chart/websphere-liberty-operator-group/values.yaml
new file mode 100755
index 0000000..09cd1a5
--- /dev/null
+++ b/chart/websphere-liberty-operator-group/values.yaml
@@ -0,0 +1,5 @@
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+operatornamespace: openshift-operators
+operatortargetnamespace: openshift-operators
diff --git a/chart/websphere-liberty-operator-sampleapp/Chart.yaml b/chart/websphere-liberty-operator-sampleapp/Chart.yaml
new file mode 100644
index 0000000..31bf613
--- /dev/null
+++ b/chart/websphere-liberty-operator-sampleapp/Chart.yaml
@@ -0,0 +1,15 @@
+apiVersion: v2
+name: ibm-websphere-liberty-operator-sampleapp
+description: A Helm chart to a sample application for the IBM WebSphere Liberty Operator
+type: application
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+# Versions are expected to follow Semantic Versioning (https://semver.org/)
+version: 0.0.1
+
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application. Versions are not expected to
+# follow Semantic Versioning. They should reflect the version the application is using.
+# It is recommended to use it with quotes.
+appVersion: "1.0.0"
diff --git a/chart/websphere-liberty-operator-sampleapp/templates/websphere-liberty-sample-app.yaml b/chart/websphere-liberty-operator-sampleapp/templates/websphere-liberty-sample-app.yaml
new file mode 100644
index 0000000..e4d7546
--- /dev/null
+++ b/chart/websphere-liberty-operator-sampleapp/templates/websphere-liberty-sample-app.yaml
@@ -0,0 +1,14 @@
+apiVersion: liberty.websphere.ibm.com/v1
+kind: WebSphereLibertyApplication
+metadata:
+ name: {{ .Values.application.name }}
+ namespace: {{ .Values.application.namespace }}
+spec:
+ license:
+ accept: true
+ edition: IBM WebSphere Application Server
+ productEntitlementSource: Standalone
+ applicationImage: >-
+ {{ .Values.application.image.path }}:{{ required "Liberty sample app version must be provided" .Values.application.image.version }}
+ manageTLS: true
+ expose: true
diff --git a/chart/websphere-liberty-operator-sampleapp/values.yaml b/chart/websphere-liberty-operator-sampleapp/values.yaml
new file mode 100644
index 0000000..cf7d794
--- /dev/null
+++ b/chart/websphere-liberty-operator-sampleapp/values.yaml
@@ -0,0 +1,6 @@
+application:
+ name: websphereliberty-app-sample
+ namespace: samplelibertyapp
+ image:
+ path: "icr.io/appcafe/open-liberty/samples/getting-started"
+ version: "latest@sha256:d735c2ceae5945a0f20adcbcb04e55472d2520b6d1abb6d3049c8521234d3b7a"
diff --git a/chart/websphere-liberty-operator/.helmignore b/chart/websphere-liberty-operator/.helmignore
new file mode 100644
index 0000000..0e8a0eb
--- /dev/null
+++ b/chart/websphere-liberty-operator/.helmignore
@@ -0,0 +1,23 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*.orig
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/chart/websphere-liberty-operator/Chart.yaml b/chart/websphere-liberty-operator/Chart.yaml
new file mode 100644
index 0000000..83f8380
--- /dev/null
+++ b/chart/websphere-liberty-operator/Chart.yaml
@@ -0,0 +1,15 @@
+apiVersion: v2
+name: ibm-websphere-liberty-operator
+description: A Helm chart to configure the Subscription for the IBM WebSphere Liberty Operator
+type: application
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+# Versions are expected to follow Semantic Versioning (https://semver.org/)
+version: 0.0.1
+
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application. Versions are not expected to
+# follow Semantic Versioning. They should reflect the version the application is using.
+# It is recommended to use it with quotes.
+appVersion: "1.0.0"
diff --git a/chart/websphere-liberty-operator/scripts/uninstall-operator-resources.sh b/chart/websphere-liberty-operator/scripts/uninstall-operator-resources.sh
new file mode 100755
index 0000000..3bfe44f
--- /dev/null
+++ b/chart/websphere-liberty-operator/scripts/uninstall-operator-resources.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+## Needed to delete resources (CSVs and installPlans) created by the OLM outside of the Terraform scope
+
+operator_names=( "ibm-websphere-liberty" )
+
+echo "Fetching and deleting CSVs and installPlans for IBM WebSphere Liberty Operator"
+
+for i in "${operator_names[@]}"
+do
+ CSV=$(kubectl get subscription "$i" -o jsonpath="{$.status.installedCSV}" -n "$1")
+
+ if [ -n "$CSV" ]
+ then
+ echo "Deleting CSV ${CSV}"
+ kubectl delete csv "$CSV" -n "$1"
+ fi
+
+ IP=$(kubectl get installPlan -n "$1" | grep "${i}" | awk '{print $1}')
+
+ if [ -n "$IP" ]
+ then
+ echo "Deleting installPlan ${IP}"
+ kubectl delete installPlan "$IP" -n "$1"
+ fi
+done
diff --git a/chart/websphere-liberty-operator/templates/ibm-websphere-liberty-operator-subscription.yaml b/chart/websphere-liberty-operator/templates/ibm-websphere-liberty-operator-subscription.yaml
new file mode 100644
index 0000000..d95e43d
--- /dev/null
+++ b/chart/websphere-liberty-operator/templates/ibm-websphere-liberty-operator-subscription.yaml
@@ -0,0 +1,11 @@
+# ibm-websphere-liberty-operator-subscription.yaml
+apiVersion: operators.coreos.com/v1alpha1
+kind: Subscription
+metadata:
+ name: ibm-websphere-liberty
+ namespace: {{ .Values.operatornamespace }}
+spec:
+ installPlanApproval: Manual
+ name: ibm-websphere-liberty
+ source: ibm-operator-catalog
+ sourceNamespace: openshift-marketplace
diff --git a/chart/websphere-liberty-operator/templates/uninstall-hook-config-map.yaml b/chart/websphere-liberty-operator/templates/uninstall-hook-config-map.yaml
new file mode 100644
index 0000000..3e62abd
--- /dev/null
+++ b/chart/websphere-liberty-operator/templates/uninstall-hook-config-map.yaml
@@ -0,0 +1,15 @@
+# The OLM created csv objects on the cluster during install - there is a need to clean up csv created by the OLM, in addition to removing the subscription
+# See https://olm.operatorframework.io/docs/tasks/uninstall-operator/#combine-steps-2-and-3 for context
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: wslo-uninstall-scripts
+ namespace: {{ .Values.operatornamespace }}
+ annotations:
+ "helm.sh/hook": pre-delete
+ "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed
+ "helm.sh/hook-weight": "3"
+data:
+ uninstall-operator-resources.sh: |-
+{{ .Files.Get "scripts/uninstall-operator-resources.sh" | indent 4}}
diff --git a/chart/websphere-liberty-operator/templates/uninstall-hook-crb.yaml b/chart/websphere-liberty-operator/templates/uninstall-hook-crb.yaml
new file mode 100644
index 0000000..db66a58
--- /dev/null
+++ b/chart/websphere-liberty-operator/templates/uninstall-hook-crb.yaml
@@ -0,0 +1,36 @@
+# The OLM created csv objects on the cluster during install - there is a need to clean up csv created by the OLM, in addition to removing the subscription
+# See https://olm.operatorframework.io/docs/tasks/uninstall-operator/#combine-steps-2-and-3 for context
+
+kind: ClusterRoleBinding
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+ name: wslo-uninstall-hook-role-binding-edit
+ annotations:
+ "helm.sh/hook": pre-delete
+ "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed
+ "helm.sh/hook-weight": "2"
+subjects:
+ - kind: ServiceAccount
+ name: wslo-uninstall-hook-role-sa
+ namespace: {{ .Values.operatornamespace }}
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: aggregate-olm-edit
+---
+kind: ClusterRoleBinding
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+ name: wslo-uninstall-hook-role-binding-view
+ annotations:
+ "helm.sh/hook": pre-delete
+ "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed
+ "helm.sh/hook-weight": "2"
+subjects:
+ - kind: ServiceAccount
+ name: wslo-uninstall-hook-role-sa
+ namespace: {{ .Values.operatornamespace }}
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: aggregate-olm-view
diff --git a/chart/websphere-liberty-operator/templates/uninstall-hook-job.yaml b/chart/websphere-liberty-operator/templates/uninstall-hook-job.yaml
new file mode 100644
index 0000000..ba0eaa2
--- /dev/null
+++ b/chart/websphere-liberty-operator/templates/uninstall-hook-job.yaml
@@ -0,0 +1,58 @@
+# The OLM created csv objects on the cluster during install - there is a need to clean up csv created by the OLM, in addition to removing the subscription
+# See https://olm.operatorframework.io/docs/tasks/uninstall-operator/#combine-steps-2-and-3 for context
+
+apiVersion: batch/v1
+kind: Job
+metadata:
+ name: wslo-uninstall-hook
+ namespace: {{ .Values.operatornamespace }}
+ annotations:
+ "helm.sh/hook": pre-delete
+ "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed
+ "helm.sh/hook-weight": "4"
+ checkov.io/skip1: CKV_K8S_21
+ checkov.io/skip2: CKV_K8S_30
+ checkov.io/skip3: CKV_K8S_28
+ checkov.io/skip4: CKV_K8S_22
+ checkov.io/skip5: CKV_K8S_20
+ checkov.io/skip6: CKV_K8S_37
+ checkov.io/skip7: CKV_K8S_23
+ checkov.io/skip8: CKV_K8S_38
+ checkov.io/skip9: CKV_K8S_29
+ checkov.io/skip10: CKV_K8S_40
+ checkov.io/skip11: CKV_K8S_31
+ checkov.io/skip12: CKV_K8S_9
+ checkov.io/skip13: CKV_K8S_16
+ checkov.io/skip14: CKV_K8S_8
+ checkov.io/skip15: CKV_K8S_43
+spec:
+ template:
+ metadata:
+ name: wslo-uninstall-hook
+ spec:
+ restartPolicy: Never
+ serviceAccountName: wslo-uninstall-hook-role-sa
+ volumes:
+ - name: scripts
+ configMap:
+ name: wslo-uninstall-scripts
+ defaultMode: 0777
+ containers:
+ - name: wslo-uninstall-hook-job
+ image: "icr.io/goldeneye_images/ubi8-cluster-tools:stable"
+ # Deliberately always pull to grab latest image at the time when uninstall hook executed,
+ # which may be a long time (multi months) after chart was deployed
+ imagePullPolicy: Always
+ command: ["/bin/sh"]
+ args: ["-xc", "/scripts/uninstall-operator-resources.sh {{ .Values.operatornamespace }}"]
+ volumeMounts:
+ - mountPath: /scripts
+ name: scripts
+ readOnly: true
+ resources:
+ limits:
+ cpu: 50m
+ memory: 50Mi
+ requests:
+ cpu: 50m
+ memory: 50Mi
diff --git a/chart/websphere-liberty-operator/templates/uninstall-hook-sa.yaml b/chart/websphere-liberty-operator/templates/uninstall-hook-sa.yaml
new file mode 100644
index 0000000..05ee5c7
--- /dev/null
+++ b/chart/websphere-liberty-operator/templates/uninstall-hook-sa.yaml
@@ -0,0 +1,12 @@
+# The OLM created csv objects on the cluster during install - there is a need to clean up csv created by the OLM, in addition to removing the subscription
+# See https://olm.operatorframework.io/docs/tasks/uninstall-operator/#combine-steps-2-and-3 for context
+
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: wslo-uninstall-hook-role-sa
+ namespace: {{ .Values.operatornamespace }}
+ annotations:
+ "helm.sh/hook": pre-delete
+ "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed
+ "helm.sh/hook-weight": "1"
diff --git a/chart/websphere-liberty-operator/values.yaml b/chart/websphere-liberty-operator/values.yaml
new file mode 100755
index 0000000..5ec3366
--- /dev/null
+++ b/chart/websphere-liberty-operator/values.yaml
@@ -0,0 +1,4 @@
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+operatornamespace: openshift-operators
diff --git a/cra-tf-validate-ignore-rules.json b/cra-tf-validate-ignore-rules.json
index adbff6e..008b080 100644
--- a/cra-tf-validate-ignore-rules.json
+++ b/cra-tf-validate-ignore-rules.json
@@ -1,3 +1,10 @@
{
- "scc_rules": []
+ "scc_rules": [
+ {
+ "scc_rule_id": "rule-64c0bea0-8760-4a6b-a56c-ee375a48961e",
+ "description": "Check whether Virtual Private Cloud (VPC) has no public gateways attached",
+ "ignore_reason": "Need public network access to collect liberty operator images",
+ "is_valid": true
+ }
+ ]
}
diff --git a/examples/basic/README.md b/examples/basic/README.md
deleted file mode 100644
index 86eab8e..0000000
--- a/examples/basic/README.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# Basic example
-
-
-
-An end-to-end basic example that will provision the following:
-- A new resource group if one is not passed in.
-- A new Cloud Object Storage instance.
diff --git a/examples/basic/main.tf b/examples/basic/main.tf
deleted file mode 100644
index 4aeca62..0000000
--- a/examples/basic/main.tf
+++ /dev/null
@@ -1,24 +0,0 @@
-########################################################################################################################
-# Resource group
-########################################################################################################################
-
-module "resource_group" {
- source = "terraform-ibm-modules/resource-group/ibm"
- version = "1.1.4"
- # if an existing resource group is not set (null) create a new one using prefix
- resource_group_name = var.resource_group == null ? "${var.prefix}-resource-group" : null
- existing_resource_group_name = var.resource_group
-}
-
-########################################################################################################################
-# COS instance
-########################################################################################################################
-
-resource "ibm_resource_instance" "cos_instance" {
- name = "${var.prefix}-cos"
- resource_group_id = module.resource_group.resource_group_id
- service = "cloud-object-storage"
- plan = "standard"
- location = "global"
- tags = var.resource_tags
-}
diff --git a/examples/basic/outputs.tf b/examples/basic/outputs.tf
deleted file mode 100644
index 04b196e..0000000
--- a/examples/basic/outputs.tf
+++ /dev/null
@@ -1,18 +0,0 @@
-########################################################################################################################
-# Outputs
-########################################################################################################################
-
-output "cos_instance_id" {
- description = "COS instance id"
- value = ibm_resource_instance.cos_instance.id
-}
-
-output "resource_group_name" {
- description = "Resource group name"
- value = module.resource_group.resource_group_name
-}
-
-output "resource_group_id" {
- description = "Resource group ID"
- value = module.resource_group.resource_group_id
-}
diff --git a/examples/basic/version.tf b/examples/basic/version.tf
deleted file mode 100644
index 46915a6..0000000
--- a/examples/basic/version.tf
+++ /dev/null
@@ -1,12 +0,0 @@
-terraform {
- required_version = ">= 1.3.0, <1.6.0"
-
- # Ensure that there is always 1 example locked into the lowest provider version of the range defined in the main
- # module's version.tf (usually a basic example), and 1 example that will always use the latest provider version.
- required_providers {
- ibm = {
- source = "IBM-Cloud/ibm"
- version = "1.49.0"
- }
- }
-}
diff --git a/examples/complete/README.md b/examples/complete/README.md
index 139f8dd..2efdcfa 100644
--- a/examples/complete/README.md
+++ b/examples/complete/README.md
@@ -1,4 +1,7 @@
# Complete example
-
-
+An end-to-end complete example that will provision the following:
+- A new resource group if one is not passed in.
+- A new VPC with 3 subnets and a new OpenShift cluster in the VPC with 3 workers pools
+- The IBM WebSphere Liberty operator in the default operator namespace
+- The IBM WebSphere Liberty sample app
diff --git a/examples/complete/main.tf b/examples/complete/main.tf
index 558c210..1f55436 100644
--- a/examples/complete/main.tf
+++ b/examples/complete/main.tf
@@ -1,3 +1,120 @@
+########################################################################################################################
+# Resource Group
+########################################################################################################################
+
+module "resource_group" {
+ source = "terraform-ibm-modules/resource-group/ibm"
+ version = "1.1.4"
+ # if an existing resource group is not set (null) create a new one using prefix
+ resource_group_name = var.resource_group == null ? "${var.prefix}-resource-group" : null
+ existing_resource_group_name = var.resource_group
+}
+
+########################################################################################################################
+# VPC
+########################################################################################################################
+
+resource "ibm_is_vpc" "vpc" {
+ name = "${var.prefix}-vpc"
+ resource_group = module.resource_group.resource_group_id
+ address_prefix_management = "auto"
+ tags = var.resource_tags
+}
+
+# public gws
+resource "ibm_is_public_gateway" "gateway" {
+ for_each = toset(["1", "2", "3"])
+ name = "${var.prefix}-gateway-${each.key}"
+ vpc = ibm_is_vpc.vpc.id
+ resource_group = module.resource_group.resource_group_id
+ zone = "${var.region}-${each.key}"
+}
+
+
+resource "ibm_is_subnet" "cluster_subnets" {
+ for_each = toset(["1", "2", "3"])
+ name = "${var.prefix}-subnet-${each.key}"
+ vpc = ibm_is_vpc.vpc.id
+ resource_group = module.resource_group.resource_group_id
+ zone = "${var.region}-${each.key}"
+ total_ipv4_address_count = 256
+ public_gateway = ibm_is_public_gateway.gateway[each.key].id
+}
+
##############################################################################
-# Complete example
+# OCP CLUSTER
##############################################################################
+
+locals {
+
+ subnets = [
+ for subnet in ibm_is_subnet.cluster_subnets :
+ {
+ id = subnet.id
+ zone = subnet.zone
+ cidr_block = subnet.ipv4_cidr_block
+ }
+ ]
+
+ # mapping of cluster worker pool names to subnets
+ cluster_vpc_subnets = {
+ zone-1 = local.subnets,
+ zone-2 = local.subnets,
+ zone-3 = local.subnets
+ }
+
+ worker_pools = [
+ {
+ subnet_prefix = "zone-1"
+ pool_name = "default" # ibm_container_vpc_cluster automatically names default pool "default" (See https://github.com/IBM-Cloud/terraform-provider-ibm/issues/2849)
+ machine_type = "bx2.4x16"
+ workers_per_zone = 1
+ labels = {}
+ },
+ {
+ subnet_prefix = "zone-2"
+ pool_name = "zone-2"
+ machine_type = "bx2.4x16"
+ workers_per_zone = 1
+ labels = { "dedicated" : "edge" }
+ },
+ {
+ subnet_prefix = "zone-3"
+ pool_name = "zone-3"
+ machine_type = "bx2.4x16"
+ workers_per_zone = 1
+ labels = { "dedicated" : "transit" }
+ }
+ ]
+}
+
+module "ocp_base" {
+ depends_on = [ibm_is_vpc.vpc, ibm_is_subnet.cluster_subnets, ibm_is_public_gateway.gateway]
+ source = "terraform-ibm-modules/base-ocp-vpc/ibm"
+ version = "3.10.1"
+ cluster_name = "${var.prefix}-cluster"
+ cos_name = "${var.prefix}-cos"
+ resource_group_id = module.resource_group.resource_group_id
+ region = var.region
+ force_delete_storage = true
+ vpc_id = ibm_is_vpc.vpc.id
+ vpc_subnets = local.cluster_vpc_subnets
+ worker_pools = local.worker_pools
+ tags = var.resource_tags
+ ibmcloud_api_key = var.ibmcloud_api_key
+ ocp_version = var.ocp_version
+}
+
+
+##############################################################################
+# IBM WebSphere Liberty operator deployment on the OCP cluster
+##############################################################################
+
+module "websphere_liberty_operator" {
+ source = "../.."
+ region = var.region
+ cluster_id = module.ocp_base.cluster_id
+ create_ws_liberty_operator_namespace = false
+ install_wslo_sampleapp = true
+ ibmcloud_api_key = var.ibmcloud_api_key
+}
diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf
index addadea..526e37f 100644
--- a/examples/complete/outputs.tf
+++ b/examples/complete/outputs.tf
@@ -1,23 +1,18 @@
-##############################################################################
+########################################################################################################################
# Outputs
-##############################################################################
+########################################################################################################################
-output "region" {
- description = "The region all resources were provisioned in"
- value = var.region
-}
-
-output "prefix" {
- description = "The prefix used to name all provisioned resources"
- value = var.prefix
+output "resource_group_name" {
+ description = "Resource group name"
+ value = module.resource_group.resource_group_name
}
-output "resource_group_name" {
- description = "The name of the resource group used"
- value = var.resource_group
+output "cluster_id" {
+ description = "Cluster ID"
+ value = module.ocp_base.cluster_id
}
-output "resource_tags" {
- description = "List of resource tags"
- value = var.resource_tags
+output "websphere_liberty_sampleapp_url" {
+ description = "Url of the IBM WebSphere Liberty sample application"
+ value = module.websphere_liberty_operator.websphere_liberty_operator_sampleapp_url
}
diff --git a/examples/complete/provider.tf b/examples/complete/provider.tf
index 2080946..9d3071e 100644
--- a/examples/complete/provider.tf
+++ b/examples/complete/provider.tf
@@ -1,8 +1,29 @@
##############################################################################
-# Provider config
+# Config providers
##############################################################################
+# IBM provider used to provision IBM Cloud resources
provider "ibm" {
ibmcloud_api_key = var.ibmcloud_api_key
region = var.region
}
+
+# Init cluster config for helm and kubernetes providers
+data "ibm_container_cluster_config" "cluster_config" {
+ cluster_name_id = module.ocp_base.cluster_id
+ resource_group_id = module.resource_group.resource_group_id
+}
+
+# Helm provider used to deploy cluster-proxy and observability agents
+provider "helm" {
+ kubernetes {
+ host = data.ibm_container_cluster_config.cluster_config.host
+ token = data.ibm_container_cluster_config.cluster_config.token
+ }
+}
+
+# Kubernetes provider used to create kube namespace(s)
+provider "kubernetes" {
+ host = data.ibm_container_cluster_config.cluster_config.host
+ token = data.ibm_container_cluster_config.cluster_config.token
+}
diff --git a/examples/complete/variables.tf b/examples/complete/variables.tf
index 170a5ab..738b0c6 100644
--- a/examples/complete/variables.tf
+++ b/examples/complete/variables.tf
@@ -1,19 +1,25 @@
variable "ibmcloud_api_key" {
type = string
- description = "The IBM Cloud API Key"
+ description = "The IBM Cloud API Token"
sensitive = true
}
+variable "prefix" {
+ type = string
+ description = "Prefix for name of all resource created by this example"
+ default = "wslop"
+}
+
variable "region" {
type = string
description = "Region to provision all resources created by this example"
- default = "us-south"
+ default = "au-syd"
}
-variable "prefix" {
+variable "ocp_version" {
+ description = "The version of the OpenShift cluster that should be provisioned (format 4.x)"
type = string
- description = "Prefix to append to all resources created by this example"
- default = "complete"
+ default = null
}
variable "resource_group" {
diff --git a/examples/complete/version.tf b/examples/complete/version.tf
index 5adb5b5..67dd3a2 100644
--- a/examples/complete/version.tf
+++ b/examples/complete/version.tf
@@ -1,12 +1,19 @@
terraform {
required_version = ">= 1.3.0, <1.6.0"
-
- # Ensure that there is always 1 example locked into the lowest provider version of the range defined in the main
- # module's version.tf (usually a basic example), and 1 example that will always use the latest provider version.
required_providers {
+ # Pin to the lowest provider version of the range defined in the main module to ensure lowest version still works
+ # OCP all inclusive requires 1.56.1, so breaking pin to lowest provider version. Note: PR tests include multiple-control-plans which is pinned
ibm = {
source = "IBM-Cloud/ibm"
- version = ">= 1.49.0, < 2.0.0"
+ version = ">= 1.59.0"
+ }
+ helm = {
+ source = "hashicorp/helm"
+ version = "2.8.0"
+ }
+ kubernetes = {
+ source = "hashicorp/kubernetes"
+ version = "2.16.1"
}
}
}
diff --git a/extensions/landing-zone/README.md b/extensions/landing-zone/README.md
new file mode 100644
index 0000000..221c490
--- /dev/null
+++ b/extensions/landing-zone/README.md
@@ -0,0 +1,3 @@
+### # Client-To-Site VPN extension for landing zone
+
+Tutorial: TBD
diff --git a/extensions/landing-zone/catalogValidationValues.json.template b/extensions/landing-zone/catalogValidationValues.json.template
new file mode 100644
index 0000000..f48a7e3
--- /dev/null
+++ b/extensions/landing-zone/catalogValidationValues.json.template
@@ -0,0 +1,3 @@
+{
+ "ibmcloud_api_key": $VALIDATION_APIKEY
+}
diff --git a/extensions/landing-zone/main.tf b/extensions/landing-zone/main.tf
new file mode 100644
index 0000000..5294cd0
--- /dev/null
+++ b/extensions/landing-zone/main.tf
@@ -0,0 +1,25 @@
+##############################################################################
+# IBM WebSphere Liberty operator deployment on the OCP cluster
+##############################################################################
+
+data "ibm_container_cluster_config" "cluster_config" {
+ cluster_name_id = var.cluster_id
+ # config_dir = "../../kubeconfig"
+ endpoint_type = var.cluster_config_endpoint_type != "default" ? var.cluster_config_endpoint_type : null # null represents default
+}
+
+module "websphere_liberty_operator" {
+ source = "../.."
+ ibmcloud_api_key = var.ibmcloud_api_key
+ region = var.region
+ cluster_id = var.cluster_id
+ add_ibm_operator_catalog = var.add_ibm_operator_catalog
+ create_ws_liberty_operator_namespace = var.create_ws_liberty_operator_namespace
+ ws_liberty_operator_namespace = var.ws_liberty_operator_namespace
+ ws_liberty_operator_target_namespace = var.ws_liberty_operator_target_namespace
+ cluster_config_endpoint_type = var.cluster_config_endpoint_type
+ install_wslo_sampleapp = var.install_wslo_sampleapp
+ wslo_sampleapp_name = var.wslo_sampleapp_name
+ wslo_sampleapp_namespace = var.wslo_sampleapp_namespace
+ operator_helm_release_namespace = var.operator_helm_release_namespace
+}
diff --git a/examples/basic/provider.tf b/extensions/landing-zone/outputs.tf
similarity index 64%
rename from examples/basic/provider.tf
rename to extensions/landing-zone/outputs.tf
index 84b6985..a75f2bd 100644
--- a/examples/basic/provider.tf
+++ b/extensions/landing-zone/outputs.tf
@@ -1,8 +1,8 @@
########################################################################################################################
-# Provider config
+# Outputs
########################################################################################################################
-provider "ibm" {
- ibmcloud_api_key = var.ibmcloud_api_key
- region = var.region
+output "websphere_liberty_operator" {
+ description = "Resource group name"
+ value = module.websphere_liberty_operator
}
diff --git a/extensions/landing-zone/provider.tf b/extensions/landing-zone/provider.tf
new file mode 100644
index 0000000..494c945
--- /dev/null
+++ b/extensions/landing-zone/provider.tf
@@ -0,0 +1,20 @@
+##############################################################################
+# Config providers
+##############################################################################
+
+provider "ibm" {
+ ibmcloud_api_key = var.ibmcloud_api_key
+ region = var.region
+}
+
+provider "helm" {
+ kubernetes {
+ host = data.ibm_container_cluster_config.cluster_config.host
+ token = data.ibm_container_cluster_config.cluster_config.token
+ }
+}
+
+provider "kubernetes" {
+ host = data.ibm_container_cluster_config.cluster_config.host
+ token = data.ibm_container_cluster_config.cluster_config.token
+}
diff --git a/extensions/landing-zone/variables.tf b/extensions/landing-zone/variables.tf
new file mode 100644
index 0000000..ece0cce
--- /dev/null
+++ b/extensions/landing-zone/variables.tf
@@ -0,0 +1,76 @@
+variable "ibmcloud_api_key" {
+ type = string
+ description = "APIkey associated with the account to use"
+ sensitive = true
+}
+
+variable "region" {
+ type = string
+ description = "Region to provision all resources created by this solution"
+ default = "au-syd"
+}
+
+variable "cluster_id" {
+ type = string
+ description = "Id of the target IBM Cloud OpenShift Cluster"
+ nullable = false
+}
+
+variable "operator_helm_release_namespace" {
+ type = string
+ description = "Namespace to deploy the helm releases. Default to liberty-operator-helm-release"
+ default = "liberty-operator-helm-release"
+}
+
+variable "add_ibm_operator_catalog" {
+ type = bool
+ description = "Flag to configure the IBM Operator Catalog in the cluster before installing the WebSphere Liberty Operator. Default is true"
+ default = true
+}
+
+variable "create_ws_liberty_operator_namespace" {
+ type = bool
+ description = "Flag to create the namespace where to deploy the WebSphere Liberty Operator. Default to false"
+ default = false
+}
+
+variable "ws_liberty_operator_namespace" {
+ type = string
+ description = "Namespace to install the WebSphere Liberty Operator. Default to openshift-operators"
+ default = "openshift-operators"
+}
+
+variable "ws_liberty_operator_target_namespace" {
+ type = string
+ description = "Namespace to be watched by the WebSphere Liberty Operator. Default to null (operator to watch all namespaces)"
+ default = null
+}
+
+variable "cluster_config_endpoint_type" {
+ description = "Specify which type of endpoint to use for for cluster config access: 'default', 'private', 'vpe', 'link'. 'default' value will use the default endpoint of the cluster."
+ type = string
+ default = "default"
+ nullable = false # use default if null is passed in
+ validation {
+ error_message = "Invalid Endpoint Type! Valid values are 'default', 'private', 'vpe', or 'link'"
+ condition = contains(["default", "private", "vpe", "link"], var.cluster_config_endpoint_type)
+ }
+}
+
+variable "install_wslo_sampleapp" {
+ description = "Flag to deploy the WebSphere Liberty sample application. Default to false"
+ type = bool
+ default = false
+}
+
+variable "wslo_sampleapp_name" {
+ description = "Application name to use for the WebSphere Liberty sample application"
+ type = string
+ default = "websphereliberty-app-sample"
+}
+
+variable "wslo_sampleapp_namespace" {
+ description = "Namespace to deploy the WebSphere Liberty sample application"
+ type = string
+ default = "samplelibertyapp"
+}
diff --git a/extensions/landing-zone/version.tf b/extensions/landing-zone/version.tf
new file mode 100644
index 0000000..59a1a3d
--- /dev/null
+++ b/extensions/landing-zone/version.tf
@@ -0,0 +1,19 @@
+terraform {
+ required_version = ">= 1.3.0, <1.6.0"
+ required_providers {
+ # Pin to the lowest provider version of the range defined in the main module to ensure lowest version still works
+ # OCP all inclusive requires 1.56.1, so breaking pin to lowest provider version. Note: PR tests include multiple-control-plans which is pinned
+ ibm = {
+ source = "IBM-Cloud/ibm"
+ version = "1.62.0"
+ }
+ helm = {
+ source = "hashicorp/helm"
+ version = "2.8.0"
+ }
+ kubernetes = {
+ source = "hashicorp/kubernetes"
+ version = "2.16.1"
+ }
+ }
+}
diff --git a/ibm_catalog.json b/ibm_catalog.json
new file mode 100644
index 0000000..11d5341
--- /dev/null
+++ b/ibm_catalog.json
@@ -0,0 +1,120 @@
+{
+ "products": [
+ {
+ "name": "deploy-arch-ibm-slz-was-operator",
+ "label": "WebSphere Liberty operator add-on for the landing zone",
+ "product_kind": "solution",
+ "tags": [
+ "ibm_created",
+ "target_terraform",
+ "terraform",
+ "reference_architecture",
+ "solution"
+ ],
+ "keywords": [
+ "vpc",
+ "slz",
+ "IaC",
+ "infrastructure as code",
+ "terraform",
+ "solution",
+ "WAS",
+ "Operator",
+ "websphere liberty operator",
+ "websphere operator",
+ "was liberty operator",
+ "was operator"
+ ],
+ "short_description": "Installs the WebSphere (WAS) Liberty operator on the landing zone (SLZ).",
+ "long_description": "Installs the WebSphere (WAS) Liberty operator on the landing zone (SLZ).",
+ "offering_docs_url": "https://github.com/terraform-ibm-modules/terraform-ibm-websphere-liberty-operator/blob/main/README.md",
+ "offering_icon_url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-websphere-liberty-operator/main/images/Websphere-icon.svg",
+ "provider_name": "IBM",
+ "features": [
+ {
+ "description": "Supports configuring the marketplace Catalog Source for the IBM Operators catalog on existing cluster.",
+ "title": "Configures Catalog Source for the IBM Operators catalog on existing cluster"
+ },
+ {
+ "description": "Supports configuring the Operator Group for the IBM WebSphere Liberty Operator on existing cluster.",
+ "title": "Configures the Operator Group for the IBM WebSphere Liberty Operator on existing cluster."
+ },
+ {
+ "description": "Supports installing the IBM WebSphere Liberty Operator on existing cluster.",
+ "title": "Installs the IBM WebSphere Liberty Operator on existing cluster."
+ },
+ {
+ "description": "Supports installing the IBM WebSphere Liberty Operator sample application on existing cluster.",
+ "title": "Installs the IBM WebSphere Liberty Operator sample application on existing cluster.."
+ }
+ ],
+ "flavors": [
+ {
+ "label": "Standard",
+ "name": "standard",
+ "install_type": "extension",
+ "working_directory": "extensions/landing-zone",
+ "dependencies": [
+ {
+ "flavors": [
+ "standard"
+ ],
+ "id": "95fccffc-ae3b-42df-b6d9-80be5914d852-global",
+ "name": "deploy-arch-ibm-slz-ocp",
+ "version": "v5.1.1-rc"
+ }
+ ],
+ "configuration": [
+ {
+ "custom_config": {
+ "config_constraints": {
+ "generationType": "2"
+ },
+ "grouping": "deployment",
+ "original_grouping": "deployment",
+ "type": "vpc_region"
+ },
+ "key": "region",
+ "required": true
+ }
+ ],
+ "architecture": {
+ "descriptions": "",
+ "features": [
+ {
+ "title": "Works with the landing zone",
+ "description": "Yes"
+ },
+ {
+ "title": "Installs catalog source the IBM Operator catalog on the existing cluster",
+ "description": "Yes"
+ },
+ {
+ "title": "Supports configuring the Operator Group for the IBM WebSphere Liberty Operator on existing cluster",
+ "description": "Yes"
+ },
+ {
+ "title": "Supports installing the IBM WebSphere Liberty Operator on existing cluster",
+ "description": "Yes"
+ },
+ {
+ "title": "Supports installing the IBM WebSphere Liberty Operator sample application on existing cluster",
+ "description": "Yes"
+ }
+ ],
+ "diagrams": [
+ {
+ "diagram": {
+ "caption": "Websphere installation on a landing zone VPC cluster.",
+ "url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-websphere-liberty-operator/main/reference-architecture/was_operator.svg",
+ "type": "image/svg+xml"
+ },
+ "description": "Websphere installation on a landing zone VPC cluster."
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+}
diff --git a/images/Websphere-icon.svg b/images/Websphere-icon.svg
new file mode 100644
index 0000000..70d00cd
--- /dev/null
+++ b/images/Websphere-icon.svg
@@ -0,0 +1,63 @@
+
+
+
diff --git a/kubeconfig/.gitignore b/kubeconfig/.gitignore
new file mode 100644
index 0000000..632a28f
--- /dev/null
+++ b/kubeconfig/.gitignore
@@ -0,0 +1,6 @@
+# Ignore everything
+*
+
+# But not these files...
+!.gitignore
+!README.md
diff --git a/kubeconfig/README.md b/kubeconfig/README.md
new file mode 100644
index 0000000..dff9dd4
--- /dev/null
+++ b/kubeconfig/README.md
@@ -0,0 +1,2 @@
+This directory must exist in source control so the `ibm_container_cluster_config` data lookup can use it to place the
+config.yml used to connect to a kubernetes cluster (See https://github.ibm.com/GoldenEye/issues/issues/552).
diff --git a/main.tf b/main.tf
index 0b919ea..444948f 100644
--- a/main.tf
+++ b/main.tf
@@ -1,3 +1,280 @@
-/********************************************************************
-This file is used to implement the ROOT module.
-*********************************************************************/
+locals {
+ # sleep times definition
+ sleep_time_catalog_create = "60s"
+ sleep_time_operator_create = "120s"
+ sleep_time_sampleapp_create = "30s"
+
+ # helm chart names
+ ibm_operator_catalog_chart = "ibm-operator-catalog"
+ websphere_liberty_operator_chart = "websphere-liberty-operator"
+ websphere_liberty_operator_group_chart = "websphere-liberty-operator-group"
+ websphere_liberty_operator_sampleapp_chart = "websphere-liberty-operator-sampleapp"
+
+ # validation of ws_liberty_operator_target_namespace - if null the value of ws_liberty_operator_namespace must be equal to "openshift-operators" https://www.ibm.com/docs/en/was-liberty/core?topic=operator-installing-red-hat-openshift-cli#in-t-cli__install-op-cli__title__1
+ default_liberty_operator_namespace = "openshift-operators"
+ operator_target_namespace_cnd = var.ws_liberty_operator_target_namespace == null && var.ws_liberty_operator_namespace != local.default_liberty_operator_namespace
+ operator_target_namespace_msg = "if input var ws_liberty_operator_target_namespace is null the value of ws_liberty_operator_namespace must be equal to ${local.default_liberty_operator_namespace}"
+ # tflint-ignore: terraform_unused_declarations
+ operator_target_namespace_chk = regex("^${local.operator_target_namespace_msg}$", (!local.operator_target_namespace_cnd ? local.operator_target_namespace_msg : ""))
+}
+
+data "ibm_container_cluster_config" "cluster_config" {
+ cluster_name_id = var.cluster_id
+ config_dir = "${path.module}/kubeconfig"
+ endpoint_type = var.cluster_config_endpoint_type != "default" ? var.cluster_config_endpoint_type : null
+}
+
+# creating the namespace to deploy the helm releases to install the WebSphere Liberty Operator
+resource "kubernetes_namespace" "helm_release_operator_namespace" {
+ metadata {
+ name = var.operator_helm_release_namespace
+ }
+
+ timeouts {
+ delete = "30m"
+ }
+
+ lifecycle {
+ ignore_changes = [
+ metadata[0].annotations,
+ metadata[0].labels
+ ]
+ }
+}
+
+locals {
+ ibm_operator_catalog_version = "v1.25-20240202.161709-9DAF3E648@sha256:92e28be4af60f68c656f52b2445aafcc052fcd0390479b868c5b0ba2d465a25a" # datasource: icr.io/cpopen/ibm-operator-catalog
+ ibm_operator_catalog_path = "icr.io/cpopen/ibm-operator-catalog"
+}
+
+# if add_ibm_operator_catalog is true going on with adding the IBM Operator Catalog source
+resource "helm_release" "ibm_operator_catalog" {
+ depends_on = [kubernetes_namespace.helm_release_operator_namespace]
+ count = var.add_ibm_operator_catalog == true ? 1 : 0
+
+ name = "ibm-operator-catalog-helm-release"
+ chart = "${path.module}/chart/${local.ibm_operator_catalog_chart}"
+ namespace = var.operator_helm_release_namespace
+ create_namespace = false
+ timeout = 300
+ # dependency_update = true
+ # force_update = false
+ force_update = true
+ cleanup_on_fail = false
+ wait = true
+ recreate_pods = true
+
+ disable_openapi_validation = false
+
+ set {
+ name = "image.path"
+ type = "string"
+ value = local.ibm_operator_catalog_path
+ }
+ set {
+ name = "image.version"
+ type = "string"
+ value = local.ibm_operator_catalog_version
+ }
+}
+
+# waiting for the catalog to be configured and correctly pulled
+resource "time_sleep" "wait_catalog" {
+ depends_on = [helm_release.ibm_operator_catalog[0]]
+ count = var.add_ibm_operator_catalog == true ? 1 : 0
+
+ create_duration = local.sleep_time_catalog_create
+}
+
+# if ws_liberty_operator_target_namespace != null the operator group must be created
+resource "helm_release" "websphere_liberty_operator_group" {
+ count = var.ws_liberty_operator_target_namespace != null ? 1 : 0
+ depends_on = [time_sleep.wait_catalog[0], kubernetes_namespace.helm_release_operator_namespace]
+
+ name = "websphere-liberty-operator-group-helm-release"
+ chart = "${path.module}/chart/${local.websphere_liberty_operator_group_chart}"
+ namespace = var.operator_helm_release_namespace
+ create_namespace = false
+ timeout = 300
+ # dependency_update = true
+ force_update = true
+ # force_update = false
+ cleanup_on_fail = false
+ wait = true
+ recreate_pods = true
+
+ disable_openapi_validation = false
+
+ set {
+ name = "operatornamespace"
+ type = "string"
+ value = var.ws_liberty_operator_namespace
+ }
+
+ set {
+ name = "operatortargetnamespace"
+ type = "string"
+ value = var.ws_liberty_operator_target_namespace
+ }
+
+}
+
+resource "kubernetes_namespace" "websphere_liberty_operator_namespace" {
+ count = var.create_ws_liberty_operator_namespace == true ? 1 : 0
+
+ metadata {
+ name = var.ws_liberty_operator_namespace
+ }
+
+ timeouts {
+ delete = "30m"
+ }
+
+ lifecycle {
+ ignore_changes = [
+ metadata[0].annotations,
+ metadata[0].labels
+ ]
+ }
+}
+
+resource "helm_release" "websphere_liberty_operator" {
+ depends_on = [time_sleep.wait_catalog[0], helm_release.websphere_liberty_operator_group[0], kubernetes_namespace.websphere_liberty_operator_namespace[0]]
+
+ name = "websphere-liberty-operator-helm-release"
+ chart = "${path.module}/chart/${local.websphere_liberty_operator_chart}"
+ namespace = var.operator_helm_release_namespace
+ create_namespace = false
+ timeout = 300
+ # dependency_update = true
+ # force_update = false
+ force_update = true
+ cleanup_on_fail = false
+ wait = true
+ recreate_pods = true
+
+ disable_openapi_validation = false
+
+ set {
+ name = "operatornamespace"
+ type = "string"
+ value = var.ws_liberty_operator_namespace
+ }
+
+ provisioner "local-exec" {
+ command = "${path.module}/scripts/approve-install-plan.sh ${var.ws_liberty_operator_namespace}"
+ interpreter = ["/bin/bash", "-c"]
+ environment = {
+ KUBECONFIG = data.ibm_container_cluster_config.cluster_config.config_file_path
+ }
+ }
+}
+
+resource "time_sleep" "wait_websphere_liberty_operator" {
+ depends_on = [helm_release.websphere_liberty_operator]
+
+ create_duration = local.sleep_time_operator_create
+}
+
+##############################################################################
+# Confirm websphere operator is operational
+##############################################################################
+
+resource "null_resource" "confirm_websphere_liberty_operator_operational" {
+
+ depends_on = [time_sleep.wait_websphere_liberty_operator]
+
+ provisioner "local-exec" {
+ command = "${path.module}/scripts/confirm-wsloperator-operational.sh ${var.ws_liberty_operator_namespace}"
+ interpreter = ["/bin/bash", "-c"]
+ environment = {
+ KUBECONFIG = data.ibm_container_cluster_config.cluster_config.config_file_path
+ }
+ }
+}
+
+resource "kubernetes_namespace" "websphere_liberty_sampleapp_namespace" {
+ depends_on = [null_resource.confirm_websphere_liberty_operator_operational]
+ count = var.install_wslo_sampleapp == true ? 1 : 0
+
+ metadata {
+ name = var.wslo_sampleapp_namespace
+ }
+
+ timeouts {
+ delete = "30m"
+ }
+
+ lifecycle {
+ ignore_changes = [
+ metadata[0].annotations,
+ metadata[0].labels
+ ]
+ }
+}
+
+locals {
+ websphere_liberty_operator_sampleapp_image_path = "icr.io/appcafe/open-liberty/samples/getting-started"
+ websphere_liberty_operator_sampleapp_image_version = "latest@sha256:d735c2ceae5945a0f20adcbcb04e55472d2520b6d1abb6d3049c8521234d3b7a" # datasource: icr.io/appcafe/open-liberty/samples/getting-started
+}
+
+resource "helm_release" "websphere_liberty_operator_sampleapp" {
+ depends_on = [kubernetes_namespace.websphere_liberty_sampleapp_namespace[0]]
+ count = var.install_wslo_sampleapp == true ? 1 : 0
+
+ name = "websphere-liberty-operator-sampleapp-helm-release"
+ chart = "${path.module}/chart/${local.websphere_liberty_operator_sampleapp_chart}"
+ namespace = var.operator_helm_release_namespace
+ create_namespace = false
+ timeout = 300
+ # dependency_update = true
+ # force_update = false
+ force_update = true
+ cleanup_on_fail = false
+ wait = true
+ recreate_pods = true
+
+ disable_openapi_validation = false
+
+ set {
+ name = "application.image.path"
+ type = "string"
+ value = local.websphere_liberty_operator_sampleapp_image_path
+ }
+ set {
+ name = "application.image.version"
+ type = "string"
+ value = local.websphere_liberty_operator_sampleapp_image_version
+ }
+
+ set {
+ name = "application.name"
+ type = "string"
+ value = var.wslo_sampleapp_name
+ }
+
+ set {
+ name = "application.namespace"
+ type = "string"
+ value = var.wslo_sampleapp_namespace
+ }
+
+}
+
+# waiting for the sample app to start before checking for the URL
+resource "time_sleep" "wait_sampleapp" {
+ depends_on = [helm_release.websphere_liberty_operator_sampleapp[0]]
+ count = var.install_wslo_sampleapp == true ? 1 : 0
+
+ create_duration = local.sleep_time_sampleapp_create
+}
+
+data "external" "websphere_liberty_operator_sampleapp_url" {
+ depends_on = [time_sleep.wait_sampleapp[0]]
+ program = ["/bin/bash", "${path.module}/scripts/get-sampleapp-url.sh"]
+ query = {
+ KUBECONFIG = data.ibm_container_cluster_config.cluster_config.config_file_path
+ APPNAMESPACE = var.wslo_sampleapp_namespace
+ APPNAME = var.wslo_sampleapp_name
+ }
+}
diff --git a/outputs.tf b/outputs.tf
index bb6ea66..8325fa3 100644
--- a/outputs.tf
+++ b/outputs.tf
@@ -2,7 +2,17 @@
# Outputs
########################################################################################################################
-#output "myoutput" {
-# description = "Description of my output"
-# value = "value"
-#}
+output "ws_liberty_operator_namespace" {
+ description = "Namespace where the WebSphere Liberty operator is installed"
+ value = var.ws_liberty_operator_namespace
+}
+
+output "ws_liberty_operator_target_namespace" {
+ description = "Namespace watched by the WebSphere Liberty operator"
+ value = var.ws_liberty_operator_target_namespace
+}
+
+output "websphere_liberty_operator_sampleapp_url" {
+ value = data.external.websphere_liberty_operator_sampleapp_url.result.sampleapp_url
+ description = "WebSphere Liberty sample application URL"
+}
diff --git a/provider.tf b/provider.tf
new file mode 100644
index 0000000..494c945
--- /dev/null
+++ b/provider.tf
@@ -0,0 +1,20 @@
+##############################################################################
+# Config providers
+##############################################################################
+
+provider "ibm" {
+ ibmcloud_api_key = var.ibmcloud_api_key
+ region = var.region
+}
+
+provider "helm" {
+ kubernetes {
+ host = data.ibm_container_cluster_config.cluster_config.host
+ token = data.ibm_container_cluster_config.cluster_config.token
+ }
+}
+
+provider "kubernetes" {
+ host = data.ibm_container_cluster_config.cluster_config.host
+ token = data.ibm_container_cluster_config.cluster_config.token
+}
diff --git a/reference-architecture/was_operator.svg b/reference-architecture/was_operator.svg
new file mode 100644
index 0000000..db4fe6a
--- /dev/null
+++ b/reference-architecture/was_operator.svg
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/renovate.json b/renovate.json
index 8954b60..4d56818 100644
--- a/renovate.json
+++ b/renovate.json
@@ -1,4 +1,13 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
- "extends": ["github>terraform-ibm-modules/common-dev-assets:commonRenovateConfig"]
+ "extends": ["github>terraform-ibm-modules/common-dev-assets:commonRenovateConfig"],
+ "packageRules": [
+ {
+ "description": "Do not allow SLZ version to be updated as we need to lock into version v5.1.1-rc",
+ "enabled": false,
+ "matchFileNames": [
+ "tests/resources/**"
+ ]
+ }
+ ]
}
diff --git a/scripts/approve-install-plan.sh b/scripts/approve-install-plan.sh
new file mode 100755
index 0000000..21768b0
--- /dev/null
+++ b/scripts/approve-install-plan.sh
@@ -0,0 +1,96 @@
+#!/bin/bash
+
+## Subscriptions are set for manual approval. This script approves the first installplan for the initial install
+
+approve_install_plan(){
+ local subscription_name=$1
+ local namespace=$2
+ local timeout_secs=900
+
+ echo "Waiting for installplan $subscription_name (${timeout_secs}s timeout)..."
+
+ local install_plan
+
+ # if running on MAC OS use "gtimeout" else run default "timeout" (
+ local timeout_cmd=timeout
+ if [[ $OSTYPE == 'darwin'* ]]; then
+ # If gtimeout not detected on mac, install coreutils
+ if ! gtimeout --help &> /dev/null; then
+ brew install coreutils
+ fi
+ timeout_cmd=gtimeout
+ fi
+ # shellcheck disable=SC2016
+ install_plan="$($timeout_cmd $timeout_secs bash -c 'while [[ "$(kubectl get subscription "'"$subscription_name"'" -n "'"$namespace"'" -o jsonpath="{$.status.installplan.name}")" == "" ]]; do sleep 2; done; echo $(kubectl get subscription "'"$subscription_name"'" -n "'"$namespace"'" -o jsonpath="{$.status.installplan.name}")')"
+
+ if [[ $install_plan != "" ]]
+ then
+ echo "Install plan $install_plan found"
+ echo "Approving install plan $install_plan"
+ kubectl patch installplan "$install_plan" --type merge --patch "{\"spec\":{\"approved\":true}}" -n "$namespace"
+ else
+ echo "Error: Install plan for $subscription_name was not found (namespace: $namespace)"
+ echo "Grabbing some debug info..."
+ echo
+ echo "kubectl get pods -n openshift-marketplace -o wide"
+ kubectl get pods -n openshift-marketplace -o wide
+ echo
+ echo "kubectl get installplan -n $namespace"
+ kubectl get installplan -n "$namespace"
+ echo
+ echo "kubectl get subscription $subscription_name -n $namespace"
+ kubectl get subscription "$subscription_name" -n "$namespace"
+ exit 1
+ fi
+
+ echo "Waiting for installplan ($subscription_name) to be installed (${timeout_secs}s timeout)..."
+ kubectl wait --for=condition=Installed --timeout ${timeout_secs}s installplan/"$install_plan" -n "$namespace"
+}
+
+wait_for_operator(){
+ local subscription_name=$1
+ local namespace=$2
+
+ echo "Waiting for $subscription_name operator to be running in $namespace (360s timeout)..."
+ local sm_csv=""
+
+ until [[ $sm_csv != "" ]]
+ do
+ echo "Waiting for csv to be created for subscription $subscription_name"
+ sm_csv=$(kubectl get subscription "$subscription_name" -o jsonpath="{$.status.installedCSV}" -n "$namespace")
+ sleep 5
+ done
+
+ local loop_count=0
+ echo "CSV found. Waiting for $subscription_name operator to be running"
+ until [[ $(kubectl get csv "$sm_csv" -o jsonpath="{$.status.phase}" -n "$namespace") == "Succeeded" || $loop_count -gt 72 ]]
+ do
+ echo "Still waiting for $subscription_name operator to be running"
+ sleep 5
+ loop_count=$((loop_count+1))
+ done
+
+ if [[ $loop_count -gt 72 ]]
+ then
+ echo "Giving up - $subscription_name operator is not running. Check the status of the operator in the $namespace namespace."
+ exit 1
+ fi
+
+ echo "Complete: $subscription_name operator is running"
+}
+
+### Main ###
+
+namespace=$1
+
+## Wait for, and approve install plan for ibm-websphere-liberty
+approve_install_plan "ibm-websphere-liberty" "$namespace"
+
+subscription_names=( "ibm-websphere-liberty" )
+## Post install waits
+for subscription_name in "${subscription_names[@]}"
+do
+ wait_for_operator "$subscription_name" "$namespace"
+done
+
+echo "IBM WebSphere Liberty Operator: Install complete"
diff --git a/scripts/confirm-wsloperator-operational.sh b/scripts/confirm-wsloperator-operational.sh
new file mode 100755
index 0000000..ab3ab25
--- /dev/null
+++ b/scripts/confirm-wsloperator-operational.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+set -e
+
+namespace=$1
+fail=false
+
+# This script is designed to verify that WebSphere Liberty operator is fully deployed through its deployment resource wlo-controller-manager
+
+WSLO_DEPLOYMENT_NAME="wlo-controller-manager"
+
+# sleep 60 seconds initially to provide time for each deployment to get created
+sleep 60
+
+# Get list of deployments in control plane namespace
+DEPLOYMENTS=()
+while IFS='' read -r line; do DEPLOYMENTS+=("$line"); done < <(kubectl get deployment "${WSLO_DEPLOYMENT_NAME}" -n "${namespace}" --no-headers | cut -f1 -d ' ')
+
+# Wait for all deployments to come up - timeout after 5 mins
+for dep in "${DEPLOYMENTS[@]}"; do
+ if ! kubectl rollout status deployment "$dep" -n "${namespace}" --timeout 5m; then
+ fail=true
+ fi
+done
+
+# Fail with some debug prints if issues detected
+if [ ${fail} == true ]; then
+ echo "Problem detected. Printing some debug info.."
+ set +e
+ echo "Describe output of ibm-operator-catalog CatalogSource in openshift-marketplace namespace"
+ kubectl describe CatalogSource ibm-operator-catalog -n openshift-marketplace
+ echo
+ echo "Describe output of ibm-websphere-liberty Subscription in ${namespace} namespace"
+ kubectl describe Subscription ibm-websphere-liberty -n "${namespace}" -o wide
+ echo
+ echo "List of ${WSLO_DEPLOYMENT_NAME} deployments in ${namespace} namespace"
+ kubectl get deployment "${WSLO_DEPLOYMENT_NAME}" -n "${namespace}" -o wide
+ echo
+ echo "List of pods for ${WSLO_DEPLOYMENT_NAME} deployment in ${namespace} namespace"
+ kubectl get pods -n "${namespace}" -o wide
+ WSLOPODS=$(kubectl get pods -n "${namespace}" --no-headers | cut -f1 -d ' ' | grep "${WSLO_DEPLOYMENT_NAME}")
+ echo
+ echo "Describe output of ${WSLO_DEPLOYMENT_NAME} deployment pods in ${namespace} namespace"
+ for pod in "${WSLOPODS[@]}"; do
+ kubectl describe pod "${pod}" -n "${namespace}"
+ done
+ exit 1
+fi
diff --git a/scripts/get-sampleapp-url.sh b/scripts/get-sampleapp-url.sh
new file mode 100644
index 0000000..b0b5be3
--- /dev/null
+++ b/scripts/get-sampleapp-url.sh
@@ -0,0 +1,38 @@
+#!/usr/bin/env bash
+
+set -eE
+
+KUBECONFIG=""
+DEBUGFILE="/tmp/getsampleappurl.log"
+if [[ -e "${DEBUGFILE}" ]]; then
+ rm -f "${DEBUGFILE}"
+fi
+
+# jq reads from stdin
+function parse_input() {
+ eval "$(jq -r '@sh "export KUBECONFIG=\(.KUBECONFIG) APPNAMESPACE=\(.APPNAMESPACE) APPNAME=\(.APPNAME)"')"
+}
+
+parse_input
+
+if [[ -z "${KUBECONFIG}" ]] || [[ -z "${APPNAMESPACE}" ]] || [[ -z "${APPNAME}" ]]; then
+ echo "[ERROR] one or more input parameter is empty" >> "${DEBUGFILE}"
+ echo "[ERROR] one or more input parameter is empty" >&2
+ SAMPLEAPPROUTE="ERROR"
+else
+ # shellcheck disable=SC2129
+ echo "[INFO] using KUBECONFIG ${KUBECONFIG}" >> "${DEBUGFILE}"
+ # shellcheck disable=SC2129
+ echo "[INFO] using APPNAMESPACE ${APPNAMESPACE}" >> "${DEBUGFILE}"
+ # shellcheck disable=SC2129
+ echo "[INFO] using APPNAME ${APPNAME}" >> "${DEBUGFILE}"
+
+ SAMPLEAPPROUTE="$(oc get routes "${APPNAME}" -n "${APPNAMESPACE}" --no-headers | awk '{print $2}')"
+
+ if [[ -z "${SAMPLEAPPROUTE}" ]]; then
+ echo "[ERROR] Error retrieving sample app url from ${APPNAMESPACE}" >> "${DEBUGFILE}"
+ SAMPLEAPPROUTE="NOTFOUND"
+ fi
+fi
+
+echo -n '{"sampleapp_url":"'"${SAMPLEAPPROUTE}"'"}'
diff --git a/tests/other_test.go b/tests/other_test.go
index d03784f..b2cc9c2 100644
--- a/tests/other_test.go
+++ b/tests/other_test.go
@@ -2,15 +2,16 @@
package test
import (
+ "github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper/testhelper"
"testing"
"github.com/stretchr/testify/assert"
)
-func TestRunBasicExample(t *testing.T) {
+func TestRunCompleteExample(t *testing.T) {
t.Parallel()
- options := setupOptions(t, "mod-template-basic", "examples/basic")
+ options := setupOptions(t, "wslo", completeExampleDir)
output, err := options.RunTestConsistency()
assert.Nil(t, err, "This should not have errored")
diff --git a/tests/pr_test.go b/tests/pr_test.go
index 896d726..55f2d75 100644
--- a/tests/pr_test.go
+++ b/tests/pr_test.go
@@ -2,9 +2,18 @@
package test
import (
+ "fmt"
+ "github.com/stretchr/testify/require"
+ "os"
+ "strings"
"testing"
+ "github.com/gruntwork-io/terratest/modules/files"
+ "github.com/gruntwork-io/terratest/modules/logger"
+ "github.com/gruntwork-io/terratest/modules/random"
+ "github.com/gruntwork-io/terratest/modules/terraform"
"github.com/stretchr/testify/assert"
+ "github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper/common"
"github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper/testhelper"
)
@@ -12,34 +21,96 @@ import (
const resourceGroup = "geretain-test-resources"
const completeExampleDir = "examples/complete"
-func setupOptions(t *testing.T, prefix string, dir string) *testhelper.TestOptions {
+func setupOptions(t *testing.T, prefix string, exampleDir string) *testhelper.TestOptions {
options := testhelper.TestOptionsDefaultWithVars(&testhelper.TestOptions{
Testing: t,
- TerraformDir: dir,
+ TerraformDir: exampleDir,
Prefix: prefix,
ResourceGroup: resourceGroup,
})
return options
}
-func TestRunCompleteExample(t *testing.T) {
+func TestRunUpgradeExample(t *testing.T) {
t.Parallel()
- options := setupOptions(t, "mod-template", completeExampleDir)
+ options := setupOptions(t, "wslo-upg", completeExampleDir)
- output, err := options.RunTestConsistency()
- assert.Nil(t, err, "This should not have errored")
- assert.NotNil(t, output, "Expected some output")
+ output, err := options.RunTestUpgrade()
+ if !options.UpgradeTestSkipped {
+ assert.Nil(t, err, "This should not have errored")
+ assert.NotNil(t, output, "Expected some output")
+ }
}
-func TestRunUpgradeExample(t *testing.T) {
+func TestRunSLZExample(t *testing.T) {
t.Parallel()
- options := setupOptions(t, "mod-template-upg", completeExampleDir)
+ // ------------------------------------------------------------------------------------
+ // Deploy SLZ ROKS Cluster first since it is needed for the WAS extension input
+ // ------------------------------------------------------------------------------------
- output, err := options.RunTestUpgrade()
- if !options.UpgradeTestSkipped {
+ prefix := fmt.Sprintf("was-%s", strings.ToLower(random.UniqueId()))
+ realTerraformDir := "./resources"
+ tempTerraformDir, _ := files.CopyTerraformFolderToTemp(realTerraformDir, fmt.Sprintf(prefix+"-%s", strings.ToLower(random.UniqueId())))
+ tags := common.GetTagsFromTravis()
+
+ // Verify ibmcloud_api_key variable is set
+ checkVariable := "TF_VAR_ibmcloud_api_key"
+ val, present := os.LookupEnv(checkVariable)
+ require.True(t, present, checkVariable+" environment variable not set")
+ require.NotEqual(t, "", val, checkVariable+" environment variable is empty")
+
+ // Programmatically determine region to use based on availability
+ region, _ := testhelper.GetBestVpcRegion(val, "../common-dev-assets/common-go-assets/cloudinfo-region-vpc-gen2-prefs.yaml", "eu-de")
+
+ logger.Log(t, "Tempdir: ", tempTerraformDir)
+ existingTerraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
+ TerraformDir: tempTerraformDir,
+ Vars: map[string]interface{}{
+ "prefix": prefix,
+ "region": region,
+ "resource_tags": tags,
+ },
+ // Set Upgrade to true to ensure latest version of providers and modules are used by terratest.
+ // This is the same as setting the -upgrade=true flag with terraform.
+ Upgrade: true,
+ })
+
+ terraform.WorkspaceSelectOrNew(t, existingTerraformOptions, prefix)
+ _, existErr := terraform.InitAndApplyE(t, existingTerraformOptions)
+ if existErr != nil {
+ assert.True(t, existErr == nil, "Init and Apply of temp existing resource failed")
+ } else {
+ // ------------------------------------------------------------------------------------
+ // Deploy WAS extension
+ // ------------------------------------------------------------------------------------
+
+ options := testhelper.TestOptionsDefault(&testhelper.TestOptions{
+ Testing: t,
+ TerraformDir: "extensions/landing-zone",
+ // Do not hard fail the test if the implicit destroy steps fail to allow a full destroy of resource to occur
+ ImplicitRequired: false,
+ TerraformVars: map[string]interface{}{
+ "cluster_id": terraform.Output(t, existingTerraformOptions, "management_cluster_id"),
+ "region": terraform.Output(t, existingTerraformOptions, "region"),
+ },
+ })
+
+ output, err := options.RunTestConsistency()
assert.Nil(t, err, "This should not have errored")
assert.NotNil(t, output, "Expected some output")
}
+
+ // Check if "DO_NOT_DESTROY_ON_FAILURE" is set
+ envVal, _ := os.LookupEnv("DO_NOT_DESTROY_ON_FAILURE")
+ // Destroy the temporary existing resources if required
+ if t.Failed() && strings.ToLower(envVal) == "true" {
+ fmt.Println("Terratest failed. Debug the test and delete resources manually.")
+ } else {
+ logger.Log(t, "START: Destroy (existing resources)")
+ terraform.Destroy(t, existingTerraformOptions)
+ terraform.WorkspaceDelete(t, existingTerraformOptions, prefix)
+ logger.Log(t, "END: Destroy (existing resources)")
+ }
}
diff --git a/tests/resources/README.md b/tests/resources/README.md
new file mode 100644
index 0000000..b4c8811
--- /dev/null
+++ b/tests/resources/README.md
@@ -0,0 +1 @@
+The terraform code in this directory is used by the tests to provision a landing zone ROKS cluster which is required by the WAS SLZ extension.
diff --git a/tests/resources/main.tf b/tests/resources/main.tf
new file mode 100644
index 0000000..b43b7c3
--- /dev/null
+++ b/tests/resources/main.tf
@@ -0,0 +1,768 @@
+##############################################################################
+# SLZ VPC
+##############################################################################
+
+module "landing_zone" {
+ source = "git::https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone//patterns//roks//module?ref=v5.1.1-rc"
+ region = var.region
+ prefix = var.prefix
+ tags = var.resource_tags
+ enable_transit_gateway = false
+ add_atracker_route = false
+
+ override_json_string = <> ${TF_VARS_FILE}
+ terraform apply -input=false -auto-approve -var-file=${TF_VARS_FILE} || exit 1
+
+ region_var_name="region"
+ cluster_id_var_name="cluster_id"
+ cluster_id_value=$(terraform output -state=terraform.tfstate -raw management_cluster_id)
+
+ echo "Appending '${cluster_id_var_name}' and '${region_var_name}' input variable values to ${JSON_FILE}.."
+
+ cd "${cwd}"
+ jq -r --arg region_var_name "${region_var_name}" \
+ --arg region_var_value "${REGION}" \
+ --arg cluster_id_var_name "${cluster_id_var_name}" \
+ --arg cluster_id_value "${cluster_id_value}" \
+ '. + {($region_var_name): $region_var_value}, ($cluster_id_var_name): $cluster_id_value' "${JSON_FILE}" > tmpfile && mv tmpfile "${JSON_FILE}" || exit 1
+
+ echo "Pre-validation complete successfully"
+)
diff --git a/variables.tf b/variables.tf
index df60434..89ea465 100644
--- a/variables.tf
+++ b/variables.tf
@@ -1,9 +1,84 @@
-########################################################################################################################
+##############################################################################
# Input Variables
-########################################################################################################################
+##############################################################################
-#variable "my_variable" {
-# type = string
-# description = "A description of my variable"
-# default = "default_value"
-#}
+variable "ibmcloud_api_key" {
+ description = "APIkey that's associated with the account to use"
+ type = string
+ sensitive = true
+ default = null
+}
+
+variable "region" {
+ description = "Cluster region"
+ type = string
+ nullable = false
+}
+
+variable "cluster_id" {
+ type = string
+ description = "Id of the target IBM Cloud OpenShift Cluster"
+ nullable = false
+}
+
+variable "operator_helm_release_namespace" {
+ type = string
+ description = "Namespace to deploy the helm releases. Default to liberty-operator-helm-release"
+ default = "liberty-operator"
+ nullable = false
+}
+
+variable "add_ibm_operator_catalog" {
+ type = bool
+ description = "Flag to configure the IBM Operator Catalog in the cluster before installing the WebSphere Liberty Operator. Default is true"
+ default = true
+}
+
+variable "create_ws_liberty_operator_namespace" {
+ type = bool
+ description = "Flag to create the namespace where to deploy the WebSphere Liberty Operator. Default to false"
+ default = false
+}
+
+variable "ws_liberty_operator_namespace" {
+ type = string
+ description = "Namespace to install the WebSphere Liberty Operator. Default to openshift-operators"
+ default = "openshift-operators"
+ nullable = false
+}
+
+variable "ws_liberty_operator_target_namespace" {
+ type = string
+ description = "Namespace to be watched by the WebSphere Liberty Operator. Default to null (operator to watch all namespaces)"
+ default = null
+}
+
+variable "cluster_config_endpoint_type" {
+ description = "Specify which type of endpoint to use for for cluster config access: 'default', 'private', 'vpe', 'link'. 'default' value will use the default endpoint of the cluster."
+ type = string
+ default = "default"
+ nullable = false # use default if null is passed in
+ validation {
+ error_message = "Invalid Endpoint Type! Valid values are 'default', 'private', 'vpe', or 'link'"
+ condition = contains(["default", "private", "vpe", "link"], var.cluster_config_endpoint_type)
+ }
+}
+
+variable "install_wslo_sampleapp" {
+ description = "Flag to deploy the WebSphere Liberty sample application. Default to false"
+ type = bool
+ default = false
+ nullable = false
+}
+
+variable "wslo_sampleapp_name" {
+ description = "Application name to use for the WebSphere Liberty sample application"
+ type = string
+ default = "websphereliberty-app-sample"
+}
+
+variable "wslo_sampleapp_namespace" {
+ description = "Namespace to deploy the WebSphere Liberty sample application"
+ type = string
+ default = "samplelibertyapp"
+}
diff --git a/version.tf b/version.tf
index bcb2505..bfcdb3f 100644
--- a/version.tf
+++ b/version.tf
@@ -1,12 +1,30 @@
terraform {
required_version = ">= 1.3.0, <1.6.0"
- # If your module requires any terraform providers, uncomment the "required_providers" section below and add all required providers.
- # Each required provider's version should be a flexible range to future proof the module's usage with upcoming minor and patch versions.
-
- # required_providers {
- # ibm = {
- # source = "IBM-Cloud/ibm"
- # version = ">= 1.49.0, < 2.0.0"
- # }
- # }
+ required_providers {
+ # Use a range in modules
+ ibm = {
+ source = "ibm-cloud/ibm"
+ version = ">= 1.59.0, < 2.0.0"
+ }
+ helm = {
+ source = "hashicorp/helm"
+ version = ">= 2.8.0, <3.0.0"
+ }
+ kubernetes = {
+ source = "hashicorp/kubernetes"
+ version = ">= 2.16.1, <3.0.0"
+ }
+ time = {
+ source = "hashicorp/time"
+ version = ">= 0.9.1, < 1.0.0"
+ }
+ null = {
+ source = "hashicorp/null"
+ version = ">= 3.2.1, < 4.0.0"
+ }
+ external = {
+ source = "hashicorp/external"
+ version = ">=2.2.3, <3.0.0"
+ }
+ }
}