From 8a28f6d506763adba3d29beb898f10cdb069becd Mon Sep 17 00:00:00 2001 From: garciadeblas Date: Wed, 11 Jun 2025 11:11:56 +0200 Subject: [PATCH] Feature 11057: Cluster management in Openshift-based infrastructures Change-Id: I8bdb1efb3ad1e9c8da688f334b3dcf7f49ad047c Signed-off-by: garciadeblas --- .../scripts/library/helper-functions.rc | 1 + .../scripts/library/krm-functions.rc | 626 +++++++++++++++++- installers/00-default-install-options.rc | 3 + installers/01-export-osm-install-options.sh | 3 + installers/40-deploy-osm.sh | 31 +- .../create-new-cluster-folder-structure.sh | 34 +- .../flux/scripts/mgmt-cluster-bootstrap.sh | 48 +- .../templates/remote-cluster-bootstrap.yaml | 178 ++++- .../templates/apps.yaml | 41 ++ .../templates/fleet-repo.yaml | 30 + .../templates/flux-system/gotk-sync.yaml | 44 ++ .../templates/flux-system/kustomization.yaml | 51 ++ .../templates/flux-system/scc.yaml | 60 ++ .../templates/infra-configs.yaml | 49 ++ .../templates/infra-controllers.yaml | 40 ++ .../templates/kustomization.yaml | 36 + .../templates/managed-resources.yaml | 52 ++ .../templates/sw-catalogs-repo.yaml | 30 + .../manifests/cluster/hostedcluster.yaml | 69 ++ .../manifests/cluster/klusterlet.yaml | 38 ++ .../manifests/cluster/managedcluster.yaml | 33 + .../openshift/manifests/cluster/nodepool.yaml | 48 ++ .../manifests/namespaces/namespaces.yaml | 31 + .../openshift/templates/openshift01.yaml | 122 ++++ ...-crossplane-cluster-and-bootstrap-wft.yaml | 3 +- 25 files changed, 1622 insertions(+), 79 deletions(-) create mode 100644 installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/apps.yaml create mode 100644 installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/fleet-repo.yaml create mode 100644 installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/flux-system/gotk-sync.yaml create mode 100644 installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/flux-system/kustomization.yaml create mode 100644 installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/flux-system/scc.yaml create mode 100644 installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/infra-configs.yaml create mode 100644 installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/infra-controllers.yaml create mode 100644 installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/kustomization.yaml create mode 100644 installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/managed-resources.yaml create mode 100644 installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/sw-catalogs-repo.yaml create mode 100644 installers/flux/templates/sw-catalogs/cloud-resources/openshift/manifests/cluster/hostedcluster.yaml create mode 100644 installers/flux/templates/sw-catalogs/cloud-resources/openshift/manifests/cluster/klusterlet.yaml create mode 100644 installers/flux/templates/sw-catalogs/cloud-resources/openshift/manifests/cluster/managedcluster.yaml create mode 100644 installers/flux/templates/sw-catalogs/cloud-resources/openshift/manifests/cluster/nodepool.yaml create mode 100644 installers/flux/templates/sw-catalogs/cloud-resources/openshift/manifests/namespaces/namespaces.yaml create mode 100644 installers/flux/templates/sw-catalogs/cloud-resources/openshift/templates/openshift01.yaml diff --git a/docker/osm-krm-functions/scripts/library/helper-functions.rc b/docker/osm-krm-functions/scripts/library/helper-functions.rc index 03614d14..53115c0e 100644 --- a/docker/osm-krm-functions/scripts/library/helper-functions.rc +++ b/docker/osm-krm-functions/scripts/library/helper-functions.rc @@ -13,6 +13,7 @@ # limitations under the License. # + # Convert input string to a safe name for K8s resources function safe_name() { local INPUT="$1" diff --git a/docker/osm-krm-functions/scripts/library/krm-functions.rc b/docker/osm-krm-functions/scripts/library/krm-functions.rc index c006729b..1fc5a5f0 100644 --- a/docker/osm-krm-functions/scripts/library/krm-functions.rc +++ b/docker/osm-krm-functions/scripts/library/krm-functions.rc @@ -17,7 +17,6 @@ ####################################################################################### - function generator_encrypted_secret_cloud_credentials() { local CLOUD_CREDENTIALS_FILENAME="$1" local SECRET_NAME="$2" @@ -228,6 +227,7 @@ EOF "${TARGET_FOLDER}" } + function scale_nodegroup() { local NODEGROUP_NAME="$1" local NODEGROUP_KUSTOMIZATION_NAME="$2" @@ -251,7 +251,7 @@ function scale_nodegroup() { local BASE_TEMPLATES_PATH="${15:-"cloud-resources"}" local MANIFEST_FILENAME="${16:-"${NODEGROUP_NAME}"}" - # Is the provider type supported? + # Is the provider type supported? local VALID_PROVIDERS=("eks" "aks" "gke") CLUSTER_TYPE="${CLUSTER_TYPE,,}" [[ ! ($(echo ${VALID_PROVIDERS[@]} | grep -w "${CLUSTER_TYPE}")) ]] && return 1 @@ -271,6 +271,7 @@ function scale_nodegroup() { "${TARGET_FOLDER}" } + # Delete nodegroup function delete_nodegroup() { local NODEGROUP_KUSTOMIZATION_NAME="$1" @@ -278,13 +279,12 @@ function delete_nodegroup() { local PROJECT_NAME="${3:-"${MGMT_PROJECT_NAME}"}" local FLEET_REPO_DIR="${4:-"${FLEET_REPO_DIR}"}" local MGMT_RESOURCES_DIR="${5:-"${MGMT_RESOURCES_DIR}"}" - local NODEGROUP_DIR="${MGMT_RESOURCES_DIR}/${CLUSTER_NAME}/${NODEGROUP_KUSTOMIZATION_NAME}" - # Delete node Kustomizations rm -rf "${NODEGROUP_DIR}" } + # TODO: Deprecated # Create AKS cluster (without bootstrap) function create_cluster_aks() { @@ -505,16 +505,15 @@ function generator_base_kustomizations_new_cluster() { local SW_CATALOGS_REPO_URL="$3" local PROJECT_NAME="${4:-"${MGMT_PROJECT_NAME}"}" local SW_CATALOGS_REPO_DIR="${5:-"${SW_CATALOGS_REPO_DIR}"}" - + # Path for the source templates + local TEMPLATES="${6:-"${SW_CATALOGS_REPO_DIR}/cloud-resources/flux-remote-bootstrap/cluster-base/templates"}" + # Optional inputs: # Paths for each profile in the Git repo - local INFRA_CONTROLLERS_PATH="${6:-"${PROJECT_NAME}/infra-controller-profiles/${CLUSTER_KUSTOMIZATION_NAME}"}" - local INFRA_CONFIGS_PATH="${7:-"${PROJECT_NAME}/infra-config-profiles/${CLUSTER_KUSTOMIZATION_NAME}"}" - local MANAGED_RESOURCES_PATH="${8:-"${PROJECT_NAME}/managed-resources/${CLUSTER_KUSTOMIZATION_NAME}"}" - local APPS_PATH="${9:-"${PROJECT_NAME}/app-profiles/${CLUSTER_KUSTOMIZATION_NAME}"}" - - # Path for the source templates - local TEMPLATES="${SW_CATALOGS_REPO_DIR}/cloud-resources/flux-remote-bootstrap/cluster-base/templates" + local INFRA_CONTROLLERS_PATH="${7:-"${PROJECT_NAME}/infra-controller-profiles/${CLUSTER_KUSTOMIZATION_NAME}"}" + local INFRA_CONFIGS_PATH="${8:-"${PROJECT_NAME}/infra-config-profiles/${CLUSTER_KUSTOMIZATION_NAME}"}" + local MANAGED_RESOURCES_PATH="${9:-"${PROJECT_NAME}/managed-resources/${CLUSTER_KUSTOMIZATION_NAME}"}" + local APPS_PATH="${10:-"${PROJECT_NAME}/app-profiles/${CLUSTER_KUSTOMIZATION_NAME}"}" # Generate export CLUSTER_KUSTOMIZATION_NAME @@ -556,6 +555,7 @@ function generator_k8s_age_secret_new_cluster() { local PRIVATE_KEY_NEW_CLUSTER="$1" local PUBLIC_KEY_MGMT="$2" local CLUSTER_AGE_SECRET_NAME="${3:-$(safe_name "sops-age-${CLUSTER_KUSTOMIZATION_NAME}")}" + local CLUSTER_AGE_SECRET_NAMESPACE="${4:-"managed-resources"}" join_lists \ <(cat) \ @@ -563,7 +563,7 @@ function generator_k8s_age_secret_new_cluster() { echo "${PRIVATE_KEY_NEW_CLUSTER}" | \ grep -v '^#' | \ kubectl create secret generic "${CLUSTER_AGE_SECRET_NAME}" \ - --namespace=managed-resources \ + --namespace="${CLUSTER_AGE_SECRET_NAMESPACE}" \ --from-file=agekey=/dev/stdin \ -o yaml --dry-run=client | \ encrypt_secret_from_stdin \ @@ -580,16 +580,28 @@ function generator_bootstrap_new_cluster() { local CLUSTER_KUSTOMIZATION_NAME="${2:-$(safe_name ${CLUSTER_NAME})}" local CLUSTER_AGE_SECRET_NAME="${3:-$(safe_name "sops-age-${CLUSTER_KUSTOMIZATION_NAME}")}" local SW_CATALOGS_REPO_DIR="${4:-"${SW_CATALOGS_REPO_DIR}"}" + local BOOTSTRAP_KUSTOMIZATION_NAMESPACE="${5:-"managed-resources"}" + local CLUSTER_KUSTOMIZATION_NAMESPACE="${6:-"managed-resources"}" + local BOOTSTRAP_SECRET_NAMESPACE="${7:-"managed-resources"}" # Paths and names for the templates - local MANIFEST_FILENAME="${5:-"cluster-bootstrap-${CLUSTER_KUSTOMIZATION_NAME}.yaml"}" - local TEMPLATES="${6:-"${SW_CATALOGS_REPO_DIR}/cloud-resources/flux-remote-bootstrap/bootstrap/templates"}" - local TEMPLATE_MANIFEST_FILENAME="${7:-"remote-cluster-bootstrap.yaml"}" + local MANIFEST_FILENAME="${7:-"cluster-bootstrap-${CLUSTER_KUSTOMIZATION_NAME}.yaml"}" + local TEMPLATES="${8:-"${SW_CATALOGS_REPO_DIR}/cloud-resources/flux-remote-bootstrap/bootstrap/templates"}" + local TEMPLATE_MANIFEST_FILENAME="${9:-"remote-cluster-bootstrap.yaml"}" + + # Variables for kubeconfig secret configuration + local CLUSTER_KUBECONFIG_SECRET_KEY=${CLUSTER_KUBECONFIG_SECRET_KEY:-"kubeconfig"} + local CLUSTER_KUBECONFIG_SECRET_NAME=${CLUSTER_KUBECONFIG_SECRET_NAME:-"kubeconfig-${CLUSTER_KUSTOMIZATION_NAME}"} # Generate manifests export CLUSTER_KUSTOMIZATION_NAME export CLUSTER_NAME export CLUSTER_AGE_SECRET_NAME + export CLUSTER_KUBECONFIG_SECRET_KEY + export CLUSTER_KUBECONFIG_SECRET_NAME + export BOOTSTRAP_KUSTOMIZATION_NAMESPACE + export CLUSTER_KUSTOMIZATION_NAMESPACE + export BOOTSTRAP_SECRET_NAMESPACE join_lists \ <(cat) \ @@ -600,7 +612,7 @@ function generator_bootstrap_new_cluster() { "${TEMPLATE_MANIFEST_FILENAME}" \ "${MANIFEST_FILENAME}" | \ replace_env_vars \ - '${CLUSTER_KUSTOMIZATION_NAME},${CLUSTER_NAME},${CLUSTER_AGE_SECRET_NAME}' + '${CLUSTER_KUSTOMIZATION_NAME},${CLUSTER_NAME},${CLUSTER_AGE_SECRET_NAME},${CLUSTER_KUBECONFIG_SECRET_KEY},${CLUSTER_KUBECONFIG_SECRET_NAME},${CLUSTER_KUSTOMIZATION_NAMESPACE},${BOOTSTRAP_KUSTOMIZATION_NAMESPACE},${BOOTSTRAP_SECRET_NAMESPACE}' ) } @@ -670,10 +682,16 @@ function create_bootstrap_for_remote_cluster() { local PUBLIC_KEY_NEW_CLUSTER="$9" local PRIVATE_KEY_NEW_CLUSTER="${10:-${PRIVATE_KEY_NEW_CLUSTER}}" local IMPORTED_CLUSTER="${11:-"false"}" - - - # Calculates the folder where managed resources area defined - local MGMT_RESOURCES_DIR="${FLEET_REPO_DIR}/${MGMT_PROJECT_NAME}/managed-resources/_management" + local MGMT_CLUSTER_NAME="${12:-"_management"}" + local CLUSTER_KUBECONFIG_SECRET_NAME=${13:-"kubeconfig-${CLUSTER_KUSTOMIZATION_NAME}"} + local CLUSTER_KUBECONFIG_SECRET_KEY=${14:-"kubeconfig"} + local TEMPLATES_DIR="${15:-"${SW_CATALOGS_REPO_DIR}/cloud-resources/flux-remote-bootstrap/cluster-base/templates"}" + local BOOTSTRAP_KUSTOMIZATION_NAMESPACE="${16:-"managed-resources"}" + local CLUSTER_KUSTOMIZATION_NAMESPACE="${17:-"managed-resources"}" + local BOOTSTRAP_SECRET_NAMESPACE="${18:-"${BOOTSTRAP_KUSTOMIZATION_NAMESPACE}"}" + + # Calculates the folder where managed resources are defined + local MGMT_RESOURCES_DIR="${FLEET_REPO_DIR}/${MGMT_PROJECT_NAME}/managed-resources/${MGMT_CLUSTER_NAME}" # Create profile folders echo "" | \ @@ -692,7 +710,8 @@ function create_bootstrap_for_remote_cluster() { "${FLEET_REPO_URL}" \ "${SW_CATALOGS_REPO_URL}" \ "${MGMT_PROJECT_NAME}" \ - "${SW_CATALOGS_REPO_DIR}" | \ + "${SW_CATALOGS_REPO_DIR}" \ + "${TEMPLATES_DIR}" | \ list2folder_cp_over \ "${CLUSTER_FOLDER}" @@ -715,11 +734,15 @@ function create_bootstrap_for_remote_cluster() { "${CLUSTER_NAME}" \ "${CLUSTER_KUSTOMIZATION_NAME}" \ "${CLUSTER_AGE_SECRET_NAME}" \ - "${SW_CATALOGS_REPO_DIR}" | \ + "${SW_CATALOGS_REPO_DIR}" \ + "${BOOTSTRAP_KUSTOMIZATION_NAMESPACE}" \ + "${CLUSTER_KUSTOMIZATION_NAMESPACE}" \ + "${BOOTSTRAP_SECRET_NAMESPACE}" | \ generator_k8s_age_secret_new_cluster \ "${PRIVATE_KEY_NEW_CLUSTER}" \ "${PUBLIC_KEY_MGMT}" \ - "${CLUSTER_AGE_SECRET_NAME}" | \ + "${CLUSTER_AGE_SECRET_NAME}" \ + "${BOOTSTRAP_SECRET_NAMESPACE}" | \ prepend_folder_path "${CLUSTER_KUSTOMIZATION_NAME}/" | \ list2folder_cp_over \ "${MGMT_RESOURCES_DIR}" @@ -802,7 +825,6 @@ function create_crossplane_cluster() { local TEMPLATE_MANIFEST_FILENAME="${26:-"${CLUSTER_TYPE,,}01.yaml"}" local MANIFEST_FILENAME="${27:-"${CLUSTER_TYPE,,}-${CLUSTER_NAME}.yaml"}" - # Is the provider type supported? local VALID_PROVIDERS=("eks" "aks" "gke") CLUSTER_TYPE="${CLUSTER_TYPE,,}" @@ -983,22 +1005,23 @@ function delete_remote_cluster() { local PROJECT_NAME="${2:-"${MGMT_PROJECT_NAME}"}" local FLEET_REPO_DIR="${3:-"${FLEET_REPO_DIR}"}" local MGMT_RESOURCES_DIR="${4:-"${MGMT_RESOURCES_DIR}"}" + local MGMT_CLUSTER_DIR="${5:-"${MGMT_CLUSTER_DIR}"}" # Optional inputs: Paths for each profile in the Git repo - local INFRA_CONTROLLERS_DIR="${5:-"${FLEET_REPO_DIR}/${PROJECT_NAME}/infra-controller-profiles/${CLUSTER_KUSTOMIZATION_NAME}"}" - local INFRA_CONFIGS_DIR="${6:-"${FLEET_REPO_DIR}/${PROJECT_NAME}/infra-config-profiles/${CLUSTER_KUSTOMIZATION_NAME}"}" - local MANAGED_RESOURCES_DIR="${7:-"${FLEET_REPO_DIR}/${PROJECT_NAME}/managed-resources/${CLUSTER_KUSTOMIZATION_NAME}"}" - local APPS_DIR="${8:-"${FLEET_REPO_DIR}/${PROJECT_NAME}/app-profiles/${CLUSTER_KUSTOMIZATION_NAME}"}" - local CLUSTER_DIR="${9:-"${FLEET_REPO_DIR}/clusters/${CLUSTER_KUSTOMIZATION_NAME}"}" + local INFRA_CONTROLLERS_DIR="${6:-"${FLEET_REPO_DIR}/${PROJECT_NAME}/infra-controller-profiles/${CLUSTER_KUSTOMIZATION_NAME}"}" + local INFRA_CONFIGS_DIR="${7:-"${FLEET_REPO_DIR}/${PROJECT_NAME}/infra-config-profiles/${CLUSTER_KUSTOMIZATION_NAME}"}" + local MANAGED_RESOURCES_DIR="${8:-"${FLEET_REPO_DIR}/${PROJECT_NAME}/managed-resources/${CLUSTER_KUSTOMIZATION_NAME}"}" + local MGMT_CLUSTER_DIR="${9:-"${FLEET_REPO_DIR}/${PROJECT_NAME}/managed-resources/${MGMT_CLUSTER_DIR}"}" + local APPS_DIR="${10:-"${FLEET_REPO_DIR}/${PROJECT_NAME}/app-profiles/${CLUSTER_KUSTOMIZATION_NAME}"}" + local CLUSTER_DIR="${11:-"${FLEET_REPO_DIR}/clusters/${CLUSTER_KUSTOMIZATION_NAME}"}" # Optional input: Do I need a purge operation first? - local PURGE="${10:-"false"}" + local PURGE="${12:-"false"}" # Perform the purge if needed if [[ "${PURGE,,}" == "true" ]]; then echo "Purging the remote Flux instalation..." - flux uninstall -s --namespace=flux-system fi echo "Deleting cluster profiles and (when applicable) its cloud resources..." @@ -1007,6 +1030,7 @@ function delete_remote_cluster() { rm -rf "${INFRA_CONTROLLERS_DIR}" rm -rf "${INFRA_CONFIGS_DIR}" rm -rf "${MANAGED_RESOURCES_DIR}" + rm -rf "${MGMT_CLUSTER_DIR}" rm -rf "${APPS_DIR}" # Delete base cluster Kustomizations @@ -1094,6 +1118,459 @@ function update_crossplane_cluster() { "${MANIFEST_FILENAME}" } +# Create remote CAPI cluster for Openstack +function create_capi_openstack_cluster() { + local CLUSTER_KUSTOMIZATION_NAME="${1}" + local CLUSTER_NAME="${2}" + local VM_SIZE="${3}" + local VM_SIZE_CONTROL_PLANE="${4:-"${VM_SIZE}"}" + local NODE_COUNT="${5}" + local NODE_COUNT_CONTROLPLANE="${6:-"1"}" + local K8S_VERSION="${7}" + # OpenStack specific + local OPENSTACK_CLOUD_NAME="${8}" + local OPENSTACK_DNS_NAMESERVERS="${9}" + local OPENSTACK_EXTERNAL_NETWORK_ID="${10}" + local OPENSTACK_FAILURE_DOMAIN="${11}" + local OPENSTACK_SSH_KEY_NAME="${12}" + local CNI="${13:-"calico"}" + local OPENSTACK_WORKER_IMAGE_NAME="${14:-"osm-capo-node-${K8S_VERSION}"}" + local OPENSTACK_CONTROL_PLANE_IMAGE_NAME="${15:-"${OPENSTACK_WORKER_IMAGE_NAME}"}" + # SOPS-AGE related + local PUBLIC_KEY_MGMT="${16:-"${PUBLIC_KEY_MGMT}"}" + local PUBLIC_KEY_NEW_CLUSTER="${17:-"${PUBLIC_KEY_NEW_CLUSTER}"}" + local PRIVATE_KEY_NEW_CLUSTER="${18:-"${PRIVATE_KEY_NEW_CLUSTER}"}" + # GitOps retaled + local FLEET_REPO_DIR="${19:-"${FLEET_REPO_DIR}"}" + local FLEET_REPO_URL="${20:-"${FLEET_REPO_URL}"}" + local SW_CATALOGS_REPO_DIR="${21:-"${SW_CATALOGS_REPO_DIR}"}" + local SW_CATALOGS_REPO_URL="${22:-"${SW_CATALOGS_REPO_URL}"}" + local SKIP_BOOTSTRAP="${23:-"false"}" + local MGMT_PROJECT_NAME="${24:-"osm_admin"}" + local MGMT_CLUSTER_NAME="${25:-"_management"}" + local BASE_TEMPLATES_PATH="${26:-"cloud-resources/capi"}" + local NAMESPACE="${27:-"managed-resources"}" + + # Varibles with valus from convention. + local CLUSTER_TYPE="openstack" + local TEMPLATE_MANIFEST_FILENAME="capi-cluster.yaml" + local MANIFEST_FILENAME="openstack-${CLUSTER_NAME}.yaml" + local CLOUD_CREDENTIALS="${OPENSTACK_CLOUD_NAME}-capo-config" + + # Determines the source dir for the templates and the target folder in Fleet + local TEMPLATES_DIR="${SW_CATALOGS_REPO_DIR}/${BASE_TEMPLATES_PATH}/openstack-kubeadm/templates" + local TARGET_FOLDER="${FLEET_REPO_DIR}/${MGMT_PROJECT_NAME}/managed-resources/${MGMT_CLUSTER_NAME}" + export CNI=${CNI,,} + + # Variables for kubeconfig secret reference + export CLUSTER_KUBECONFIG_SECRET_NAME="${CLUSTER_KUSTOMIZATION_NAME}-kubeconfig" + export CLUSTER_KUBECONFIG_SECRET_KEY="value" + + export CLUSTER_KUSTOMIZATION_NAME + export OPENSTACK_CLOUD_NAME + + folder2list \ + "${TEMPLATES_DIR}" | \ + replace_env_vars \ + '${CLUSTER_KUSTOMIZATION_NAME},${CNI},${CLUSTER_KUBECONFIG_SECRET_NAME},${CLUSTER_KUBECONFIG_SECRET_KEY},${OPENSTACK_CLOUD_NAME}' | \ + patch_replace \ + ".spec.postBuild.substitute.cluster_name" \ + "${CLUSTER_NAME}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.cni" \ + "${CNI}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.control_plane_machine_count" \ + "${NODE_COUNT_CONTROLPLANE}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.kubernetes_version" \ + "v${K8S_VERSION}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.namespace" \ + "${NAMESPACE}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.worker_machine_count" \ + "${NODE_COUNT}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.openstack_cloud" \ + "${OPENSTACK_CLOUD_NAME}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.openstack_cloud_conf" \ + "${CLOUD_CREDENTIALS}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.openstack_control_plane_machine_flavor" \ + "${VM_SIZE_CONTROL_PLANE}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.openstack_dns_nameservers" \ + "${OPENSTACK_DNS_NAMESERVERS}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.openstack_external_network_id" \ + "${OPENSTACK_EXTERNAL_NETWORK_ID}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.openstack_failure_domain" \ + "${OPENSTACK_FAILURE_DOMAIN}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.openstack_worker_image_name" \ + "${OPENSTACK_WORKER_IMAGE_NAME}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.openstack_control_plane_image_name" \ + "${OPENSTACK_CONTROL_PLANE_IMAGE_NAME}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.openstack_node_machine_flavor" \ + "${VM_SIZE}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.openstack_ssh_key_name" \ + "${OPENSTACK_SSH_KEY_NAME}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + rename_file_in_items \ + "${TEMPLATE_MANIFEST_FILENAME}" \ + "${MANIFEST_FILENAME}" | \ + prepend_folder_path "${CLUSTER_KUSTOMIZATION_NAME}/" | \ + list2folder_cp_over \ + "${TARGET_FOLDER}" + + # Bootstrap (unless asked to skip) + if [[ "${SKIP_BOOTSTRAP,,}" == "true" ]]; then + return 0 + fi + + create_bootstrap_for_remote_cluster \ + "${CLUSTER_NAME}" \ + "${CLUSTER_KUSTOMIZATION_NAME}" \ + "${FLEET_REPO_DIR}" \ + "${SW_CATALOGS_REPO_DIR}" \ + "${FLEET_REPO_URL}" \ + "${SW_CATALOGS_REPO_URL}" \ + "${MGMT_PROJECT_NAME}" \ + "${PUBLIC_KEY_MGMT}" \ + "${PUBLIC_KEY_NEW_CLUSTER}" \ + "${PRIVATE_KEY_NEW_CLUSTER}" \ + "false" \ + '' \ + "${CLUSTER_KUBECONFIG_SECRET_NAME}" \ + "${CLUSTER_KUBECONFIG_SECRET_KEY}" + +} + +# Update remote CAPI cluster for Openstack +function update_capi_openstack_cluster() { + local CLUSTER_KUSTOMIZATION_NAME="${1}" + local CLUSTER_NAME="${2}" + local VM_SIZE="${3}" + local VM_SIZE_CONTROL_PLANE="${4}" + local NODE_COUNT="${5}" + local NODE_COUNT_CONTROLPLANE="${6}" + local K8S_VERSION="${7}" + # OpenStack specific + local OPENSTACK_CLOUD_NAME="${8}" + local OPENSTACK_DNS_NAMESERVERS="${9}" + local OPENSTACK_EXTERNAL_NETWORK_ID="${10}" + local OPENSTACK_FAILURE_DOMAIN="${11}" + local OPENSTACK_SSH_KEY_NAME="${12}" + local CNI="${13:-"calico"}" + local OPENSTACK_WORKER_IMAGE_NAME="${14:-"osm-capo-node-${K8S_VERSION}"}" + local OPENSTACK_CONTROL_PLANE_IMAGE_NAME="${15:-"${OPENSTACK_WORKER_IMAGE_NAME}"}" + # SOPS-AGE related + local PUBLIC_KEY_MGMT="${16:-"${PUBLIC_KEY_MGMT}"}" + local PUBLIC_KEY_NEW_CLUSTER="${17:-"${PUBLIC_KEY_NEW_CLUSTER}"}" + local PRIVATE_KEY_NEW_CLUSTER="${18:-"${PRIVATE_KEY_NEW_CLUSTER}"}" + # GitOps retaled + local FLEET_REPO_DIR="${19:-"${FLEET_REPO_DIR}"}" + local FLEET_REPO_URL="${20:-"${FLEET_REPO_URL}"}" + local SW_CATALOGS_REPO_DIR="${21:-"${SW_CATALOGS_REPO_DIR}"}" + local SW_CATALOGS_REPO_URL="${22:-"${SW_CATALOGS_REPO_URL}"}" + local MGMT_PROJECT_NAME="${23:-"osm_admin"}" + local MGMT_CLUSTER_NAME="${24:-"_management"}" + local BASE_TEMPLATES_PATH="${25:-"cloud-resources/capi"}" + local NAMESPACE="${26:-"managed-resources"}" + + # Determine key folders in Fleet + local MGMT_RESOURCES_DIR="${FLEET_REPO_DIR}/${MGMT_PROJECT_NAME}/managed-resources/${MGMT_CLUSTER_NAME}" + + # Updating no new cluster + local SKIP_BOOTSTRAP="true" + + create_capi_openstack_cluster \ + "${CLUSTER_KUSTOMIZATION_NAME}" \ + "${CLUSTER_NAME}" \ + "${VM_SIZE}" \ + "${VM_SIZE_CONTROL_PLANE}" \ + "${NODE_COUNT}" \ + "${NODE_COUNT_CONTROLPLANE}" \ + "${K8S_VERSION}" \ + "${OPENSTACK_CLOUD_NAME}" \ + "${OPENSTACK_DNS_NAMESERVERS}" \ + "${OPENSTACK_EXTERNAL_NETWORK_ID}" \ + "${OPENSTACK_FAILURE_DOMAIN}" \ + "${OPENSTACK_SSH_KEY_NAME}" \ + "${CNI}" \ + "${OPENSTACK_WORKER_IMAGE_NAME}" \ + "${OPENSTACK_CONTROL_PLANE_IMAGE_NAME}" \ + "${PUBLIC_KEY_MGMT}" \ + "${PUBLIC_KEY_NEW_CLUSTER}" \ + "${PRIVATE_KEY_NEW_CLUSTER}" \ + "${FLEET_REPO_DIR}" \ + "${FLEET_REPO_URL}" \ + "${SW_CATALOGS_REPO_DIR}" \ + "${SW_CATALOGS_REPO_URL}" \ + "${SKIP_BOOTSTRAP}" \ + "${MGMT_PROJECT_NAME}" \ + "${MGMT_CLUSTER_NAME}" \ + "${BASE_TEMPLATES_PATH}" \ + "${NAMESPACE}" +} + +# Create remote Openshift cluster via ACM +function create_openshift_cluster { + local CLUSTER_KUSTOMIZATION_NAME="${1}" + local CLUSTER_NAME="${2}" + # This has to be void. Stored in database + local K8S_VERSION="${3:-"''"}" + # SOPS-AGE related + local PUBLIC_KEY_ACM="${4}" + local PUBLIC_KEY_NEW_CLUSTER="${5:-"${PUBLIC_KEY_NEW_CLUSTER}"}" + local PRIVATE_KEY_NEW_CLUSTER="${6:-"${PRIVATE_KEY_NEW_CLUSTER}"}" + # OpenShift + local OPENSHIFT_RELEASE="${7}" + local INFRA_PUBLIC_SSH_KEY="${8}" + local CONTROL_PLANE_AVAILABILITY="${9}" + local WORKER_COUNT="${10}" + local WORKER_CORES="${11}" + local WORKER_MEMORY="${12}" + local WORKER_VOLUME_SIZE="${13}" + local STORAGE_CLASS="${14}" + local BASE_DOMAIN="${15}" + local MGMT_CLUSTER_NAME="${16}" + local HOSTED_CLUSTERS_PROJECT="${17:-"clusters"}" + local ETCD_VOLUME_SIZE="${18:-"8"}" + # GitOps retaled + local FLEET_REPO_DIR="${19:-"${FLEET_REPO_DIR}"}" + local FLEET_REPO_URL="${20:-"${FLEET_REPO_URL}"}" + local SW_CATALOGS_REPO_DIR="${21:-"${SW_CATALOGS_REPO_DIR}"}" + local SW_CATALOGS_REPO_URL="${22:-"${SW_CATALOGS_REPO_URL}"}" + local SKIP_BOOTSTRAP="${23:-"false"}" + # Only change if absolutely needeed + local MGMT_PROJECT_NAME="${24:-"osm_admin"}" + local BASE_TEMPLATES_PATH="${25:-"cloud-resources"}" + local TEMPLATE_MANIFEST_FILENAME="${26:-"openshift01.yaml"}" + local MANIFEST_FILENAME="${27:-"openshift-${CLUSTER_NAME}.yaml"}" + + local TEMPLATES_DIR="${SW_CATALOGS_REPO_DIR}/cloud-resources/openshift/templates" + local TARGET_FOLDER="${FLEET_REPO_DIR}/${MGMT_PROJECT_NAME}/managed-resources/${MGMT_CLUSTER_NAME}" + + # Internally ACM creates several projects for each cluster. + # Specifically the klusterletaddonconfig must land in a project with the same name as the cluster. + # This will be specifically controlled by the variable `CLUSTER_PROJECT`. + # + # It must be notes that CLUSTER_NAME, CLUSTER_KUSTOMIZATION_NAME and CLUSTER_PROJECT have the same value, + # but they are conceptually different. + local CLUSTER_PROJECT="${CLUSTER_KUSTOMIZATION_NAME}" + + export CLUSTER_KUSTOMIZATION_NAME + + folder2list \ + "${TEMPLATES_DIR}" | \ + replace_env_vars \ + '${CLUSTER_KUSTOMIZATION_NAME}' | \ + patch_replace \ + ".spec.postBuild.substitute.base_domain" \ + "${BASE_DOMAIN}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.cluster_name" \ + "${CLUSTER_NAME}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.cluster_project" \ + "${CLUSTER_PROJECT}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.hosted_cluster_project" \ + "${HOSTED_CLUSTERS_PROJECT}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.etcd_volume_size" \ + "${ETCD_VOLUME_SIZE}Gi" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.openshift_release" \ + "${OPENSHIFT_RELEASE}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.storage_class" \ + "${STORAGE_CLASS}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.control_plane_availability" \ + "${CONTROL_PLANE_AVAILABILITY}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.worker_count" \ + "${WORKER_COUNT}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.worker_cores" \ + "${WORKER_CORES}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.worker_memory" \ + "${WORKER_MEMORY}Gi" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.worker_volume_size" \ + "${WORKER_VOLUME_SIZE}Gi" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}\")" | \ + patch_replace \ + ".spec.postBuild.substitute.cluster_project" \ + "${CLUSTER_PROJECT}" \ + "| select(.kind == \"Kustomization\") | select(.metadata.name == \"${CLUSTER_KUSTOMIZATION_NAME}-ns\")" | \ + rename_file_in_items \ + "${TEMPLATE_MANIFEST_FILENAME}" \ + "${MANIFEST_FILENAME}" | \ + prepend_folder_path "${CLUSTER_KUSTOMIZATION_NAME}/" | \ + list2folder_cp_over \ + "${TARGET_FOLDER}" + + echo "" | \ + make_generator \ + "pull-secret.yaml" \ + kubectl_encrypt \ + "${PUBLIC_KEY_ACM}" \ + create \ + secret \ + generic \ + "pullsecret-cluster-${CLUSTER_NAME}" \ + --namespace="${HOSTED_CLUSTERS_PROJECT}" \ + --from-file=".dockerconfigjson"=<(echo "${DOCKERCONFIGJSON}") \ + -o=yaml \ + --dry-run=client | \ + make_generator \ + "ssh-key-secret.yaml" \ + kubectl_encrypt \ + "${PUBLIC_KEY_ACM}" \ + create \ + secret \ + generic \ + "sshkey-cluster-${CLUSTER_NAME}" \ + --namespace="${HOSTED_CLUSTERS_PROJECT}" \ + --from-file='id_rsa.pub'=<(echo "${INFRA_PUBLIC_SSH_KEY}") \ + -o=yaml \ + --dry-run=client | \ + list2folder_cp_over \ + "${TARGET_FOLDER}/${CLUSTER_KUSTOMIZATION_NAME}" + + # Bootstrap (unless asked to skip) + if [[ "${SKIP_BOOTSTRAP,,}" == "true" ]]; then + return 0 + fi + + local CLUSTER_KUBECONFIG_SECRET_NAME="${CLUSTER_KUSTOMIZATION_NAME}-admin-kubeconfig" + local CLUSTER_KUBECONFIG_SECRET_KEY="kubeconfig" + local BOOTSTRAP_KUSTOMIZATION_NAMESPACE="${HOSTED_CLUSTERS_PROJECT}" + local CLUSTER_KUSTOMIZATION_NAMESPACE="managed-resources" + local BOOTSTRAP_SECRET_NAMESPACE="managed-resources" + + create_bootstrap_for_remote_cluster \ + "${CLUSTER_NAME}" \ + "${CLUSTER_KUSTOMIZATION_NAME}" \ + "${FLEET_REPO_DIR}" \ + "${SW_CATALOGS_REPO_DIR}" \ + "${FLEET_REPO_URL}" \ + "${SW_CATALOGS_REPO_URL}" \ + "${MGMT_PROJECT_NAME}" \ + "${PUBLIC_KEY_ACM}" \ + "${PUBLIC_KEY_NEW_CLUSTER}" \ + "${PRIVATE_KEY_NEW_CLUSTER}" \ + "false" \ + "${MGMT_CLUSTER_NAME}" \ + "${CLUSTER_KUBECONFIG_SECRET_NAME}" \ + "${CLUSTER_KUBECONFIG_SECRET_KEY}" \ + "${SW_CATALOGS_REPO_DIR}/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates" \ + "${BOOTSTRAP_KUSTOMIZATION_NAMESPACE}" \ + "${CLUSTER_KUSTOMIZATION_NAMESPACE}" \ + "${BOOTSTRAP_SECRET_NAMESPACE}" + +} + +# Update remote Openshift cluster via ACM +function update_openshift_cluster { + local CLUSTER_KUSTOMIZATION_NAME="${1}" + local CLUSTER_NAME="${2}" + # This has to be void. Stored in database + local K8S_VERSION="${3:-"''"}" + # SOPS-AGE related + local PUBLIC_KEY_ACM="${4}" + local PUBLIC_KEY_NEW_CLUSTER="${5:-"${PUBLIC_KEY_NEW_CLUSTER}"}" + local PRIVATE_KEY_NEW_CLUSTER="${6:-"${PRIVATE_KEY_NEW_CLUSTER}"}" + # OpenShift specific + local OPENSHIFT_RELEASE="${7}" + local INFRA_PUBLIC_SSH_KEY="${8}" + local CONTROL_PLANE_AVAILABILITY="${9}" + local WORKER_COUNT="${10}" + local WORKER_CORES="${11}" + local WORKER_MEMORY="${12}" + local WORKER_VOLUME_SIZE="${13}" + local STORAGE_CLASS="${14}" + local BASE_DOMAIN="${15}" + local MGMT_CLUSTER_NAME="${16}" + local HOSTED_CLUSTERS_PROJECT="${17:-"clusters"}" + local ETCD_VOLUME_SIZE="${18:-"8"}" + # GitOps retaled + local FLEET_REPO_DIR="${19:-"${FLEET_REPO_DIR}"}" + local FLEET_REPO_URL="${20:-"${FLEET_REPO_URL}"}" + local SW_CATALOGS_REPO_DIR="${21:-"${SW_CATALOGS_REPO_DIR}"}" + local SW_CATALOGS_REPO_URL="${22:-"${SW_CATALOGS_REPO_URL}"}" + local SKIP_BOOTSTRAP="${23:-"false"}" + # Only change if absolutely needeed + local MGMT_PROJECT_NAME="${24:-"osm_admin"}" + + # Determine key folders in Fleet + local MGMT_RESOURCES_DIR="${FLEET_REPO_DIR}/${MGMT_PROJECT_NAME}/managed-resources/${MGMT_CLUSTER_NAME}" + + # Updating no new cluster + local SKIP_BOOTSTRAP="true" + + create_openshift_cluster \ + "${CLUSTER_KUSTOMIZATION_NAME}" \ + "${CLUSTER_NAME}" \ + "${K8S_VERSION}" \ + "${PUBLIC_KEY_ACM}" \ + "${PUBLIC_KEY_NEW_CLUSTER}" \ + "${PRIVATE_KEY_NEW_CLUSTER}" \ + "${OPENSHIFT_RELEASE}" \ + "${INFRA_PUBLIC_SSH_KEY}" \ + "${CONTROL_PLANE_AVAILABILITY}" \ + "${WORKER_COUNT}" \ + "${WORKER_CORES}" \ + "${WORKER_MEMORY}" \ + "${WORKER_VOLUME_SIZE}" \ + "${STORAGE_CLASS}" \ + "${BASE_DOMAIN}" \ + "${MGMT_CLUSTER_NAME}" \ + "${HOSTED_CLUSTERS_PROJECT}" \ + "${ETCD_VOLUME_SIZE}" \ + "${FLEET_REPO_DIR}" \ + "${FLEET_REPO_URL}" \ + "${SW_CATALOGS_REPO_DIR}" \ + "${SW_CATALOGS_REPO_URL}" \ + "${SKIP_BOOTSTRAP}" \ + "${MGMT_PROJECT_NAME}" +} # ----- Helper functions for adding/removing a profile from a cluster ----- @@ -2186,6 +2663,91 @@ function update_crossplane_providerconfig() { } +# Create a CloudConfig for CAPI provider +function create_capi_openstack_cloudconf() { + local OPENSTACK_CLOUD_NAME="${1}" + local PUBLIC_KEY="${2:-"${PUBLIC_KEY_MGMT}"}" + local CONFIG_DIR="${3:-"${MGMT_ADDON_CONFIG_DIR}"}" + + local NAMESPACE="managed-resources" + + local CLOUDS_YAML="${OPENSTACK_CLOUDS_YAML}" + local CACERT="${OPENSTACK_CACERT}" + + local CLOUD_CREDENTIALS_SECRET_NAME="${OPENSTACK_CLOUD_NAME}-capo-config" + local CLOUD_CREDENTIALS_CLOUDS_KEY="clouds.yaml" + local CLOUD_CREDENTIALS_CACERT_KEY="cacert" + local CLOUD_CREDENTIALS_FILENAME="credentials-secret.yaml" + + local CLOUD_CREDENTIALS_TOML_SECRET_NAME="${OPENSTACK_CLOUD_NAME}-capo-config-toml" + local CLOUD_CREDENTIALS_TOML_FILENAME="credentials-toml-secret.yaml" + + local TARGET_FOLDER="${CONFIG_DIR}/capi-providerconfigs/capo/${OPENSTACK_CLOUD_NAME}-config" + mkdir -p "${TARGET_FOLDER}" + + echo "" | \ + make_generator \ + "${CLOUD_CREDENTIALS_FILENAME}" \ + kubectl_encrypt \ + "${PUBLIC_KEY}" \ + create \ + secret \ + generic \ + "${CLOUD_CREDENTIALS_SECRET_NAME}" \ + --namespace="${NAMESPACE}" \ + --from-file="${CLOUD_CREDENTIALS_CLOUDS_KEY}"=<(echo "${CLOUDS_YAML}") \ + --from-file="${CLOUD_CREDENTIALS_CACERT_KEY}"=<(echo "${CACERT}") \ + -o=yaml \ + --dry-run=client | \ + make_generator \ + "${CLOUD_CREDENTIALS_TOML_FILENAME}" \ + kubectl_encrypt \ + "${PUBLIC_KEY}" \ + create \ + secret \ + generic \ + "${CLOUD_CREDENTIALS_TOML_SECRET_NAME}" \ + --namespace="${NAMESPACE}" \ + --from-file="os_auth_url"=<(echo "${OS_AUTH_URL}") \ + --from-file="os_region_name"=<(echo "${OS_REGION_NAME}") \ + --from-file="os_username"=<(echo "${OS_USERNAME}") \ + --from-file="os_password"=<(echo "${OS_PASSWORD}") \ + --from-file="os_project_id"=<(echo "${OS_PROJECT_ID}") \ + --from-file="os_project_domain_id"=<(echo "${OS_PROJECT_DOMAIN_ID}") \ + -o=yaml \ + --dry-run=client | \ + list2folder_cp_over \ + "${TARGET_FOLDER}" +} + +# Update a CloudConfig for CAPI provider +function update_capi_openstack_cloudconf() { + local CLOUD_CONFIG_NAME="${1}" + local PUBLIC_KEY="${2:-"${PUBLIC_KEY_MGMT}"}" + local CONFIG_DIR="${3:-"${MGMT_ADDON_CONFIG_DIR}"}" + + delete_capi_openstack_cloudconf \ + "${CLOUD_CONFIG_NAME}" \ + "${CONFIG_DIR}" + + create_capi_openstack_cloudconf \ + "${CLOUD_CONFIG_NAME}" \ + "${PUBLIC_KEY}" \ + "${CONFIG_DIR}" +} + + +# Delete a CloudConfig for CAPI provider +function delete_capi_openstack_cloudconf() { + local OPENSTACK_CLOUD_NAME="$1" + local CONFIG_DIR="${2:-"${MGMT_ADDON_CONFIG_DIR}"}" + + local TARGET_FOLDER="${CONFIG_DIR}/capi-providerconfigs/capo/${OPENSTACK_CLOUD_NAME}-config" + + # Delete the encrypted secrets files. + rm -rf "${TARGET_FOLDER}" +} + # Helper function to return the relative path of a location in SW Catalogs for an OKA function path_to_catalog() { local OKA_TYPE="$1" diff --git a/installers/00-default-install-options.rc b/installers/00-default-install-options.rc index fa1fb0a6..9afcf70b 100644 --- a/installers/00-default-install-options.rc +++ b/installers/00-default-install-options.rc @@ -44,3 +44,6 @@ export KUBECONFIG_AUX_CLUSTER= export KUBECONFIG_MGMT_CLUSTER= export KUBECONFIG_OSM_CLUSTER= export OSM_BEHIND_PROXY= +export OPENSHIFT_MGMT_CLUSTER= +export MGMT_CLUSTER_CA_FILE= +export OSM_K8S_NGINX_IPADDRESS= \ No newline at end of file diff --git a/installers/01-export-osm-install-options.sh b/installers/01-export-osm-install-options.sh index 963c9246..2aca7444 100755 --- a/installers/01-export-osm-install-options.sh +++ b/installers/01-export-osm-install-options.sh @@ -60,6 +60,9 @@ export KUBECONFIG_AUX_CLUSTER=${KUBECONFIG_AUX_CLUSTER} export KUBECONFIG_MGMT_CLUSTER=${KUBECONFIG_MGMT_CLUSTER} export KUBECONFIG_OSM_CLUSTER=${KUBECONFIG_OSM_CLUSTER} export OSM_BEHIND_PROXY=${OSM_BEHIND_PROXY} +export OPENSHIFT_MGMT_CLUSTER=${OPENSHIFT_MGMT_CLUSTER} +export MGMT_CLUSTER_CA_FILE=${MGMT_CLUSTER_CA_FILE} +export OSM_K8S_NGINX_IPADDRESS=${OSM_K8S_NGINX_IPADDRESS} EOF cat "${OSM_HOME_DIR}/user-install-options.rc" diff --git a/installers/40-deploy-osm.sh b/installers/40-deploy-osm.sh index 8e1d1eac..34d7d06e 100755 --- a/installers/40-deploy-osm.sh +++ b/installers/40-deploy-osm.sh @@ -26,7 +26,6 @@ source "${HERE}/00-default-install-options.rc" source "${CREDENTIALS_DIR}/git_environment.rc" OSM_HELM_WORK_DIR="/etc/osm/helm" -OSM_K8S_EXTERNAL_IP=${OSM_K8S_EXTERNAL_IP:-""} KUBECONFIG_AUX_CLUSTER_FILE="${OSM_HOME_DIR}/clusters/kubeconfig-aux-svc.yaml" KUBECONFIG_MGMT_CLUSTER_FILE="${OSM_HOME_DIR}/clusters/kubeconfig-mgmt.yaml" [ "${HERE}" == "/usr/share/osm-devops/installers" ] || OSM_HELM_UPDATE_DEPENDENCIES="y" @@ -41,19 +40,30 @@ else fi export KUBECONFIG="${OSM_HOME_DIR}/clusters/kubeconfig-osm.yaml" +if [ -z "${OSM_K8S_NGINX_IPADDRESS}" ]; then + echo "OSM_K8S_NGINX_IPADDRESS is not set, will try to get it from the cluster" + OSM_K8S_NGINX_IPADDRESS=$(kubectl get svc ingress-nginx-controller -n ingress-nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}' 2>/dev/null) +fi +echo "Using OSM_K8S_NGINX_IPADDRESS=${OSM_K8S_NGINX_IPADDRESS}" # Create folder to store helm values sudo mkdir -p ${OSM_HELM_WORK_DIR} # Saving secrets echo "Creating namespace ${OSM_NAMESPACE}" -kubectl create ns ${OSM_NAMESPACE} +kubectl get ns "${OSM_NAMESPACE}" >/dev/null 2>&1 || kubectl create ns "${OSM_NAMESPACE}" echo "Saving age keys in OSM cluster" +kubectl -n ${OSM_NAMESPACE} get secret mgmt-cluster-age-keys >/dev/null 2>&1 || \ kubectl -n ${OSM_NAMESPACE} create secret generic mgmt-cluster-age-keys --from-file=privkey="${CREDENTIALS_DIR}/age.mgmt.key" --from-file=pubkey="${CREDENTIALS_DIR}/age.mgmt.pub" echo "Creating secrets with kubeconfig files" -kubectl -n ${OSM_NAMESPACE} create secret generic auxcluster-secret --from-file=kubeconfig="${KUBECONFIG_AUX_CLUSTER_FILE}" -kubectl -n ${OSM_NAMESPACE} create secret generic mgmtcluster-secret --from-file=kubeconfig="${KUBECONFIG_MGMT_CLUSTER_FILE}" - +if [ -f "${KUBECONFIG_AUX_CLUSTER_FILE}" ]; then + kubectl -n ${OSM_NAMESPACE} get secret auxcluster-secret >/dev/null 2>&1 || \ + kubectl -n ${OSM_NAMESPACE} create secret generic auxcluster-secret --from-file=kubeconfig="${KUBECONFIG_AUX_CLUSTER_FILE}" +fi +if [ -f "${KUBECONFIG_MGMT_CLUSTER_FILE}" ]; then + kubectl -n ${OSM_NAMESPACE} get secret mgmtcluster-secret >/dev/null 2>&1 || \ + kubectl -n ${OSM_NAMESPACE} create secret generic mgmtcluster-secret --from-file=kubeconfig="${KUBECONFIG_MGMT_CLUSTER_FILE}" +fi # Update helm dependencies [ -n "${OSM_HELM_UPDATE_DEPENDENCIES}" ] && \ echo "Updating helm dependencies" && \ @@ -69,10 +79,11 @@ OSM_HELM_OPTS="${OSM_HELM_OPTS} --set global.image.repositoryBase=${DOCKER_REGIS [ ! "$OSM_DOCKER_TAG" == "testing-daily" ] && OSM_HELM_OPTS="${OSM_HELM_OPTS} --set-string global.image.tag=${OSM_DOCKER_TAG}" [ ! "$OSM_DOCKER_TAG" == "testing-daily" ] && OSM_HELM_OPTS="${OSM_HELM_OPTS} --set prometheus.server.sidecarContainers.prometheus-config-sidecar.image=${DOCKER_REGISTRY_URL}${DOCKER_USER}/prometheus:${OSM_DOCKER_TAG}" -OSM_HELM_OPTS="${OSM_HELM_OPTS} --set global.hostname=${OSM_K8S_EXTERNAL_IP}.nip.io" -OSM_HELM_OPTS="${OSM_HELM_OPTS} --set grafana.ingress.hosts={grafana.${OSM_K8S_EXTERNAL_IP}.nip.io}" -OSM_HELM_OPTS="${OSM_HELM_OPTS} --set prometheus.server.ingress.hosts={prometheus.${OSM_K8S_EXTERNAL_IP}.nip.io}" -# OSM_HELM_OPTS="${OSM_HELM_OPTS} --set prometheus.alertmanager.ingress.hosts={alertmanager.${OSM_K8S_EXTERNAL_IP}.nip.io}" +OSM_BASE_DOMAIN="${OSM_BASE_DOMAIN:-"${OSM_K8S_NGINX_IPADDRESS}.nip.io"}" +OSM_HELM_OPTS="${OSM_HELM_OPTS} --set global.hostname=${OSM_BASE_DOMAIN}" +OSM_HELM_OPTS="${OSM_HELM_OPTS} --set grafana.ingress.hosts={grafana.${OSM_BASE_DOMAIN}}" +OSM_HELM_OPTS="${OSM_HELM_OPTS} --set prometheus.server.ingress.hosts={prometheus.${OSM_BASE_DOMAIN}}" +# OSM_HELM_OPTS="${OSM_HELM_OPTS} --set prometheus.alertmanager.ingress.hosts={alertmanager.${OSM_BASE_DOMAIN}}" if [ -z "${OSM_GITOPS_ENABLED}" ]; then OSM_HELM_OPTS="${OSM_HELM_OPTS} --set global.gitops.enabled=false" else @@ -117,7 +128,7 @@ set -e echo -e "Saving OSM enviroment to credentials folder..." OSM_HOSTNAME=$(kubectl get --namespace osm -o jsonpath="{.spec.rules[0].host}" ingress nbi-ingress) -# OSM_HOSTNAME="nbi.${OSM_K8S_EXTERNAL_IP}.nip.io:443" +# OSM_HOSTNAME="nbi.${OSM_BASE_DOMAIN}:443" echo -e "OSM HOSTNAME: ${OSM_HOSTNAME}" cat << EOF > "${CREDENTIALS_DIR}/osm_environment.rc" diff --git a/installers/flux/scripts/create-new-cluster-folder-structure.sh b/installers/flux/scripts/create-new-cluster-folder-structure.sh index ef1b0cbb..1ea1dedc 100755 --- a/installers/flux/scripts/create-new-cluster-folder-structure.sh +++ b/installers/flux/scripts/create-new-cluster-folder-structure.sh @@ -111,17 +111,31 @@ envsubst < "${TEMPLATES_DIR}/sw-catalogs-repo.yaml" > "${CLUSTER_DIR}/sw-catalog # Secrets to access both Git repos # (NOTE: these are the last secrets to be added imperatively) kubectl delete secret fleet-repo --namespace flux-system 2> /dev/null || true -kubectl create secret generic fleet-repo \ - --namespace flux-system \ - --from-literal=username="${FLEET_REPO_GIT_USERNAME}" \ - --from-literal=password="${FLEET_REPO_GIT_USER_PASS}" - +if [ -n "${MGMT_CLUSTER_CA_FILE}" ]; then + kubectl create secret generic fleet-repo \ + --namespace flux-system \ + --from-literal=username="${FLEET_REPO_GIT_USERNAME}" \ + --from-literal=password="${FLEET_REPO_GIT_USER_PASS}" \ + --from-file=ca.crt="${MGMT_CLUSTER_CA_FILE}" +else + kubectl create secret generic fleet-repo \ + --namespace flux-system \ + --from-literal=username="${FLEET_REPO_GIT_USERNAME}" \ + --from-literal=password="${FLEET_REPO_GIT_USER_PASS}" +fi kubectl delete secret sw-catalogs --namespace flux-system 2> /dev/null || true -kubectl create secret generic sw-catalogs \ - --namespace flux-system \ - --from-literal=username="${SW_CATALOGS_REPO_GIT_USERNAME}" \ - --from-literal=password="${SW_CATALOGS_REPO_GIT_USER_PASS}" - +if [ -n "${MGMT_CLUSTER_CA_FILE}" ]; then + kubectl create secret generic sw-catalogs \ + --namespace flux-system \ + --from-literal=username="${SW_CATALOGS_REPO_GIT_USERNAME}" \ + --from-literal=password="${SW_CATALOGS_REPO_GIT_USER_PASS}" \ + --from-file=ca.crt="${MGMT_CLUSTER_CA_FILE}" +else + kubectl create secret generic sw-catalogs \ + --namespace flux-system \ + --from-literal=username="${SW_CATALOGS_REPO_GIT_USERNAME}" \ + --from-literal=password="${SW_CATALOGS_REPO_GIT_USER_PASS}" +fi # Render Flux `Kustomizations` to sync with default profiles envsubst < "${TEMPLATES_DIR}/infra-controllers.yaml" > "${CLUSTER_DIR}/infra-controllers.yaml" envsubst < "${TEMPLATES_DIR}/infra-configs.yaml" > "${CLUSTER_DIR}/infra-configs.yaml" diff --git a/installers/flux/scripts/mgmt-cluster-bootstrap.sh b/installers/flux/scripts/mgmt-cluster-bootstrap.sh index c4aa0fce..2917a5ae 100755 --- a/installers/flux/scripts/mgmt-cluster-bootstrap.sh +++ b/installers/flux/scripts/mgmt-cluster-bootstrap.sh @@ -23,17 +23,49 @@ source "${HERE}/library/functions.sh" source "${HERE}/library/trap.sh" +# Preparation for Openshift +if [ -n "${OPENSHIFT_MGMT_CLUSTER}" ]; then + m "Detected OpenShift management cluster, initilializing flux with SCC..." "${GREEN}" + # Preparation for Openshift + pushd "${FLEET_REPO_DIR}" > /dev/null + FLUX_SYSTEM_DIR="clusters/_management/flux-system" + FLUX_SYSTEM_SW_CATALOG_DIR="${HERE}/../templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/flux-system" + mkdir -p "${FLUX_SYSTEM_DIR}" + touch "${FLUX_SYSTEM_DIR}/gotk-components.yaml" + touch "${FLUX_SYSTEM_DIR}/gotk-sync.yaml" + cp "${FLUX_SYSTEM_SW_CATALOG_DIR}/scc.yaml" "${FLUX_SYSTEM_DIR}" + cp "${FLUX_SYSTEM_SW_CATALOG_DIR}/kustomization.yaml" "${FLUX_SYSTEM_DIR}" + # git status + git add -A + git commit -m "init flux" + git pull origin main + git push -u origin main + popd > /dev/null +fi + # Bootstrap GIT_PATH=./clusters/_management GIT_BRANCH=main -flux bootstrap git \ - --url=${FLEET_REPO_HTTP_URL} \ - --allow-insecure-http=true \ - --username=${FLEET_REPO_GIT_USERNAME} \ - --password="${FLEET_REPO_GIT_USER_PASS}" \ - --token-auth=true \ - --branch=${GIT_BRANCH} \ - --path=${GIT_PATH} +if [ -n "${MGMT_CLUSTER_CA_FILE}" ]; then + flux bootstrap git \ + --url=${FLEET_REPO_HTTP_URL} \ + --allow-insecure-http=true \ + --username=${FLEET_REPO_GIT_USERNAME} \ + --password="${FLEET_REPO_GIT_USER_PASS}" \ + --token-auth=true \ + --branch=${GIT_BRANCH} \ + --ca-file=${MGMT_CLUSTER_CA_FILE} \ + --path=${GIT_PATH} +else + flux bootstrap git \ + --url=${FLEET_REPO_HTTP_URL} \ + --allow-insecure-http=true \ + --username=${FLEET_REPO_GIT_USERNAME} \ + --password="${FLEET_REPO_GIT_USER_PASS}" \ + --token-auth=true \ + --branch=${GIT_BRANCH} \ + --path=${GIT_PATH} +fi # Check if successful flux check diff --git a/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/bootstrap/templates/remote-cluster-bootstrap.yaml b/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/bootstrap/templates/remote-cluster-bootstrap.yaml index d138660e..e533cfa6 100644 --- a/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/bootstrap/templates/remote-cluster-bootstrap.yaml +++ b/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/bootstrap/templates/remote-cluster-bootstrap.yaml @@ -28,7 +28,7 @@ apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 kind: Kustomization metadata: name: ${CLUSTER_KUSTOMIZATION_NAME}-bstrp-ns - namespace: managed-resources + namespace: ${BOOTSTRAP_KUSTOMIZATION_NAMESPACE} labels: cluster: ${CLUSTER_KUSTOMIZATION_NAME} spec: @@ -38,6 +38,7 @@ spec: timeout: 5m dependsOn: - name: ${CLUSTER_KUSTOMIZATION_NAME} + namespace: ${CLUSTER_KUSTOMIZATION_NAMESPACE} prune: true # wait: true # force: true @@ -48,8 +49,8 @@ spec: path: ./cloud-resources/flux-remote-bootstrap/bootstrap/manifests/namespaces kubeConfig: secretRef: - name: kubeconfig-${CLUSTER_KUSTOMIZATION_NAME} - key: kubeconfig + name: ${CLUSTER_KUBECONFIG_SECRET_NAME} + key: ${CLUSTER_KUBECONFIG_SECRET_KEY} --- # Creates remote `flux-system.flux-system` secret @@ -57,7 +58,7 @@ apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 kind: Kustomization metadata: name: ${CLUSTER_KUSTOMIZATION_NAME}-bstrp-secret-flux - namespace: managed-resources + namespace: ${BOOTSTRAP_KUSTOMIZATION_NAMESPACE} labels: cluster: ${CLUSTER_KUSTOMIZATION_NAME} spec: @@ -77,8 +78,8 @@ spec: path: ./cloud-resources/flux-remote-bootstrap/bootstrap/manifests/secret kubeConfig: secretRef: - name: kubeconfig-${CLUSTER_KUSTOMIZATION_NAME} - key: kubeconfig + name: ${CLUSTER_KUBECONFIG_SECRET_NAME} + key: ${CLUSTER_KUBECONFIG_SECRET_KEY} patches: - patch: |- apiVersion: v1 @@ -98,13 +99,60 @@ spec: - kind: Secret name: flux-system +--- +# Creates remote `flux-system.managed-resources` secret +apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 +kind: Kustomization +metadata: + name: ${CLUSTER_KUSTOMIZATION_NAME}-bstrp-secret-managedresources-flux + namespace: ${BOOTSTRAP_KUSTOMIZATION_NAMESPACE} + labels: + cluster: ${CLUSTER_KUSTOMIZATION_NAME} +spec: + # interval: 1h + interval: 5m + retryInterval: 1m + timeout: 5m + dependsOn: + - name: ${CLUSTER_KUSTOMIZATION_NAME}-bstrp-ns + prune: true + # wait: true + force: true + sourceRef: + kind: GitRepository + name: sw-catalogs + namespace: flux-system + path: ./cloud-resources/flux-remote-bootstrap/bootstrap/manifests/secret + kubeConfig: + secretRef: + name: ${CLUSTER_KUBECONFIG_SECRET_NAME} + key: ${CLUSTER_KUBECONFIG_SECRET_KEY} + patches: + - patch: |- + apiVersion: v1 + kind: Secret + metadata: + name: ${secret_name} + namespace: ${secret_namespace} + stringData: + username: ${username} + password: ${password} + # Inputs: + postBuild: + substitute: + secret_name: flux-system + secret_namespace: ${BOOTSTRAP_SECRET_NAMESPACE} + substituteFrom: + - kind: Secret + name: flux-system + --- # Creates remote `sops-age` secret apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 kind: Kustomization metadata: name: ${CLUSTER_KUSTOMIZATION_NAME}-bstrp-secret-sops - namespace: managed-resources + namespace: ${BOOTSTRAP_KUSTOMIZATION_NAMESPACE} labels: cluster: ${CLUSTER_KUSTOMIZATION_NAME} spec: @@ -124,8 +172,8 @@ spec: path: ./cloud-resources/flux-remote-bootstrap/bootstrap/manifests/secret kubeConfig: secretRef: - name: kubeconfig-${CLUSTER_KUSTOMIZATION_NAME} - key: kubeconfig + name: ${CLUSTER_KUBECONFIG_SECRET_NAME} + key: ${CLUSTER_KUBECONFIG_SECRET_KEY} patches: - patch: |- apiVersion: v1 @@ -150,7 +198,7 @@ apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 kind: Kustomization metadata: name: ${CLUSTER_KUSTOMIZATION_NAME}-bstrp-secret-fleet - namespace: managed-resources + namespace: ${BOOTSTRAP_KUSTOMIZATION_NAMESPACE} labels: cluster: ${CLUSTER_KUSTOMIZATION_NAME} spec: @@ -170,8 +218,8 @@ spec: path: ./cloud-resources/flux-remote-bootstrap/bootstrap/manifests/secret kubeConfig: secretRef: - name: kubeconfig-${CLUSTER_KUSTOMIZATION_NAME} - key: kubeconfig + name: ${CLUSTER_KUBECONFIG_SECRET_NAME} + key: ${CLUSTER_KUBECONFIG_SECRET_KEY} patches: - patch: |- apiVersion: v1 @@ -191,13 +239,60 @@ spec: - kind: Secret name: fleet-repo +--- +# Creates remote `fleet-repo.managed-resources` secret +apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 +kind: Kustomization +metadata: + name: ${CLUSTER_KUSTOMIZATION_NAME}-bstrp-secret-managedresources-fleet + namespace: ${BOOTSTRAP_KUSTOMIZATION_NAMESPACE} + labels: + cluster: ${CLUSTER_KUSTOMIZATION_NAME} +spec: + # interval: 1h + interval: 5m + retryInterval: 1m + timeout: 5m + dependsOn: + - name: ${CLUSTER_KUSTOMIZATION_NAME}-bstrp-ns + prune: true + # wait: true + force: true + sourceRef: + kind: GitRepository + name: sw-catalogs + namespace: flux-system + path: ./cloud-resources/flux-remote-bootstrap/bootstrap/manifests/secret + kubeConfig: + secretRef: + name: ${CLUSTER_KUBECONFIG_SECRET_NAME} + key: ${CLUSTER_KUBECONFIG_SECRET_KEY} + patches: + - patch: |- + apiVersion: v1 + kind: Secret + metadata: + name: ${secret_name} + namespace: ${secret_namespace} + stringData: + username: ${username} + password: ${password} + # Inputs: + postBuild: + substitute: + secret_name: fleet-repo + secret_namespace: ${BOOTSTRAP_SECRET_NAMESPACE} + substituteFrom: + - kind: Secret + name: fleet-repo + --- # Creates remote `sw-catalogs.flux-system` secret apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 kind: Kustomization metadata: name: ${CLUSTER_KUSTOMIZATION_NAME}-bstrp-secret-catalogs - namespace: managed-resources + namespace: ${BOOTSTRAP_KUSTOMIZATION_NAMESPACE} labels: cluster: ${CLUSTER_KUSTOMIZATION_NAME} spec: @@ -217,8 +312,8 @@ spec: path: ./cloud-resources/flux-remote-bootstrap/bootstrap/manifests/secret kubeConfig: secretRef: - name: kubeconfig-${CLUSTER_KUSTOMIZATION_NAME} - key: kubeconfig + name: ${CLUSTER_KUBECONFIG_SECRET_NAME} + key: ${CLUSTER_KUBECONFIG_SECRET_KEY} patches: - patch: |- apiVersion: v1 @@ -238,13 +333,60 @@ spec: - kind: Secret name: sw-catalogs +--- +# Creates remote `sw-catalogs.managed-resources` secret +apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 +kind: Kustomization +metadata: + name: ${CLUSTER_KUSTOMIZATION_NAME}-bstrp-secret-managedresources-catalogs + namespace: ${BOOTSTRAP_KUSTOMIZATION_NAMESPACE} + labels: + cluster: ${CLUSTER_KUSTOMIZATION_NAME} +spec: + # interval: 1h + interval: 5m + retryInterval: 1m + timeout: 5m + dependsOn: + - name: ${CLUSTER_KUSTOMIZATION_NAME}-bstrp-ns + prune: true + # wait: true + force: true + sourceRef: + kind: GitRepository + name: sw-catalogs + namespace: flux-system + path: ./cloud-resources/flux-remote-bootstrap/bootstrap/manifests/secret + kubeConfig: + secretRef: + name: ${CLUSTER_KUBECONFIG_SECRET_NAME} + key: ${CLUSTER_KUBECONFIG_SECRET_KEY} + patches: + - patch: |- + apiVersion: v1 + kind: Secret + metadata: + name: ${secret_name} + namespace: ${secret_namespace} + stringData: + username: ${username} + password: ${password} + # Inputs: + postBuild: + substitute: + secret_name: sw-catalogs + secret_namespace: ${BOOTSTRAP_SECRET_NAMESPACE} + substituteFrom: + - kind: Secret + name: sw-catalogs + --- # Remote installation of Flux controller (to let the cluster be autonomous) apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: ${CLUSTER_KUSTOMIZATION_NAME}-bstrp-fluxctrl - namespace: managed-resources + namespace: ${BOOTSTRAP_KUSTOMIZATION_NAMESPACE} labels: cluster: ${CLUSTER_KUSTOMIZATION_NAME} spec: @@ -261,5 +403,5 @@ spec: namespace: flux-system kubeConfig: secretRef: - name: kubeconfig-${CLUSTER_KUSTOMIZATION_NAME} - key: kubeconfig + name: ${CLUSTER_KUBECONFIG_SECRET_NAME} + key: ${CLUSTER_KUBECONFIG_SECRET_KEY} diff --git a/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/apps.yaml b/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/apps.yaml new file mode 100644 index 00000000..607b8c93 --- /dev/null +++ b/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/apps.yaml @@ -0,0 +1,41 @@ +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +####################################################################################### + +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: apps + namespace: flux-system + labels: + osm_profile_type: apps +spec: + interval: 10m0s + dependsOn: + - name: infra-configs + sourceRef: + kind: GitRepository + name: fleet-repo + path: ${APPS_PATH} + prune: true + wait: true + timeout: 5m0s + # Decryption configuration starts here + decryption: + provider: sops + secretRef: + name: sops-age diff --git a/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/fleet-repo.yaml b/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/fleet-repo.yaml new file mode 100644 index 00000000..4f70cd72 --- /dev/null +++ b/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/fleet-repo.yaml @@ -0,0 +1,30 @@ +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +####################################################################################### + +--- +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: fleet-repo + namespace: flux-system +spec: + interval: 1m0s + ref: + branch: main + secretRef: + name: fleet-repo + url: ${FLEET_REPO_URL} diff --git a/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/flux-system/gotk-sync.yaml b/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/flux-system/gotk-sync.yaml new file mode 100644 index 00000000..4346fee6 --- /dev/null +++ b/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/flux-system/gotk-sync.yaml @@ -0,0 +1,44 @@ +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +####################################################################################### + +# This manifest was generated by flux. DO NOT EDIT. +--- +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: flux-system + namespace: flux-system +spec: + interval: 1m0s + ref: + branch: main + secretRef: + name: flux-system + url: ${FLEET_REPO_URL} +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: flux-system + namespace: flux-system +spec: + interval: 10m0s + path: ./clusters/${CLUSTER_KUSTOMIZATION_NAME} + prune: true + sourceRef: + kind: GitRepository + name: flux-system diff --git a/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/flux-system/kustomization.yaml b/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/flux-system/kustomization.yaml new file mode 100644 index 00000000..c923e882 --- /dev/null +++ b/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/flux-system/kustomization.yaml @@ -0,0 +1,51 @@ +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +####################################################################################### + +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - gotk-components.yaml + - gotk-sync.yaml + - scc.yaml +patches: + - patch: | + apiVersion: apps/v1 + kind: Deployment + metadata: + name: all + spec: + template: + spec: + securityContext: + $patch: delete + containers: + - name: manager + securityContext: + runAsUser: 65534 + seccompProfile: + $patch: delete + target: + kind: Deployment + labelSelector: app.kubernetes.io/part-of=flux + - patch: |- + - op: remove + path: /metadata/labels/pod-security.kubernetes.io~1warn + - op: remove + path: /metadata/labels/pod-security.kubernetes.io~1warn-version + target: + kind: Namespace + labelSelector: app.kubernetes.io/part-of=flux diff --git a/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/flux-system/scc.yaml b/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/flux-system/scc.yaml new file mode 100644 index 00000000..65220670 --- /dev/null +++ b/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/flux-system/scc.yaml @@ -0,0 +1,60 @@ +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +####################################################################################### + +# Allow Flux controllers to run as non-root on OpenShift +# Docs: https://fluxcd.io/flux/installation/configuration/openshift/ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: flux-scc +rules: + - apiGroups: + - security.openshift.io + resources: + - securitycontextconstraints + resourceNames: + - nonroot + verbs: + - use +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: flux-scc +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: flux-scc +subjects: + - kind: ServiceAccount + name: source-controller + namespace: flux-system + - kind: ServiceAccount + name: kustomize-controller + namespace: flux-system + - kind: ServiceAccount + name: helm-controller + namespace: flux-system + - kind: ServiceAccount + name: notification-controller + namespace: flux-system + - kind: ServiceAccount + name: image-reflector-controller + namespace: flux-system + - kind: ServiceAccount + name: image-automation-controller + namespace: flux-system diff --git a/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/infra-configs.yaml b/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/infra-configs.yaml new file mode 100644 index 00000000..d2879eb1 --- /dev/null +++ b/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/infra-configs.yaml @@ -0,0 +1,49 @@ +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +####################################################################################### + +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: infra-configs + namespace: flux-system + labels: + osm_profile_type: infra-configs +spec: + dependsOn: + - name: infra-controllers + interval: 1h + retryInterval: 1m + timeout: 5m + sourceRef: + kind: GitRepository + name: fleet-repo + path: ${INFRA_CONFIGS_PATH} + prune: true + # Decryption configuration starts here + decryption: + provider: sops + secretRef: + name: sops-age + # patches: + # - patch: | + # - op: replace + # path: /spec/acme/server + # value: https://acme-v02.api.letsencrypt.org/directory + # target: + # kind: ClusterIssuer + # name: letsencrypt diff --git a/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/infra-controllers.yaml b/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/infra-controllers.yaml new file mode 100644 index 00000000..671afc8f --- /dev/null +++ b/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/infra-controllers.yaml @@ -0,0 +1,40 @@ +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +####################################################################################### + +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: infra-controllers + namespace: flux-system + labels: + osm_profile_type: infra-controllers +spec: + interval: 1h + retryInterval: 1m + timeout: 5m + sourceRef: + kind: GitRepository + name: fleet-repo + path: ${INFRA_CONTROLLERS_PATH} + prune: true + wait: true + # Decryption configuration starts here + decryption: + provider: sops + secretRef: + name: sops-age diff --git a/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/kustomization.yaml b/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/kustomization.yaml new file mode 100644 index 00000000..6e3c9af0 --- /dev/null +++ b/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/kustomization.yaml @@ -0,0 +1,36 @@ +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +####################################################################################### + +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + # Repos + - fleet-repo.yaml + - sw-catalogs-repo.yaml + + # Base cluster structure (CRDs, operators and their configs) + - infra-controllers.yaml + - infra-configs.yaml + + # Managed resources + - managed-resources.yaml + + # Managed apps + - apps.yaml + + # Adds also the `flux-system` folder to preserve bootstrap structure + - flux-system diff --git a/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/managed-resources.yaml b/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/managed-resources.yaml new file mode 100644 index 00000000..2d59cc95 --- /dev/null +++ b/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/managed-resources.yaml @@ -0,0 +1,52 @@ +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +####################################################################################### + +--- +# Namespace +# apiVersion: v1 +# kind: Namespace +# metadata: +# name: managed-resources + +--- +# Managed resources +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: managed-resources + namespace: flux-system + labels: + osm_profile_type: managed-resources +spec: + # interval: 10m0s + interval: 7m0s + dependsOn: + - name: infra-configs + sourceRef: + kind: GitRepository + name: fleet-repo + path: ${MANAGED_RESOURCES_PATH} + prune: true + wait: true + # timeout: 5m0s + timeout: 7m0s + retryInterval: 2m0s + # Decryption configuration starts here + decryption: + provider: sops + secretRef: + name: sops-age diff --git a/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/sw-catalogs-repo.yaml b/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/sw-catalogs-repo.yaml new file mode 100644 index 00000000..75bc1384 --- /dev/null +++ b/installers/flux/templates/sw-catalogs/cloud-resources/flux-remote-bootstrap/cluster-base-openshift/templates/sw-catalogs-repo.yaml @@ -0,0 +1,30 @@ +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +####################################################################################### + +--- +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: sw-catalogs + namespace: flux-system +spec: + interval: 1m0s + ref: + branch: main + secretRef: + name: sw-catalogs + url: ${SW_CATALOGS_REPO_URL} diff --git a/installers/flux/templates/sw-catalogs/cloud-resources/openshift/manifests/cluster/hostedcluster.yaml b/installers/flux/templates/sw-catalogs/cloud-resources/openshift/manifests/cluster/hostedcluster.yaml new file mode 100644 index 00000000..59f206e7 --- /dev/null +++ b/installers/flux/templates/sw-catalogs/cloud-resources/openshift/manifests/cluster/hostedcluster.yaml @@ -0,0 +1,69 @@ +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +####################################################################################### + +apiVersion: hypershift.openshift.io/v1beta1 +kind: HostedCluster +metadata: + name: ${cluster_name} + namespace: ${hosted_cluster_project} + labels: + cluster: ${cluster_name} + "cluster.open-cluster-management.io/clusterset": "default" +spec: + etcd: + managed: + storage: + persistentVolume: + size: "${etcd_volume_size}" + storageClassName: ${storage_class} + type: PersistentVolume + managementType: Managed + release: + image: "quay.io/openshift-release-dev/ocp-release:${openshift_release}" + pullSecret: + name: "pullsecret-cluster-${cluster_name}" + sshKey: + name: "sshkey-cluster-${cluster_name}" + networking: + clusterNetwork: + - cidr: 10.132.0.0/14 + serviceNetwork: + - cidr: 172.31.0.0/16 + networkType: OVNKubernetes + controllerAvailabilityPolicy: ${control_plane_availability} + infrastructureAvailabilityPolicy: ${control_plane_availability} + platform: + type: KubeVirt + kubevirt: + baseDomainPassthrough: true + infraID: ${cluster_name} + services: + - service: OAuthServer + servicePublishingStrategy: + type: Route + - service: OIDC + servicePublishingStrategy: + type: Route + - service: Konnectivity + servicePublishingStrategy: + type: Route + - service: Ignition + servicePublishingStrategy: + type: Route + - service: APIServer + servicePublishingStrategy: + type: LoadBalancer diff --git a/installers/flux/templates/sw-catalogs/cloud-resources/openshift/manifests/cluster/klusterlet.yaml b/installers/flux/templates/sw-catalogs/cloud-resources/openshift/manifests/cluster/klusterlet.yaml new file mode 100644 index 00000000..c436d311 --- /dev/null +++ b/installers/flux/templates/sw-catalogs/cloud-resources/openshift/manifests/cluster/klusterlet.yaml @@ -0,0 +1,38 @@ +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +####################################################################################### + +apiVersion: agent.open-cluster-management.io/v1 +kind: KlusterletAddonConfig +metadata: + name: ${cluster_name} + namespace: ${cluster_project} + labels: + cluster: ${cluster_name} +spec: + clusterName: ${cluster_name} + clusterNamespace: ${cluster_project} + clusterLabels: + cloud: BareMetal + vendor: OpenShift + applicationManager: + enabled: true + policyController: + enabled: true + searchCollector: + enabled: true + certPolicyController: + enabled: true diff --git a/installers/flux/templates/sw-catalogs/cloud-resources/openshift/manifests/cluster/managedcluster.yaml b/installers/flux/templates/sw-catalogs/cloud-resources/openshift/manifests/cluster/managedcluster.yaml new file mode 100644 index 00000000..e1fc0aa0 --- /dev/null +++ b/installers/flux/templates/sw-catalogs/cloud-resources/openshift/manifests/cluster/managedcluster.yaml @@ -0,0 +1,33 @@ +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +####################################################################################### + +apiVersion: cluster.open-cluster-management.io/v1 +kind: ManagedCluster +metadata: + annotations: + import.open-cluster-management.io/hosting-cluster-name: local-cluster + import.open-cluster-management.io/klusterlet-deploy-mode: Hosted + open-cluster-management/created-via: hypershift + labels: + cloud: BareMetal + cluster: ${cluster_name} + vendor: OpenShift + name: ${cluster_name} + cluster.open-cluster-management.io/clusterset: "default" + name: ${cluster_name} +spec: + hubAcceptsClient: true diff --git a/installers/flux/templates/sw-catalogs/cloud-resources/openshift/manifests/cluster/nodepool.yaml b/installers/flux/templates/sw-catalogs/cloud-resources/openshift/manifests/cluster/nodepool.yaml new file mode 100644 index 00000000..d7f442d1 --- /dev/null +++ b/installers/flux/templates/sw-catalogs/cloud-resources/openshift/manifests/cluster/nodepool.yaml @@ -0,0 +1,48 @@ +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +####################################################################################### + +apiVersion: hypershift.openshift.io/v1beta1 +kind: NodePool +metadata: + name: "${cluster_name}-np1" + namespace: ${hosted_cluster_project} + labels: + cluster: ${cluster_name} +spec: + arch: amd64 + clusterName: ${cluster_name} + replicas: ${worker_count} + management: + autoRepair: false + upgradeType: Replace + platform: + type: KubeVirt + kubevirt: + compute: + cores: ${worker_cores} + memory: "${worker_memory}" + rootVolume: + type: Persistent + persistent: + size: "${worker_volume_size}" + accessModes: + - ReadWriteMany + storageClass: ${storage_class} + volumeMode: Block + # defaultPodNetwork: true + release: + image: "quay.io/openshift-release-dev/ocp-release:${openshift_release}" diff --git a/installers/flux/templates/sw-catalogs/cloud-resources/openshift/manifests/namespaces/namespaces.yaml b/installers/flux/templates/sw-catalogs/cloud-resources/openshift/manifests/namespaces/namespaces.yaml new file mode 100644 index 00000000..d3745f84 --- /dev/null +++ b/installers/flux/templates/sw-catalogs/cloud-resources/openshift/manifests/namespaces/namespaces.yaml @@ -0,0 +1,31 @@ +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +####################################################################################### +--- +apiVersion: v1 +kind: Namespace +metadata: + name: "${cluster_project}" +--- +apiVersion: v1 +kind: Namespace +metadata: + name: "clusters-${cluster_project}" +--- +apiVersion: v1 +kind: Namespace +metadata: + name: "klusterlet-${cluster_project}" diff --git a/installers/flux/templates/sw-catalogs/cloud-resources/openshift/templates/openshift01.yaml b/installers/flux/templates/sw-catalogs/cloud-resources/openshift/templates/openshift01.yaml new file mode 100644 index 00000000..26842558 --- /dev/null +++ b/installers/flux/templates/sw-catalogs/cloud-resources/openshift/templates/openshift01.yaml @@ -0,0 +1,122 @@ +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +####################################################################################### +--- +# TEMPLATE_PARAMETERS: +# =================== +# +# CLUSTER_KUSTOMIZATION_NAME: Name of the cluster in the ACM management cluster (e.g., for `Kustomization`s). +# CLUSTER_PROJECT: Name of one of the three projects for the cluster that will be created in the ACM management cluster. +# +# PARAMETERS TO PATCH: +# =================== +# +# .spec.postBuild.substitute.cluster_project: Project name to be created + +# Cluster projects +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: ${CLUSTER_KUSTOMIZATION_NAME}-ns + namespace: managed-resources + labels: + cluster: ${CLUSTER_KUSTOMIZATION_NAME} +spec: + commonMetadata: + labels: + cluster: ${CLUSTER_KUSTOMIZATION_NAME} + interval: 1h + retryInterval: 1m + timeout: 5m + sourceRef: + kind: GitRepository + name: sw-catalogs + namespace: flux-system + path: ./cloud-resources/openshift/manifests/namespaces + prune: true + # force: true + wait: true + # Input parameters + postBuild: + substitute: + cluster_project: ${CLUSTER_PROJECT} +--- +# TEMPLATE_PARAMETERS: +# =================== +# +# CLUSTER_KUSTOMIZATION_NAME: Name of the cluster in the management cluster (e.g., for `Kustomization`s). +# - Alternatively, it can be patched at: +# .metadata.name +# .metadata.labels.cluster +# .spec.commonMetadata.labels.cluster +# .spec.postBuild.substitute.cluster_resource_name +# +# PARAMETERS TO PATCH: +# =================== +# +# .spec.postBuild.substitute.base_domain: Domain name to use as base. +# .spec.postBuild.substitute.cluster_name: Name of the cluster in the target cloud. It may differ from `CLUSTER_KUSTOMIZATION_NAME` since naming restrictions are often different from K8s resource naming restrictions (e.g., hyphens vs. underscores). +# .spec.postBuild.substitute.cluster_project: Project name to use +# .spec.postBuild.substitute.hosted_cluster_project: Common project name to use for use with all workload clusters. +# .spec.postBuild.substitute.etcd_volume_size: Volume size of ETCD in Gi +# .spec.postBuild.substitute.openshift_release: Flavor of worker node VMs. +# .spec.postBuild.substitute.storage_class: OpenShift StorageClass to use to create volumes. +# .spec.postBuild.substitute.control_plane_availability: Availability of the contro plane. Valid only SingleReplica or HighAvailability +# .spec.postBuild.substitute.worker_count: Number of Workers. +# .spec.postBuild.substitute.worker_cores: CPU count of Workers. +# .spec.postBuild.substitute.worker_memory: Memory size of Workers in Gi. +# .spec.postBuild.substitute.worker_volume_size: Volume size of Workers in Gi. + +# Cluster resource +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: ${CLUSTER_KUSTOMIZATION_NAME} + namespace: managed-resources + labels: + cluster: ${CLUSTER_KUSTOMIZATION_NAME} +spec: + dependsOn: + - name: ${CLUSTER_KUSTOMIZATION_NAME}-ns + commonMetadata: + labels: + cluster: ${CLUSTER_KUSTOMIZATION_NAME} + interval: 1h + retryInterval: 1m + timeout: 5m + sourceRef: + kind: GitRepository + name: sw-catalogs + namespace: flux-system + path: ./cloud-resources/openshift/manifests/cluster + prune: true + # force: true + wait: true + # Input parameters + postBuild: + substitute: + base_domain: ${BASE_DOMAIN} + cluster_name: ${CLUSTER_NAME} + cluster_project: ${CLUSTER_PROJECT} + hosted_cluster_project: ${HOSTED_CLUSTER_PROJECT} + etcd_volume_size: ${ETCD_VOLUME_SIZE} + openshift_release: ${OPENSHIFT_RELEASE} + storage_class: ${STORAGE_CLASS} + control_plane_availability: ${CONTROL_PLANE_AVAILABILITY} + worker_count: ${WORKER_COUNT} + worker_cores: ${WORKER_CORES} + worker_memory: ${WORKER_MEMORY} + worker_volume_size: ${WORKER_VOLUME_SIZE} diff --git a/installers/flux/templates/sw-catalogs/infra-configs/osm-workflows/templates/wf-templates/canned-operations/full-create-crossplane-cluster-and-bootstrap-wft.yaml b/installers/flux/templates/sw-catalogs/infra-configs/osm-workflows/templates/wf-templates/canned-operations/full-create-crossplane-cluster-and-bootstrap-wft.yaml index 0123e7f3..f0e47c7a 100644 --- a/installers/flux/templates/sw-catalogs/infra-configs/osm-workflows/templates/wf-templates/canned-operations/full-create-crossplane-cluster-and-bootstrap-wft.yaml +++ b/installers/flux/templates/sw-catalogs/infra-configs/osm-workflows/templates/wf-templates/canned-operations/full-create-crossplane-cluster-and-bootstrap-wft.yaml @@ -303,4 +303,5 @@ spec: value: osm_contrib - name: dry_run value: "{{inputs.parameters.dry_run}}" -# ------ end of commit transaction \ No newline at end of file +# ------ end of commit transaction + -- 2.25.1