From ef09c1f7a416b043c20a8db9081761e237ec58eb Mon Sep 17 00:00:00 2001 From: "shiva.barik@oracle.com" Date: Tue, 12 Apr 2022 02:32:26 -0700 Subject: [PATCH 1/4] WebCenter Sites Terraform Script --- .../OracleWebCenterSites/.gitignore | 11 + .../OracleWebCenterSites/LICENSE | 26 ++ .../OracleWebCenterSites/README.md | 416 +++++++++++++++++ .../access_k8s_dashboard.sh | 12 + .../charts/wc-sites/.helmignore | 23 + .../charts/wc-sites/Chart.yaml | 26 ++ .../charts/wc-sites/LICENSE.txt | 35 ++ .../charts/wc-sites/create-domain-job.sh | 73 +++ .../charts/wc-sites/create-domain-script.sh | 34 ++ .../charts/wc-sites/createSitesDomain.py | 434 +++++++++++++++++ .../charts/wc-sites/createSitesDomain.sh | 177 +++++++ .../charts/wc-sites/drop-rcu-schema.sh | 27 ++ .../charts/wc-sites/dropRepository.sh | 57 +++ .../charts/wc-sites/read-domain-secret.py | 17 + .../charts/wc-sites/server-config-update.sh | 184 ++++++++ .../charts/wc-sites/templates/_helpers.tpl | 77 +++ .../charts/wc-sites/templates/db.Secret.yaml | 16 + .../wc-sites/templates/domain.Domain.yaml | 162 +++++++ .../templates/domain.PersistentVolume.yaml | 26 ++ .../domain.PersistentVolumeClaim.yaml | 16 + .../wc-sites/templates/domain.Secret.yaml | 16 + .../templates/domain.create.ConfigMap.yaml | 17 + .../wc-sites/templates/domain.create.Job.yaml | 175 +++++++ .../wc-sites/templates/domain.delete.Job.yaml | 71 +++ .../charts/wc-sites/templates/rcu.Secret.yaml | 16 + .../wc-sites/templates/serviceaccount.yaml | 15 + .../wc-sites/templates/traefik.Ingress.yaml | 48 ++ .../wc-sites/templates/wcs.services.yaml | 193 ++++++++ .../charts/wc-sites/unicast.py | 120 +++++ .../charts/wc-sites/utility.sh | 59 +++ .../charts/wc-sites/values.schema.json | 439 ++++++++++++++++++ .../charts/wc-sites/values.yaml | 147 ++++++ .../OracleWebCenterSites/datasources.tf | 6 + .../OracleWebCenterSites/images/wcs-1.PNG | Bin 0 -> 30168 bytes .../OracleWebCenterSites/images/wcs-2.PNG | Bin 0 -> 50202 bytes .../OracleWebCenterSites/images/wcs-3.PNG | Bin 0 -> 50618 bytes .../OracleWebCenterSites/images/wcs-4.PNG | Bin 0 -> 62747 bytes .../OracleWebCenterSites/locals.tf | 6 + .../OracleWebCenterSites/main.tf | 81 ++++ .../modules/database/datasources.tf | 6 + .../modules/database/inputs.tf | 35 ++ .../modules/database/main.tf | 42 ++ .../modules/database/outputs.tf | 6 + .../modules/fss/datasource.tf | 13 + .../modules/fss/inputs.tf | 19 + .../OracleWebCenterSites/modules/fss/main.tf | 57 +++ .../modules/fss/outputs.tf | 12 + .../modules/k8s/inputs.tf | 28 ++ .../modules/k8s/kube_config.tf | 23 + .../OracleWebCenterSites/modules/k8s/main.tf | 57 +++ .../modules/k8s/outputs.tf | 10 + .../modules/node_pool/datasources.tf | 27 ++ .../modules/node_pool/inputs.tf | 10 + .../modules/node_pool/main.tf | 49 ++ .../modules/oci-adb/LICENSE | 27 ++ .../modules/oci-adb/README.md | 68 +++ .../modules/oci-adb/adb.tf | 49 ++ .../modules/oci-adb/datasources.tf | 11 + .../modules/oci-adb/network.tf | 98 ++++ .../modules/oci-adb/outputs.tf | 14 + .../modules/oci-adb/variables.tf | 124 +++++ .../modules/vcn/datasources.tf | 8 + .../modules/vcn/inputs.tf | 12 + .../OracleWebCenterSites/modules/vcn/main.tf | 329 +++++++++++++ .../modules/vcn/outputs.tf | 25 + .../OracleWebCenterSites/outputs.tf | 40 ++ .../OracleWebCenterSites/provider.tf | 17 + .../OracleWebCenterSites/provisioners.tf | 341 ++++++++++++++ .../templates/cluster-kube-config.tpl | 5 + .../templates/create-domain-credentials.tpl | 12 + .../templates/create-rcu-credentials.tpl | 13 + .../templates/create_namespace.tpl | 6 + .../templates/create_secret.tpl | 8 + .../templates/delete_namespace.tpl | 4 + .../templates/deploy-sites.tpl | 12 + .../templates/deploy-traefik.tpl | 20 + .../templates/deploy-weblogic-operator.tpl | 32 ++ .../templates/docker-registry-secret.tpl | 6 + .../templates/helm.values.tpl | 34 ++ .../templates/ingress-hostname.tpl | 12 + .../templates/oke-admin.ServiceAccount.yaml | 21 + .../templates/undeploy-sites.tpl | 9 + .../terraform.tfvars.template | 122 +++++ .../OracleWebCenterSites/variables.tf | 209 +++++++++ 84 files changed, 5340 insertions(+) create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/.gitignore create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/LICENSE create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/README.md create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/access_k8s_dashboard.sh create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/.helmignore create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/Chart.yaml create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/LICENSE.txt create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/create-domain-job.sh create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/create-domain-script.sh create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/createSitesDomain.py create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/createSitesDomain.sh create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/drop-rcu-schema.sh create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/dropRepository.sh create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/read-domain-secret.py create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/server-config-update.sh create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/_helpers.tpl create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/db.Secret.yaml create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.Domain.yaml create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.PersistentVolume.yaml create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.PersistentVolumeClaim.yaml create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.Secret.yaml create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.create.ConfigMap.yaml create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.create.Job.yaml create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.delete.Job.yaml create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/rcu.Secret.yaml create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/serviceaccount.yaml create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/traefik.Ingress.yaml create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/wcs.services.yaml create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/unicast.py create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/utility.sh create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/values.schema.json create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/values.yaml create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/datasources.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/images/wcs-1.PNG create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/images/wcs-2.PNG create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/images/wcs-3.PNG create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/images/wcs-4.PNG create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/locals.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/main.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/database/datasources.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/database/inputs.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/database/main.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/database/outputs.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/fss/datasource.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/fss/inputs.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/fss/main.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/fss/outputs.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/k8s/inputs.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/k8s/kube_config.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/k8s/main.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/k8s/outputs.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/node_pool/datasources.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/node_pool/inputs.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/node_pool/main.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/LICENSE create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/README.md create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/adb.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/datasources.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/network.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/outputs.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/variables.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/vcn/datasources.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/vcn/inputs.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/vcn/main.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/vcn/outputs.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/outputs.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/provider.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/provisioners.tf create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/cluster-kube-config.tpl create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/create-domain-credentials.tpl create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/create-rcu-credentials.tpl create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/create_namespace.tpl create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/create_secret.tpl create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/delete_namespace.tpl create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/deploy-sites.tpl create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/deploy-traefik.tpl create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/deploy-weblogic-operator.tpl create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/docker-registry-secret.tpl create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/helm.values.tpl create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/ingress-hostname.tpl create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/oke-admin.ServiceAccount.yaml create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/undeploy-sites.tpl create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/terraform.tfvars.template create mode 100755 FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/variables.tf diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/.gitignore b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/.gitignore new file mode 100755 index 000000000..8e0755c51 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/.gitignore @@ -0,0 +1,11 @@ +.terraform +terraform.tfstate +terraform.tfstate.backup +TF_VARS.sh +*.tfvars +*.pem +*.p12 +cluster_admin_oci_config.txt +.terraform.tfstate.lock.info +fromtf.auto.yaml +.terraform.lock.hcl diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/LICENSE b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/LICENSE new file mode 100755 index 000000000..21c0d2760 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2022, Oracle and/or its affiliates. +Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +Subject to the condition set forth below, permission is hereby granted to any person obtaining a copy of this +software, associated documentation and/or data (collectively the "Software"), free of charge and under any and +all copyright rights in the Software, and any and all patent rights owned or freely licensable by each licensor +hereunder covering either (i) the unmodified Software as contributed to or provided by such licensor, or +(ii) the Larger Works (as defined below), to deal in both + +(a) the Software, and +(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if one is included with the Software +(each a “Larger Work” to which the Software is contributed by such licensors), + +without restriction, including without limitation the rights to copy, create derivative works of, display, +perform, and distribute the Software and make, use, sell, offer for sale, import, export, have made, and have +sold the Software and the Larger Work(s), and to sublicense the foregoing rights on either these or other terms. + +This license is subject to the following condition: +The above copyright notice and either this complete permission notice or at a minimum a reference to the UPL must +be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. \ No newline at end of file diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/README.md b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/README.md new file mode 100755 index 000000000..24368221a --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/README.md @@ -0,0 +1,416 @@ +# Terraform scripts for WCS-K8S + +#### Disclaimer + +This deployment of Oracle WebCenter Sites makes use of the Terraform scripts and Oracle WebCenter Sites Helm Chart based on the [fmw-kubernetes](https://github.com/oracle/fmw-kubernetes) release. + +#### Caveats + +Although this release follows the same flow as the [fmw-kubernetes](https://github.com/oracle/fmw-kubernetes) release, only the Traefik ingress controller is currently supported. + +#### Contents + +* [Prerequisites](#prerequisites) +* [Installation](#installation) +* [Access the Deployment](#access-the-deployment) +* [If deploying with Sub-domain and SSL](#if-deploying-with-sub-domain-and-ssl) +* [Configure WebCenter Sites](#configure-webcenter-sites) + + +### Prerequisites + +This terraform deployment requires the prior installation of the following: + +- **terraform >= 0.14** + + [tfswitch](https://tfswitch.warrensbox.com/Install/) can be used for flexibility of working with multiple versions of terraform, but it is only available on Linux and Mac OS X, for Windows or if you prefer to install the base software, see [https://learn.hashicorp.com/tutorials/terraform/install-cli](https://learn.hashicorp.com/tutorials/terraform/install-cli) for basic installation instructions. + +- **kubectl >= 1.18.10 (the Kubernetes cli)** + + See [https://kubernetes.io/docs/tasks/tools/install-kubectl/](https://kubernetes.io/docs/tasks/tools/install-kubectl/) for installation instructions, although kubectl is usually installed as part of Docker Desktop, so if you use Docker it is likely already installed. + +- **helm >= 3.5.4** + + Helm is a kubernetes deployment package manager. The OCI Service Broker is packaged in a Helm chart, and so is the etcd cluster deployment. + See [https://helm.sh/docs/intro/install/](https://helm.sh/docs/intro/install/) to install helm locally. + +- **OCI Command Line Interface (CLI)** + + See [https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/cliinstall.htm](https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/cliinstall.htm) for a quick starting guide. Make sure you upload your **public key** in your OCI account and note the fingerprint information. + + The OCI CLI is used to configure the access to the OKE cluster locally only, so this deployment could be modified to only use `kubectl` if this is intended for a remote setup, but configuring the CLI helps in several tasks. + +- **Follow this document to set up OCI Terraform** + [https://docs.oracle.com/en-us/iaas/developer-tutorials/tutorials/tf-provider/01-summary.htm](https://docs.oracle.com/en-us/iaas/developer-tutorials/tutorials/tf-provider/01-summary.htm) + + +### Installation + +#### 1. Get the repository + +* Download the Terraform scripts to deploy WebCenter Sites from this [repository](https://github.com/oracle/fmw-kubernetes.git). + + ```bash + $ git clone https://github.com/oracle/fmw-kubernetes.git + ``` + +* You can now use the deployment scripts from fmw-kubernetes/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites to set up the WebCenter Sites domain as further described in this document. This will be your home directory to run the terraform scripts. + + ```bash + $ cd fmw-kubernetes/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites + ``` + +#### 2. Update terraform.tfvars file + +Create a `terraform.tfvars` file from the `terraform.tfvars.template` file and populate the following mandatory information: + +``` +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +tenancy_ocid = "ocid1.tenancy.oc1..." +compartment_ocid = "ocid1.compartment.oc1..." +region = "us-ashburn-1" + +## Things to provision +# VCN, OKE cluster, node_pool(s) +# if false, the template assumes the cluster is provisioned and that kubectl has access to the cluster. +provision_cluster = true + +# File Storage and mount point export +provision_filesystem = true +provision_mount_target = true +provision_export = true + +# Database (DBaaS on OCI) +# If false, a database jdbc_connection URL needs to be provided, and the database needs to be reachable from this VCN +provision_database = true + +# Autonomous Database (User can use DBAAS or Autonomous DB. Turn this on if provision_adb is false) +provision_adb = false +# possible values (OLTP) +adb_database_db_workload = "OLTP" +adb_password = "Oradoc_db12W#_" + +# WebLogic Operator +provision_weblogic_operator = true +# Ingress controller +provision_traefik = true +provision_secrets = true +#This will deploy the site in environment +provision_sites = true + +## File storage details +# If the VCN is not provided by this template, the following variables must be provided +fss_subnet_id = null +# If the cluster and VCN are not provided by this template, +fss_source_cidr = "0.0.0.0/0" +# File Storage mount target Availability Domain index +ad_number = 2 + +#if using existing file system. exportset and filesystem must belong to same ad. +#filesystem_ocid = "" +#if using existing mount target. +#mount_target_ocid = "" +#mount_target_ip = "" + +## Credentials +# Input your Container registry login credentials +# this is the registry where sites images is going to be looked at +container_registry = "phx.ocir.io" +container_registry_username = "devcec/WCSitesUser" +container_registry_email = "" +container_registry_password = "MNOPabcd:>123xyZ" +container_registry_image = "oracle/wcsites:12.2.1.4" + +# Create WCSites domain Admin Console credentials +sites_domain_admin_username = "weblogic" +# Password must contain 1 Upper, 1 number and be at least 8 characters long +sites_domain_admin_password = "Welcome1" + +# Create Database credentials +# Password must be 9 to 30 characters and contain at least 2 uppercase, 2 lowercase, 2 special, and 2 numeric characters. +# The special characters must be _, #, or -. +db_sys_password = "Oradoc_db12W#x_" + +# Create RCU Schema credentials +# rcu_prefix must be less than or equals to 5 characters +rcu_prefix = "WCS1" +rcu_username = "WCS1" +# Password must be 9 to 30 characters and contain at least 2 uppercase, 2 lowercase, 2 special, and 2 numeric characters. +# The special characters must be _, #, or -. +rcu_password = "Oradoc_db12W#x_" +# If connecting to an external DB, specify the jdbc_connection_url +# !!! You will need to adjust the security list on your database VCN/subnet to authorize access from the OKE cluster nodes, +# which may require VCN peering (not provided here) +jdbc_connection_url = null + +# Database information max 8 charachtor allowed for db system +database_name = "sitesdb" +database_unique_name = "sitesdb" + +# Kubernetes namespaces (no need to change) +#sites_kubernetes_namespace = "wcsites-ns" +#weblogic_operator_namespace = "operator-ns" +#ingress_controller_namespace = "traefik" + +# Domain name +sites_dns_name ="" + +# VCN config +vcn_cidr = "10.0.0.0/16" + +# SSH key to access database and Kubernetes nodes +ssh_authorized_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDtmEF/NbYdBMiF1XjTPgY6M4Nw8RI9AezkXKk7eJ7YylJH8AAApBb0aw7ERgEza3cTkQVK74MH6Rz9nvi7BdoMB/HWv/Ap/StsqFP2oC3BNi+ljVzXreNtVv1G1JqiRbKzjLNtyHw02wtuTKeoXwaex/ElcAObLdqbuxTgw1M1pw+XnSdnBazqAU6otVpnlgkGNiZDE1yvk7t5tL85tZj8dhrIBGEbHu0/lPA/d15PqgAi5bAIO/E0Dt2vh5hJJMjtM0BWf7PyhMgkOeTszERRHuteBroFbZyzxTvJZiUmL16SMcvLnDt3jL4gIzUkOqBIA9haFyo0poGBC8cYECiB vk" + +# Cluster config +oke_cluster = { + name = "OKE_Cluster" + k8s_version = "v1.20.8" + pods_cidr = "10.1.0.0/16" + services_cidr = "10.2.0.0/16" + cluster_options_add_ons_is_kubernetes_dashboard_enabled = true + cluster_options_add_ons_is_tiller_enabled = true +} + +# defaults to 1 pool, feel free to add more if needed. +node_pools = [ + { + pool_name = "pool1" + node_shape = "VM.Standard2.4" + node_count = 2 + node_labels = { + "pool_name" = "pool1" + } + } +] + +# Optional parameter, requires a vault and key to be created in the account. +secrets_encryption_key_ocid = null +``` + +* Update tenancy_ocid, compartment_ocid, region as per your Oracle Cloud Infrastructure account. +* Update ssh_authorized_key with your SSH public key. This key used to access database and Kubernetes nodes. +* If you don't want to create a new database on the Oracle Database Service and want to use an existing database, keep variable provision_database as false and specify the jdbc_connection_url value in the terraform.tfvars config file. +`Example : jdbc_connection_url = ":/."` +* If you wish to encrypt Kubernetes secrets at rest, you can provision a vault and key and reference this key OCID as secrets_encryption_key_ocid to use in the kubernetes cluster. + +#### 3. Push WCSites Image to OCIR + +- **Create Oracle Cloud Infrastructure Registry** + + Under Solutions and Platform, go to Developer Services and click Container Registry + Click on Create repository + Enter Repository name and Access type to create a repository. + + ![README](images/wcs-1.PNG) + +- **Push wcsites docker image to OCIR** + + Download latest sites docker image from [here](https://support.oracle.com/epmos/faces/ui/patch/PatchDetail.jspx?patchId=33579457). + Unzip the downloaded zip file. + + ```bash + $ unzip p33579457_122140_Linux-x86-64.zip + ``` + + Load the image archive using the docker load command. + + ```bash + $ docker load < wcsites-20210422.tar.gz + ``` + +- **Create an "Auth token" which will be used as docker password to push/pull images from OCIR** + + Login to OCI Console, navigate to Profile, User Settings, Auth Tokens, click on Generate Tokens button. + Enter Description and then click Generate Tokens. + Token will get generated + Copy the generated token. `NOTE: It will only be displayed one time, so you need to copy it to a secure place for further use.` + +- **Docker login** + + Do a docker login on any OCI node where you need to push/pull images : + ``` + docker login .ocir.io + Username: /oracleidentitycloudservice/ + Password: + ``` + + example : + + ```bash + $ docker login phx.ocir.io + Username: axcmmdmzqtqb/oracleidentitycloudservice/ + Password: + ``` + +- **Push an image** + ``` + docker tag .ocir.io//: + docker push .ocir.io//: + ``` + example : + + ```bash + $ docker tag oracle/wcsites:12.2.1.4 phx.ocir.io/axcmmdmzqtqb/oracle/wcsites:12.2.1.4 + $ docker push phx.ocir.io/axcmmdmzqtqb/oracle/wcsites:12.2.1.4 + ``` + +- **Update Container registry details in terraform.tfvars** + + Input your Container registry login credentials in terraform.tfvars file. Update below variables in terraform.tfvars. + + ``` + container_registry - + container_registry_username - + container_registry_email - + container_registry_password - + container_registry_image - + ``` + +#### 4. Deploying with Sub Domain + +If you want to deploy with sub-domain then update sites_dns_name variable in terraform.tfvars +`sites_dns_name =""` + +#### 5. Deployment Options + +By default, the template will deploy the following infrastrucutre resources: + +* A Virtual Cloud Network (VCN). +* Subnets for the Kubernetes Load Balancers (public subnet) and nodes (private subnet). +* A Kubernetes cluster on the Oracle Kubernetes Engine service. +* A database on the Oracle Database Service. +* A file storage Network File Server (NFS) and mount point export path. +* Security lists to allow proper communication. + +On the Kubernetes cluster provisioned, the template also create or deploy: + +* Namespaces for the different components. +* The secrets containing the credentials required. +* The required WebLogic Operator Helm chart. +* The required ingress controller (using Traefik). + +#### 6. Deploy the Infrastructure + +* Use the following commands: + + ```bash + $ terraform init + $ terraform plan + $ terraform apply + ``` + + and answer Yes at the prompt to deploy the stack. + + +### Access the Deployment + +* Get the public IP of the load balancer created by the ingress controller + + ```bash + $ kubectl get services -n traefik + ``` + + This should output something like: + + ```bash + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + traefik LoadBalancer 10.2.13.1 132.226.115.178 9000:31473/TCP,30305:30305/TCP,30443:30443/TCP 7d19h + ``` + + If it is still pending, wait a few more minutes before checking again. + Get the EXTERNAL-IP value for the load balancer + +* Make sure the WebCenter Sites domain servers are running: + You can check running pods with: + + ```bash + $ kubectl get pods -n wcsites-ns + ``` + You should see: + + ```bash + NAME READY STATUS RESTARTS AGE + wcsitesinfra-adminserver 1/1 Running 0 7d19h + wcsitesinfra-create-fmw-infra-sample-domain-job-4gdn4 0/1 Completed 0 7d19h + wcsitesinfra-wcsites-server1 1/1 Running 0 7d18h + ``` + + Make sure the STATUS is RUNNING and that READY is 1/1 for pods above before checking the UR + +* With the public IP gathered earlier, browse to http://PUBLIC_IP:30305/console to get to the WebLogic console. + +* You can log into the console with the `sites_domain_admin_username` and `sites_domain_admin_password` you specified in the `terraform.tfvars` file. + + +### If deploying with Sub-domain and SSL + +If you are deploying WCSites with Sub-domain and SSL then follow these steps else move to Configure WebCenter Sites directly. +Map the loadbalancer EXTERNAL-IP with the sub-domain. +Get SSL certificates from your DNS provider. +That includes 3 files : + +* SSL Certificate +* CA Certificate +* Private Key + +Login to OCI console and go to the Load Balancer created be terraform script in your compartment + +* Go to Certificates, Certificate Resource - Load Balancer Managed Certificate +* Click on add Certificate. Give a name and add all 3 files +* Click on Listeners +* Add a new Listener "TCP-443" +* Port - 443 (select SSL checkbox) +* Add certificate here +* Backend Set - TCP-30305 +* Click on Save Changes to save + +![README](images/wcs-2.PNG) + +Configure WebCenter Sites by hitting url : http://PUBLIC_IP:30305/sites/sitesconfigsetup +**update hostname as sub-domain name, port as 443 and secure connection as yes.** + +![README](images/wcs-3.PNG) + +![README](images/wcs-4.PNG) + + +### Configure WebCenter Sites + +* Configure WebCenter Sites by hitting url : http://PUBLIC_IP:30305/sites/sitesconfigsetup +When installing, select sample sites to be installed and enter the required passwords. Do not change the sites-config location. If you change the location, installation will fail. + +* After the configuration is complete, edit the domain, and restart the Managed Server. +To stop Managed Servers: + + ```bash + $ kubectl patch domain wcsitesinfra -n wcsites-ns --type='json' -p='[{"op": "replace", "path": "/spec/clusters/0/replicas", "value": 0 }]' + ``` + + To start all configured Managed Servers: + + ```bash + $ kubectl patch domain wcsitesinfra -n wcsites-ns --type='json' -p='[{"op": "replace", "path": "/spec/clusters/0/replicas", "value": 3 }]' + ``` + +* You can check running pods with: + + ```bash + $ kubectl get pods -n wcsites-ns + ``` + + You should see: + + ```bash + NAME READY STATUS RESTARTS AGE + wcsitesinfra-adminserver 1/1 Running 0 7d19h + wcsitesinfra-create-fmw-infra-sample-domain-job-4gdn4 0/1 Completed 0 7d19h + wcsitesinfra-wcsites-server1 1/1 Running 0 7d18h + wcsitesinfra-wcsites-server2 1/1 Running 0 11m + wcsitesinfra-wcsites-server3 1/1 Running 0 11m + ``` + +* Access WebCenter Sites by hitting url : http://PUBLIC_IP:30305/sites/ + + Incase of Sub-domain with SSL : https://SUB-DOMAIN/sites/ diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/access_k8s_dashboard.sh b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/access_k8s_dashboard.sh new file mode 100755 index 000000000..2bbcab4e8 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/access_k8s_dashboard.sh @@ -0,0 +1,12 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +echo "Use the token described below to connect" +kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep oke-admin | awk '{print $1}') + +echo "Running k8s proxy..." +kubectl proxy & + +echo "Opening browser..." +sleep 3 +open 'http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/login' diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/.helmignore b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/.helmignore new file mode 100755 index 000000000..0e8a0eb36 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/.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/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/Chart.yaml b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/Chart.yaml new file mode 100755 index 000000000..182cac502 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/Chart.yaml @@ -0,0 +1,26 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +apiVersion: v2 +name: wc-sites +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +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.1.0 + +# 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. +appVersion: 1.0.0 diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/LICENSE.txt b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/LICENSE.txt new file mode 100755 index 000000000..837b39bb8 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/LICENSE.txt @@ -0,0 +1,35 @@ +Copyright (c) 2022, Oracle and/or its affiliates. + +The Universal Permissive License (UPL), Version 1.0 + +Subject to the condition set forth below, permission is hereby granted to any +person obtaining a copy of this software, associated documentation and/or data +(collectively the "Software"), free of charge and under any and all copyright +rights in the Software, and any and all patent rights owned or freely +licensable by each licensor hereunder covering either (i) the unmodified +Software as contributed to or provided by such licensor, or (ii) the Larger +Works (as defined below), to deal in both + +(a) the Software, and +(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +one is included with the Software (each a "Larger Work" to which the Software +is contributed by such licensors), + +without restriction, including without limitation the rights to copy, create +derivative works of, display, perform, and distribute the Software and make, +use, sell, offer for sale, import, export, have made, and have sold the +Software and the Larger Work(s), and to sublicense the foregoing rights on +either these or other terms. + +This license is subject to the following condition: +The above copyright notice and either this complete permission notice or at +a minimum a reference to the UPL must be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/create-domain-job.sh b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/create-domain-job.sh new file mode 100755 index 000000000..8596d9cbf --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/create-domain-job.sh @@ -0,0 +1,73 @@ +#!/bin/bash +# Copyright (c) 2022, Oracle and/or its affiliates. +# +# Licensed under the Universal Permissive License v 1.0 as shown at +# https://oss.oracle.com/licenses/upl +# + +function exitIfError { + if [ "$1" != "0" ]; then + echo "$2" + exit $1 + fi +} + +# Include common utility functions +source ${CREATE_DOMAIN_SCRIPT_DIR}/utility.sh + +export CUSTOM_MANAGED_BASE_NAME=${CUSTOM_MANAGED_BASE_NAME,,} +export CUSTOM_ADMIN_NAME=${CUSTOM_ADMIN_NAME,,} + +# Verify the script to create the domain exists +script=${CREATE_DOMAIN_SCRIPT_DIR}/createSitesDomain.sh + +checkCreateDomainScript $script + +# Execute the script to create the domain +source $script +exitIfError $? "ERROR: $script failed." + +# Verify the script to create the domain exists +script=${CREATE_DOMAIN_SCRIPT_DIR}/create-domain-script.sh + +checkCreateDomainScript $script +checkDomainSecret +prepareDomainHomeDir + +# Execute the script to create the domain +source $script +exitIfError $? "ERROR: $script failed." + +echo "Copying ${CREATE_DOMAIN_SCRIPT_DIR}/server-config-update.sh to PV ${DOMAIN_HOME_DIR}" +cp ${CREATE_DOMAIN_SCRIPT_DIR}/server-config-update.sh ${DOMAIN_HOME_DIR} +chmod +x ${DOMAIN_HOME_DIR}/server-config-update.sh + +echo "Copying ${CREATE_DOMAIN_SCRIPT_DIR}/unicast.py to PV ${DOMAIN_HOME_DIR}" +cp ${CREATE_DOMAIN_SCRIPT_DIR}/unicast.py ${DOMAIN_HOME_DIR} +chmod +x ${DOMAIN_HOME_DIR}/unicast.py + +echo "replacing tokens in ${DOMAIN_HOME_DIR}/server-config-update.sh" +sed -i -e "s:%LOAD_BALANCER_HOSTNAME%:${LB_HOST}:g" ${DOMAIN_HOME_DIR}/server-config-update.sh +sed -i -e "s:%LOAD_BALANCER_PORTNUMBER%:${LB_PORT}:g" ${DOMAIN_HOME_DIR}/server-config-update.sh +sed -i -e "s:%LOAD_BALANCER_PROTOCOL%:${LB_PROTOCOL}:g" ${DOMAIN_HOME_DIR}/server-config-update.sh + +sed -i -e "s:%SITES_SAMPLES%:${SITES_SAMPLES}:g" ${DOMAIN_HOME_DIR}/server-config-update.sh + +sed -i -e "s:%SITES_CACHE_PORTS%:${SITES_CACHE_PORTS}:g" ${DOMAIN_HOME_DIR}/server-config-update.sh + +sed -i -e "s:%MANAGED_SERVER_PORT%:${MANAGED_SERVER_PORT}:g" ${DOMAIN_HOME_DIR}/server-config-update.sh + +sed -i -e "s:%SITES_ADMIN_USERNAME%:${SITES_ADMIN_USERNAME}:g" ${DOMAIN_HOME_DIR}/server-config-update.sh +sed -i -e "s:%SITES_ADMIN_PASSWORD%:${SITES_ADMIN_PASSWORD}:g" ${DOMAIN_HOME_DIR}/server-config-update.sh +sed -i -e "s:%SITES_APP_USERNAME%:${SITES_APP_USERNAME}:g" ${DOMAIN_HOME_DIR}/server-config-update.sh +sed -i -e "s:%SITES_APP_PASSWORD%:${SITES_APP_PASSWORD}:g" ${DOMAIN_HOME_DIR}/server-config-update.sh +sed -i -e "s:%SITES_SS_USERNAME%:${SITES_SS_USERNAME}:g" ${DOMAIN_HOME_DIR}/server-config-update.sh +sed -i -e "s:%SITES_SS_PASSWORD%:${SITES_SS_PASSWORD}:g" ${DOMAIN_HOME_DIR}/server-config-update.sh +sed -i -e "s:%DOMAIN_HOME%:${DOMAIN_HOME_DIR}:g" ${DOMAIN_HOME_DIR}/server-config-update.sh +sed -i -e "s:%DOMAIN_ROOT_DIR%:${DOMAIN_ROOT_DIR}:g" ${DOMAIN_HOME_DIR}/server-config-update.sh + + +# DON'T REMOVE THIS +# This script has to contain this log message. +# It is used to determine if the job is really completed. +echo "Successfully Completed" diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/create-domain-script.sh b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/create-domain-script.sh new file mode 100755 index 000000000..df5cf2403 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/create-domain-script.sh @@ -0,0 +1,34 @@ +#!/bin/bash +# Copyright (c) 2022, Oracle and/or its affiliates. +# +# Licensed under the Universal Permissive License v 1.0 as shown at +# https://oss.oracle.com/licenses/upl + +export DOMAIN_HOME=${DOMAIN_HOME_DIR} + +echo wlst.sh -skipWLSModuleScanning ${CREATE_DOMAIN_SCRIPT_DIR}/createSitesDomain.py -oh ${ORACLE_HOME} -jh ${JAVA_HOME} -parent ${DOMAIN_HOME}/.. -name ${CUSTOM_DOMAIN_NAME} -user `cat /weblogic-operator/secrets/username` -password `cat /weblogic-operator/secrets/password` -rcuDb ${CUSTOM_CONNECTION_STRING} -rcuPrefix ${CUSTOM_RCUPREFIX} -rcuSchemaPwd `cat /weblogic-operator/rcu-secrets/password` -adminListenPort ${CUSTOM_ADMIN_LISTEN_PORT} -adminName ${CUSTOM_ADMIN_NAME} -managedNameBase ${CUSTOM_MANAGED_BASE_NAME} -managedServerPort ${CUSTOM_MANAGEDSERVER_PORT} -prodMode ${CUSTOM_PRODUCTION_MODE} -managedServerCount ${CUSTOM_MANAGED_SERVER_COUNT} -clusterName ${CUSTOM_CLUSTER_NAME} -exposeAdminT3Channel ${EXPOSE_T3_CHANNEL_PREFIX} -t3ChannelPublicAddress ${T3_PUBLIC_ADDRESS} -t3ChannelPort ${T3_CHANNEL_PORT} -domainType wcsites -machineName wcsites_machine + +# Create the domain +wlst.sh -skipWLSModuleScanning \ + ${CREATE_DOMAIN_SCRIPT_DIR}/createSitesDomain.py \ + -oh ${ORACLE_HOME} \ + -jh ${JAVA_HOME} \ + -parent ${DOMAIN_HOME}/.. \ + -name ${CUSTOM_DOMAIN_NAME} \ + -user `cat /weblogic-operator/secrets/username` \ + -password `cat /weblogic-operator/secrets/password` \ + -rcuDb ${CUSTOM_CONNECTION_STRING} \ + -rcuPrefix ${CUSTOM_RCUPREFIX} \ + -rcuSchemaPwd `cat /weblogic-operator/rcu-secrets/password` \ + -adminListenPort ${CUSTOM_ADMIN_LISTEN_PORT} \ + -adminName ${CUSTOM_ADMIN_NAME} \ + -managedNameBase ${CUSTOM_MANAGED_BASE_NAME} \ + -managedServerPort ${CUSTOM_MANAGEDSERVER_PORT} \ + -prodMode ${CUSTOM_PRODUCTION_MODE} \ + -managedServerCount ${CUSTOM_MANAGED_SERVER_COUNT} \ + -clusterName ${CUSTOM_CLUSTER_NAME} \ + -exposeAdminT3Channel ${EXPOSE_T3_CHANNEL_PREFIX} \ + -t3ChannelPublicAddress ${T3_PUBLIC_ADDRESS} \ + -t3ChannelPort ${T3_CHANNEL_PORT} \ + -domainType wcsites \ + -machineName wcsites_machine diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/createSitesDomain.py b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/createSitesDomain.py new file mode 100755 index 000000000..2694b54f6 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/createSitesDomain.py @@ -0,0 +1,434 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. +# +# Licensed under the Universal Permissive License v 1.0 as shown at +# https://oss.oracle.com/licenses/upl + +import os +import sys + +import com.oracle.cie.domain.script.jython.WLSTException as WLSTException + +class WCSITES12214Provisioner: + + MACHINES = { + 'wcsites_machine' : { + 'NMType': 'SSL', + 'ListenAddress': 'localhost', + 'ListenPort': 5658 + } + } + + MANAGED_SERVERS = [] + + JRF_12214_TEMPLATES = { + 'baseTemplate' : '@@ORACLE_HOME@@/wlserver/common/templates/wls/wls.jar', + 'extensionTemplates' : [ + '@@ORACLE_HOME@@/oracle_common/common/templates/wls/oracle.jrf_template.jar', + '@@ORACLE_HOME@@/em/common/templates/wls/oracle.em_wls_template.jar' + ], + 'serverGroupsToTarget' : [ 'JRF-MAN-SVR' ] + } + + WCSITES_12214_TEMPLATES = { + 'extensionTemplates' : [ + '@@ORACLE_HOME@@/wcsites/common/templates/wls/oracle.wcsites.examples.template.jar' + ], + 'serverGroupsToTarget' : [ 'WCSITES-MGD-SVR' ] + } + + def __init__(self, oracleHome, javaHome, domainParentDir, adminListenPort, adminName, managedNameBase, managedServerPort, prodMode, managedCount, clusterName): + self.oracleHome = self.validateDirectory(oracleHome) + self.javaHome = self.validateDirectory(javaHome) + self.domainParentDir = self.validateDirectory(domainParentDir, create=True) + return + + def createWCSitesDomain(self, domainName, user, password, db, dbPrefix, dbPassword, adminListenPort, adminName, managedNameBase, managedServerPort, prodMode, managedCount, clusterName, domainType, exposeAdminT3Channel=None, t3ChannelPublicAddress=None, t3ChannelPort=None): + domainHome = self.createBaseDomain(domainName, user, password, adminListenPort, adminName, managedNameBase, managedServerPort, prodMode, managedCount, clusterName, domainType) + + if domainType == "wcsites": + self.extendWcsitesDomain(domainHome, db, dbPrefix, dbPassword, exposeAdminT3Channel, t3ChannelPublicAddress, t3ChannelPort) + + def createManagedServers(self, ms_count, managedNameBase, ms_port, cluster_name, ms_servers): + # Create managed servers + for index in range(0, ms_count): + cd('/') + msIndex = index+1 + cd('/') + name = '%s%s' % (managedNameBase, msIndex) + create(name, 'Server') + cd('/Servers/%s/' % name ) + print('managed server name is %s' % name); + set('ListenPort', ms_port) + set('NumOfRetriesBeforeMSIMode', 0) + set('RetryIntervalBeforeMSIMode', 1) + set('Cluster', cluster_name) + set('Machine', machineName) + ms_servers.append(name) + print ms_servers + return ms_servers + + def createBaseDomain(self, domainName, user, password, adminListenPort, adminName, managedNameBase, managedServerPort, prodMode, managedCount, clusterName, domainType): + baseTemplate = self.replaceTokens(self.JRF_12214_TEMPLATES['baseTemplate']) + + readTemplate(baseTemplate) + setOption('DomainName', domainName) + setOption('JavaHome', self.javaHome) + if (prodMode == 'true'): + setOption('ServerStartMode', 'prod') + else: + setOption('ServerStartMode', 'dev') + set('Name', domainName) + + admin_port = int(adminListenPort) + ms_port = int(managedServerPort) + ms_count = int(managedCount) + + # Create Admin Server + # ======================= + print 'Creating Admin Server...' + cd('/Servers/AdminServer') + #set('ListenAddress', '%s-%s' % (domain_uid, admin_server_name_svc)) + set('ListenPort', admin_port) + set('Name', adminName) + + # Define the user password for weblogic + # ===================================== + cd('/Security/' + domainName + '/User/weblogic') + set('Name', user) + set('Password', password) + + # Create a cluster + # ====================== + print 'Creating cluster...' + cd('/') + cl=create(clusterName, 'Cluster') + + # Create Node Manager + # ======================= + print 'Creating Node Managers...' + for machine in self.MACHINES: + cd('/') + create(machine, 'Machine') + cd('Machine/' + machine) + create(machine, 'NodeManager') + cd('NodeManager/' + machine) + for param in self.MACHINES[machine]: + set(param, self.MACHINES[machine][param]) + + # Create managed servers + self.MANAGED_SERVERS = self.createManagedServers(ms_count, managedNameBase, ms_port, clusterName, self.MANAGED_SERVERS) + + setOption('OverwriteDomain', 'true') + domainHome = self.domainParentDir + '/' + domainName + print 'Will create Base domain at ' + domainHome + + print 'Writing base domain...' + writeDomain(domainHome) + closeTemplate() + print 'Base domain created at ' + domainHome + return domainHome + + def readAndApplyJRFTemplates(self, domainHome, db, dbPrefix, dbPassword, exposeAdminT3Channel, t3ChannelPublicAddress, t3ChannelPort): + print 'Extending domain at ' + domainHome + print 'Database ' + db + readDomain(domainHome) + setOption('AppDir', self.domainParentDir + '/applications') + + print 'ExposeAdminT3Channel %s with %s:%s ' % (exposeAdminT3Channel, t3ChannelPublicAddress, t3ChannelPort) + if 'true' == exposeAdminT3Channel: + self.enable_admin_channel(t3ChannelPublicAddress, t3ChannelPort) + + self.applyJRFTemplates() + print 'Extension Templates added' + return + + def applyJRFTemplates(self): + print 'Applying JRF templates...' + for extensionTemplate in self.JRF_12214_TEMPLATES['extensionTemplates']: + addTemplate(self.replaceTokens(extensionTemplate)) + return + + def applyWCSITESTemplates(self): + print 'Applying WCSITES templates...' + for extensionTemplate in self.WCSITES_12214_TEMPLATES['extensionTemplates']: + addTemplate(self.replaceTokens(extensionTemplate)) + return + + def targetWCSITESServers(self,serverGroupsToTarget): + print 'Targeting Server Groups...' + cd('/') + for managedName in self.MANAGED_SERVERS: + setServerGroups(managedName, serverGroupsToTarget) + print "Set CoherenceClusterSystemResource to defaultCoherenceCluster for server:" + managedName + cd('/Servers/' + managedName) + set('CoherenceClusterSystemResource', 'defaultCoherenceCluster') + return + + def targetWCSITESCluster(self): + print 'Targeting Cluster ...' + cd('/') + print "Set CoherenceClusterSystemResource to defaultCoherenceCluster for cluster:" + clusterName + cd('/Cluster/' + clusterName) + set('CoherenceClusterSystemResource', 'defaultCoherenceCluster') + return + + def extendWcsitesDomain(self, domainHome, db, dbPrefix, dbPassword, exposeAdminT3Channel, t3ChannelPublicAddress, t3ChannelPort): + self.readAndApplyJRFTemplates(domainHome, db, dbPrefix, dbPassword, exposeAdminT3Channel, t3ChannelPublicAddress, t3ChannelPort) + self.applyWCSITESTemplates() + + print 'Extension Templates added' + + if 'wcsites_server1' not in self.MANAGED_SERVERS: + print 'INFO: deleting wcsites_server1' + cd('/') + delete('wcsites_server1','Server') + print 'INFO: deleted wcsites_server1' + + self.configureJDBCTemplates(db,dbPrefix,dbPassword) + + print 'Targeting Server Groups...' + serverGroupsToTarget = list(self.JRF_12214_TEMPLATES['serverGroupsToTarget']) + serverGroupsToTarget.extend(self.WCSITES_12214_TEMPLATES['serverGroupsToTarget']) + + cd('/') + self.targetWCSITESServers(serverGroupsToTarget) + + cd('/') + self.targetWCSITESCluster() + + print "Set WLS clusters as target of defaultCoherenceCluster:[" + clusterName + "]" + cd('/CoherenceClusterSystemResource/defaultCoherenceCluster') + set('Target', clusterName) + + print 'Preparing to update domain...' + updateDomain() + print 'Domain updated successfully' + closeDomain() + return + + def configureJDBCTemplates(self,db,dbPrefix,dbPassword): + print 'Configuring the Service Table DataSource...' + #fmwDb = db + fmwDb = 'jdbc:oracle:thin:@' + db + driverName = 'oracle.jdbc.OracleDriver' + print "fmwDb..." + fmwDb + + cd('/JdbcSystemResource/opss-data-source/JdbcResource/opss-data-source/JdbcDriverParams/NO_NAME_0') + set('DriverName', driverName) + set('URL', fmwDb) + set('PasswordEncrypted', dbPassword) + + user = dbPrefix + '_OPSS' + cd('Properties/NO_NAME_0/Property/user') + set('Value', user) + + print "Set user..." + user + + cd('/JdbcSystemResource/opss-audit-DBDS/JdbcResource/opss-audit-DBDS/JdbcDriverParams/NO_NAME_0') + set('DriverName', driverName) + set('URL', fmwDb) + set('PasswordEncrypted', dbPassword) + + user = dbPrefix + '_IAU_APPEND' + cd('Properties/NO_NAME_0/Property/user') + set('Value', user) + + print "Set user..." + user + + cd('/JdbcSystemResource/opss-audit-viewDS/JdbcResource/opss-audit-viewDS/JdbcDriverParams/NO_NAME_0') + set('DriverName', driverName) + set('URL', fmwDb) + set('PasswordEncrypted', dbPassword) + + user = dbPrefix + '_IAU_VIEWER' + cd('Properties/NO_NAME_0/Property/user') + set('Value', user) + + print "Set user..." + user + + cd('/JdbcSystemResource/LocalSvcTblDataSource/JdbcResource/LocalSvcTblDataSource/JdbcDriverParams/NO_NAME_0') + set('DriverName', driverName) + set('URL', fmwDb) + set('PasswordEncrypted', dbPassword) + + user = dbPrefix + '_STB' + cd('Properties/NO_NAME_0/Property/user') + set('Value', user) + + print "Set user..." + user + + cd('/JdbcSystemResource/wcsitesDS/JdbcResource/wcsitesDS/JdbcDriverParams/NO_NAME_0') + set('DriverName', driverName) + set('URL', fmwDb) + set('PasswordEncrypted', dbPassword) + + user = dbPrefix + '_WCSITES' + cd('Properties/NO_NAME_0/Property/user') + set('Value', user) + + print "Set user..." + user + + print 'Getting Database Defaults...' + getDatabaseDefaults() + return + ########################################################################### + # Helper Methods # + ########################################################################### + + def validateDirectory(self, dirName, create=False): + directory = os.path.realpath(dirName) + if not os.path.exists(directory): + if create: + os.makedirs(directory) + else: + message = 'Directory ' + directory + ' does not exist' + raise WLSTException(message) + elif not os.path.isdir(directory): + message = 'Directory ' + directory + ' is not a directory' + raise WLSTException(message) + return self.fixupPath(directory) + + + def fixupPath(self, path): + result = path + if path is not None: + result = path.replace('\\', '/') + return result + + + def replaceTokens(self, path): + result = path + if path is not None: + result = path.replace('@@ORACLE_HOME@@', oracleHome) + return result + + def enable_admin_channel(self, admin_channel_address, admin_channel_port): + if admin_channel_address == None or admin_channel_port == 'None': + return + cd('/') + admin_server_name = get('AdminServerName') + print('setting admin server t3channel for ' + admin_server_name) + cd('/Servers/' + admin_server_name) + create('T3Channel', 'NetworkAccessPoint') + cd('/Servers/' + admin_server_name + '/NetworkAccessPoint/T3Channel') + set('ListenPort', int(admin_channel_port)) + set('PublicPort', int(admin_channel_port)) + set('PublicAddress', admin_channel_address) + +############################# +# Entry point to the script # +############################# + +def usage(): + print sys.argv[0] + ' -oh -jh -parent -name ' + \ + '-user -password ' + \ + '-rcuDb -rcuPrefix -rcuSchemaPwd ' \ + '-adminListenPort -adminName ' \ + '-managedNameBase -managedServerPort -prodMode ' \ + '-managedServerCount -clusterName ' \ + '-domainType ' \ + '-exposeAdminT3Channel -t3ChannelPublicAddress
' \ + '-t3ChannelPort -machineName ' + sys.exit(0) + +# Uncomment for Debug only +#print str(sys.argv[0]) + " called with the following sys.argv array:" +#for index, arg in enumerate(sys.argv): +# print "sys.argv[" + str(index) + "] = " + str(sys.argv[index]) + +if len(sys.argv) < 18: + usage() +#oracleHome will be passed by command line parameter -oh. +oracleHome = None +#javaHome will be passed by command line parameter -jh. +javaHome = None +#domainParentDir will be passed by command line parameter -parent. +domainParentDir = None +#domainUser is hard-coded to weblogic. You can change to other name of your choice. Command line paramter -user. +domainUser = 'weblogic' +#domainPassword will be passed by Command line parameter -password. +domainPassword = None +#rcuDb will be passed by command line parameter -rcuDb. +rcuDb = None +#change rcuSchemaPrefix to your infra schema prefix. Command line parameter -rcuPrefix. +rcuSchemaPrefix = 'WCS1' +#change rcuSchemaPassword to your infra schema password. Command line parameter -rcuSchemaPwd. +rcuSchemaPassword = None +exposeAdminT3Channel = None +t3ChannelPort = None +t3ChannelPublicAddress = None +machineName = None + +i = 1 +while i < len(sys.argv): + if sys.argv[i] == '-oh': + oracleHome = sys.argv[i + 1] + i += 2 + elif sys.argv[i] == '-jh': + javaHome = sys.argv[i + 1] + i += 2 + elif sys.argv[i] == '-parent': + domainParentDir = sys.argv[i + 1] + i += 2 + elif sys.argv[i] == '-name': + domainName = sys.argv[i + 1] + i += 2 + elif sys.argv[i] == '-user': + domainUser = sys.argv[i + 1] + i += 2 + elif sys.argv[i] == '-password': + domainPassword = sys.argv[i + 1] + i += 2 + elif sys.argv[i] == '-rcuDb': + rcuDb = sys.argv[i + 1] + i += 2 + elif sys.argv[i] == '-rcuPrefix': + rcuSchemaPrefix = sys.argv[i + 1] + i += 2 + elif sys.argv[i] == '-rcuSchemaPwd': + rcuSchemaPassword = sys.argv[i + 1] + i += 2 + elif sys.argv[i] == '-adminListenPort': + adminListenPort = sys.argv[i + 1] + i += 2 + elif sys.argv[i] == '-adminName': + adminName = sys.argv[i + 1] + i += 2 + elif sys.argv[i] == '-managedNameBase': + managedNameBase = sys.argv[i + 1] + i += 2 + elif sys.argv[i] == '-managedServerPort': + managedServerPort = sys.argv[i + 1] + i += 2 + elif sys.argv[i] == '-prodMode': + prodMode = sys.argv[i + 1] + i += 2 + elif sys.argv[i] == '-managedServerCount': + managedCount = sys.argv[i + 1] + i += 2 + elif sys.argv[i] == '-clusterName': + clusterName = sys.argv[i + 1] + i += 2 + elif sys.argv[i] == '-t3ChannelPublicAddress': + t3ChannelPublicAddress = sys.argv[i + 1] + i += 2 + elif sys.argv[i] == '-t3ChannelPort': + t3ChannelPort = sys.argv[i + 1] + i += 2 + elif sys.argv[i] == '-exposeAdminT3Channel': + exposeAdminT3Channel = sys.argv[i + 1] + i += 2 + elif sys.argv[i] == '-domainType': + domainType = sys.argv[i + 1] + i += 2 + elif sys.argv[i] == '-machineName': + machineName = sys.argv[i + 1] + i += 2 + else: + print 'Unexpected argument switch at position ' + str(i) + ': ' + str(sys.argv[i]) + usage() + sys.exit(1) + + +provisioner = WCSITES12214Provisioner(oracleHome, javaHome, domainParentDir, adminListenPort, adminName, managedNameBase, managedServerPort, prodMode, managedCount, clusterName) +provisioner.createWCSitesDomain(domainName, domainUser, domainPassword, rcuDb, rcuSchemaPrefix, rcuSchemaPassword, adminListenPort, adminName, managedNameBase, managedServerPort, prodMode, managedCount, clusterName, domainType, exposeAdminT3Channel, t3ChannelPublicAddress, t3ChannelPort) diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/createSitesDomain.sh b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/createSitesDomain.sh new file mode 100755 index 000000000..c7c038151 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/createSitesDomain.sh @@ -0,0 +1,177 @@ +#!/bin/bash +# Copyright (c) 2022, Oracle and/or its affiliates. +# +# Licensed under the Universal Permissive License v 1.0 as shown at +# https://oss.oracle.com/licenses/upl +# +# Description: This script is used to create WCSites Domain. +# + +########### SIGINT handler ############ +function _int() { + echo "Stopping container." + echo "SIGINT received, shutting down Admin Server!" + $DOMAIN_HOME/bin/stopWebLogic.sh + exit; +} + +########### SIGTERM handler ############ +function _term() { + echo "Stopping container." + echo "SIGTERM received, shutting down Admin Server!" + $DOMAIN_HOME/bin/stopWebLogic.sh + exit; +} + +########### SIGKILL handler ############ +function _kill() { + echo "SIGKILL received, shutting down the server!" + kill -9 $childPID +} + +#######Random Password Generation######## +function rand_pwd(){ + while true; do + s=$(cat /dev/urandom | tr -dc "A-Za-z0-9" | fold -w 8 | head -n 1) + if [[ ${#s} -ge 8 && "$s" == *[A-Z]* && "$s" == *[a-z]* && "$s" == *[0-9]* ]] + then + break + else + echo "Password does not Match the criteria, re-generating..." >&2 + fi + done + echo "${s}" +} + +########### updateListenAddress ############ +updateListenAddress() { + mkdir -p ${DOMAIN_HOME}/logs + + export thehost=`hostname -I` + echo "INFO: Updating the listen address - ${thehost} ${ADMIN_HOST}" + cmd="/u01/oracle/oracle_common/common/bin/wlst.sh -skipWLSModuleScanning /u01/oracle/dockertools/updListenAddress.py $vol_name ${thehost} AdminServer ${ADMIN_HOST}" +} + +INSTALL_START=$(date '+%s') + +# Set SIGINT handler +trap _int SIGINT + +# Set SIGTERM handler +trap _term SIGTERM + +# Set SIGKILL handler +trap _kill SIGKILL + +#Check on required parameters +PARAMS=true + +DB_SCHEMA_PASSWORD_AUTOGENERATED=false +ADMIN_PASSWORD_AUTOGENERATED=false +SITES_ADMIN_PASSWORD_AUTOGENERATED=false +SITES_APP_PASSWORD_AUTOGENERATED=false +SITES_SS_PASSWORD_AUTOGENERATED=false + +DB_CONNECTSTRING=$CUSTOM_CONNECTION_STRING +DB_USER=`cat /weblogic-operator/rcu-secrets/sys_username` +DB_PASSWORD=`cat /weblogic-operator/rcu-secrets/sys_password` +DB_SCHEMA_PASSWORD=`cat /weblogic-operator/rcu-secrets/password` +RCU_PREFIX=$CUSTOM_RCUPREFIX + + +# These values can be parameterized later on. Hardcoding for now. +export DOCKER_HOST=$LB_HOST + +#Database Parameters +export DB_USER=$DB_USER +export DB_PASSWORD=$DB_PASSWORD +export DB_CONNECTSTRING=$DB_CONNECTSTRING + +#Installer Parameters +export RCU_PREFIX=$RCU_PREFIX +export SAMPLES=$SAMPLES +export DOMAIN_NAME=$DOMAIN_NAME +export SITES_SERVER_NAME=$SITES_SERVER_NAME +export ADMIN_USERNAME=$ADMIN_USERNAME +export ADMIN_PORT=7001 +export WCSITES_MANAGED_PORT=7002 +export ADMIN_SSL_PORT=9001 +export WCSITES_SSL_PORT=9002 +WORK_DIR=/u01/wcs-wls-docker-install/work + +#Hostname Parameters +export WCSITES_ADMIN_HOSTNAME=$(sed -r 's/\./\\\./g' <<< $(hostname -I)) + +#-------------------------------------------------------------------------------------------- +cd /u01/wcs-wls-docker-install + +sed -i 's,^\(script.rcu.prefix=\).*,\1'$RCU_PREFIX',' bootstrap.properties +sed -i 's,^\(script.java.path=\).*,\1'$JAVA_HOME',' bootstrap.properties +sed -i 's,^\(script.oracle.wcsites.hostname=\).*,\1'$WCSITES_ADMIN_HOSTNAME',' bootstrap.properties +sed -i 's,^\(script.oracle.wcsites.portnumber=\).*,\1'$WCSITES_MANAGED_PORT',' bootstrap.properties +sed -i 's,^\(script.db.user=\).*,\1'$DB_USER',' bootstrap.properties +sed -i 's,^\(script.db.password=\).*,\1'$DB_PASSWORD',' bootstrap.properties +sed -i 's,^\(script.db.schema.password=\).*,\1'$DB_SCHEMA_PASSWORD',' bootstrap.properties +sed -i 's,^\(script.db.connectstring=\).*,\1'$DB_CONNECTSTRING',' bootstrap.properties +sed -i 's,^\(script.oracle.home=\).*,\1'$ORACLE_HOME',' bootstrap.properties +sed -i 's,^\(script.work.dir=\).*,\1'$WORK_DIR',' bootstrap.properties +sed -i 's,^\(script.oracle.wcsites.examples.avisports=\).*,\1'$SAMPLES',' bootstrap.properties +sed -i 's,^\(script.oracle.wcsites.examples.fsii=\).*,\1'$SAMPLES',' bootstrap.properties +sed -i 's,^\(script.oracle.wcsites.examples.Samples=\).*,\1'$SAMPLES',' bootstrap.properties +sed -i 's,^\(script.oracle.wcsites.examples.blogs=\).*,\1'$SAMPLES',' bootstrap.properties +sed -i 's,^\(script.wcsites.binaries.install.with.examples=\).*,\1'$SAMPLES',' bootstrap.properties +sed -i 's,^\(script.oracle.domain=\).*,\1'$DOMAIN_NAME',' bootstrap.properties +sed -i 's,^\(script.server.name=\).*,\1'$SITES_SERVER_NAME',' bootstrap.properties +sed -i 's,^\(script.admin.server.username=\).*,\1'$ADMIN_USERNAME',' bootstrap.properties +sed -i 's,^\(script.admin.server.password=\).*,\1'$ADMIN_PASSWORD',' bootstrap.properties +sed -i 's,^\(script.admin.server.port=\).*,\1'$ADMIN_PORT',' bootstrap.properties +sed -i 's,^\(script.admin.server.ssl.port=\).*,\1'$ADMIN_SSL_PORT',' bootstrap.properties +sed -i 's,^\(script.sites.server.ssl.port=\).*,\1'$WCSITES_SSL_PORT',' bootstrap.properties +sed -i 's,^\(script.oracle.wcsites.system.admin.user=\).*,\1'$SITES_ADMIN_USERNAME',' bootstrap.properties +sed -i 's,^\(script.oracle.wcsites.system.admin.password=\).*,\1'$SITES_ADMIN_PASSWORD',' bootstrap.properties +sed -i 's,^\(script.oracle.wcsites.app.user=\).*,\1'$SITES_APP_USERNAME',' bootstrap.properties +sed -i 's,^\(script.oracle.wcsites.app.password=\).*,\1'$SITES_APP_PASSWORD',' bootstrap.properties +sed -i 's,^\(script.oracle.wcsites.satellite.user=\).*,\1'$SITES_SS_USERNAME',' bootstrap.properties +sed -i 's,^\(script.oracle.wcsites.satellite.password=\).*,\1'$SITES_SS_PASSWORD',' bootstrap.properties + +sed -i 's,^\(script.run.configwizard=\).*,\1'false',' bootstrap.properties +sed -i 's,^\(script.run.sitesconfig=\).*,\1'false',' bootstrap.properties + +#-------------------------------------------------------------------------------------------- +#RCU +#Groovy files are responsible for exexuting RCU + ConfigWizard +#Source files for the same are located at ./OracleWebCenterSites/dockerfiles/12.2.1.4/wcs-wls-docker-install/src/ +java -jar wcs-wls-docker-install.jar + +#-------------------------------------------------------------------------------------------- + +if [ -e $WORK_DIR/WCSites_RCU_$RCU_PREFIX.suc ] +then + echo "" + echo "Sites RCU Phase completed successfull!!!" +else + echo "" + echo "Sites RCU Phase failed. Please check logs for details" + exit +fi + +# +# Export Domain Home/Root +#========================= +export DOMAIN_NAME=$DOMAIN_NAME +export DOMAIN_ROOT=$DOMAIN_ROOT_DIR +export DOMAIN_HOME="${DOMAIN_ROOT}/${DOMAIN_NAME}" + +echo "" +if [ $DB_SCHEMA_PASSWORD_AUTOGENERATED == "true" ]; then + echo " ----> Oracle Database Schema Credential: Password: $DB_SCHEMA_PASSWORD" +fi + + + +INSTALL_END=$(date '+%s') +INSTALL_ELAPSED=`expr $INSTALL_END - $INSTALL_START` + +echo "Sites Installation completed in $INSTALL_ELAPSED seconds." +echo "---------------------------------------------------------" +echo "" diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/drop-rcu-schema.sh b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/drop-rcu-schema.sh new file mode 100755 index 000000000..00c4a19cb --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/drop-rcu-schema.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# Copyright (c) 2022, Oracle and/or its affiliates. +# +# Licensed under the Universal Permissive License v 1.0 as shown at +# https://oss.oracle.com/licenses/upl +# + +# Drop the RCU schema based on schemaPreifix and Database URL + +DB_CONNECTSTRING=$CUSTOM_CONNECTION_STRING +DB_USER=`cat /weblogic-operator/rcu-secrets/sys_username` +DB_PASSWORD=`cat /weblogic-operator/rcu-secrets/sys_password` +DB_SCHEMA_PASSWORD=`cat /weblogic-operator/rcu-secrets/password` +RCU_PREFIX=$CUSTOM_RCUPREFIX +rcuType=fmw +SITES_DOMAIN_HOME=$DOMAIN_HOME_DIR +SITES_DOMAIN_LOGS=$DOMAIN_LOGS_DIR +echo "Cleaning direcotry ${SITES_DOMAIN_HOME}" +rm -rf ${SITES_DOMAIN_HOME} +echo "Cleaning direcotry ${SITES_DOMAIN_LOGS}" +rm -rf ${SITES_DOMAIN_LOGS} + +echo "${DB_PASSWORD}" > pwd.txt +echo "${DB_SCHEMA_PASSWORD}" >> pwd.txt + +echo "dropping RCU schema with following parameters ${DB_CONNECTSTRING} ${RCU_PREFIX} ${rcuType} ${DB_PASSWORD}" +source ${CREATE_DOMAIN_SCRIPT_DIR}/dropRepository.sh ${DB_CONNECTSTRING} ${RCU_PREFIX} ${rcuType} ${DB_PASSWORD} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/dropRepository.sh b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/dropRepository.sh new file mode 100755 index 000000000..2360e1678 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/dropRepository.sh @@ -0,0 +1,57 @@ +#!/bin/bash +# Copyright (c) 2022, Oracle and/or its affiliates. +# +# Licensed under the Universal Permissive License v 1.0 as shown at +# https://oss.oracle.com/licenses/upl + +/u01/oracle/wlserver/server/bin/setWLSEnv.sh + +echo "Check if the DB Service is ready to accept request " +connectString=${1:-db.db.oke.oraclevcn.com:1521/pdb.db.oke.oraclevcn.com} +schemaPrefix=${2:-WCS1} +rcuType=${3:-fmw} +sysPassword=${4:-Oradoc_db1} + +echo "DB Connection String [$connectString] schemaPrefix [${schemaPrefix}] rcuType[${rcuType}]" + +max=20 +counter=0 +while [ $counter -le ${max} ] +do + java utils.dbping ORACLE_THIN "sys as sysdba" ${sysPassword} ${connectString} > dbping.err 2>&1 + [[ $? == 0 ]] && break; + ((counter++)) + echo "[$counter/${max}] Retrying the DB Connection ..." + sleep 10 +done + +if [ $counter -gt ${max} ]; then + echo "[ERROR] Oracle DB Service is not ready after [${max}] iterations ..." + #exit -1 +else + java utils.dbping ORACLE_THIN "sys as sysdba" ${sysPassword} ${connectString} +fi + +case $rcuType in + fmw) + extComponents="" + extVariables="" + echo "Dropping RCU Schema for FMW Domain ..." + ;; + * ) + echo "[ERROR] Unknown RCU Schema Type [$rcuType]" + echo "Supported values: fmw(default)" + exit -1 + ;; +esac + +echo "Extra RCU Schema Component(s) Choosen[${extComponents}]" +echo "Extra RCU Schema Variable(s) Choosen[${extVariables}]" + +/u01/oracle/oracle_common/bin/rcu -silent -dropRepository \ + -databaseType ORACLE -connectString ${connectString} \ + -dbUser sys -dbRole sysdba \ + -selectDependentsForComponents true \ + -schemaPrefix ${schemaPrefix} ${extComponents} ${extVariables} \ + -component WCSITES -component IAU -component IAU_APPEND -component IAU_VIEWER \ + -component OPSS -component WLS -component WLS_RUNTIME -component STB < /u01/oracle/pwd.txt diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/read-domain-secret.py b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/read-domain-secret.py new file mode 100755 index 000000000..e9a4a7f6a --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/read-domain-secret.py @@ -0,0 +1,17 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. +# +# Licensed under the Universal Permissive License v 1.0 as shown at +# https://oss.oracle.com/licenses/upl +# + +# Read username secret +file = open('/weblogic-operator/secrets/username', 'r') +admin_username = file.read() +file.close() + +# Read password secret +file = open('/weblogic-operator/secrets/password', 'r') +admin_password = file.read() +file.close() + + diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/server-config-update.sh b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/server-config-update.sh new file mode 100755 index 000000000..d1237f302 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/server-config-update.sh @@ -0,0 +1,184 @@ +#!/bin/bash +# Copyright (c) 2022, Oracle and/or its affiliates. +# +# Licensed under the Universal Permissive License v 1.0 as shown at +# https://oss.oracle.com/licenses/upl + +echo "Executing sample script to update the server configuration" + +echo "Printing env" +env + +sleep 10 +LB_PROTOCOL="%LOAD_BALANCER_PROTOCOL%" +LB_HOST="%LOAD_BALANCER_HOSTNAME%" +LB_PORT="%LOAD_BALANCER_PORTNUMBER%" +SITES_ADMIN_USERNAME="%SITES_ADMIN_USERNAME%" +SITES_ADMIN_PASSWORD="%SITES_ADMIN_PASSWORD%" +SITES_APP_USERNAME="%SITES_APP_USERNAME%" +SITES_APP_PASSWORD="%SITES_APP_PASSWORD%" +SITES_SS_USERNAME="%SITES_SS_USERNAME%" +SITES_SS_PASSWORD="%SITES_SS_PASSWORD%" +SITES_SAMPLES="%SITES_SAMPLES%" +SITES_CACHE_PORTS="%SITES_CACHE_PORTS%" +MANAGED_SERVER_PORT="%MANAGED_SERVER_PORT%" + +echo ADMIN_SERVER_NAME : ${ADMIN_SERVER_NAME} +echo DOMAIN_UID : ${DOMAIN_UID} +echo LB_PROTOCOL : ${LB_PROTOCOL} +echo LB_HOST : ${LB_HOST} +echo LB_PORT : ${LB_PORT} +echo HOSTNAME : ${HOSTNAME} +SERVER_NAME="${HOSTNAME/$DOMAIN_UID-/}" +echo SERVER_NAME : ${SERVER_NAME} + +echo "Final SERVER_NAME=${SERVER_NAME}" +echo SERVER_NAME : ${SERVER_NAME} + +echo MANAGED_SERVER_PORT: ${MANAGED_SERVER_PORT} + +SER_HOST_NAME=$(echo ${SERVER_NAME} | tr '_' '- ') +echo SER_HOST_NAME : ${SER_HOST_NAME} +CONTEXTPATH="sites" + +if [[ $SERVER_NAME == *?[0-9] ]];then + echo "Input ends with number" +else + echo "Input does not end with number " +fi + +DOMAIN_HOME="%DOMAIN_HOME%" +DOMAIN_ROOT_DIR="%DOMAIN_ROOT_DIR%" +SITES_SHARED=${DOMAIN_ROOT_DIR}/shared +echo DOMAIN_HOME : ${DOMAIN_HOME} + +# This check skips the servers for which the configuration was already updated. + + if [ ${SERVER_NAME,,} != ${ADMIN_SERVER_NAME,,} ] && [ ! -f "${DOMAIN_HOME}/config/fmwconfig/servers/${SERVER_NAME}/config/updated.txt" ]; then + # Logic to update the config file goes here + + if [ ! -f "${DOMAIN_HOME}/config/fmwconfig/wcsconfig/updated.txt" ]; then + echo "--------------------------------------------" + echo "Updating the configuration at: ${DOMAIN_HOME}/config/fmwconfig/wcsconfig" + + SHARED=${DOMAIN_HOME}/config/fmwconfig/wcsconfig + NODECONFIG=${DOMAIN_HOME}/config/fmwconfig/servers/${SERVER_NAME}/config + + + cd ${SHARED} + + sed -i 's,^\(oracle.wcsites.node.config=\).*,\1'${NODECONFIG}',' wcs_properties_bootstrap.ini + + sed -i 's,^\(oracle.wcsites.hostname=\).*,\1'${LB_HOST}',' wcs_properties_bootstrap.ini + sed -i 's,^\(oracle.wcsites.portnumber=\).*,\1'${LB_PORT}',' wcs_properties_bootstrap.ini + sed -i 's,^\(oracle.wcsites.cas.hostname=\).*,\1'${LB_HOST}',' wcs_properties_bootstrap.ini + sed -i 's,^\(oracle.wcsites.cas.portnumber=\).*,\1'${LB_PORT}',' wcs_properties_bootstrap.ini + sed -i 's,^\(oracle.wcsites.cas.hostnameActual=\).*,\1'${LB_HOST}',' wcs_properties_bootstrap.ini + sed -i 's,^\(oracle.wcsites.cas.hostnameLocal=\).*,\1'${LB_HOST}',' wcs_properties_bootstrap.ini + sed -i 's,^\(oracle.wcsites.cas.portnumberLocal=\).*,\1'${LB_PORT}',' wcs_properties_bootstrap.ini + sed -i 's,^\(oracle.wcsites.system.admin.user=\).*,\1'${SITES_ADMIN_USERNAME}',' wcs_properties_bootstrap.ini + sed -i 's,^\(oracle.wcsites.system.admin.password=\).*,\1'${SITES_ADMIN_PASSWORD}',' wcs_properties_bootstrap.ini + sed -i 's,^\(oracle.wcsites.app.user=\).*,\1'${SITES_APP_USERNAME}',' wcs_properties_bootstrap.ini + sed -i 's,^\(oracle.wcsites.app.password=\).*,\1'${SITES_APP_PASSWORD}',' wcs_properties_bootstrap.ini + sed -i 's,^\(oracle.wcsites.satellite.user=\).*,\1'${SITES_SS_USERNAME}',' wcs_properties_bootstrap.ini + sed -i 's,^\(oracle.wcsites.satellite.password=\).*,\1'${SITES_SS_PASSWORD}',' wcs_properties_bootstrap.ini + + sed -i 's,^\(oracle.wcsites.database.type=\).*,\1'Oracle',' wcs_properties_bootstrap.ini + sed -i 's,^\(oracle.wcsites.database.datasource=\).*,\1'wcsitesDS',' wcs_properties_bootstrap.ini + sed -i 's,^\(oracle.wcsites.examples=\).*,\1'true',' wcs_properties_bootstrap.ini + sed -i 's,^\(oracle.wcsites.examples.fsii=\).*,\1'${SITES_SAMPLES}',' wcs_properties_bootstrap.ini + sed -i 's,^\(oracle.wcsites.examples.avisports=\).*,\1'${SITES_SAMPLES}',' wcs_properties_bootstrap.ini + sed -i 's,^\(oracle.wcsites.examples.Samples=\).*,\1'${SITES_SAMPLES}',' wcs_properties_bootstrap.ini + sed -i 's,^\(oracle.wcsites.bootstrap.status=\).*,\1'never_done',' wcs_properties_bootstrap.ini + + sed -i 's,^\(oracle.wcsites.contextpath=\).*,\1'/${CONTEXTPATH}/',' wcs_properties_bootstrap.ini + sed -i 's,^\(oracle.wcsites.shared=\).*,\1'${SITES_SHARED}',' wcs_properties_bootstrap.ini + sed -i 's,^\(oracle.wcsites.appserver.type=\).*,\1'wls92',' wcs_properties_bootstrap.ini + sed -i 's,^\(oracle.wcsites.protocol=\).*,\1'${LB_PROTOCOL}',' wcs_properties_bootstrap.ini + + + touch ${DOMAIN_HOME}/config/fmwconfig/wcsconfig/updated.txt + echo "Updated the configuration at: ${DOMAIN_HOME}/config/fmwconfig/wcsconfig" + echo "--------------------------------------------" + fi + + echo "--------------------------------------------" ${SERVER_NAME} "--------------------------------------------" + echo "Updating the configuration at: ${DOMAIN_HOME}/config/fmwconfig/servers/${SERVER_NAME}/config" + cp ${DOMAIN_HOME}/config/fmwconfig/wcsconfig/wcs_properties.json ${SITES_SHARED}/ + + replaceString="127.0.0.1" + + # Print the values + replaceWith=${DOMAIN_UID}-${SER_HOST_NAME} + location=${DOMAIN_HOME}/config/fmwconfig/servers/${SERVER_NAME}/config/ + + echo replacing for ${SERVER_NAME} "timeToLive=0 to timeToLive=1" + grep -rl timeToLive=0 ${location} + grep -rl timeToLive=0 ${location} | xargs sed -i "s/timeToLive=0/timeToLive=1/g" + + echo replacing for ${SERVER_NAME} "ip_ttl=0 to ip_ttl=1" + grep -rl ip_ttl=\"0\" ${location} + grep -rl ip_ttl=\"0\" ${location} | xargs sed -i "s/ip_ttl=\"0\"/ip_ttl=\"1\"/g" + + echo replacing for ${SERVER_NAME} ${location}host.properties + sed -i "s/@unique_id@/${replaceWith}/g" ${location}host.properties + + echo replacing for ${SERVER_NAME} ${location}deployerConfigContext.xml + sed -i "s/@CSConnectPrefix@/${LB_PROTOCOL}/g" ${location}deployerConfigContext.xml + sed -i "s/@hostname@/${LB_HOST}/g" ${location}deployerConfigContext.xml + sed -i "s/@portnumber@/${LB_PORT}/g" ${location}deployerConfigContext.xml + sed -i "s/@context-path@/${CONTEXTPATH}/g" ${location}deployerConfigContext.xml + + echo replacing for ${SERVER_NAME} ${location}cas.properties + sed -i "s/@CSConnectPrefix@/${LB_PROTOCOL}/g" ${location}cas.properties + sed -i "s/@hostname@/${replaceWith}/g" ${location}cas.properties + sed -i "s/@portnumber@/${MANAGED_SERVER_PORT}/g" ${location}cas.properties + + echo replacing for ${SERVER_NAME} ${location}customBeans.xml + sed -i "s/@CSConnectPrefix@/${LB_PROTOCOL}/g" ${location}customBeans.xml + sed -i "s/@hostname@/${LB_HOST}/g" ${location}customBeans.xml + sed -i "s/@portnumber@/${LB_PORT}/g" ${location}customBeans.xml + sed -i "s/@context-path@/${CONTEXTPATH}/g" ${location}customBeans.xml + + echo "--------------------------------------------" + + if [ -z "$SITES_CACHE_PORTS" ] + then + echo "\$SITES_CACHE_PORTS is empty" + else + echo "\$SITES_CACHE_PORTS is NOT empty" + python ${DOMAIN_HOME}/unicast.py ${DOMAIN_HOME} ${HOSTNAME::-1} ${SERVER_NAME} ${SITES_CACHE_PORTS} + fi + + + echo "--------------------------------------------" + + rm ${DOMAIN_HOME}/config/fmwconfig/servers/${SERVER_NAME}/config/wcs_properties.json + rm ${DOMAIN_HOME}/config/fmwconfig/servers/${SERVER_NAME}/config/wcs_properties_bootstrap.ini + + touch ${DOMAIN_HOME}/config/fmwconfig/servers/${SERVER_NAME}/config/updated.txt + + + + else + # Case where the configuration of the server was already updated or not required to udpate. + echo "Not updating configuration of the server ${SERVER_NAME}." + fi + +echo "--------------------------------------------" +echo "checking the availability of custom extend.sites.webapp-lib.war" + +CUSTOM_EXTEND_LIB=${DOMAIN_ROOT_DIR}/sites-home/extend.sites.webapp-lib.war +EXTEND_LIB=/u01/oracle/wcsites/webcentersites/sites-home/extend.sites.webapp-lib.war + +if [ -f "$CUSTOM_EXTEND_LIB" ]; then + EXTEND_LIB=$(echo $EXTEND_LIB | sed 's_/_\\/_g') + CUSTOM_EXTEND_LIB=$(echo $CUSTOM_EXTEND_LIB | sed 's_/_\\/_g') + echo "replacing $EXTEND_LIB with custom $CUSTOM_EXTEND_LIB in config.xml" + sed -i "s/${EXTEND_LIB}/${CUSTOM_EXTEND_LIB}/g" ${DOMAIN_HOME}/config/config.xml +else + EXTEND_LIB=$(echo $EXTEND_LIB | sed 's_/_\\/_g') + CUSTOM_EXTEND_LIB=$(echo $CUSTOM_EXTEND_LIB | sed 's_/_\\/_g') + echo "reverting custom $CUSTOM_EXTEND_LIB to $EXTEND_LIB in config.xml" + sed -i "s/${CUSTOM_EXTEND_LIB}/${EXTEND_LIB}/g" ${DOMAIN_HOME}/config/config.xml +fi diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/_helpers.tpl b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/_helpers.tpl new file mode 100755 index 000000000..787cd3d01 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/_helpers.tpl @@ -0,0 +1,77 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +{{/* +Expand the name of the chart. +*/}} +{{- define "wc-sites.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "wc-sites.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "wc-sites.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "wc-sites.labels" -}} +helm.sh/chart: {{ include "wc-sites.chart" . }} +{{ include "wc-sites.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "wc-sites.selectorLabels" -}} +app.kubernetes.io/name: {{ include "wc-sites.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "wc-sites.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "wc-sites.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Build the database URL +*/}} +{{- define "wc-sites.databaseUrl" -}} +{{- if (.Values.oracledb.url) }} +{{- .Values.oracledb.url }} +{{- else }} +{{- .Release.Name }}-oracledb.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.oracledb.service.port }}/{{ .Values.oracledb.pdb }}.{{ .Values.oracledb.domain }} +{{- end }} +{{- end }} + diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/db.Secret.yaml b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/db.Secret.yaml new file mode 100755 index 000000000..2f9d23f34 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/db.Secret.yaml @@ -0,0 +1,16 @@ +{{ if not .Values.oracledb.credentials.secretName }} +# Copyright (c) 2022, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + labels: + weblogic.domainName: {{ .Values.domain.domainName }} + weblogic.domainUID: {{ .Values.domain.domainName }} + name: {{ .Values.domain.domainName }}-db-credentials +data: + username: {{ .Values.oracledb.credentials.username | b64enc | quote }} + password: {{ .Values.oracledb.credentials.password | b64enc | quote }} +{{ end }} \ No newline at end of file diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.Domain.yaml b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.Domain.yaml new file mode 100755 index 000000000..0b191cfb3 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.Domain.yaml @@ -0,0 +1,162 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +# +# This is an example of how to define a Domain resource. +# +apiVersion: "weblogic.oracle/v8" +kind: Domain +metadata: + name: {{ .Values.domain.domainName }} + namespace: {{ .Values.domain.namespace }} + labels: + weblogic.domainUID: {{ .Values.domain.domainName }} +spec: + managedServers: + {{- if gt (.Values.domain.wcsCluster.managedServers.count | int) 0}} + - serverName: wcsites-server1 + serverStartPolicy: "IF_NEEDED" + {{- end }} + {{- if gt (.Values.domain.wcsCluster.managedServers.count | int) 1}} + - serverName: wcsites-server2 + serverStartPolicy: "IF_NEEDED" + {{- end }} + {{- if gt (.Values.domain.wcsCluster.managedServers.count | int) 2}} + - serverName: wcsites-server3 + serverStartPolicy: "IF_NEEDED" + {{- end }} + + # The WebLogic Domain Home + domainHome: {{ .Values.domain.rootDir }}/domains/{{ .Values.domain.domainName }} + + # The domain home source type + # Set to PersistentVolume for domain-in-pv + domainHomeSourceType: PersistentVolume + + # The WebLogic Server Docker image that the Operator uses to start the domain + {{- if .Values.image.name }} + image: "{{ .Values.image.name }}" + {{- else }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} + + # imagePullPolicy defaults to "Always" if image version is :latest + imagePullPolicy: "IfNotPresent" + + # Identify which Secret contains the credentials for pulling an image + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + + # Identify which Secret contains the WebLogic Admin credentials (note that there is an example of + # how to create that Secret at the end of this file) + webLogicCredentialsSecret: + name: {{ .Values.domain.domainName }}-domain-credentials + + configuration: + introspectorJobActiveDeadlineSeconds: 300 + + # Whether to include the server out file into the pod's stdout, default is true + includeServerOutInPodLog: {{ .Values.domain.includeServerOutInPodLog }} + + # Whether to enable log home + logHomeEnabled: {{ .Values.domain.logHomeEnabled }} + + # Whether to write HTTP access log file to log home + httpAccessLogInLogHome: {{ .Values.domain.httpAccessLogInLogHome }} + + # The in-pod location for domain log, server logs, server out, and Node Manager log files + logHome: {{ .Values.domain.rootDir }}/logs/{{ .Values.domain.domainName }} + # An (optional) in-pod location for data storage of default and custom file stores. + # If not specified or the value is either not set or empty (e.g. dataHome: "") then the + # data storage directories are determined from the WebLogic domain home configuration. + dataHome: "" + + + # serverStartPolicy legal values are "NEVER", "IF_NEEDED", or "ADMIN_ONLY" + # This determines which WebLogic Servers the Operator will start up when it discovers this Domain + # - "NEVER" will not start any server in the domain + # - "ADMIN_ONLY" will start up only the administration server (no managed servers will be started) + # - "IF_NEEDED" will start all non-clustered servers, including the administration server and clustered servers up to the replica count + serverStartPolicy: "IF_NEEDED" + + serverPod: + initContainers: + - name: server-config-update + {{- if .Values.image.name }} + image: "{{ .Values.image.name }}" + {{- else }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} + env: + - name: DOMAIN_UID + value: {{ .Values.domain.domainName }} + - name: ADMIN_SERVER_NAME + value: "{{ .Values.domain.admin.name }}" + command: ['bash', '-c', '{{ .Values.domain.rootDir }}/domains/{{ .Values.domain.domainName }}/server-config-update.sh'] + volumeMounts: + - name: weblogic-domain-storage-volume + mountPath: {{ .Values.domain.rootDir }} + + # an (optional) list of environment variable to be set on the servers + env: + - name: JAVA_OPTIONS + value: "{{ .Values.domain.javaOptions }}" + - name: USER_MEM_ARGS + value: "-Djava.security.egd=file:/dev/./urandom -Xms256m -Xmx1024m " + resources: + requests: + memory: "12G" + cpu: "1000m" + limits: + memory: "16G" + cpu: "2000m" + volumes: + - name: weblogic-domain-storage-volume + persistentVolumeClaim: + claimName: {{ .Values.domain.domainName }}-domain-pvc + volumeMounts: + - mountPath: {{ .Values.domain.rootDir }} + name: weblogic-domain-storage-volume + + # adminServer is used to configure the desired behavior for starting the administration server. + adminServer: + # serverStartState legal values are "RUNNING" or "ADMIN" + # "RUNNING" means the listed server will be started up to "RUNNING" mode + # "ADMIN" means the listed server will be start up to "ADMIN" mode + serverStartState: "RUNNING" + + # clusters is used to configure the desired behavior for starting member servers of a cluster. + # If you use this entry, then the rules will be applied to ALL servers that are members of the named clusters. + clusters: + - clusterName: {{ .Values.domain.wcsCluster.name }} + clusterService: + annotations: + traefik.ingress.kubernetes.io/affinity: "true" + traefik.ingress.kubernetes.io/session-cookie-name: sticky + serverStartState: "RUNNING" + serverPod: + # Instructs Kubernetes scheduler to prefer nodes for new cluster members where there are not + # already members of the same cluster. + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: "weblogic.clusterName" + operator: In + values: + - $(CLUSTER_NAME) + topologyKey: "kubernetes.io/hostname" + replicas: 1 + # The number of managed servers to start for unlisted clusters + # replicas: 1 + + # Istio + # configuration: + # istio: + # enabled: + # readinessPort: + diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.PersistentVolume.yaml b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.PersistentVolume.yaml new file mode 100755 index 000000000..6b52caec6 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.PersistentVolume.yaml @@ -0,0 +1,26 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +apiVersion: v1 +kind: PersistentVolume +metadata: + name: {{ .Values.domain.domainName }}-domain-pv + labels: + weblogic.domainUID: {{ .Values.domain.domainName }} +spec: + storageClassName: {{ .Values.domain.domainName }}-domain-storage-class + capacity: + storage: {{ .Values.domain.storage.capacity }} + accessModes: + - ReadWriteMany + # Valid values are Retain, Delete or Recycle + persistentVolumeReclaimPolicy: Retain + {{- if eq .Values.domain.storage.type "nfs"}} + nfs: + server: {{ .Values.domain.storage.nfs.server }} + path: {{ .Values.domain.storage.path }} + {{- end }} + {{- if eq .Values.domain.storage.type "hostpath" }} + hostPath: + path: {{ .Values.domain.storage.path }} + {{- end }} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.PersistentVolumeClaim.yaml b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.PersistentVolumeClaim.yaml new file mode 100755 index 000000000..a12c04c95 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.PersistentVolumeClaim.yaml @@ -0,0 +1,16 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ .Values.domain.domainName }}-domain-pvc + labels: + weblogic.domainUID: {{ .Values.domain.domainName }} +spec: + storageClassName: {{ .Values.domain.domainName }}-domain-storage-class + accessModes: + - ReadWriteMany + resources: + requests: + storage: {{ .Values.domain.storage.capacity }} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.Secret.yaml b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.Secret.yaml new file mode 100755 index 000000000..afebb6479 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.Secret.yaml @@ -0,0 +1,16 @@ +{{ if not .Values.domain.credentials.secretName }} +# Copyright (c) 2022, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + labels: + weblogic.domainName: {{ .Values.domain.domainName }} + weblogic.domainUID: {{ .Values.domain.domainName }} + name: {{ .Values.domain.domainName }}-domain-credentials +data: + username: {{ .Values.domain.credentials.username | b64enc | quote }} + password: {{ .Values.domain.credentials.password | b64enc | quote }} +{{ end }} \ No newline at end of file diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.create.ConfigMap.yaml b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.create.ConfigMap.yaml new file mode 100755 index 000000000..a01b19a21 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.create.ConfigMap.yaml @@ -0,0 +1,17 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Values.domain.domainName }}-create-fmw-infra-sample-domain-job-cm + labels: + weblogic.domainName: {{ .Values.domain.domainName }} + weblogic.domainUID: {{ .Values.domain.domainName }} + +data: + {{- $files := .Files }} + {{- range tuple "create-domain-job.sh" "createSitesDomain.sh" "drop-rcu-schema.sh" "dropRepository.sh" "read-domain-secret.py" "server-config-update.sh" "createSitesDomain.py" "create-domain-script.sh" "utility.sh" "unicast.py" }} + {{ . }}: |- +{{ $files.Get . | indent 8 }} + {{- end }} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.create.Job.yaml b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.create.Job.yaml new file mode 100755 index 000000000..18ed1fabe --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.create.Job.yaml @@ -0,0 +1,175 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. +# +# Licensed under the Universal Permissive License v 1.0 as shown at +# https://oss.oracle.com/licenses/upl +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ .Values.domain.domainName }}-create-fmw-infra-sample-domain-job + namespace: {{ .Values.domain.namespace }} + annotations: + # This is what defines this resource as a hook. Without this line, the + # job is considered part of the release. + "helm.sh/hook": post-install + "helm.sh/hook-weight": "-5" +spec: + template: + metadata: + labels: + weblogic.resourceVersion: domain-v2 + weblogic.domainUID: {{ .Values.domain.domainName }} + weblogic.domainName: {{ .Values.domain.domainName }} + app: {{ .Values.domain.domainName }}-create-fmw-infra-sample-domain-job + spec: + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + restartPolicy: Never + {{- if eq .Values.domain.storage.type "nfs" }} + initContainers: + - name: fix-pvc-owner + {{- if .Values.image.name }} + image: "{{ .Values.image.name }}" + {{- else }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} + command: ["sh", "-c", "chown 1000:0 /u01/oracle/user_projects/. && find /u01/oracle/user_projects/. -maxdepth 1 ! -name '.snapshot' ! -name '.' -print0 | xargs -r -0 chown -R 1000:0"] + volumeMounts: + - name: fmw-infra-sample-domain-storage-volume + mountPath: {{ .Values.domain.rootDir }} + securityContext: + runAsUser: 0 + runAsGroup: 0 + {{- end }} + containers: + - name: create-fmw-infra-sample-domain-job + {{- if .Values.image.name }} + image: "{{ .Values.image.name }}" + {{- else }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} + imagePullPolicy: IfNotPresent + ports: + - containerPort: 7001 + volumeMounts: + - mountPath: {{ .Values.domain.scriptDir }} + name: create-fmw-infra-sample-domain-job-cm-volume + - mountPath: {{ .Values.domain.rootDir }} + name: fmw-infra-sample-domain-storage-volume + - mountPath: /weblogic-operator/secrets + name: fmw-infra-credentials-volume + - mountPath: /weblogic-operator/rcu-secrets + name: rcu-credentials-volume + command: ["/bin/sh"] + args: ["{{ .Values.domain.scriptDir }}/create-domain-job.sh"] + env: + - name: DOMAIN_UID + value: "{{ .Values.domain.domainName }}" + - name: ADMIN_SERVER_NAME_SVC + value: "{{ .Values.domain.admin.name }}" + - name: T3_CHANNEL_PORT + value: "{{ or .Values.domain.t3Channel.port 30012 }}" + - name: T3_PUBLIC_ADDRESS + value: "{{ or .Values.domain.t3Channel.publicIp "0.0.0.0" }}" + - name: MANAGED_SERVER_NAME_BASE_SVC + value: "wcsites-server" + - name: CREATE_DOMAIN_SCRIPT_DIR + value: "{{ .Values.domain.scriptDir }}" + - name: DOMAIN_ROOT_DIR + value: "{{ .Values.domain.rootDir }}" + - name: DOMAIN_HOME_DIR + value: "{{ .Values.domain.rootDir }}/domains/{{ .Values.domain.domainName }}" + - name: DOMAIN_LOGS_DIR + value: "{{ .Values.domain.rootDir }}/logs/{{ .Values.domain.domainName }}" + - name: CUSTOM_DOMAIN_NAME + value: "{{ .Values.domain.domainName }}" + - name: CUSTOM_ADMIN_LISTEN_PORT + value: "{{ .Values.domain.admin.listenPort }}" + - name: CUSTOM_ADMIN_NAME + value: "{{ .Values.domain.admin.name }}" + - name: CUSTOM_ADMIN_HOST + value: "%CUSTOM_ADMIN_HOST%" + - name: CUSTOM_MANAGEDSERVER_PORT + value: "{{ .Values.domain.wcsCluster.managedServers.listenPort }}" + - name: CUSTOM_MANAGED_BASE_NAME + value: "{{ .Values.domain.wcsCluster.managedServers.name }}" + - name: CUSTOM_MANAGED_SERVER_COUNT + value: "{{ .Values.domain.wcsCluster.managedServers.count }}" + - name: CUSTOM_CLUSTER_NAME + value: "{{ .Values.domain.wcsCluster.name }}" + - name: CUSTOM_RCUPREFIX + value: "{{ .Values.domain.rcuSchema.prefix }}" + - name: CUSTOM_PRODUCTION_MODE + value: "true" + - name: CUSTOM_CONNECTION_STRING + value: "{{ .Values.oracledb.url }}" + - name: EXPOSE_T3_CHANNEL_PREFIX + value: "false" + - name: DOMAIN_NAME + value: "{{ .Values.domain.domainName }}" + - name: ADMIN_SERVER_NAME + value: "{{ .Values.domain.admin.name }}" + - name: ADMIN_PORT + value: "{{ .Values.domain.admin.listenPort }}" + - name: CLUSTER_NAME + value: "{{ .Values.domain.wcsCluster.name }}" + - name: MANAGED_SERVER_NAME_BASE + value: "{{ .Values.domain.wcsCluster.managedServers.name }}" + - name: CONFIGURED_MANAGED_SERVER_COUNT + value: "{{ .Values.domain.wcsCluster.managedServers.count }}" + - name: MANAGED_SERVER_PORT + value: "{{ .Values.domain.wcsCluster.managedServers.listenPort }}" + - name: PRODUCTION_MODE_ENABLED + value: "true" + - name: LB_HOST + value: "{{ .Values.ingress.hostname }}" + - name: LB_PORT + value: "{{ .Values.ingress.port }}" + - name: LB_PROTOCOL + value: "{{ .Values.ingress.scheme }}" + - name: SITES_CACHE_PORTS + value: "50000" + - name: SITES_SAMPLES + value: "false" + - name: SITES_ADMIN_USERNAME + value: ContentServer + - name: SITES_ADMIN_PASSWORD + value: password + - name: SITES_APP_USERNAME + value: fwadmin + - name: SITES_APP_PASSWORD + value: xceladmin + - name: SITES_SS_USERNAME + value: SatelliteServer + - name: SITES_SS_PASSWORD + value: password + - name: ADMIN_USERNAME + valueFrom: + secretKeyRef: + name: wcsitesinfra-domain-credentials + key: username + - name: ADMIN_PASSWORD + valueFrom: + secretKeyRef: + name: wcsitesinfra-domain-credentials + key: password + - name: MANAGED_SERVER + value: "wcsites-server" + - name: DOMAIN_TYPE + value: {{ .Values.domain.type }} + volumes: + - name: create-fmw-infra-sample-domain-job-cm-volume + configMap: + name: {{ .Values.domain.domainName }}-create-fmw-infra-sample-domain-job-cm + - name: fmw-infra-sample-domain-storage-volume + persistentVolumeClaim: + claimName: {{ .Values.domain.domainName }}-domain-pvc + - name: fmw-infra-credentials-volume + secret: + secretName: {{ .Values.domain.domainName }}-domain-credentials + - name: rcu-credentials-volume + secret: + secretName: {{ .Values.domain.domainName }}-rcu-credentials + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.delete.Job.yaml b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.delete.Job.yaml new file mode 100755 index 000000000..09ccc2214 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/domain.delete.Job.yaml @@ -0,0 +1,71 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. +# +# Licensed under the Universal Permissive License v 1.0 as shown at +# https://oss.oracle.com/licenses/upl + +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ .Values.domain.domainName }}-delete-fmw-infra-sample-domain-job + namespace: {{ .Values.domain.namespace }} + annotations: + # This is what defines this resource as a hook. Without this line, the + # job is considered part of the release. + "helm.sh/hook": pre-delete + "helm.sh/hook-weight": "5" + #"helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded +spec: + template: + metadata: + labels: + weblogic.resourceVersion: domain-v2 + weblogic.domainUID: {{ .Values.domain.domainName }} + weblogic.domainName: {{ .Values.domain.domainName }} + app: {{ .Values.domain.domainName }}-delete-fmw-infra-sample-domain-job + spec: + restartPolicy: Never + containers: + - name: delete-fmw-infra-sample-domain-job + {{- if .Values.image.name }} + image: "{{ .Values.image.name }}" + {{- else }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} + imagePullPolicy: IfNotPresent + ports: + - containerPort: 7001 + volumeMounts: + - mountPath: {{ .Values.domain.scriptDir }} + name: create-fmw-infra-sample-domain-job-cm-volume + - mountPath: {{ .Values.domain.rootDir }} + name: fmw-infra-sample-domain-storage-volume + - mountPath: /weblogic-operator/rcu-secrets + name: rcu-credentials-volume + command: ["/bin/sh"] + args: ["{{ .Values.domain.scriptDir }}/drop-rcu-schema.sh"] + env: + - name: DOMAIN_HOME_DIR + value: {{ .Values.domain.rootDir }}/domains/{{ .Values.domain.domainName }} + - name: DOMAIN_LOGS_DIR + value: {{ .Values.domain.rootDir }}/logs/{{ .Values.domain.domainName }} + - name: CUSTOM_RCUPREFIX + value: "{{ .Values.domain.rcuSchema.prefix }}" + - name: CUSTOM_CONNECTION_STRING + value: "{{ .Values.oracledb.url }}" + - name: CREATE_DOMAIN_SCRIPT_DIR + value: "{{ .Values.domain.scriptDir }}" + + volumes: + - name: create-fmw-infra-sample-domain-job-cm-volume + configMap: + name: {{ .Values.domain.domainName }}-create-fmw-infra-sample-domain-job-cm + - name: fmw-infra-sample-domain-storage-volume + persistentVolumeClaim: + claimName: {{ .Values.domain.domainName }}-domain-pvc + - name: rcu-credentials-volume + secret: + secretName: {{ .Values.domain.domainName }}-rcu-credentials + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/rcu.Secret.yaml b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/rcu.Secret.yaml new file mode 100755 index 000000000..f99a2fe51 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/rcu.Secret.yaml @@ -0,0 +1,16 @@ +{{ if not .Values.domain.rcuSchema.credentials.secretName }} +# Copyright (c) 2022, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + labels: + weblogic.domainName: {{ .Values.domain.domainName }} + weblogic.domainUID: {{ .Values.domain.domainName }} + name: {{ .Values.domain.domainName }}-rcu-credentials +data: + username: {{ .Values.domain.rcuSchema.credentials.username | b64enc | quote }} + password: {{ .Values.domain.rcuSchema.credentials.password | b64enc | quote }} +{{ end }} \ No newline at end of file diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/serviceaccount.yaml b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/serviceaccount.yaml new file mode 100755 index 000000000..f2dec763a --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/serviceaccount.yaml @@ -0,0 +1,15 @@ +{{- if .Values.serviceAccount.create -}} +# Copyright (c) 2022, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "wc-sites.serviceAccountName" . }} + labels: + {{- include "wc-sites.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/traefik.Ingress.yaml b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/traefik.Ingress.yaml new file mode 100755 index 000000000..3b81e4d69 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/traefik.Ingress.yaml @@ -0,0 +1,48 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +apiVersion: networking.k8s.io/v1beta1 +kind: Ingress +metadata: + name: {{ .Values.domain.domainName }}-traefik + labels: + weblogic.resourceVersion: domain-v2 + annotations: + kubernetes.io/ingress.class: traefik +{{- if .Values.ingress.tls }} + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + traefik.ingress.kubernetes.io/router.middlewares: wcsites-ns-wls-proxy-ssl@kubernetescrd +{{- end }} +spec: + rules: + - host: '' + http: + paths: + - path: /console + backend: + serviceName: '{{ .Values.domain.domainName }}-{{ .Values.domain.admin.name | lower | replace "_" "-" }}' + servicePort: {{ .Values.domain.admin.listenPort }} + - path: /em + backend: + serviceName: '{{ .Values.domain.domainName }}-{{ .Values.domain.admin.name | lower | replace "_" "-" }}' + servicePort: {{ .Values.domain.admin.listenPort }} + - path: /weblogic/ready + backend: + serviceName: '{{ .Values.domain.domainName }}-{{ .Values.domain.admin.name | lower | replace "_" "-" }}' + servicePort: {{ .Values.domain.admin.listenPort }} + - path: /sites + backend: + serviceName: '{{ .Values.domain.domainName }}-cluster-{{ .Values.domain.wcsCluster.name | lower | replace "_" "-" }}' + servicePort: {{ .Values.domain.wcsCluster.managedServers.listenPort }} + - path: /cas + backend: + serviceName: '{{ .Values.domain.domainName }}-cluster-{{ .Values.domain.wcsCluster.name | lower | replace "_" "-" }}' + servicePort: {{ .Values.domain.wcsCluster.managedServers.listenPort }} +{{- if .Values.ingress.tls }} + tls: + - hosts: + - '{{ .Values.ingress.dnsname }}' + secretName: {{ .Values.domain.domainName }}-tls-cert +{{- end }} + diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/wcs.services.yaml b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/wcs.services.yaml new file mode 100755 index 000000000..87d2e4c76 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/templates/wcs.services.yaml @@ -0,0 +1,193 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. +# +# Licensed under the Universal Permissive License v 1.0 as shown at +# https://oss.oracle.com/licenses/upl + +apiVersion: v1 +kind: Service +metadata: + name: wcsitesinfra-wcsites-server1-np + namespace: wcsites-ns +spec: + type: NodePort + ports: + - name: defaultnp + port: 8001 + protocol: TCP + selector: + weblogic.domainUID: wcsitesinfra + weblogic.serverName: wcsites-server1 +--- +apiVersion: v1 +kind: Service +metadata: + name: wcsitesinfra-wcsites-server1-svc + namespace: wcsites-ns +spec: + clusterIP: None + ports: + - name: ticket-cache + port: 50000 + protocol: TCP + targetPort: 50000 + - name: ticket-cache1 + port: 50001 + protocol: TCP + targetPort: 50001 + - name: mcast-linked-cache + port: 50002 + protocol: TCP + targetPort: 50002 + - name: mcast-linked-cache1 + port: 50003 + protocol: TCP + targetPort: 50003 + - name: mcast-cs-cache + port: 50004 + protocol: TCP + targetPort: 50004 + - name: mcast-cs-cache1 + port: 50005 + protocol: TCP + targetPort: 50005 + - name: mcast-cas-cache + port: 50006 + protocol: TCP + targetPort: 50006 + - name: mcast-cas-cache1 + port: 50007 + protocol: TCP + targetPort: 50007 + - name: mcast-ss-cache + port: 50008 + protocol: TCP + targetPort: 50008 + - name: mcast-ss-cache1 + port: 50009 + protocol: TCP + targetPort: 50009 + publishNotReadyAddresses: true + selector: + weblogic.createdByOperator: "true" + weblogic.domainUID: wcsitesinfra + weblogic.serverName: wcsites-server1 + sessionAffinity: None + type: ClusterIP +status: + loadBalancer: {} +--- +apiVersion: v1 +kind: Service +metadata: + name: wcsitesinfra-wcsites-server2-svc + namespace: wcsites-ns +spec: + clusterIP: None + ports: + - name: ticket-cache + port: 50000 + protocol: TCP + targetPort: 50000 + - name: ticket-cache1 + port: 50001 + protocol: TCP + targetPort: 50001 + - name: mcast-linked-cache + port: 50002 + protocol: TCP + targetPort: 50002 + - name: mcast-linked-cache1 + port: 50003 + protocol: TCP + targetPort: 50003 + - name: mcast-cs-cache + port: 50004 + protocol: TCP + targetPort: 50004 + - name: mcast-cs-cache1 + port: 50005 + protocol: TCP + targetPort: 50005 + - name: mcast-cas-cache + port: 50006 + protocol: TCP + targetPort: 50006 + - name: mcast-cas-cache1 + port: 50007 + protocol: TCP + targetPort: 50007 + - name: mcast-ss-cache + port: 50008 + protocol: TCP + targetPort: 50008 + - name: mcast-ss-cache1 + port: 50009 + protocol: TCP + targetPort: 50009 + publishNotReadyAddresses: true + selector: + weblogic.createdByOperator: "true" + weblogic.domainUID: wcsitesinfra + weblogic.serverName: wcsites-server2 + sessionAffinity: None + type: ClusterIP +status: + loadBalancer: {} +--- +apiVersion: v1 +kind: Service +metadata: + name: wcsitesinfra-wcsites-server3-svc + namespace: wcsites-ns +spec: + clusterIP: None + ports: + - name: ticket-cache + port: 50000 + protocol: TCP + targetPort: 50000 + - name: ticket-cache1 + port: 50001 + protocol: TCP + targetPort: 50001 + - name: mcast-linked-cache + port: 50002 + protocol: TCP + targetPort: 50002 + - name: mcast-linked-cache1 + port: 50003 + protocol: TCP + targetPort: 50003 + - name: mcast-cs-cache + port: 50004 + protocol: TCP + targetPort: 50004 + - name: mcast-cs-cache1 + port: 50005 + protocol: TCP + targetPort: 50005 + - name: mcast-cas-cache + port: 50006 + protocol: TCP + targetPort: 50006 + - name: mcast-cas-cache1 + port: 50007 + protocol: TCP + targetPort: 50007 + - name: mcast-ss-cache + port: 50008 + protocol: TCP + targetPort: 50008 + - name: mcast-ss-cache1 + port: 50009 + protocol: TCP + targetPort: 50009 + publishNotReadyAddresses: true + selector: + weblogic.createdByOperator: "true" + weblogic.domainUID: wcsitesinfra + weblogic.serverName: wcsites-server3 + sessionAffinity: None + type: ClusterIP +status: + loadBalancer: {} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/unicast.py b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/unicast.py new file mode 100755 index 000000000..e7ee6d842 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/unicast.py @@ -0,0 +1,120 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. +# +# Licensed under the Universal Permissive License v 1.0 as shown at +# https://oss.oracle.com/licenses/upl + +import xml.dom.minidom +import re +import sys + +def getManagedServerCount(domainHome): +# use the parse() function to load and parse an XML file + doc = xml.dom.minidom.parse(domainHome + "/config/config.xml") + servers = doc.getElementsByTagName("server") + print "Total Configured Managed Servers: %d " % (servers.length - 1) + return servers.length - 1; + + +# Method to uncomment and comment the required tag and save back +def replaceXml(domainHome, ms_server): + f = open(domainHome + "/config/fmwconfig/servers/" + ms_server + "/config/ticket-cache.xml","r+w") + filecontent = f.read() + #Uncomment the one to be used + filecontent = re.sub ( r'','cas_tgt" />', filecontent,1) + #Comment the one not used + filecontent = re.sub ( r'','propertySeparator="," -->', filecontent,1) + f.seek(0) + f.write(filecontent) + f.write("\n\n\n") + f.close() + +# Method to replace the properties +def replaceRmiUrlsInCache(domainHome, prefix, n, ms_server, excludedServerNumber, filename, port): + doc = xml.dom.minidom.parse(domainHome + "/config/fmwconfig/servers/" + ms_server + "/config/" + filename) + abc = doc.getElementsByTagName("cacheManagerPeerProviderFactory") + processString = "peerDiscovery=manual,rmiUrls=//localhost:/notifier" + + for element in abc: + element.setAttribute("properties", processString) + + for x in range (1,n-1): + processString = processString + "|//localhost:/notifier" + + # We should have got the properties attribute now tokenized with localhost and 41001. Exclude 1 add the rest + for i in range (1,n+1): + if i <> int(excludedServerNumber): + processString = re.sub ( r'localhost',prefix + str(i), processString,1) + processString = re.sub ( r'',str(port), processString,1) + + element.setAttribute("properties", processString) + print(processString) + ghi = doc.getElementsByTagName("cacheManagerPeerListenerFactory") + for element in ghi: + processString = element.getAttribute("properties") + processString = "hostName="+prefix+ str(excludedServerNumber) +",port=" + str(port) +",remoteObjectPort=" + str(int(port)+1) + ",socketTimeoutMillis=12000" + element.setAttribute("properties", processString) + myfile = open(domainHome + "/config/fmwconfig/servers/" + ms_server + "/config/" + filename , "w") + myfile.write(doc.toxml()) + myfile.close() + print("Updated " + filename) + +# Method to replace the properties +def replaceRmiUrls(domainHome, prefix, n, ms_server, excludedServerNumber, port): + doc = xml.dom.minidom.parse(domainHome + "/config/fmwconfig/servers/" + ms_server + "/config/ticket-cache.xml") + abc = doc.getElementsByTagName("cacheManagerPeerProviderFactory") + processString = "" + + for element in abc: + processString = element.getAttribute("properties") + + for x in range (1,n-1): + processString = processString + "|//localhost:41001/cas_st|//localhost:41001/cas_tgt" + + # We should have got the properties attribute now tokenized with localhost and 41001. Exclude 1 add the rest + for i in range (1,n+1): + if i <> int(excludedServerNumber): + processString = re.sub ( r'localhost',prefix + str(i), processString,1) + processString = re.sub ( r'41001',str(port), processString,1) + processString = re.sub ( r'localhost',prefix + str(i), processString,1) + processString = re.sub ( r'41001',str(port), processString,1) + + element.setAttribute("properties", processString) + print(processString) + ghi = doc.getElementsByTagName("cacheManagerPeerListenerFactory") + for element in ghi: + processString = element.getAttribute("properties") + processString = "hostName=" + prefix + str(excludedServerNumber) + ",port=" + str(port) + ",remoteObjectPort=" + str(int(port)+1) + ",socketTimeoutMillis=12000" + element.setAttribute("properties", processString) + myfile = open(domainHome + "/config/fmwconfig/servers/" + ms_server + "/config/ticket-cache.xml", "w") + myfile.write(doc.toxml()) + myfile.close() + print("Updated " + "ticket-cache.xml") + +def main(): + # count the arguments + arguments = len(sys.argv) - 1 + print ("The script is called with %i arguments" % (arguments)) + domainHome = sys.argv[1] + serverPrefix = sys.argv[2] + ms_server = sys.argv[3] + port = sys.argv[4] + excludedServerNumber = ms_server[-1] + print("Host prefix set to " + serverPrefix) + print("Managed Server set to - " + ms_server) + print("Excluded Server Number set to - " + excludedServerNumber) + print("Starting port set to - " + port) + replaceXml(domainHome, ms_server) + servercount = getManagedServerCount(domainHome) + replaceRmiUrls(domainHome, serverPrefix, servercount, ms_server, excludedServerNumber, port) + replaceRmiUrlsInCache(domainHome, serverPrefix, servercount, ms_server, excludedServerNumber, "linked-cache.xml", int(port) + 2) + replaceRmiUrlsInCache(domainHome, serverPrefix, servercount, ms_server, excludedServerNumber, "cs-cache.xml", int(port) + 4) + replaceRmiUrlsInCache(domainHome, serverPrefix, servercount, ms_server, excludedServerNumber, "cas-cache.xml", int(port) + 6 ) + replaceRmiUrlsInCache(domainHome, serverPrefix, servercount, ms_server, excludedServerNumber, "ss-cache.xml", int(port) + 8 ) + + +if __name__ == "__main__": + # calling main function + main() + diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/utility.sh b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/utility.sh new file mode 100755 index 000000000..da91525f1 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/utility.sh @@ -0,0 +1,59 @@ +#!/bin/bash +# Copyright (c) 2022, Oracle and/or its affiliates. +# +# Licensed under the Universal Permissive License v 1.0 as shown at +# https://oss.oracle.com/licenses/upl + +# +# Report an error and fail the job +# $1 - text of error +function fail { + echo ERROR: $1 + exit 1 +} + +# +# Create a folder +# $1 - path of folder to create +function createFolder { + mkdir -m 777 -p $1 + if [ ! -d $1 ]; then + fail "Unable to create folder $1" + fi +} + +function checkCreateDomainScript { + if [ -f $1 ]; then + echo The domain will be created using the script $1 + else + fail "Could not locate the domain creation script ${1}" + fi +} + +function checkDomainSecret { + + # Validate the domain secrets exist before proceeding. + if [ ! -f /weblogic-operator/secrets/username ]; then + fail "The domain secret /weblogic-operator/secrets/username was not found" + fi + if [ ! -f /weblogic-operator/secrets/password ]; then + fail "The domain secret /weblogic-operator/secrets/password was not found" + fi +} + +function prepareDomainHomeDir { + # Do not proceed if the domain already exists + local domainFolder=${DOMAIN_HOME_DIR} + if [ -d ${domainFolder} ]; then + fail "The create domain job will not overwrite an existing domain. The domain folder ${domainFolder} already exists" + fi + + # Create the base folders + createFolder ${DOMAIN_ROOT_DIR}/domains + createFolder ${DOMAIN_LOGS_DIR} + createFolder ${DOMAIN_ROOT_DIR}/applications + createFolder ${DOMAIN_ROOT_DIR}/stores + createFolder ${DOMAIN_ROOT_DIR}/shared + createFolder ${DOMAIN_ROOT_DIR}/sites-home +} + diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/values.schema.json b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/values.schema.json new file mode 100755 index 000000000..e23109a8d --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/values.schema.json @@ -0,0 +1,439 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "required": [ + "kubernetesVersion", + "image", + "imagePullSecrets", + "domain", + "oracledb", + "ingress" + ], + "definitions": { + "cluster": { + "type": "object", + "required": [ + "name", + "managedServers" + ], + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z-_]{1,25}$" + }, + "managedServers": { + "type": "object", + "required": [ + "count", + "name", + "listenPort" + ], + "properties": { + "count": { + "type": "integer", + "minimum": 0 + }, + "name": { + "type": "string", + "pattern": "^[a-z-_]{1,25}$" + }, + "listentPort": { + "type": "integer", + "minimum": 1024, + "maximum": 65535 + }, + "sslListenPort": { + "type": "integer", + "minimum": 1024, + "maximum": 65535 + } + } + } + } + }, + "ip": { + "type": "string", + "pattern": "^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}$" + } + }, + "properties": { + "kubernetesVersion": { + "type": "string", + "enum": ["1.20", "1.19"] + }, + "image": { + "type": "object", + "required": [ + "repository", + "pullPolicy" + ], + "properties": { + "repository": { + "type": "string", + "pattern": "^[a-z0-9-_./]+$" + }, + "pullPolicy": { + "type": "string", + "pattern": "^(Always|Never|IfNotPresent)$" + } + } + }, + "imagePullSecrets": { + "type": "array" + }, + "domain": { + "type": "object", + "required": [ + "enabled", + "type", + "domainName", + "productionMode", + "rootDir", + "scriptDir", + "credentials", + "t3Channel", + "sslEnabled", + "persistenceStore", + "logHomeEnabled", + "logHome", + "includeServerOutInPodLog", + "httpAccessLogInLogHome", + "serverStartPolicy", + "javaOptions", + "maxManagedServerCount", + "admin", + "wcsCluster", + "storage", + "rcuSchema" + ], + "properties": { + "enabled": { + "type": "boolean" + }, + "type": { + "type": "string", + "enum": ["sitestype","wcsites"] + }, + "domainName": { + "type": "string", + "pattern": "^[a-zA-Z0-9-_]+$", + "maxLength": 99 + }, + "productionMode": { + "type": "boolean" + }, + "rootDir": { + "type": "string", + "pattern": "^/([a-zA-z0-9-_]+/*)+$" + }, + "scriptDir": { + "type": "string", + "pattern": "^/([a-zA-z0-9-_]+/*)+$" + }, + "credentials": { + "type": [ + "object" + ], + "anyOf": [ + { "required": [ + "secretName" + ], + "properties": { + "secretName": { + "type": ["string"] + } + } + }, + { "required": [ + "username", + "password" + ], + "properties": { + "secretName": { + "type": "null" + }, + "username": { + "type": ["string"], + "pattern": "^[a-zA-Z0-9]+$" + }, + "password": { + "type": ["string"], + "pattern": "^[a-zA-Z0-9.]{8,}$", + "description": "The domain password must contain at least 1 uppercase and 1 number and be at least 8 characters long." + } + }, + "dependencies": { + "username": { "required": ["password"] } + } + } + ] + }, + "t3Channel": { + "type": "object", + "required": [ + "exposed" + ], + "properties": { + "exposed": { + "type": "boolean" + } + }, + "oneOf": [ + { + "properties": { + "exposed": { "const": true }, + "port": { + "type": "integer", + "minimum": 30000, + "maximum": 35635 + }, + "publicIp": { + "$ref": "#/definitions/ip" + } + }, + "required": ["publicIp", "port"] + }, + { + "properties": { + "exposed": { "const": false } + } + } + ] + }, + "sslEnabled": { + "type": "boolean" + }, + "persistenceStore": { + "type": [ + "string", + "null" + ], + "enum": ["jdbc", ""] + }, + "logHomeEnabled": { + "type": "boolean" + }, + "logHome": { + "type": [ + "string", + "null" + ], + "pattern": "^/([a-zA-z0-9-_]+/*)+$" + }, + "includeServerOutInPodLog": { + "type": [ + "boolean", + "null" + ] + }, + "httpAccessLogInLogHome": { + "type": [ + "boolean", + "null" + ] + }, + "serverStartPolicy": { + "type": "string", + "enum": ["NEVER", "ADMIN_ONLY", "IF_NEEDED"] + }, + "javaOptions": { + "type": "string", + "pattern": "^(-D[a-zA-Z0-9.]+=.*|)" + }, + "maxManagedServerCount": { + "type": "integer", + "minimum": 1, + "maximum": 20 + }, + "admin": { + "type": "object", + "required": [ + "name", + "listenPort", + "exposeNodePort" + ], + "properties": { + "name": { + "type": "string", + "pattern": "^[a-zA-Z0-9-_]+$" + }, + "listenPort": { + "type": "integer", + "minimum": 1024, + "maximum": 65535 + }, + "sslListenPort": { + "type": "integer", + "minimum": 1024, + "maximum": 65535 + }, + "exposeNodePort": { + "type": "boolean" + }, + "nodePort": { + "type": "integer", + "minimum": 30000, + "maximum": 65535 + } + }, + "dependencies": { + "exposedNodePort": { "required": ["nodePort"] } + } + }, + "wcsCluster": { + "$ref": "#/definitions/cluster" + }, + "storage": { + "type": "object", + "required": [ + "capacity", + "reclaimPolicy", + "type", + "path" + ], + "properties": { + "capacity": { + "type": "string", + "pattern": "^[1-9][0-9]*(M|G)i$" + }, + "reclaimPolicy": { + "type": "string", + "enum": ["Retain", "Delete", "Recycle"] + }, + "type": { + "type": "string", + "enum": ["nfs", "hostpath"] + }, + "path": { + "type": "string", + "pattern": "^/[a-zA-Z0-9/-_]+$" + }, + "nfs": { + "type": "object", + "required": [ + "server" + ], + "properties": { + "server": { + "$ref": "#/definitions/ip" + } + } + } + } + }, + "rcuSchema": { + "type": "object", + "required": [ + "prefix", + "profileType", + "credentials" + ], + "properties": { + "prefix": { + "type": "string", + "maxLength": 5 + }, + "profileType": { + "type": "string", + "enum": ["SMALL", "MED", "LARGE"] + }, + "credentials": { + "type": [ + "object" + ], + "anyOf": [ + { "required": + [ "secretName" ], + "properties": { + "secretName": { + "type": ["string"] + } + } + }, + { "required": + [ "username", "password" ], + "properties": { + "secretName": { + "type": "null" + }, + "username": { + "type": ["string"], + "pattern": "^[a-zA-Z0-9]+$" + }, + "password": { + "type": ["string"], + "pattern": "^[a-zA-Z0-9-_#]{9,30}$", + "description": "The domain password must contain at least 2 uppercase, 2 lowercase, 2 numbers, and 2 special and be at least 9 to 30 characters long." + } + }, + "dependencies": { + "username": { "required": ["password"] } + } + } + ] + } + } + } + } + }, + "oracledb": { + "type": "object", + "required": [ + "provision" + ], + "properties": { + "provision": { + "type": "boolean" + }, + "url": { + "type": ["string", "null"], + "pattern": "^[a-zA-Z0-9-_.]+:[1-9][0-9]{2,4}/[a-zA-Z0-9-_.]+$" + }, + "cdb": { + "type": "string" + }, + "pdb": { + "type": "string" + }, + "domain": { + "type": "string" + }, + "credentials": { + "type": [ + "object" + ], + "anyOf": [ + { "required": + [ "secretName" ], + "properties": { + "secretName": { + "type": ["string"] + } + } + }, + { "required": + [ "username", "password" ], + "properties": { + "secretName": { + "type": "null" + }, + "username": { + "type": ["string"], + "enum": ["SYS","ADMIN"] + }, + "password": { + "type": ["string"], + "pattern": "^[a-zA-Z0-9-_#]{9,30}$", + "description": "The domain password must contain at least 2 uppercase, 2 lowercase, 2 numbers, and 2 special and be at least 9 to 30 characters long." + } + }, + "dependencies": { + "username": { "required": ["password"] } + } + } + ] + } + } + } + } +} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/values.yaml b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/values.yaml new file mode 100755 index 000000000..1587a9e82 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/charts/wc-sites/values.yaml @@ -0,0 +1,147 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +# Default values for wcsites. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +nameOverride: "" +fullnameOverride: "" + +kubernetesVersion: "1.20" + +image: + repository: "oracle/wcsites" + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "12.2.1.4" + name: "oracle/wcsites:12.2.1.4" +# List of secrets to use to pull images from private registry +imagePullSecrets: + -name: image-secret + +# Service Account for this specific deployment +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +podAnnotations: {} + +podSecurityContext: {} + +securityContext: {} + +domain: + # Set this flag to false to remove the domain before tear-down (default true) + enabled: true + # supported types: sites + type: wcsites + + # domainName should have no space, _ or - it is same domainUUID + domainName: wcsitesinfra + namespace: wcsites-ns + productionMode: true + + rootDir: /u01/oracle/user_projects + scriptDir: /u01/weblogic + + # Weblogic user credentials for the domain + # Either provide username and password, + # or provide the name of a secret containing username and password key/value pairs + credentials: + secretName: + username: weblogic + password: Welcome1 + + t3Channel: + exposed: false + port: 30012 + publicIp: "0.0.0.0" + + sslEnabled: false + + # 'jdbc' for persistence in database, otherwise null + persistenceStore: jdbc + + # Logs + logHomeEnabled: true + logHome: /u01/oracle/user_projects/domains/logs + includeServerOutInPodLog: true + httpAccessLogInLogHome: true + + # serverStartPolicy legal values are "NEVER", "IF_NEEDED", or "ADMIN_ONLY" + # This determines which WebLogic Servers the Operator will start up when it discovers this Domain + # - "NEVER" will not start any server in the domain + # - "ADMIN_ONLY" will start up only the administration server (no managed servers will be started) + # - "IF_NEEDED" will start all non-clustered servers, including the administration server and clustered servers up to the replica count + serverStartPolicy: IF_NEEDED + javaOptions: "-Dweblogic.StdoutDebugEnabled=false" + maxManagedServerCount: 5 + + admin: + name: AdminServer + listenPort: 7001 + sslListenPort: 7002 + exposeNodePort: false + nodePort: 30701 + + wcsCluster: + name: wcsites_cluster + managedServers: + count: 3 + name: wcsites-server + listenPort: 8001 + sslListenPort: 8002 + + storage: + capacity: 10Gi + # The valid values are: 'Retain', 'Delete', and 'Recycle' + reclaimPolicy: Retain + # valid types are nfs or hostpath + type: nfs + path: /scratch/K8SVolume/WCSites + nfs: + server: 10.0.10.190 + + rcuSchema: + prefix: WCS + # profileType: supported values: SMALL(default), MED, LARGE + profileType: SMALL + credentials: + # provide either the secretName of the secret containing 'username' and 'password' + # or provide 'username' and 'password' values + # If a secret is specified it takes precedence over the plaintext entries + secretName: + username: "WCS1" + password: "Oradoc_db12W#-" + +oracledb: + # select enabled: true if the database should be provisioned + provision: false + url: db.db.oke.oraclevcn.com:1521/pdb.db.oke.oraclevcn.com + # If url is not provided, deploy the DB and use the following params: + # name of the Container DB + cdb: cdb + # name of the Pluggable DB + pdb: pdb + # domain + domain: k8s + credentials: + # provide either the secretName of the secret containing 'username' and 'password' + # or provide 'username' and 'password' values + secretName: + username: SYS + password: "Oradoc_db12W#-" + +ingress: + type: traefik + tls: false + hostname: "" + dnsname: "" + port: 30305 + scheme: http diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/datasources.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/datasources.tf new file mode 100755 index 000000000..1c741b176 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/datasources.tf @@ -0,0 +1,6 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +data "oci_identity_tenancy" "tenancy" { + tenancy_id = var.tenancy_ocid +} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/images/wcs-1.PNG b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/images/wcs-1.PNG new file mode 100755 index 0000000000000000000000000000000000000000..1bef0c8ff65a147ee0b7ef9a5e302ad2ec50057a GIT binary patch literal 30168 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%0AF#6+a!SsNWDX1I(XiWF}ure=b+xg1G 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 A;{X5v literal 0 HcmV?d00001 diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/images/wcs-2.PNG b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/images/wcs-2.PNG new file mode 100755 index 0000000000000000000000000000000000000000..35bdb769bc79bc007c1f904844e7449e2a64faf7 GIT binary patch literal 50202 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 literal 0 HcmV?d00001 diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/images/wcs-3.PNG b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/images/wcs-3.PNG new file mode 100755 index 0000000000000000000000000000000000000000..0b1f21152740b3781caeca56b78ca93bd5aa255d GIT binary patch literal 50618 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 literal 0 HcmV?d00001 diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/images/wcs-4.PNG b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/images/wcs-4.PNG new file mode 100755 index 0000000000000000000000000000000000000000..ff4515e1a049d20fdfba74b3865f7f258f261044 GIT binary patch literal 62747 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�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 ASO5S3 literal 0 HcmV?d00001 diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/locals.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/locals.tf new file mode 100755 index 000000000..0aeab8eb4 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/locals.tf @@ -0,0 +1,6 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +locals { + cluster_name = "${var.deployment_name}-cluster" +} \ No newline at end of file diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/main.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/main.tf new file mode 100755 index 000000000..2b3eccc47 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/main.tf @@ -0,0 +1,81 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +module "vcn" { + source = "./modules/vcn" + compartment_ocid = var.compartment_ocid + vcn_cidr = var.vcn_cidr + oke_cluster = var.oke_cluster + provision_database = var.provision_database +} + +# provision autonomous database +module "oci-adb" { + source = "./modules/oci-adb" + provision_adb = var.provision_adb + compartment_ocid = var.compartment_ocid + adb_password = var.adb_password + adb_database_db_workload = var.adb_database_db_workload + use_existing_vcn = true + vcn_id = module.vcn.vcn_id + adb_subnet_id = module.vcn.database_subnet_id +} + +# provision database system +module "database" { + source = "./modules/database" + provision_database = var.provision_database + compartment_ocid = var.compartment_ocid + database_name = var.database_name + database_unique_name = var.database_unique_name + db_version = var.db_version + pdb_name = var.pdb_name + admin_password = var.db_sys_password + db_system_shape = var.db_system_shape + db_system_cpu_core_count = var.db_system_cpu_core_count + ssh_public_keys = [var.ssh_authorized_key] + subnet_id = module.vcn.database_subnet_id + db_system_license_model = var.db_system_license_model + db_system_db_system_options_storage_management = var.db_system_db_system_options_storage_management +} + +module "cluster" { + source = "./modules/k8s" + provision_cluster = var.provision_cluster + cluster_name = local.cluster_name + tenancy_ocid = var.tenancy_ocid + compartment_ocid = var.compartment_ocid + vcn_id = module.vcn.vcn_id + oke_cluster = var.oke_cluster + cluster_lb_subnet_ids = [module.vcn.cluster_lb_subnet_id] + secrets_encryption_key_ocid = var.secrets_encryption_key_ocid +} + +module "node_pools" { + source = "./modules/node_pool" + provision_node_pool = var.provision_cluster + compartment_ocid = var.compartment_ocid + cluster_id = module.cluster.cluster.id + kubernetes_version = var.oke_cluster.k8s_version + ssh_authorized_key = var.ssh_authorized_key + node_pools = var.node_pools + nodes_subnet_id = module.vcn.cluster_nodes_subnet_id +} + + + +module "fss" { + source = "./modules/fss" + provision_filesystem = var.provision_filesystem + provision_mount_target = var.provision_mount_target + provision_export = var.provision_export + compartment_ocid = var.compartment_ocid + subnet_id = var.fss_subnet_id == null ? module.vcn.cluster_nodes_subnet_id : var.fss_subnet_id + ad_number = var.ad_number + encryption_key_id = var.secrets_encryption_key_ocid + mount_path = var.mount_path + source_cidr = var.provision_cluster == true ? module.vcn.cluster_nodes_subnet_cidr : var.fss_source_cidr + filesystem_ocid = var.filesystem_ocid + mount_target_ocid = var.mount_target_ocid + server_ip = var.mount_target_ip +} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/database/datasources.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/database/datasources.tf new file mode 100755 index 000000000..26d96469b --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/database/datasources.tf @@ -0,0 +1,6 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +data "oci_identity_availability_domains" "ads" { + compartment_id = var.compartment_ocid +} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/database/inputs.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/database/inputs.tf new file mode 100755 index 000000000..9db756855 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/database/inputs.tf @@ -0,0 +1,35 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +variable "provision_database" {} +variable "compartment_ocid" {} +variable "database_name" {} +variable "database_unique_name" {} +variable "db_version" {} +variable "pdb_name" { + default = "pdb" +} +variable "admin_username" { + default = "SYS" +} +variable "admin_password" {} +variable "db_system_shape" { + default = "VM.Standard2.1" +} +variable "db_system_cpu_core_count" { + default = 1 +} +variable "db_system_data_storage_size_in_gb" { + default = 256 +} +variable "db_system_database_edition" { + default = "ENTERPRISE_EDITION" +} +variable "ssh_public_keys" {} +variable "subnet_id" {} +variable "db_system_license_model" { + default = "LICENSE_INCLUDED" +} +variable "db_system_db_system_options_storage_management" { + default = "LVM" +} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/database/main.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/database/main.tf new file mode 100755 index 000000000..44d087ee9 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/database/main.tf @@ -0,0 +1,42 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +resource "oci_database_db_system" "db_system" { + count = var.provision_database ? 1 : 0 + + #Required + availability_domain = data.oci_identity_availability_domains.ads.availability_domains.0.name + compartment_id = var.compartment_ocid + db_home { + #Required + database { + #Required + admin_password = var.admin_password + + #Optional + db_name = var.database_name + db_workload = "OLTP" + pdb_name = var.pdb_name + } + + #Optional + db_version = var.db_version + display_name = var.database_name + } + hostname = "db" + shape = var.db_system_shape + ssh_public_keys = var.ssh_public_keys + subnet_id = var.subnet_id + + #Optional + cpu_core_count = var.db_system_cpu_core_count + data_storage_size_in_gb = var.db_system_data_storage_size_in_gb + database_edition = var.db_system_database_edition + db_system_options { + + #Optional + storage_management = var.db_system_db_system_options_storage_management + } + license_model = var.db_system_license_model + node_count = 1 +} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/database/outputs.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/database/outputs.tf new file mode 100755 index 000000000..e20f39ec2 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/database/outputs.tf @@ -0,0 +1,6 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +output "jdbc_connection_url" { + value = var.provision_database ? "${oci_database_db_system.db_system.0.hostname}.${oci_database_db_system.db_system.0.domain}:1521/${var.pdb_name}.${oci_database_db_system.db_system.0.domain}" : "" +} \ No newline at end of file diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/fss/datasource.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/fss/datasource.tf new file mode 100755 index 000000000..42297297a --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/fss/datasource.tf @@ -0,0 +1,13 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +data "oci_identity_availability_domain" "ad" { + compartment_id = var.compartment_ocid + ad_number = var.ad_number +} + +# Get the Private IP of the mount target +data "oci_core_private_ip" "private_ip" { + #Required + private_ip_id = var.provision_mount_target ? oci_file_storage_mount_target.mount_target.0.private_ip_ids[0] : "na" +} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/fss/inputs.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/fss/inputs.tf new file mode 100755 index 000000000..8d5a42184 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/fss/inputs.tf @@ -0,0 +1,19 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +variable "subnet_id" {} +variable "compartment_ocid" {} +variable "ad_number" { + default = 2 +} +variable "encryption_key_id" { + default = null +} +variable "mount_path" {} +variable "source_cidr" {} +variable "provision_filesystem" {} +variable "provision_mount_target" {} +variable "provision_export" {} +variable "filesystem_ocid" {} +variable "mount_target_ocid" {} +variable "server_ip" {} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/fss/main.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/fss/main.tf new file mode 100755 index 000000000..1cdc4a0ff --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/fss/main.tf @@ -0,0 +1,57 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +resource "oci_file_storage_file_system" "fss" { + count = var.provision_filesystem ? 1 : 0 + + #Required + availability_domain = data.oci_identity_availability_domain.ad.name + compartment_id = var.compartment_ocid + + #Optional + display_name = "Oracle WebCenter Sites File System" + kms_key_id = var.encryption_key_id +} + +resource "oci_file_storage_mount_target" "mount_target" { + count = var.provision_mount_target ? 1 : 0 + + #Required + availability_domain = data.oci_identity_availability_domain.ad.name + compartment_id = var.compartment_ocid + subnet_id = var.subnet_id + + #Optional + display_name = "Oracle WebCenter Sites Mount Target" +} + +resource "oci_file_storage_export_set" "export_set" { + count = var.provision_export ? 1 : 0 + + #Required + mount_target_id = var.provision_mount_target ? oci_file_storage_mount_target.mount_target.0.id : var.mount_target_ocid + + #Optional + display_name = "Oracle WebCenter Sites Export Set" +} + +resource "oci_file_storage_export" "export" { + #Required + count = var.provision_export ? 1 : 0 + export_set_id = oci_file_storage_export_set.export_set.0.id + file_system_id = var.provision_filesystem ? oci_file_storage_file_system.fss.0.id : var.filesystem_ocid + path = var.mount_path + + #Optional + export_options { + #Required + source = var.source_cidr + + #Optional + access = "READ_WRITE" + anonymous_gid = null + anonymous_uid = null + identity_squash = "NONE" + require_privileged_source_port = false + } +} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/fss/outputs.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/fss/outputs.tf new file mode 100755 index 000000000..98e3a7b03 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/fss/outputs.tf @@ -0,0 +1,12 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +# File Storage Server IP address +output "server_ip" { + value = var.provision_mount_target ? data.oci_core_private_ip.private_ip.ip_address : var.server_ip +} + +output "path" { + value = length(oci_file_storage_export.export) > 0 ? oci_file_storage_export.export[0].path : null +} + diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/k8s/inputs.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/k8s/inputs.tf new file mode 100755 index 000000000..6897e7164 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/k8s/inputs.tf @@ -0,0 +1,28 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +variable "tenancy_ocid" {} +variable "compartment_ocid" {} +variable "vcn_id" {} +variable "cluster_name" {} + +variable "provision_cluster" {} + +variable "oke_cluster" { + default = { + k8s_version = "v1.20.8" + pods_cidr = "10.1.0.0/16" + services_cidr = "10.2.0.0/16" + } +} +variable "cluster_lb_subnet_ids" {} + +variable "cluster_options_add_ons_is_kubernetes_dashboard_enabled" { + default = true +} +variable "cluster_options_add_ons_is_tiller_enabled" { + default = true +} +variable "secrets_encryption_key_ocid" { + default = null +} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/k8s/kube_config.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/k8s/kube_config.tf new file mode 100755 index 000000000..1efca602f --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/k8s/kube_config.tf @@ -0,0 +1,23 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +variable "cluster_kube_config_expiration" { + default = 2592000 +} + +variable "cluster_kube_config_token_version" { + default = "2.0.0" +} + +data "oci_containerengine_cluster_kube_config" "cluster_kube_config" { + #Required + cluster_id = oci_containerengine_cluster.cluster[0].id + + #Optional + expiration = var.cluster_kube_config_expiration + token_version = var.cluster_kube_config_token_version +} + +output "kube_config" { + value = data.oci_containerengine_cluster_kube_config.cluster_kube_config.content +} \ No newline at end of file diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/k8s/main.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/k8s/main.tf new file mode 100755 index 000000000..6b371db64 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/k8s/main.tf @@ -0,0 +1,57 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +# Cluster dynamic group needed for nodes to apply the key access policy if it was defined. +resource "oci_identity_dynamic_group" "cluster_dynamic_group" { + count = var.secrets_encryption_key_ocid == null ? 0 : 1 + #Required + compartment_id = var.tenancy_ocid + description = "OKE Clusters" + matching_rule = "ALL {resource.type = 'cluster', resource.compartment.id = '${var.compartment_ocid}'}" + name = "oke_${md5(var.compartment_ocid)}" +} + +# Cluster dynamic group policy needed for nodes to access the encryption key if it was defined +resource "oci_identity_policy" "k8s_secrets_policy" { + count = var.secrets_encryption_key_ocid == null ? 0 : 1 + depends_on = [oci_identity_dynamic_group.cluster_dynamic_group] + #Required + compartment_id = var.tenancy_ocid + description = "OKE Secrets encryption policies" + name = "OKE_Secrets" + statements = [ + "Allow dynamic-group oke_${md5(var.compartment_ocid)} to use keys in tenancy where target.key.id = '${var.secrets_encryption_key_ocid}'", + "Allow service oke to use keys in tenancy where target.key.id = '${var.secrets_encryption_key_ocid}'" + ] +} + + +resource "oci_containerengine_cluster" "cluster" { + count = var.provision_cluster ? 1 : 0 + + depends_on = [oci_identity_policy.k8s_secrets_policy] + #Required + compartment_id = var.compartment_ocid + kubernetes_version = var.oke_cluster["k8s_version"] + name = var.cluster_name + vcn_id = var.vcn_id + kms_key_id = var.secrets_encryption_key_ocid + + #Optional + options { + service_lb_subnet_ids = var.cluster_lb_subnet_ids + + #Optional + add_ons { + #Optional + is_kubernetes_dashboard_enabled = var.cluster_options_add_ons_is_kubernetes_dashboard_enabled + is_tiller_enabled = var.cluster_options_add_ons_is_tiller_enabled + } + + kubernetes_network_config { + #Optional + pods_cidr = var.oke_cluster["pods_cidr"] + services_cidr = var.oke_cluster["services_cidr"] + } + } +} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/k8s/outputs.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/k8s/outputs.tf new file mode 100755 index 000000000..814cdb015 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/k8s/outputs.tf @@ -0,0 +1,10 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +output "cluster" { + value = var.provision_cluster ? { + id = oci_containerengine_cluster.cluster[0].id + kubernetes_version = oci_containerengine_cluster.cluster[0].kubernetes_version + name = oci_containerengine_cluster.cluster[0].name + } : {} +} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/node_pool/datasources.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/node_pool/datasources.tf new file mode 100755 index 000000000..836dc5a76 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/node_pool/datasources.tf @@ -0,0 +1,27 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +data "oci_containerengine_node_pool_option" "node_pool_options" { + node_pool_option_id = var.cluster_id +} + +data "oci_core_images" "compatible_images" { + count = length(var.node_pools) + compartment_id = var.compartment_ocid + shape = var.node_pools[count.index].node_shape + state = "AVAILABLE" + sort_by = "TIMECREATED" + sort_order = "DESC" +} + +data "oci_identity_availability_domains" "ads" { + compartment_id = var.compartment_ocid +} + +locals { + node_pool_images = [for i in data.oci_core_images.compatible_images[*].images[*].id : [for x in data.oci_containerengine_node_pool_option.node_pool_options.sources : x if contains(i, x.image_id)]] +} + +output "images" { + value = data.oci_core_images.compatible_images[*].images[*].id +} \ No newline at end of file diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/node_pool/inputs.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/node_pool/inputs.tf new file mode 100755 index 000000000..3a8e567e1 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/node_pool/inputs.tf @@ -0,0 +1,10 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +variable "compartment_ocid" {} +variable "cluster_id" {} +variable "ssh_authorized_key" {} +variable "kubernetes_version" {} +variable "node_pools" {} +variable "nodes_subnet_id" {} +variable "provision_node_pool" {} \ No newline at end of file diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/node_pool/main.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/node_pool/main.tf new file mode 100755 index 000000000..92e8d3103 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/node_pool/main.tf @@ -0,0 +1,49 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +resource "oci_containerengine_node_pool" "node_pool" { + count = var.provision_node_pool ? length(var.node_pools) : 0 + + #Required + cluster_id = var.cluster_id + compartment_id = var.compartment_ocid + kubernetes_version = var.kubernetes_version + name = var.node_pools[count.index]["pool_name"] + node_shape = var.node_pools[count.index]["node_shape"] + + #Optional + dynamic "initial_node_labels" { + for_each = var.node_pools[count.index]["node_labels"] + content { + key = initial_node_labels.key + value = initial_node_labels.value + } + } + + node_source_details { + #Required + image_id = local.node_pool_images[count.index].0.image_id + source_type = local.node_pool_images[count.index].0.source_type + } + + node_config_details { + dynamic "placement_configs" { + for_each = [for ad in data.oci_identity_availability_domains.ads.availability_domains : { + name = ad.name + }] + content { + subnet_id = var.nodes_subnet_id + availability_domain = placement_configs.value.name + } + } + size = var.node_pools[count.index]["node_count"] + } + ssh_public_key = var.ssh_authorized_key + + provisioner "local-exec" { + command = "sleep 5" + when = destroy + } +} + + diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/LICENSE b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/LICENSE new file mode 100755 index 000000000..8eefc2202 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2022, Oracle and/or its affiliates. + +Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +Subject to the condition set forth below, permission is hereby granted to any person obtaining a copy of this +software, associated documentation and/or data (collectively the "Software"), free of charge and under any and +all copyright rights in the Software, and any and all patent rights owned or freely licensable by each licensor +hereunder covering either (i) the unmodified Software as contributed to or provided by such licensor, or +(ii) the Larger Works (as defined below), to deal in both + +(a) the Software, and +(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if one is included with the Software +(each a “Larger Work” to which the Software is contributed by such licensors), + +without restriction, including without limitation the rights to copy, create derivative works of, display, +perform, and distribute the Software and make, use, sell, offer for sale, import, export, have made, and have +sold the Software and the Larger Work(s), and to sublicense the foregoing rights on either these or other terms. + +This license is subject to the following condition: +The above copyright notice and either this complete permission notice or at a minimum a reference to the UPL must +be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/README.md b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/README.md new file mode 100755 index 000000000..31d23afe6 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/README.md @@ -0,0 +1,68 @@ +# oci-adb + +These is Terraform module that deploys [Autonomous Database (ADB)](https://docs.oracle.com/en-us/iaas/Content/Database/Concepts/adboverview.htm) on [Oracle Cloud Infrastructure (OCI)](https://cloud.oracle.com/en_US/cloud-infrastructure). + +## About +Oracle Cloud Infrastructure's Autonomous Database is a fully managed, preconfigured database environment with four workload types available, which are: Autonomous Transaction Processing, Autonomous Data Warehouse, Oracle APEX Application Development, and Autonomous JSON Database. + +## Prerequisites +1. Download and install Terraform (v1.0 or later) +2. Download and install the OCI Terraform Provider (v4.4.0 or later) +3. Export OCI credentials. (this refer to the https://github.com/oracle/terraform-provider-oci ) + + +## What's a Module? +A Module is a canonical, reusable, best-practices definition for how to run a single piece of infrastructure, such as a database or server cluster. Each Module is created using Terraform, and includes automated tests, examples, and documentation. It is maintained both by the open source community and companies that provide commercial support. +Instead of figuring out the details of how to run a piece of infrastructure from scratch, you can reuse existing code that has been proven in production. And instead of maintaining all that infrastructure code yourself, you can leverage the work of the Module community to pick up infrastructure improvements through a version number bump. + +## How to use this Module +This Module has the following folder structure: +* [root](): This folder contains a root module. +* [examples](examples): This folder contains examples of how to use the module: + - [Fully Private ADB + network deployed by module](examples/adb-fully-private-no-existing-network): This is an example of how to use the oci-adb module to deploy Autonomous Transation Processing Database (ATP) with Private Endpoint support with network cloud infrastrucutre elements deployed within the body of the module. + - [Fully Private ADB + custom network injected into module](examples/adb-fully-private-use-existing-network): This is an example of how to use the oci-adb module to deploy Autonomous Data Warehouse Database (ADW) with Private Endpoint support but network cloud infrastrucutre elements will be injected into the module. + - [Fully Public ADB](examples/adb-fully-public): This is an example of how to use the oci-adb module to deploy Autonomous JSON Database (AJD) without Private Endpoint support (exposed to the public Internet). + +To deploy OKE using this Module with minimal effort use this: + +```hcl +module "oci-adb" { + source = "github.com/oci-quickstart/oci-adb" + compartment_ocid = var.compartment_ocid + adb_password = var.adb_password + adb_database_db_workload = var.adb_database_db_workload + use_existing_vcn = true + vcn = var.vcn_id + adb_subnet_id = var.adb_subnet_id +} + +``` + +Argument | Description +--- | --- +compartment_ocid | Compartment's OCID where OKE will be created +use_existing_vcn | If you want to inject already exisitng VCN then you need to set the value to TRUE. +vcn_cidr | If use_existing_vcn is set to FALSE then you can define VCN CIDR block and then it will used to create VCN within the module. +vcn_id | If use_existing_vcn is set to TRUE then you can pass VCN OCID and module will use it to create Private Endpoint for ADB. +node_subnet_id | If use_existing_vcn is set to TRUE then you can pass Subnet OCID and module will use it to nest ADB with Private Endpoint. +adb_subnet_cidr | If use_existing_vcn is set to FALSE then you can define ADB Subnet CIDR block and then it will used to nest ADB with Private Endpoint. +adb_nsg_id | If use_existing_vcn is set to TRUE then you can pass Network Security Group OCID and module will use it to nest ADB with Private Endpoint. +adb_free_tier | If you want to use Free Tier then you need to set the value to TRUE. +adb_private_endpoint | If you want to use Autonomous Database Private Endpoint then you need to set the value to TRUE (default value). +whitelisted_ips | If adb_private_endpoint is set to FALSE then you can define whitelisted IP Addresses in the Internet to access publicly exposed Autonomous Database. +is_data_guard_enabled | Enanle or disable ADB Data Guard +is_auto_scaling_enabled | Enable or disable ADB Autoscaling. +adb_private_endpoint_label | If adb_private_endpoint is set to TRUE then you can define Private Endpoint Label. +adb_database_cpu_core_count | Define how many OCPUs shoule be used by Autonomous Database +adb_database_data_storage_size_in_tbs | Define in terabytes what will be the size of Autonomous Database +adb_database_display_name | Define the database display name of your Autonomous Database +adb_database_db_name | Define the database name of your Autonomous Database +adb_database_db_version | Define the version of your Autonomous Database +adb_db_workload | Define the workload type of your Autonomous Database: {OLTP, DW, AJD, APEX} +adb_database_license_model | Define the license model for your Autonomous Database: {LICENSE_INCLUDED, BRING_YOUR_OWN_LICENSE} +adb_data_safe_status | Define the status of DataSafe for your Autonomous Database +adb_database_defined_tags_value | Define values for the defined tags associated with your Autonomous Database +adb_database_freeform_tags | Define values for the freeform tags associated with your Autonomous Database +adb_tde_wallet_zip_file | Define TDE wallet zip file name of your Autonomous Database + + diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/adb.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/adb.tf new file mode 100755 index 000000000..9903f6ff7 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/adb.tf @@ -0,0 +1,49 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +locals { + adb_nsg_id = (!var.use_existing_vcn && var.adb_private_endpoint) ? oci_core_network_security_group.adb_nsg[0].id : var.adb_nsg_id + adb_subnet_id = (!var.use_existing_vcn && var.adb_private_endpoint) ? oci_core_subnet.adb_subnet[0].id : var.adb_subnet_id +} + +resource "oci_database_autonomous_database" "adb_database" { + count = var.provision_adb ? 1 : 0 + admin_password = var.adb_password + compartment_id = var.compartment_ocid + cpu_core_count = var.adb_database_cpu_core_count + data_storage_size_in_tbs = var.adb_database_data_storage_size_in_tbs + db_name = var.adb_database_db_name + db_version = var.adb_database_db_version + data_safe_status = var.adb_data_safe_status + db_workload = var.adb_database_db_workload + display_name = var.adb_database_display_name + freeform_tags = var.adb_database_freeform_tags + license_model = var.adb_database_license_model + is_free_tier = var.adb_free_tier + is_data_guard_enabled = var.is_data_guard_enabled + is_auto_scaling_enabled = var.is_auto_scaling_enabled + #is_access_control_enabled = var.adb_private_endpoint ? false : true + whitelisted_ips = var.adb_private_endpoint ? null : var.whitelisted_ips + nsg_ids = var.adb_private_endpoint ? [local.adb_nsg_id] : null + private_endpoint_label = var.adb_private_endpoint ? var.adb_private_endpoint_label : null + subnet_id = var.adb_private_endpoint ? local.adb_subnet_id : null + defined_tags = var.defined_tags + lifecycle { + ignore_changes = [defined_tags["Oracle-Tags.CreatedBy"], defined_tags["Oracle-Tags.CreatedOn"]] + } +} + +resource "random_password" "wallet_password" { + count = var.provision_adb ? 1 : 0 + length = var.adb_wallet_password_length + special = var.adb_wallet_password_specials + min_numeric = var.adb_wallet_password_min_numeric + override_special = var.adb_wallet_password_override_special +} + +resource "oci_database_autonomous_database_wallet" "adb_database_wallet" { + count = var.provision_adb ? 1 : 0 + autonomous_database_id = oci_database_autonomous_database.adb_database[0].id + password = random_password.wallet_password[0].result + base64_encode_content = "true" +} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/datasources.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/datasources.tf new file mode 100755 index 000000000..119a37418 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/datasources.tf @@ -0,0 +1,11 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +data "oci_core_services" "AllOCIServices" { + count = (!var.use_existing_vcn && var.adb_private_endpoint) ? 1 : 0 + filter { + name = "name" + values = ["All .* Services In Oracle Services Network"] + regex = true + } +} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/network.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/network.tf new file mode 100755 index 000000000..ce483e562 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/network.tf @@ -0,0 +1,98 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +resource "oci_core_vcn" "adb_vcn" { + count = (!var.use_existing_vcn && var.adb_private_endpoint) ? 1 : 0 + cidr_block = var.vcn_cidr + compartment_id = var.compartment_ocid + display_name = "adb_vcn" + dns_label = "adbvcn" + defined_tags = var.defined_tags +} + +resource "oci_core_service_gateway" "adb_sg" { + count = (!var.use_existing_vcn && var.adb_private_endpoint) ? 1 : 0 + compartment_id = var.compartment_ocid + display_name = "adb_sg" + vcn_id = oci_core_vcn.adb_vcn[0].id + services { + service_id = lookup(data.oci_core_services.AllOCIServices[0].services[0], "id") + } + defined_tags = var.defined_tags +} + +resource "oci_core_nat_gateway" "adb_natgw" { + count = (!var.use_existing_vcn && var.adb_private_endpoint) ? 1 : 0 + compartment_id = var.compartment_ocid + display_name = "adb_natgw" + vcn_id = oci_core_vcn.adb_vcn[0].id + defined_tags = var.defined_tags +} + +resource "oci_core_route_table" "adb_rt_via_natgw_and_sg" { + count = (!var.use_existing_vcn && var.adb_private_endpoint) ? 1 : 0 + compartment_id = var.compartment_ocid + vcn_id = oci_core_vcn.adb_vcn[0].id + display_name = "adb_rt_via_natgw" + defined_tags = var.defined_tags + + route_rules { + destination = "0.0.0.0/0" + destination_type = "CIDR_BLOCK" + network_entity_id = oci_core_nat_gateway.adb_natgw[0].id + } + + route_rules { + destination = lookup(data.oci_core_services.AllOCIServices[0].services[0], "cidr_block") + destination_type = "SERVICE_CIDR_BLOCK" + network_entity_id = oci_core_service_gateway.adb_sg[0].id + } +} + +resource "oci_core_network_security_group" "adb_nsg" { + count = (!var.use_existing_vcn && var.adb_private_endpoint) ? 1 : 0 + compartment_id = var.compartment_ocid + display_name = "adb_nsg" + vcn_id = oci_core_vcn.adb_vcn[0].id + defined_tags = var.defined_tags +} + +resource "oci_core_network_security_group_security_rule" "adb_nsg_egress_group_sec_rule" { + count = (!var.use_existing_vcn && var.adb_private_endpoint) ? 1 : 0 + network_security_group_id = oci_core_network_security_group.adb_nsg[0].id + direction = "EGRESS" + protocol = "6" + destination = var.vcn_cidr + destination_type = "CIDR_BLOCK" +} + +resource "oci_core_network_security_group_security_rule" "adb_nsg_ingress_group_sec_rule" { + count = (!var.use_existing_vcn && var.adb_private_endpoint) ? 1 : 0 + network_security_group_id = oci_core_network_security_group.adb_nsg[0].id + direction = "INGRESS" + protocol = "6" + source = var.vcn_cidr + source_type = "CIDR_BLOCK" + tcp_options { + destination_port_range { + max = 1522 + min = 1522 + } + } +} + +resource "oci_core_subnet" "adb_subnet" { + count = (!var.use_existing_vcn && var.adb_private_endpoint) ? 1 : 0 + cidr_block = var.adb_subnet_cidr + compartment_id = var.compartment_ocid + vcn_id = oci_core_vcn.adb_vcn[0].id + display_name = "adb_subnet" + dns_label = "adbnet" + security_list_ids = [oci_core_vcn.adb_vcn[0].default_security_list_id] + route_table_id = oci_core_route_table.adb_rt_via_natgw_and_sg[0].id + prohibit_public_ip_on_vnic = true + defined_tags = var.defined_tags +} + + + diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/outputs.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/outputs.tf new file mode 100755 index 000000000..2fc138e80 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/outputs.tf @@ -0,0 +1,14 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +output "adb_database" { + value = { + adb_database_id = var.provision_adb ? oci_database_autonomous_database.adb_database[0].id : "" + connection_urls = var.provision_adb ? oci_database_autonomous_database.adb_database[0].connection_urls : "" + adb_wallet_content = var.provision_adb ? oci_database_autonomous_database_wallet.adb_database_wallet[0].content : "" + adb_nsg_id = (!var.use_existing_vcn && var.adb_private_endpoint) ? oci_core_network_security_group.adb_nsg[0].id : var.adb_nsg_id + } +} + + + diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/variables.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/variables.tf new file mode 100755 index 000000000..c51677a84 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/oci-adb/variables.tf @@ -0,0 +1,124 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +variable "compartment_ocid" { + default = "" +} + +variable "provision_adb" {} + +variable "adb_password" {} + +variable "use_existing_vcn" { + default = true +} + +variable "vcn_cidr" { + default = "10.0.0.0/16" +} + +variable "vcn_id" { + default = "" +} + +variable "adb_subnet_cidr" { + default = "10.0.1.0/24" +} + +variable "adb_subnet_id" { + default = "" +} + +variable "adb_nsg_id" { + default = "" +} + +variable "adb_free_tier" { + default = false +} + +variable "adb_private_endpoint" { + default = true +} + +variable "adb_database_cpu_core_count" { + default = 1 +} + +variable "adb_database_data_storage_size_in_tbs" { + default = 1 +} + +variable "adb_database_db_name" { + default = "ociadb" +} + +variable "adb_database_db_version" { + default = "19c" +} + +variable "adb_database_db_workload" { + default = "OLTP" +} + +variable "adb_data_safe_status" { + default = "NOT_REGISTERED" +} + +variable "adb_database_defined_tags_value" { + default = "" +} + +variable "adb_database_display_name" { + default = "ADB" +} + +variable "adb_database_freeform_tags" { + default = { + "Owner" = "ADB" + } +} + +variable "adb_database_license_model" { + default = "LICENSE_INCLUDED" +} + +variable "adb_tde_wallet_zip_file" { + default = "tde_wallet_adb1.zip" +} + +variable "adb_private_endpoint_label" { + default = "adbprivendpoint" +} + +variable "whitelisted_ips" { + default = [""] +} + +variable "is_data_guard_enabled" { + default = false +} + +variable "is_auto_scaling_enabled" { + default = false +} + +variable "adb_wallet_password_specials" { + default = true +} + +variable "adb_wallet_password_length" { + default = 16 +} + +variable "adb_wallet_password_min_numeric" { + default = 2 +} + +variable "adb_wallet_password_override_special" { + default = "" +} + +variable "defined_tags" { + default = {} +} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/vcn/datasources.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/vcn/datasources.tf new file mode 100755 index 000000000..bbce22297 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/vcn/datasources.tf @@ -0,0 +1,8 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +# Get list of availability domains + +data "oci_identity_availability_domains" "ads" { + compartment_id = var.compartment_ocid +} \ No newline at end of file diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/vcn/inputs.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/vcn/inputs.tf new file mode 100755 index 000000000..f190b4512 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/vcn/inputs.tf @@ -0,0 +1,12 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +# Variables passed into vcn module + +variable "compartment_ocid" {} + +variable "vcn_cidr" { + default = "10.0.0.0/16" +} +variable "oke_cluster" {} +variable "provision_database" {} \ No newline at end of file diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/vcn/main.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/vcn/main.tf new file mode 100755 index 000000000..463b7f91c --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/vcn/main.tf @@ -0,0 +1,329 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +# Create VCN + +resource "oci_core_virtual_network" "vcn" { + cidr_block = var.vcn_cidr + compartment_id = var.compartment_ocid + display_name = "oke-vcn" + dns_label = "oke" +} + +# Create internet gateway to allow public internet traffic from load balancer subnet + +resource "oci_core_internet_gateway" "igw" { + compartment_id = var.compartment_ocid + display_name = "internet-gateway" + vcn_id = oci_core_virtual_network.vcn.id +} + +resource "oci_core_nat_gateway" "natgw" { + compartment_id = var.compartment_ocid + display_name = "nat-gateway" + vcn_id = oci_core_virtual_network.vcn.id +} + +# Create route table to connect public subnet to internet gateway + +resource "oci_core_route_table" "public_rt" { + compartment_id = var.compartment_ocid + vcn_id = oci_core_virtual_network.vcn.id + display_name = "public-subnet-rt-table" + route_rules { + destination = "0.0.0.0/0" + destination_type = "CIDR_BLOCK" + network_entity_id = oci_core_internet_gateway.igw.id + } +} + +# Create private subnert Route table to connect to NAT gateway + +resource "oci_core_route_table" "private_rt" { + compartment_id = var.compartment_ocid + vcn_id = oci_core_virtual_network.vcn.id + display_name = "private-subnet-rt-table" + route_rules { + destination = "0.0.0.0/0" + destination_type = "CIDR_BLOCK" + network_entity_id = oci_core_nat_gateway.natgw.id + } +} + +# Create security list for public subnet for the load balancers + +resource "oci_core_security_list" "lb_sl" { + compartment_id = var.compartment_ocid + display_name = "lb-security-list" + vcn_id = oci_core_virtual_network.vcn.id + + egress_security_rules { + destination = "0.0.0.0/0" + protocol = "6" + stateless = true + } + + ingress_security_rules { + + protocol = "6" + source = "0.0.0.0/0" + stateless = true + } +} + +# Create securty list for the nodes private subnet + +resource "oci_core_security_list" "node_sl" { + compartment_id = var.compartment_ocid + display_name = "nodes-security-list" + vcn_id = oci_core_virtual_network.vcn.id + + # tcp to anywhere + egress_security_rules { + destination = "0.0.0.0/0" + protocol = "6" + stateless = false + } + + # any traffic to cluster Pods subnet + egress_security_rules { + protocol = "all" + destination = cidrsubnet(var.vcn_cidr, 8, 10) + stateless = true + } + + # any traffic to cluster Services subnet + egress_security_rules { + protocol = "all" + destination = cidrsubnet(var.vcn_cidr, 8, 20) + stateless = true + } + + # all traffic from cluster Pods subnet + ingress_security_rules { + protocol = "all" + source = cidrsubnet(var.vcn_cidr, 8, 10) + stateless = true + } + + # all traffic from cluster Services subnet + ingress_security_rules { + protocol = "all" + source = cidrsubnet(var.vcn_cidr, 8, 20) + stateless = true + } + + # SSH traffic to nodes subnet + ingress_security_rules { + protocol = "6" + source = "0.0.0.0/0" + stateless = false + tcp_options { + max = 22 + min = 22 + } + } + + # DNS traffic from anywhere + ingress_security_rules { + protocol = "17" + source = "0.0.0.0/0" + stateless = false + udp_options { + max = 53 + min = 53 + } + } + + ingress_security_rules { + + protocol = "6" + source = "0.0.0.0/0" + stateless = false + tcp_options { + min = 30000 + max = 32767 + } + } + + ingress_security_rules { + + protocol = 1 + source = "0.0.0.0/0" + stateless = false + + icmp_options { + type = 3 + code = 4 + } + } + + # File Storage ports + # TCP 111 + ingress_security_rules { + + protocol = "6" + source = var.vcn_cidr + stateless = false + tcp_options { + min = 111 + max = 111 + } + } + + # TCP 2048-50 + ingress_security_rules { + + protocol = "6" + source = var.vcn_cidr + stateless = false + tcp_options { + min = 2048 + max = 2050 + } + } + + + # UDP 111 + ingress_security_rules { + + protocol = "17" + source = var.vcn_cidr + stateless = false + udp_options { + min = 111 + max = 111 + } + } + + # UDP 2048 + ingress_security_rules { + + protocol = "17" + source = var.vcn_cidr + stateless = false + udp_options { + min = 2048 + max = 2048 + } + } + + # UDP 111 + egress_security_rules { + + protocol = "17" + destination = var.vcn_cidr + stateless = false + udp_options { + min = 111 + max = 111 + } + } + + # TCP 2048-2050 + egress_security_rules { + + protocol = "6" + destination = var.vcn_cidr + stateless = false + tcp_options { + min = 2048 + max = 2050 + } + } + + # TCP 111 + egress_security_rules { + + protocol = "6" + destination = var.vcn_cidr + stateless = false + tcp_options { + min = 111 + max = 111 + } + } + +} + +# Create securty list for the database subnet + +resource "oci_core_security_list" "database_sl" { + count = var.provision_database ? 1 : 0 + compartment_id = var.compartment_ocid + display_name = "database-security-list" + vcn_id = oci_core_virtual_network.vcn.id + + # TCP traffic from cluster Pods subnet + ingress_security_rules { + protocol = "6" + source = cidrsubnet(var.vcn_cidr, 8, 10) + stateless = false + tcp_options { + max = 1521 + min = 1521 + } + } +} + +# Create regional subnets in vcn + +resource "oci_core_subnet" "cluster_lb_subnet" { + cidr_block = cidrsubnet(var.vcn_cidr, 8, 20) + display_name = "lb-public-subnet" + compartment_id = var.compartment_ocid + vcn_id = oci_core_virtual_network.vcn.id + dhcp_options_id = oci_core_virtual_network.vcn.default_dhcp_options_id + route_table_id = oci_core_route_table.public_rt.id + security_list_ids = [oci_core_security_list.lb_sl.id] + dns_label = "lb" + + provisioner "local-exec" { + command = "sleep 5" + } + provisioner "local-exec" { + when = destroy + command = "sleep 5" + } +} + +resource "oci_core_subnet" "cluster_nodes_subnet" { + cidr_block = cidrsubnet(var.vcn_cidr, 8, 10) + display_name = "nodes-private-subnet" + compartment_id = var.compartment_ocid + vcn_id = oci_core_virtual_network.vcn.id + dhcp_options_id = oci_core_virtual_network.vcn.default_dhcp_options_id + route_table_id = oci_core_route_table.private_rt.id + security_list_ids = [oci_core_security_list.node_sl.id] + prohibit_public_ip_on_vnic = true + dns_label = "nodes" + + provisioner "local-exec" { + command = "sleep 5" + } + provisioner "local-exec" { + when = destroy + command = "sleep 5" + } +} + +resource "oci_core_subnet" "database_subnet" { + count = var.provision_database ? 1 : 0 + cidr_block = cidrsubnet(var.vcn_cidr, 8, 30) + display_name = "db-private-subnet" + compartment_id = var.compartment_ocid + vcn_id = oci_core_virtual_network.vcn.id + dhcp_options_id = oci_core_virtual_network.vcn.default_dhcp_options_id + route_table_id = oci_core_route_table.private_rt.id + security_list_ids = [oci_core_security_list.database_sl.0.id] + prohibit_public_ip_on_vnic = true + dns_label = "db" + + provisioner "local-exec" { + command = "sleep 5" + } + provisioner "local-exec" { + when = destroy + command = "sleep 5" + } +} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/vcn/outputs.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/vcn/outputs.tf new file mode 100755 index 000000000..1399efd42 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/modules/vcn/outputs.tf @@ -0,0 +1,25 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +# Output variables from created vcn + +output "vcn_id" { + value = oci_core_virtual_network.vcn.id +} + +output "cluster_lb_subnet_id" { + value = oci_core_subnet.cluster_lb_subnet.id +} + +output "cluster_nodes_subnet_id" { + value = oci_core_subnet.cluster_nodes_subnet.id +} + +output "cluster_nodes_subnet_cidr" { + value = oci_core_subnet.cluster_nodes_subnet.cidr_block +} + +output "database_subnet_id" { + value = var.provision_database ? oci_core_subnet.database_subnet.0.id : "" +} + diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/outputs.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/outputs.tf new file mode 100755 index 000000000..fe6a3de0e --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/outputs.tf @@ -0,0 +1,40 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +output "kube_config" { + value = module.cluster.kube_config +} + +# output "images" { +# value = module.node_pools.images +# } + +output "jdbc_connection_url" { + value = module.database.jdbc_connection_url +} + +output "nfs_server_ip" { + value = module.fss.server_ip +} + +output "nfs_path" { + value = module.fss.path +} + + +resource "local_file" "helm_values" { + filename = "./fromtf.auto.yaml" + content = templatefile("./templates/helm.values.tpl", { + sites_domain_name = var.sites_domain_name + sites_domain_type = var.sites_domain_type + sites_domain_secret = "${var.sites_domain_name}-domain-credentials" + rcu_prefix = var.rcu_prefix + rcu_secret = "${var.sites_domain_name}-rcu-credentials" + db_secret = "${var.sites_domain_name}-db-credentials" + jdbc_connection_url = var.jdbc_connection_url != null ? var.jdbc_connection_url : module.database.jdbc_connection_url + nfs_server_ip = module.fss.server_ip + path = module.fss.path + sites_dns_name = var.sites_dns_name + container_registry_image = var.container_registry_image + }) +} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/provider.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/provider.tf new file mode 100755 index 000000000..174aa4b34 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/provider.tf @@ -0,0 +1,17 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +terraform { + required_version = ">= 0.14.0" + required_providers { + oci = { + version = ">= 4.27.0" + } + } +} + +provider "oci" { + region = var.region + disable_auto_retries = "true" + config_file_profile = "DEFAULT" +} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/provisioners.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/provisioners.tf new file mode 100755 index 000000000..a97259fa9 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/provisioners.tf @@ -0,0 +1,341 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +# Configure the cluster with kube-config + +resource "null_resource" "cluster_kube_config" { + + count = var.provision_cluster ? 1 : 0 + + depends_on = [module.node_pools, module.cluster] + + provisioner "local-exec" { + command = templatefile("./templates/cluster-kube-config.tpl", + { + cluster_id = module.cluster.cluster.id + region = var.region + }) + } + provisioner "local-exec" { + when = destroy + command = "kubectl delete all --all --force" + on_failure = continue + } +} + +# Create the cluster-admin user to use with the kubernetes dashboard + +resource "null_resource" "oke_admin_service_account" { + count = var.provision_cluster && var.oke_cluster["cluster_options_add_ons_is_kubernetes_dashboard_enabled"] ? 1 : 0 + + depends_on = [null_resource.cluster_kube_config] + + provisioner "local-exec" { + command = "kubectl create -f ./templates/oke-admin.ServiceAccount.yaml" + } + provisioner "local-exec" { + when = destroy + command = "kubectl delete ServiceAccount oke-admin -n kube-system" + on_failure = continue + } +} + +# Create the namespace for the WebLogic Operator + +resource "null_resource" "create_wls_operator_namespace" { + count = var.provision_weblogic_operator ? 1 : 0 + + depends_on = [null_resource.cluster_kube_config] + + triggers = { + weblogic_operator_namespace = var.weblogic_operator_namespace + } + + provisioner "local-exec" { + command = "kubectl create namespace ${var.weblogic_operator_namespace}" + } + provisioner "local-exec" { + when = destroy + command = "kubectl delete all -n ${self.triggers.weblogic_operator_namespace} --force && kubectl delete namespace ${self.triggers.weblogic_operator_namespace}" + on_failure = continue + } +} + +# Create the namespace for the Sites deployment +resource "null_resource" "create_sites_namespace" { + depends_on = [null_resource.cluster_kube_config] + + triggers = { + sites_kubernetes_namespace = var.sites_kubernetes_namespace + } + + provisioner "local-exec" { + command = "kubectl create namespace ${var.sites_kubernetes_namespace}" + } + provisioner "local-exec" { + when = destroy + command = "kubectl delete all -n ${self.triggers.sites_kubernetes_namespace} --force && kubectl delete namespace ${self.triggers.sites_kubernetes_namespace}" + on_failure = continue + } +} + +# Create the user secret to use to pull docker images from Oracle Container Registry + +resource "null_resource" "docker_registry" { + + depends_on = [null_resource.cluster_kube_config, null_resource.create_sites_namespace] + + triggers = { + sites_kubernetes_namespace = var.sites_kubernetes_namespace + } + + provisioner "local-exec" { + command = templatefile("./templates/docker-registry-secret.tpl", + { + username = var.container_registry_username + email = var.container_registry_email + password = var.container_registry_password + namespace = var.sites_kubernetes_namespace + repository = var.container_registry + }) + } + provisioner "local-exec" { + when = destroy + command = "kubectl delete secret image-secret -n ${self.triggers.sites_kubernetes_namespace}" + on_failure = continue + } +} + +# Create the namespace for the Traefik deployment +resource "null_resource" "create_traefik_namespace" { + + count = var.provision_traefik ? 1 : 0 + + depends_on = [null_resource.cluster_kube_config] + + triggers = { + ingress_namespace = var.ingress_controller_namespace + } + + provisioner "local-exec" { + command = "if [[ ! $(kubectl get ns ${var.ingress_controller_namespace}) ]]; then kubectl create namespace ${var.ingress_controller_namespace}; fi" + } + provisioner "local-exec" { + when = destroy + command = "kubectl delete namespace ${self.triggers.ingress_namespace}" + on_failure = continue + } +} + +# Deploy the Kubernetes Operator helm chart + +resource "null_resource" "deploy_wls_operator" { + + count = var.provision_weblogic_operator ? 1 : 0 + + depends_on = [null_resource.create_wls_operator_namespace, null_resource.create_sites_namespace] + + triggers = { + weblogic_operator_namespace = var.weblogic_operator_namespace + sites_namespace = var.sites_kubernetes_namespace + } + + provisioner "local-exec" { + command = templatefile("./templates/deploy-weblogic-operator.tpl", { + weblogic_operator_namespace = var.weblogic_operator_namespace + sites_namespace = var.sites_kubernetes_namespace + }) + } + provisioner "local-exec" { + when = destroy + command = "helm delete weblogic-operator --namespace ${self.triggers.weblogic_operator_namespace} && kubectl delete crds domains.weblogic.oracle" + on_failure = continue + } +} + +# Deploy the Traefik helm chart + +resource "null_resource" "deploy_traefik" { + count = var.provision_traefik ? 1 : 0 + + depends_on = [null_resource.create_traefik_namespace, null_resource.create_sites_namespace] + + triggers = { + ingress_namespace = var.ingress_controller_namespace + sites_namespace = var.sites_kubernetes_namespace + } + + provisioner "local-exec" { + command = templatefile("./templates/deploy-traefik.tpl", { + ingress_namespace = var.ingress_controller_namespace + sites_namespace = var.sites_kubernetes_namespace + }) + } + provisioner "local-exec" { + when = destroy + command = "helm delete traefik --namespace ${self.triggers.ingress_namespace}" + on_failure = continue + } +} + +# Update ingress hostname in fromtf.auto.yaml + +resource "null_resource" "get_ingress_hostname" { + count = var.provision_traefik ? 1 : 0 + + depends_on = [null_resource.create_traefik_namespace, null_resource.create_sites_namespace, null_resource.deploy_traefik] + + triggers = { + ingress_namespace = var.ingress_controller_namespace + } + + provisioner "local-exec" { + command = templatefile("./templates/ingress-hostname.tpl", { + ingress_namespace = var.ingress_controller_namespace + }) + } +} + +# Create secrets +resource "null_resource" "create_sites_domain_secret" { + count = var.provision_secrets ? 1 : 0 + + depends_on = [null_resource.create_sites_namespace] + + triggers = { + name = "${var.sites_domain_name}-domain-credentials" + namespace = var.sites_kubernetes_namespace + username = var.sites_domain_admin_username + password = var.sites_domain_admin_password + } + + provisioner "local-exec" { + command = templatefile("./templates/create_secret.tpl", { + name = "${var.sites_domain_name}-domain-credentials" + namespace = var.sites_kubernetes_namespace + username = var.sites_domain_admin_username + password = var.sites_domain_admin_password + }) + } + provisioner "local-exec" { + when = destroy + command = "kubectl delete secret ${self.triggers.name} --namespace ${self.triggers.namespace}" + on_failure = continue + } +} + +resource "null_resource" "create_rcu_secret" { + count = var.provision_secrets ? 1 : 0 + + depends_on = [null_resource.create_sites_namespace] + + triggers = { + name = "${var.sites_domain_name}-rcu-credentials" + namespace = var.sites_kubernetes_namespace + username = var.provision_adb ? var.adb_username : var.rcu_username + password = var.provision_adb ? var.adb_password : var.rcu_password + sys_username = var.provision_adb ? var.adb_username : var.db_sys_username + sys_password = var.provision_adb ? var.adb_password : var.db_sys_password + domainUID = var.sites_domain_name + } + + provisioner "local-exec" { + command = templatefile("./templates/create-rcu-credentials.tpl", { + name = "${var.sites_domain_name}-rcu-credentials" + namespace = var.sites_kubernetes_namespace + username = var.provision_adb ? var.adb_username : var.rcu_username + password = var.provision_adb ? var.adb_password : var.rcu_password + sys_username = var.provision_adb ? var.adb_username : var.db_sys_username + sys_password = var.provision_adb ? var.adb_password : var.db_sys_password + domainUID = var.sites_domain_name + }) + } + provisioner "local-exec" { + when = destroy + command = "kubectl delete secret ${self.triggers.name} --namespace ${self.triggers.namespace}" + on_failure = continue + } +} + +resource "null_resource" "create_db_secret" { + count = var.provision_secrets ? 1 : 0 + + depends_on = [null_resource.create_sites_namespace] + + triggers = { + name = "${var.sites_domain_name}-db-credentials" + namespace = var.sites_kubernetes_namespace + username = var.provision_adb ? var.adb_username : "SYS" + password = var.provision_adb ? var.adb_password : var.db_sys_password + } + + provisioner "local-exec" { + command = templatefile("./templates/create_secret.tpl", { + name = "${var.sites_domain_name}-db-credentials" + namespace = var.sites_kubernetes_namespace + username = var.provision_adb ? var.adb_username : "SYS" + password = var.provision_adb ? var.adb_password : var.db_sys_password + }) + } + provisioner "local-exec" { + when = destroy + command = "kubectl delete secret ${self.triggers.name} --namespace ${self.triggers.namespace}" + on_failure = continue + } +} + + +# Deploy the Sites Suite helm chart +resource "null_resource" "deploy_sites" { + count = var.provision_sites ? 1 : 0 + + depends_on = [ + null_resource.deploy_wls_operator, + null_resource.deploy_traefik, + null_resource.get_ingress_hostname, + module.database, + null_resource.docker_registry, + null_resource.create_db_secret, + null_resource.create_rcu_secret, + null_resource.create_sites_domain_secret, + local_file.helm_values + ] + + triggers = { + sites_domain_name = var.sites_domain_name + sites_domain_type = var.sites_domain_type + sites_namespace = var.sites_kubernetes_namespace + sites_domain_secret = "${var.sites_domain_name}-domain-credentials" + rcu_prefix = var.rcu_prefix + rcu_secret = "${var.sites_domain_name}-rcu-credentials" + db_secret = "${var.sites_domain_name}-db-credentials" + jdbc_connection_url = var.jdbc_connection_url != null ? var.jdbc_connection_url : var.provision_adb ? module.oci-adb.connection_urls : module.database.jdbc_connection_url + # db_sys_password = var.db_sys_password + nfs_server_ip = var.mount_target_ip !=null ? var.mount_target_ip : module.fss.server_ip + path = module.fss.path + } + + provisioner "local-exec" { + command = templatefile("./templates/deploy-sites.tpl", { + sites_domain_name = var.sites_domain_name + sites_domain_type = var.sites_domain_type + sites_namespace = var.sites_kubernetes_namespace + sites_domain_secret = "${var.sites_domain_name}-domain-credentials" + rcu_prefix = var.rcu_prefix + rcu_secret = "${var.sites_domain_name}-rcu-credentials" + db_secret = "${var.sites_domain_name}-db-credentials" + jdbc_connection_url = var.jdbc_connection_url != null ? var.jdbc_connection_url : var.provision_adb ? module.oci-adb.connection_urls : module.database.jdbc_connection_url + # db_sys_password = var.db_sys_password + nfs_server_ip = module.fss.server_ip + path = module.fss.path + }) + } + provisioner "local-exec" { + when = destroy + command = templatefile("./templates/undeploy-sites.tpl", { + sites_domain_name = self.triggers.sites_domain_name + sites_namespace = self.triggers.sites_namespace + }) + on_failure = continue + } +} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/cluster-kube-config.tpl b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/cluster-kube-config.tpl new file mode 100755 index 000000000..021ea8fcf --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/cluster-kube-config.tpl @@ -0,0 +1,5 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +mkdir -p $HOME/.kube/ +oci ce cluster create-kubeconfig --cluster-id ${cluster_id} --file $HOME/.kube/config --region ${region} --token-version 2.0.0 diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/create-domain-credentials.tpl b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/create-domain-credentials.tpl new file mode 100755 index 000000000..1c3a7631e --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/create-domain-credentials.tpl @@ -0,0 +1,12 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +if [[ ! $(kubectl get secret ${name} -n ${namespace}) ]]; then + kubectl create secret generic ${name} -n ${namespace} \ + --from-literal=username=${username} \ + --from-literal=password='${password}' + + kubectl label secret ${name} -n ${namespace} \ + weblogic.domainUID=${domainUID} \ + weblogic.domainName=${domainName} +fi diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/create-rcu-credentials.tpl b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/create-rcu-credentials.tpl new file mode 100755 index 000000000..da31b24a6 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/create-rcu-credentials.tpl @@ -0,0 +1,13 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +if [[ ! $(kubectl get secret ${name} -n ${namespace}) ]]; then + kubectl create secret generic ${name} -n ${namespace} \ + --from-literal=username=${username} \ + --from-literal=password='${password}' \ + --from-literal=sys_username=${sys_username} \ + --from-literal=sys_password='${sys_password}' +fi +if [[ $(kubectl get secret ${name} -n ${namespace}) ]]; then + kubectl label secret ${name} -n ${namespace} weblogic.domainUID=${domainUID} weblogic.domainName=${domainUID} +fi \ No newline at end of file diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/create_namespace.tpl b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/create_namespace.tpl new file mode 100755 index 000000000..2624031f2 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/create_namespace.tpl @@ -0,0 +1,6 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +if [[ ! $(kubectl get ns ${namespace}) ]]; then + kubectl create namespace ${namespace}; +fi \ No newline at end of file diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/create_secret.tpl b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/create_secret.tpl new file mode 100755 index 000000000..98c6f3f9c --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/create_secret.tpl @@ -0,0 +1,8 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +if [[ ! $(kubectl get secret ${name} -n ${namespace}) ]]; then + kubectl create secret generic ${name} -n ${namespace} \ + --from-literal=username=${username} \ + --from-literal=password='${password}' +fi \ No newline at end of file diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/delete_namespace.tpl b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/delete_namespace.tpl new file mode 100755 index 000000000..c97250d7f --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/delete_namespace.tpl @@ -0,0 +1,4 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +kubectl delete namespace ${namespace} --ignore-not-found=true \ No newline at end of file diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/deploy-sites.tpl b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/deploy-sites.tpl new file mode 100755 index 000000000..6600b03e1 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/deploy-sites.tpl @@ -0,0 +1,12 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + + +helm install ${sites_domain_name} ./charts/wc-sites \ + -f fromtf.auto.yaml \ + --namespace ${sites_namespace} \ + --version 0.1.0 \ + --wait \ + --timeout 600s || exit 1 + +echo "Sites Domain is installed, please wait for all pods to be READY" diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/deploy-traefik.tpl b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/deploy-traefik.tpl new file mode 100755 index 000000000..c43dad984 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/deploy-traefik.tpl @@ -0,0 +1,20 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +CHART_VERSION=2.2.8 + +helm repo add traefik https://helm.traefik.io/traefik + +helm install traefik \ +traefik/traefik \ +--namespace ${ingress_namespace} \ +--set image.tag=2.2.8 \ +--set ports.traefik.expose=true \ +--set ports.web.exposedPort=30305 \ +--set ports.web.nodePort=30305 \ +--set ports.websecure.exposedPort=30443 \ +--set ports.websecure.nodePort=30443 \ +--set "kubernetes.namespaces={${ingress_namespace},${sites_namespace}}" \ +--wait + +echo "Traefik is installed and running" diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/deploy-weblogic-operator.tpl b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/deploy-weblogic-operator.tpl new file mode 100755 index 000000000..aebe55f42 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/deploy-weblogic-operator.tpl @@ -0,0 +1,32 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +if [[ ! $(kubectl get serviceaccount weblogic-operator -n ${weblogic_operator_namespace}) ]]; then + kubectl create serviceaccount -n ${weblogic_operator_namespace} weblogic-operator; +fi + +# wait for at least 1 node to be ready + +while [[ $(for i in $(kubectl get nodes -o 'jsonpath={..status.conditions[?(@.type=="Ready")].status}'); do if [[ "$i" == "True" ]]; then echo $i; fi; done | wc -l | tr -d " ") -lt 1 ]]; do + echo "waiting for at least 1 node to be ready..." && sleep 1; +done + +CHART_VERSION=3.1.4 + +helm repo add weblogic-operator https://oracle.github.io/weblogic-kubernetes-operator/charts --force-update + +helm install weblogic-operator weblogic-operator/weblogic-operator \ + --version $CHART_VERSION \ + --namespace ${weblogic_operator_namespace} \ + --set image=ghcr.io/oracle/weblogic-kubernetes-operator:$CHART_VERSION \ + --set serviceAccount=weblogic-operator \ + --set "domainNamespaces={${sites_namespace}}" \ + --wait \ + --timeout 600s || exit 1 + +while [[ ! $(kubectl get customresourcedefinition domains.weblogic.oracle -n ${weblogic_operator_namespace}) ]]; do + echo "Waiting for CRD to be created"; + sleep 1; +done + +echo "WebLogic Operator is installed and running" diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/docker-registry-secret.tpl b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/docker-registry-secret.tpl new file mode 100755 index 000000000..89331e8f8 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/docker-registry-secret.tpl @@ -0,0 +1,6 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl +if [[ ! $(kubectl get secret image-secret -n ${namespace}) ]]; then + kubectl create secret docker-registry image-secret -n ${namespace} --docker-server='${repository}' --docker-username='${username}' --docker-password='${password}' +fi + diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/helm.values.tpl b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/helm.values.tpl new file mode 100755 index 000000000..029f1ad34 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/helm.values.tpl @@ -0,0 +1,34 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +imagePullSecrets: + - name: image-secret + +image: + name: ${container_registry_image} + +oracledb: + provision: false + credentials: + secretName: ${db_secret} + url: ${jdbc_connection_url} + +domain: + domainName: ${sites_domain_name} + type: ${sites_domain_type} + credentials: + secretName: ${sites_domain_secret} + rcuSchema: + prefix: ${rcu_prefix} + credentials: + secretName: ${rcu_secret} + storage: + path: ${path} + nfs: + server: ${nfs_server_ip} + +ingress: + type: traefik + tls: false + hostname: "" + dnsname: ${sites_dns_name} \ No newline at end of file diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/ingress-hostname.tpl b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/ingress-hostname.tpl new file mode 100755 index 000000000..62505b683 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/ingress-hostname.tpl @@ -0,0 +1,12 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +value=$(kubectl get svc traefik -n ${ingress_namespace} -o jsonpath="{.status.loadBalancer.ingress[*].ip}") +hostname=' hostname: "'$value'"' +echo "$hostname" + +line=$(grep -n 'hostname:' ./fromtf.auto.yaml | cut -d ':' -f1) + +sed -i "$line s/.*/$hostname/" ./fromtf.auto.yaml +echo "updated ingress hostname on fromtf.auto.yaml file" + diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/oke-admin.ServiceAccount.yaml b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/oke-admin.ServiceAccount.yaml new file mode 100755 index 000000000..dbaa95f24 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/oke-admin.ServiceAccount.yaml @@ -0,0 +1,21 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: oke-admin + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: oke-admin +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin +subjects: +- kind: ServiceAccount + name: oke-admin + namespace: kube-system diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/undeploy-sites.tpl b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/undeploy-sites.tpl new file mode 100755 index 000000000..dd668039c --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/templates/undeploy-sites.tpl @@ -0,0 +1,9 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +helm upgrade ${sites_domain_name} ./charts/wc-sites -n ${sites_namespace} \ + --reuse-values \ + --set domain.enabled=false \ + --wait + +helm delete ${sites_domain_name} -n ${sites_namespace} diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/terraform.tfvars.template b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/terraform.tfvars.template new file mode 100755 index 000000000..f345db0a6 --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/terraform.tfvars.template @@ -0,0 +1,122 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +tenancy_ocid = "ocid1.tenancy.oc1..." +compartment_ocid = "ocid1.compartment.oc1..." +region = "us-ashburn-1" + +## Things to provision +# VCN, OKE cluster, node_pool(s) +# if false, the template assumes the cluster is provisioned and that kubectl has access to the cluster. +provision_cluster = true + +# File Storage and mount point export +provision_filesystem = true +provision_mount_target = true +provision_export = true + +# Database (DBaaS on OCI) +# If false, a database jdbc_connection URL needs to be provided, and the database needs to be reachable from this VCN +provision_database = true + +# Autonomous Database (User can use DBAAS or Autonomous DB. Turn this on if provision_adb is false) +provision_adb = false +# possible values (OLTP) +adb_database_db_workload = "OLTP" +adb_password = "Oradoc_db12W#_" + +# WebLogic Operator +provision_weblogic_operator = true +# Ingress controller +provision_traefik = true +provision_secrets = true +#This will deploy the site in environment +provision_sites = true + +## File storage details +# If the VCN is not provided by this template, the following variables must be provided +fss_subnet_id = null +# If the cluster and VCN are not provided by this template, +fss_source_cidr = "0.0.0.0/0" +# File Storage mount target Availability Domain index +ad_number = 2 + +#if using existing file system. exportset and filesystem must belong to same ad. +#filesystem_ocid = "" +#if using existing mount target. +#mount_target_ocid = "" +#mount_target_ip = "" + +## Credentials +# Input your Container registry login credentials +# this is the registry where sites images is going to be looked at +container_registry = "phx.ocir.io" +container_registry_username = "devcec/WCSitesUser" +container_registry_email = "" +container_registry_password = "MNOPabcd:>123xyZ" +container_registry_image = "oracle/wcsites:12.2.1.4" + +# Create WCSites domain Admin Console credentials +sites_domain_admin_username = "weblogic" +# Password must contain 1 Upper, 1 number and be at least 8 characters long +sites_domain_admin_password = "Welcome1" + +# Create Database credentials +# Password must be 9 to 30 characters and contain at least 2 uppercase, 2 lowercase, 2 special, and 2 numeric characters. +# The special characters must be _, #, or -. +db_sys_password = "Oradoc_db12W#x_" + +# Create RCU Schema credentials +# rcu_prefix must be less than or equals to 5 characters +rcu_prefix = "WCS1" +rcu_username = "WCS1" +# Password must be 9 to 30 characters and contain at least 2 uppercase, 2 lowercase, 2 special, and 2 numeric characters. +# The special characters must be _, #, or -. +rcu_password = "Oradoc_db12W#x_" +# If connecting to an external DB, specify the jdbc_connection_url +# !!! You will need to adjust the security list on your database VCN/subnet to authorize access from the OKE cluster nodes, +# which may require VCN peering (not provided here) +jdbc_connection_url = null + +# Database information max 8 charachtor allowed for db system +database_name = "sitesdb" +database_unique_name = "sitesdb" + +# Kubernetes namespaces (no need to change) +#sites_kubernetes_namespace = "wcsites-ns" +#weblogic_operator_namespace = "operator-ns" +#ingress_controller_namespace = "traefik" + +# Domain name +sites_dns_name ="" + +# VCN config +vcn_cidr = "10.0.0.0/16" + +# SSH key to access database and Kubernetes nodes +ssh_authorized_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDtmEF/NbYdBMiF1XjTPgY6M4Nw8RI9AezkXKk7eJ7YylJH8AAApBb0aw7ERgEza3cTkQVK74MH6Rz9nvi7BdoMB/HWv/Ap/StsqFP2oC3BNi+ljVzXreNtVv1G1JqiRbKzjLNtyHw02wtuTKeoXwaex/ElcAObLdqbuxTgw1M1pw+XnSdnBazqAU6otVpnlgkGNiZDE1yvk7t5tL85tZj8dhrIBGEbHu0/lPA/d15PqgAi5bAIO/E0Dt2vh5hJJMjtM0BWf7PyhMgkOeTszERRHuteBroFbZyzxTvJZiUmL16SMcvLnDt3jL4gIzUkOqBIA9haFyo0poGBC8cYECiB vk" + +# Cluster config +oke_cluster = { + name = "OKE_Cluster" + k8s_version = "v1.20.8" + pods_cidr = "10.1.0.0/16" + services_cidr = "10.2.0.0/16" + cluster_options_add_ons_is_kubernetes_dashboard_enabled = true + cluster_options_add_ons_is_tiller_enabled = true +} + +# defaults to 1 pool, feel free to add more if needed. +node_pools = [ + { + pool_name = "pool1" + node_shape = "VM.Standard2.4" + node_count = 2 + node_labels = { + "pool_name" = "pool1" + } + } +] + +# Optional parameter, requires a vault and key to be created in the account. +secrets_encryption_key_ocid = null diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/variables.tf b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/variables.tf new file mode 100755 index 000000000..a5348cb9e --- /dev/null +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/variables.tf @@ -0,0 +1,209 @@ +## Copyright (c) 2022, Oracle and/or its affiliates. +## Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +variable "tenancy_ocid" {} +variable "compartment_ocid" {} +variable "region" {} +variable "ssh_authorized_key" {} + +## General inputs + +variable "deployment_name" { + default = "sites-k8s" +} + + +## Selector to define what to provision +variable "provision_cluster" { + default = true +} +variable "provision_filesystem" { + default = true +} +variable "provision_mount_target" { + default = true +} +variable "provision_export" { + default = true +} +variable "provision_database" { + default = true +} +variable "provision_weblogic_operator" { + default = true +} +variable "provision_traefik" { + default = true +} +variable "provision_secrets" { + default = true +} +variable "provision_sites" { + default = true +} + + +## File Storage details +# If file storage is provisioned by this template but the VCN is not, the subnet ocid is required. +variable "fss_subnet_id" { + default = null +} +# If the cluster is not provisioned by this template, the fss_source_cidr must be specified. +variable "fss_source_cidr" { + default = "0.0.0.0/0" +} +variable "ad_number" { + default = 2 +} + +variable "mount_path" { + default = "/scratch/K8SVolume/WCSites" +} +variable "mount_target_ip" { + default = null +} + +variable "filesystem_ocid" { + default = null +} + +variable "mount_target_ocid" { + default = null +} + +## Kubernetes Namespaces to use +variable "sites_kubernetes_namespace" { + default = "wcsites-ns" +} +variable "weblogic_operator_namespace" { + default = "operator-ns" +} +variable "ingress_controller_namespace" { + default = "traefik" +} + +## Credentials for Oracle Container Registry +variable "container_registry_email" {} +variable "container_registry_password" {} +variable "container_registry_username" {} +variable "container_registry" {} +variable "container_registry_image" {} + + +## Sites domain details + +variable "sites_domain_name" { + type = string + default = "wcsitesinfra" +} +variable "sites_domain_type" { + type = string + default = "wcsites" +} + +variable "sites_domain_admin_username" {} +variable "sites_domain_admin_password" { + type = string + sensitive = true +} +## Schema Database details +variable "jdbc_connection_url" { + # if provisioned by this template, this should be null, otherwise provide for externally provisioned database + default = null +} + +variable "db_sys_password" { + type = string + sensitive = true +} + +variable "db_sys_username" { + type = string + default = "sys" +} + +variable "rcu_prefix" { + default = "Sites" +} +variable "rcu_username" { + default = "sys" +} +variable "rcu_password" { + type = string + sensitive = true +} +## Autonomous database related variables +variable "provision_adb" { + default = false +} + +variable "adb_database_db_workload" { + default = "OLTP" +} + +variable "adb_password" {} +variable "adb_username" { + default = "Admin" +} + +## Database provisioning details +variable "database_name" {} +variable "database_unique_name" {} +variable "db_version" { + default = "19.0.0.0" +} +variable "pdb_name" { + default = "pdb" +} +variable "db_system_shape" { + default = "VM.Standard2.1" +} +variable "db_system_cpu_core_count" { + default = 1 +} +variable "db_system_license_model" { + default = "LICENSE_INCLUDED" +} +variable "db_system_db_system_options_storage_management" { + default = "LVM" +} + +## Domain name +variable "sites_dns_name" { + type = string + default = null +} + +## VCN details +variable "vcn_cidr" { + default = "10.0.0.0/16" +} + +## OKE cluster details +variable "oke_cluster" { + default = { + k8s_version = "v1.20.8" + pods_cidr = "10.1.0.0/16" + services_cidr = "10.2.0.0/16" + cluster_options_add_ons_is_kubernetes_dashboard_enabled = true + cluster_options_add_ons_is_tiller_enabled = true + } +} + +variable "node_pools" { + default = [ + { + pool_name = "pool1" + node_shape = "VM.Standard2.4" + node_count = 3 + node_labels = { + "pool_name" = "pool1" + } + } + ] +} + +## Optional KMS Key for encrypting File system and Kubernetes secrets at rest +variable "secrets_encryption_key_ocid" { + default = null +} From 37f6f8f9716cd9e165eefbe33816160dddd67e63 Mon Sep 17 00:00:00 2001 From: Shiva Barik <83459369+scbarikGIT@users.noreply.github.com> Date: Tue, 12 Apr 2022 17:17:45 +0530 Subject: [PATCH 2/4] Updating README file --- .../OracleWebCenterSites/README.md | 80 +++++++++---------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/README.md b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/README.md index 24368221a..1979d3a42 100755 --- a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/README.md +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/README.md @@ -1,4 +1,4 @@ -# Terraform scripts for WCS-K8S +# Terraform scripts for Deploying WebCenter Sites on Kubernetes #### Disclaimer @@ -13,7 +13,7 @@ Although this release follows the same flow as the [fmw-kubernetes](https://gith * [Prerequisites](#prerequisites) * [Installation](#installation) * [Access the Deployment](#access-the-deployment) -* [If deploying with Sub-domain and SSL](#if-deploying-with-sub-domain-and-ssl) +* [Deploying with Sub-domain and SSL](#deploying-with-sub-domain-and-ssl) * [Configure WebCenter Sites](#configure-webcenter-sites) @@ -54,7 +54,7 @@ This terraform deployment requires the prior installation of the following: $ git clone https://github.com/oracle/fmw-kubernetes.git ``` -* You can now use the deployment scripts from fmw-kubernetes/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites to set up the WebCenter Sites domain as further described in this document. This will be your home directory to run the terraform scripts. +* You can now use the deployment scripts from `fmw-kubernetes/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites` to set up the WebCenter Sites domain as further described in this document. This will be your home directory to run the terraform scripts. ```bash $ cd fmw-kubernetes/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites @@ -199,16 +199,16 @@ secrets_encryption_key_ocid = null - **Create Oracle Cloud Infrastructure Registry** - Under Solutions and Platform, go to Developer Services and click Container Registry - Click on Create repository - Enter Repository name and Access type to create a repository. + - Under `Solutions and Platform`, go to `Developer Services` and click `Container Registry`. + - Click on `Create repository`. + - Enter Repository name and Access type to create a repository. ![README](images/wcs-1.PNG) - **Push wcsites docker image to OCIR** - Download latest sites docker image from [here](https://support.oracle.com/epmos/faces/ui/patch/PatchDetail.jspx?patchId=33579457). - Unzip the downloaded zip file. + - Download latest sites docker image from [here](https://support.oracle.com/epmos/faces/ui/patch/PatchDetail.jspx?patchId=33579457). + - Unzip the downloaded zip file. ```bash $ unzip p33579457_122140_Linux-x86-64.zip @@ -222,10 +222,10 @@ secrets_encryption_key_ocid = null - **Create an "Auth token" which will be used as docker password to push/pull images from OCIR** - Login to OCI Console, navigate to Profile, User Settings, Auth Tokens, click on Generate Tokens button. - Enter Description and then click Generate Tokens. - Token will get generated - Copy the generated token. `NOTE: It will only be displayed one time, so you need to copy it to a secure place for further use.` + - Login to OCI Console, navigate to Profile, User Settings, Auth Tokens, click on Generate Tokens button. + - Enter Description and then click Generate Tokens. + - Token will get generated. + - Copy the generated token. `NOTE: It will only be displayed one time, so you need to copy it to a secure place for further use.` - **Docker login** @@ -319,8 +319,8 @@ On the Kubernetes cluster provisioned, the template also create or deploy: traefik LoadBalancer 10.2.13.1 132.226.115.178 9000:31473/TCP,30305:30305/TCP,30443:30443/TCP 7d19h ``` - If it is still pending, wait a few more minutes before checking again. - Get the EXTERNAL-IP value for the load balancer + - If it is still pending, wait a few more minutes before checking again. + - Get the EXTERNAL-IP value for the load balancer. * Make sure the WebCenter Sites domain servers are running: You can check running pods with: @@ -337,39 +337,38 @@ On the Kubernetes cluster provisioned, the template also create or deploy: wcsitesinfra-wcsites-server1 1/1 Running 0 7d18h ``` - Make sure the STATUS is RUNNING and that READY is 1/1 for pods above before checking the UR + Make sure the STATUS is RUNNING and that READY is 1/1 for pods above before checking the URL. -* With the public IP gathered earlier, browse to http://PUBLIC_IP:30305/console to get to the WebLogic console. +* With the public IP gathered earlier, browse to `http://PUBLIC_IP:30305/console` to get to the WebLogic console. * You can log into the console with the `sites_domain_admin_username` and `sites_domain_admin_password` you specified in the `terraform.tfvars` file. -### If deploying with Sub-domain and SSL +### Deploying with Sub-domain and SSL -If you are deploying WCSites with Sub-domain and SSL then follow these steps else move to Configure WebCenter Sites directly. -Map the loadbalancer EXTERNAL-IP with the sub-domain. -Get SSL certificates from your DNS provider. -That includes 3 files : +`If you are deploying WCSites with Sub-domain and SSL then follow below steps else move to Configure WebCenter Sites directly.` +- Map the loadbalancer EXTERNAL-IP with the sub-domain. +- Get SSL certificates from your DNS provider. +- That includes 3 files : + * SSL Certificate + * CA Certificate + * Private Key -* SSL Certificate -* CA Certificate -* Private Key +Login to OCI console and go to the Load Balancer created be terraform script in your compartment. -Login to OCI console and go to the Load Balancer created be terraform script in your compartment - -* Go to Certificates, Certificate Resource - Load Balancer Managed Certificate -* Click on add Certificate. Give a name and add all 3 files -* Click on Listeners -* Add a new Listener "TCP-443" -* Port - 443 (select SSL checkbox) -* Add certificate here -* Backend Set - TCP-30305 -* Click on Save Changes to save +* Go to `Certificates`, Certificate Resource - `Load Balancer Managed Certificate`. +* Click on `add Certificate`. Give a name and add all 3 files. +* Click on `Listeners`. +* Add a new Listener "TCP-443". +* Port - 443 (select SSL checkbox). +* Add certificate here. +* Backend Set - TCP-30305. +* Click on `Save Changes` to save. ![README](images/wcs-2.PNG) -Configure WebCenter Sites by hitting url : http://PUBLIC_IP:30305/sites/sitesconfigsetup -**update hostname as sub-domain name, port as 443 and secure connection as yes.** +- Configure WebCenter Sites by hitting url : `http://PUBLIC_IP:30305/sites/sitesconfigsetup` +- **update hostname as sub-domain name, port as 443 and secure connection as yes.** ![README](images/wcs-3.PNG) @@ -378,8 +377,9 @@ Configure WebCenter Sites by hitting url : http://PUBLIC_IP:30305/sites/sitescon ### Configure WebCenter Sites -* Configure WebCenter Sites by hitting url : http://PUBLIC_IP:30305/sites/sitesconfigsetup -When installing, select sample sites to be installed and enter the required passwords. Do not change the sites-config location. If you change the location, installation will fail. +* Configure WebCenter Sites by hitting url : `http://PUBLIC_IP:30305/sites/sitesconfigsetup` + - When installing, select sample sites to be installed and enter the required passwords. + - Do not change the sites-config location. If you change the location, installation will fail. * After the configuration is complete, edit the domain, and restart the Managed Server. To stop Managed Servers: @@ -411,6 +411,6 @@ To stop Managed Servers: wcsitesinfra-wcsites-server3 1/1 Running 0 11m ``` -* Access WebCenter Sites by hitting url : http://PUBLIC_IP:30305/sites/ +* Access WebCenter Sites by hitting url : `http://PUBLIC_IP:30305/sites/` - Incase of Sub-domain with SSL : https://SUB-DOMAIN/sites/ + Incase of Sub-domain with SSL : `https://SUB-DOMAIN/sites/` From 647fd1fce5d9026d395b3a5e590c0615058adcc9 Mon Sep 17 00:00:00 2001 From: Shiva Barik <83459369+scbarikGIT@users.noreply.github.com> Date: Tue, 12 Apr 2022 17:22:06 +0530 Subject: [PATCH 3/4] Updating readme file --- .../OracleWebCenterSites/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/README.md b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/README.md index 1979d3a42..e1b776514 100755 --- a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/README.md +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/README.md @@ -1,4 +1,4 @@ -# Terraform scripts for Deploying WebCenter Sites on Kubernetes +# Terraform scripts for Deploying Oracle WebCenter Sites on Kubernetes #### Disclaimer From 4a1740163e08f93a9f4fcf3d68c39dd6d0cb310b Mon Sep 17 00:00:00 2001 From: Shiva Barik <83459369+scbarikGIT@users.noreply.github.com> Date: Tue, 12 Apr 2022 18:04:12 +0530 Subject: [PATCH 4/4] updating readme file. --- .../OracleWebCenterSites/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/README.md b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/README.md index e1b776514..720f020e6 100755 --- a/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/README.md +++ b/FMWKubernetesMAA/OracleEnterpriseDeploymentAutomation/OracleWebCenterSites/README.md @@ -346,7 +346,7 @@ On the Kubernetes cluster provisioned, the template also create or deploy: ### Deploying with Sub-domain and SSL -`If you are deploying WCSites with Sub-domain and SSL then follow below steps else move to Configure WebCenter Sites directly.` +If you are deploying WCSites with Sub-domain and SSL then follow below steps else move to Configure WebCenter Sites directly. - Map the loadbalancer EXTERNAL-IP with the sub-domain. - Get SSL certificates from your DNS provider. - That includes 3 files : @@ -368,7 +368,7 @@ Login to OCI console and go to the Load Balancer created be terraform script in ![README](images/wcs-2.PNG) - Configure WebCenter Sites by hitting url : `http://PUBLIC_IP:30305/sites/sitesconfigsetup` -- **update hostname as sub-domain name, port as 443 and secure connection as yes.** +- Update hostname as sub-domain name, port as 443 and secure connection as yes. ![README](images/wcs-3.PNG)