├── ansible ├── .gitkeep ├── playbooks │ ├── e2e-demo │ │ ├── .gitkeep │ │ ├── snow_undeploy_cluster.yml │ │ └── snow_deploy_cluster.yml │ ├── testing │ │ ├── debug_acm_vars.yml │ │ ├── debug_openstack_creds.yml │ │ ├── vault_lookup_test.yml │ │ ├── test_dns_records.yml │ │ ├── test_sso_config.yml │ │ ├── test_vault_config.yml │ │ ├── test_gitops_create.yml │ │ ├── test_gitops_destroy.yml │ │ ├── netbox_test.yaml │ │ └── test_openstack_allocation.yml │ ├── undeploy_protected_cluster.yml │ ├── undeploy_cluster.yml │ └── deploy_cluster.yml ├── roles │ ├── lb_config │ │ ├── defaults │ │ │ └── main.yml │ │ ├── vars │ │ │ └── main.yml │ │ ├── handlers │ │ │ └── main.yml │ │ ├── meta │ │ │ └── main.yml │ │ ├── README.md │ │ └── tasks │ │ │ └── main.yml │ ├── resource_allocation │ │ ├── tasks │ │ │ ├── providers │ │ │ │ ├── infra_env_hybrid.yml │ │ │ │ ├── openstack.yml │ │ │ │ └── vsphere.yml │ │ │ ├── main.yml │ │ │ └── external_vips.yml │ │ ├── vars │ │ │ └── main.yml │ │ ├── meta │ │ │ └── main.yml │ │ ├── defaults │ │ │ └── main.yml │ │ └── README.md │ ├── dns_config │ │ ├── vars │ │ │ └── main.yml │ │ ├── defaults │ │ │ └── main.yml │ │ ├── meta │ │ │ └── main.yml │ │ ├── tasks │ │ │ ├── providers │ │ │ │ ├── route53.yml │ │ │ │ └── freeipa.yml │ │ │ └── main.yml │ │ └── README.md │ ├── sso_client │ │ ├── vars │ │ │ └── main.yml │ │ ├── defaults │ │ │ └── main.yml │ │ ├── README.md │ │ ├── meta │ │ │ └── main.yml │ │ └── tasks │ │ │ └── main.yml │ ├── vault_config │ │ ├── vars │ │ │ └── main.yml │ │ ├── defaults │ │ │ └── main.yml │ │ ├── meta │ │ │ └── main.yml │ │ ├── README.md │ │ └── tasks │ │ │ └── main.yml │ └── gitops_cluster_build │ │ ├── vars │ │ └── main.yml │ │ ├── meta │ │ └── main.yml │ │ ├── README.md │ │ ├── defaults │ │ └── main.yml │ │ ├── templates │ │ ├── base-config-app.yaml.j2 │ │ ├── cluster-deploy-app.yaml.j2 │ │ ├── base-config-values.yaml.j2 │ │ ├── vsphere-build-values.yaml.j2 │ │ ├── openstack-build-values.yaml.j2 │ │ └── vsphere-install-config.yaml.j2 │ │ └── tasks │ │ └── main.yml ├── execution-environment │ ├── python-requirements.txt │ ├── execution-environment.yml │ └── collections │ │ └── requirements.yml └── inventories │ └── fixed-assets ├── charts ├── .gitkeep ├── mce-cluster-build │ ├── templates │ │ ├── namespace.yaml │ │ ├── cluster-image-set.yaml │ │ ├── provider-trust-bundle.yaml │ │ ├── nmstate-configs.yaml │ │ ├── managed-cluster.yaml │ │ ├── ssh-privatekey-vault.yaml │ │ ├── pull-secret-vault.yaml │ │ ├── install-config-vault.yaml │ │ ├── provider-creds-vault.yaml │ │ ├── klusterlet-config.yaml │ │ ├── infra-env.yaml │ │ ├── agent-cluster-install.yaml │ │ ├── _helpers.tpl │ │ ├── gitops-manifestwork.yaml │ │ ├── install-config-secret.yaml │ │ └── cluster-deployment.yaml │ ├── Chart.yaml │ ├── .helmignore │ └── values.yaml └── ocp-base-config │ ├── Chart.yaml │ ├── templates │ ├── external-secrets │ │ ├── namespace.yaml │ │ ├── operator-group.yaml │ │ ├── subscription.yaml │ │ ├── cluster-issuer.yaml │ │ ├── rbac.yaml │ │ └── operator-config.yaml │ ├── ca-trust │ │ ├── cluster-proxy.yaml │ │ └── configmap.yaml │ ├── cert-manager │ │ ├── operator-group.yaml │ │ ├── default-ingress-controller.yaml │ │ ├── subscription.yaml │ │ ├── namespace.yaml │ │ ├── cluster-apiserver.yaml │ │ ├── clusterissuer.yaml │ │ ├── cert-manager-config.yaml │ │ ├── external-secret.yaml │ │ ├── api-cert.yaml │ │ └── apps-cert.yaml │ ├── networking │ │ └── cluster-network.yaml │ ├── auth │ │ ├── global-admins-binding.yaml │ │ ├── external-secret.yaml │ │ └── oauth-config.yaml │ ├── odf │ │ ├── storage-cluster.yaml │ │ ├── default-sc.yaml │ │ ├── external-secret.yaml │ │ └── operator.yaml │ ├── monitoring │ │ └── cluster-monitoring-config.yaml │ ├── timesync │ │ ├── _helpers.tpl │ │ ├── master-chrony-config.yaml │ │ └── worker-chrony-config.yaml │ ├── gitops │ │ ├── cluster-argocd-config.yaml │ │ └── application-set.yaml │ └── _helpers.tpl │ ├── .helmignore │ └── values.yaml ├── argocd ├── clusters │ ├── rhte-acm-hub │ │ └── live │ │ │ ├── .gitkeep │ │ │ ├── cluster-builds │ │ │ ├── .gitkeep │ │ │ └── demo-feb9.yaml │ │ │ ├── rhacm-base │ │ │ ├── mco-namespace.yaml │ │ │ ├── mco-obc.yaml │ │ │ ├── hive-config.yaml │ │ │ ├── kustomization.yaml │ │ │ ├── thanos-secret.yaml │ │ │ ├── mch.yaml │ │ │ ├── mco-pull-secret.yaml │ │ │ ├── rhacm-operator.yaml │ │ │ ├── gitops-integration.yaml │ │ │ ├── mco.yaml │ │ │ └── hive-ca-bundle.yaml │ │ │ ├── aap-base │ │ │ ├── namespace.yaml │ │ │ ├── secret-view-cr.yaml │ │ │ ├── secret-view-crb.yaml │ │ │ ├── managed-cluster-view-crb.yaml │ │ │ ├── managed-cluster-view-cr.yaml │ │ │ ├── secret-key.yaml │ │ │ ├── admin-password.yaml │ │ │ ├── rbac.yaml │ │ │ ├── ca-bundle-secret.yaml │ │ │ ├── operator-sub.yaml │ │ │ └── aap-controller.yaml │ │ │ ├── cluster-monitoring │ │ │ └── cm-config.yaml │ │ │ ├── base-config │ │ │ └── base-config-app.yaml │ │ │ └── rhacm-policies │ │ │ └── install-gitops.yaml │ ├── rhte-mce-hub │ │ └── live │ │ │ ├── .gitkeep │ │ │ ├── cluster-builds │ │ │ └── .gitkeep │ │ │ ├── mce │ │ │ ├── mce-namespace.yaml │ │ │ ├── cluster-metal-operator-config.yaml │ │ │ ├── mce-cr.yaml │ │ │ ├── hive-imageset-app.yaml │ │ │ ├── agent-service-config.yaml │ │ │ └── subscription.yaml │ │ │ ├── cluster-monitoring │ │ │ └── cm-config.yaml │ │ │ └── base-config │ │ │ └── base-config-app.yaml │ └── managed-clusters │ │ ├── demo-feb9 │ │ ├── live │ │ │ ├── virt │ │ │ │ ├── hco.yaml │ │ │ │ ├── storage-profile.yaml │ │ │ │ └── operator.yaml │ │ │ └── base-configs │ │ │ │ └── base-config-app.yaml │ │ └── helm-values │ │ │ ├── base-config-values.yaml │ │ │ └── build-values.yaml │ │ ├── demo-jun1 │ │ ├── live │ │ │ └── base-configs │ │ │ │ └── base-config-app.yaml │ │ └── helm-values │ │ │ ├── base-config-values.yaml │ │ │ └── build-values.yaml │ │ └── demo-jun2 │ │ ├── live │ │ └── base-configs │ │ │ └── base-config-app.yaml │ │ └── helm-values │ │ ├── base-config-values.yaml │ │ └── build-values.yaml └── install-gitops.yaml ├── ansible.cfg ├── .gitignore ├── .gitleaks.toml ├── README.md └── LICENSE /ansible/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /charts/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ansible/playbooks/e2e-demo/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-mce-hub/live/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | roles_path=ansible/roles 3 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/cluster-builds/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-mce-hub/live/cluster-builds/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | ansible/execution-environment/context 3 | -------------------------------------------------------------------------------- /ansible/roles/lb_config/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | cluster_hosts: {} 3 | -------------------------------------------------------------------------------- /ansible/roles/resource_allocation/tasks/providers/infra_env_hybrid.yml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ansible/roles/dns_config/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for dns_config 3 | -------------------------------------------------------------------------------- /ansible/roles/lb_config/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for lb_config 3 | -------------------------------------------------------------------------------- /ansible/roles/sso_client/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for sso_client 3 | -------------------------------------------------------------------------------- /ansible/roles/vault_config/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for vault_config 3 | -------------------------------------------------------------------------------- /ansible/roles/dns_config/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for dns_config 3 | -------------------------------------------------------------------------------- /ansible/roles/sso_client/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for sso_client 3 | -------------------------------------------------------------------------------- /ansible/roles/vault_config/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for vault_config 3 | -------------------------------------------------------------------------------- /ansible/roles/gitops_cluster_build/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for gitops_cluster_build 3 | -------------------------------------------------------------------------------- /ansible/roles/resource_allocation/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for resource_allocation 3 | -------------------------------------------------------------------------------- /ansible/roles/lb_config/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: reload haproxy 3 | ansible.builtin.systemd: 4 | name: haproxy.service 5 | state: reloaded 6 | become: true 7 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/rhacm-base/mco-namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: open-cluster-management-observability 5 | spec: {} 6 | status: {} 7 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-mce-hub/live/mce/mce-namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: multicluster-engine 5 | annotations: 6 | argocd.argoproj.io/sync-wave: '0' 7 | -------------------------------------------------------------------------------- /charts/mce-cluster-build/templates/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: {{ .Values.cluster.name }} 5 | annotations: 6 | argocd.argoproj.io/sync-wave: '-1' 7 | -------------------------------------------------------------------------------- /charts/ocp-base-config/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: ocp-base-config 3 | description: Base cluster configurations via Helm 4 | 5 | type: application 6 | 7 | version: 0.0.1 8 | 9 | appVersion: "4.11" 10 | -------------------------------------------------------------------------------- /ansible/execution-environment/python-requirements.txt: -------------------------------------------------------------------------------- 1 | kubernetes==25.3.0 2 | python-hpilo==4.4.3 3 | pynetbox==7.0.0 4 | hvac==1.0.2 5 | openstackclient==4.0.0 6 | pyOpenSSL==21.0.0 7 | cryptography==37.0.2 8 | pysnow==0.7.17 9 | -------------------------------------------------------------------------------- /charts/mce-cluster-build/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: mce-cluster-build 3 | description: Helm chart for generating cluster build manifests 4 | 5 | type: application 6 | 7 | version: 0.0.1 8 | 9 | appVersion: "4.11" 10 | -------------------------------------------------------------------------------- /ansible/roles/resource_allocation/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Run platform-specific tasks 3 | include_tasks: "providers/{{ cluster_platform }}.yml" 4 | 5 | - name: Handle external VIP allocation 6 | include_tasks: "external_vips.yml" 7 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/aap-base/namespace.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | labels: 6 | openshift.io/cluster-monitoring: "true" 7 | annotations: 8 | argocd.argoproj.io/sync-wave: '0' 9 | name: aap 10 | -------------------------------------------------------------------------------- /ansible/roles/dns_config/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: Andrew Austin Byrum 3 | description: Manage DNS records for the RHTE 2023 Fleet GitOps Demo. 4 | company: Red Hat 5 | license: Apache-2.0 6 | min_ansible_version: 2.12 7 | galaxy_tags: [] 8 | dependencies: [] 9 | -------------------------------------------------------------------------------- /ansible/roles/lb_config/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: Andrew Austin Byrum 3 | description: Configured an haproxy load balancer for various cluster configurations 4 | company: Red Hat 5 | license: Apache-2.0 6 | min_ansible_version: 2.12 7 | galaxy_tags: [] 8 | dependencies: [] 9 | -------------------------------------------------------------------------------- /ansible/roles/vault_config/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: Andrew Austin Byrum 3 | description: Create and delete Hashicorp Vault auth methods for managed clusters 4 | company: Red Hat 5 | license: Apache-2.0 6 | min_ansible_version: 2.12 7 | galaxy_tags: [] 8 | dependencies: [] 9 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/external-secrets/namespace.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.externalSecrets.enabled -}} 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: external-secrets-operator 6 | annotations: 7 | argocd.argoproj.io/sync-wave: '-2' 8 | spec: {} 9 | {{ end }} 10 | -------------------------------------------------------------------------------- /ansible/execution-environment/execution-environment.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1 3 | 4 | build_arg_defaults: 5 | EE_BASE_IMAGE: 'quay.io/ansible/ansible-runner:stable-2.12-devel' 6 | 7 | dependencies: 8 | galaxy: collections/requirements.yml 9 | python: python-requirements.txt 10 | #system: bindep.txt 11 | -------------------------------------------------------------------------------- /ansible/inventories/fixed-assets: -------------------------------------------------------------------------------- 1 | all: 2 | children: 3 | ipaservers: 4 | hosts: 5 | xna-ipa-1.home.signal9.gg: {} 6 | loadbalancers: 7 | hosts: 8 | xna-haproxy-a.lab.signal9.gg: {} 9 | xna-haproxy-b.lab.signal9.gg: {} 10 | xna-haproxy-c.home.signal9.gg: {} 11 | -------------------------------------------------------------------------------- /ansible/roles/gitops_cluster_build/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: Andrew Austin Byrum 3 | description: Creates cluster and base config definitions in the RHTE 2023 example gitops repo 4 | company: Red Hat 5 | license: Apache-2.0 6 | min_ansible_version: 2.12 7 | galaxy_tags: [] 8 | dependencies: [] 9 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/aap-base/secret-view-cr.yaml: -------------------------------------------------------------------------------- 1 | kind: ClusterRole 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | metadata: 4 | name: aap-secret-view 5 | rules: 6 | - verbs: 7 | - get 8 | - list 9 | apiGroups: 10 | - '' 11 | resources: 12 | - secrets 13 | 14 | -------------------------------------------------------------------------------- /ansible/roles/resource_allocation/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: Andrew Austin Byrum 3 | description: Allocates resources (IP addresses and hardware) for the RHTE 2023 Fleet GitOps Demo. 4 | company: Red Hat 5 | license: Apache-2.0 6 | min_ansible_version: 2.12 7 | galaxy_tags: [] 8 | dependencies: [] 9 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/rhacm-base/mco-obc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: objectbucket.io/v1alpha1 2 | kind: ObjectBucketClaim 3 | metadata: 4 | name: thanos-s3-storage 5 | namespace: open-cluster-management-observability 6 | spec: 7 | generateBucketName: acm-hub-thanos 8 | storageClassName: openshift-storage.noobaa.io 9 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-mce-hub/live/mce/cluster-metal-operator-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: metal3.io/v1alpha1 2 | kind: Provisioning 3 | metadata: 4 | name: provisioning-configuration 5 | spec: 6 | provisioningMacAddresses: 7 | - ac:1f:6b:79:e3:da 8 | provisioningNetwork: Disabled 9 | watchAllNamespaces: true 10 | -------------------------------------------------------------------------------- /charts/mce-cluster-build/templates/cluster-image-set.yaml: -------------------------------------------------------------------------------- 1 | {{- if and (eq .Values.provider.type "InfraEnv") .Values.cluster.releaseImage -}} 2 | apiVersion: hive.openshift.io/v1 3 | kind: ClusterImageSet 4 | metadata: 5 | name: {{ .Values.cluster.name }}-custom 6 | spec: 7 | releaseImage: {{ .Values.cluster.releaseImage }} 8 | {{- end -}} 9 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-mce-hub/live/mce/mce-cr.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: multicluster.openshift.io/v1 2 | kind: MultiClusterEngine 3 | metadata: 4 | name: multiclusterengine 5 | namespace: multicluster-engine 6 | annotations: 7 | argocd.argoproj.io/sync-wave: '2' 8 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 9 | spec: {} 10 | -------------------------------------------------------------------------------- /argocd/clusters/managed-clusters/demo-feb9/live/virt/hco.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: hco.kubevirt.io/v1beta1 2 | kind: HyperConverged 3 | metadata: 4 | name: kubevirt-hyperconverged 5 | namespace: openshift-cnv 6 | annotations: 7 | argocd.argoproj.io/sync-wave: "3" 8 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 9 | spec: {} 10 | -------------------------------------------------------------------------------- /ansible/roles/gitops_cluster_build/README.md: -------------------------------------------------------------------------------- 1 | gitops_cluster_build 2 | ========= 3 | 4 | This role is reponsible for templating gitops configurations to build or destroy a cluster. 5 | 6 | Requirements 7 | ------------ 8 | 9 | The execurtion environment must have git and ssh commands available 10 | 11 | License 12 | ------- 13 | 14 | Apache 2.0 15 | 16 | -------------------------------------------------------------------------------- /.gitleaks.toml: -------------------------------------------------------------------------------- 1 | [allowlist] 2 | description = "Global Allowlist" 3 | 4 | # Ignore based on any subset of the file path 5 | paths = [ 6 | # Ignore revoked oauth data from servicenow app export used as test data 7 | '''\/oauth_entity_a685e6952f306110d3fc4ae72799b65a.xml''', 8 | '''\/oauth_entity_ab0436892fb02110d3fc4ae72799b6d9.xml''', 9 | ] 10 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/rhacm-base/hive-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: hive.openshift.io/v1 2 | kind: HiveConfig 3 | metadata: 4 | name: hive 5 | annotations: 6 | argocd.argoproj.io/sync-wave: '3' 7 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 8 | spec: 9 | additionalCertificateAuthoritiesSecretRef: 10 | name: signal9-ca-bundle 11 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/aap-base/secret-view-crb.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: aap-secret-view-binding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: aap-secret-view 9 | subjects: 10 | - kind: ServiceAccount 11 | name: acm-hub-aap 12 | namespace: aap 13 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/ca-trust/cluster-proxy.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.cluster.trustedCABundle -}} 2 | apiVersion: config.openshift.io/v1 3 | kind: Proxy 4 | metadata: 5 | name: cluster 6 | annotations: 7 | argocd.argoproj.io/sync-options: ServerSideApply=true 8 | argocd.argoproj.io/sync-wave: '2' 9 | spec: 10 | trustedCA: 11 | name: "base-config-ca-certs" 12 | {{- end -}} 13 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/aap-base/managed-cluster-view-crb.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: aap-managedcluster-view-binding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: aap-managedcluster-view 9 | subjects: 10 | - kind: ServiceAccount 11 | name: acm-hub-aap 12 | namespace: aap 13 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/ca-trust/configmap.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.cluster.trustedCABundle -}} 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: base-config-ca-certs 6 | namespace: openshift-config 7 | annotations: 8 | argocd.argoproj.io/compare-options: IgnoreExtraneous 9 | data: 10 | ca-bundle.crt: | 11 | {{ .Values.cluster.trustedCABundle | indent 4 }} 12 | {{- end -}} 13 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/cert-manager/operator-group.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.certManager.enabled -}} 2 | apiVersion: operators.coreos.com/v1alpha2 3 | kind: OperatorGroup 4 | metadata: 5 | name: cert-manager-operator 6 | namespace: cert-manager-operator 7 | annotations: 8 | argocd.argoproj.io/sync-wave: '-1' 9 | spec: 10 | targetNamespaces: 11 | - cert-manager-operator 12 | {{ end }} 13 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/external-secrets/operator-group.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.externalSecrets.enabled -}} 2 | apiVersion: operators.coreos.com/v1alpha2 3 | kind: OperatorGroup 4 | metadata: 5 | name: external-secrets 6 | namespace: external-secrets-operator 7 | annotations: 8 | argocd.argoproj.io/sync-wave: '-1' 9 | spec: 10 | targetNamespaces: 11 | - external-secrets-operator 12 | {{ end }} 13 | -------------------------------------------------------------------------------- /ansible/playbooks/testing/debug_acm_vars.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | gather_facts: true 3 | tasks: 4 | - name: debug cluster_deployment 5 | ansible.builtin.debug: 6 | var: cluster_deployment 7 | 8 | - name: debug cluster_info 9 | ansible.builtin.debug: 10 | var: cluster_info 11 | 12 | - name: debug install_config 13 | ansible.builtin.debug: 14 | var: install_config 15 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/rhacm-base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - rhacm-operator.yaml 6 | - mch.yaml 7 | - mco-namespace.yaml 8 | - mco-pull-secret.yaml 9 | - mco-obc.yaml 10 | - gitops-integration.yaml 11 | # These must be re-enabled after adding the s3 bucket credentials to vault 12 | - thanos-secret.yaml 13 | - mco.yaml 14 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/networking/cluster-network.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.network.hostRouting -}} 2 | apiVersion: operator.openshift.io/v1 3 | kind: Network 4 | metadata: 5 | annotations: 6 | argocd.argoproj.io/sync-options: ServerSideApply=true,Validate=false 7 | name: cluster 8 | spec: 9 | defaultNetwork: 10 | ovnKubernetesConfig: 11 | gatewayConfig: 12 | routingViaHost: true 13 | {{- end -}} 14 | -------------------------------------------------------------------------------- /ansible/execution-environment/collections/requirements.yml: -------------------------------------------------------------------------------- 1 | --- 2 | collections: 3 | - name: community.general 4 | - name: kubernetes.core 5 | - name: hpe.ilo 6 | - name: netbox.netbox 7 | - name: freeipa.ansible_freeipa 8 | - name: https://github.com/marbindrakon/community.hashi_vault.git 9 | type: git 10 | version: delete_function 11 | - name: amazon.aws 12 | - name: openstack.cloud 13 | - name: servicenow.itsm 14 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/auth/global-admins-binding.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.auth.enabled -}} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRoleBinding 4 | metadata: 5 | name: global-admins-binding 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: ClusterRole 9 | name: cluster-admin 10 | subjects: 11 | - apiGroup: rbac.authorization.k8s.io 12 | kind: Group 13 | name: global-admins 14 | {{ end }} 15 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/cert-manager/default-ingress-controller.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.certManager.enabled .Values.certManager.defaultIngressCert -}} 2 | apiVersion: operator.openshift.io/v1 3 | kind: IngressController 4 | metadata: 5 | name: default 6 | namespace: openshift-ingress-operator 7 | annotations: 8 | argocd.argoproj.io/sync-wave: "3" 9 | spec: 10 | defaultCertificate: 11 | name: acme-apps 12 | {{ end }} 13 | -------------------------------------------------------------------------------- /argocd/clusters/managed-clusters/demo-feb9/live/virt/storage-profile.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cdi.kubevirt.io/v1beta1 2 | kind: StorageProfile 3 | metadata: 4 | name: standard-csi 5 | annotations: 6 | argocd.argoproj.io/sync-options: ServerSideApply=true,Validate=false 7 | argocd.argoproj.io/sync-wave: "4" 8 | spec: 9 | claimPropertySets: 10 | - accessModes: 11 | - ReadWriteOnce 12 | volumeMode: Filesystem 13 | cloneStrategy: snapshot 14 | -------------------------------------------------------------------------------- /charts/mce-cluster-build/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /charts/ocp-base-config/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/odf/storage-cluster.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.odfStorage.enabled .Values.odfStorage.external -}} 2 | apiVersion: ocs.openshift.io/v1 3 | kind: StorageCluster 4 | metadata: 5 | name: ocs-external-storagecluster 6 | namespace: openshift-storage 7 | annotations: 8 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 9 | argocd.argoproj.io/sync-wave: '2' 10 | spec: 11 | externalStorage: 12 | enable: true 13 | {{- end -}} 14 | -------------------------------------------------------------------------------- /ansible/playbooks/testing/debug_openstack_creds.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | gather_facts: false 3 | vars: 4 | config_file: "{{ lookup('env', 'OS_CLIENT_CONFIG_FILE') }}" 5 | tasks: 6 | - debug: msg="{{ config_file }}" 7 | - stat: path="{{ config_file }}" 8 | register: st 9 | - include_vars: "{{ config_file }}" 10 | when: st.stat.exists and st.stat.isreg 11 | 12 | - name: "Print out clouds variable" 13 | debug: msg="{{ clouds|default('No clouds found') }}" 14 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/aap-base/managed-cluster-view-cr.yaml: -------------------------------------------------------------------------------- 1 | kind: ClusterRole 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | metadata: 4 | name: aap-managedcluster-view 5 | rules: 6 | - verbs: 7 | - get 8 | - list 9 | apiGroups: 10 | - 'cluster.open-cluster-management.io' 11 | resources: 12 | - managedclusters 13 | 14 | - verbs: 15 | - get 16 | - list 17 | apiGroups: 18 | - '' 19 | resources: 20 | - namespaces 21 | 22 | -------------------------------------------------------------------------------- /ansible/playbooks/undeploy_protected_cluster.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | gather_facts: false 3 | vars: 4 | cluster_state: unchanged 5 | gitops_task: unprotect 6 | tasks: 7 | - name: include gitops_cluster_build role 8 | ansible.builtin.include_role: 9 | name: gitops_cluster_build 10 | 11 | - name: wait 30 seconds 12 | ansible.builtin.pause: 13 | seconds: 30 14 | 15 | - name: include undeploy plays 16 | ansible.builtin.import_playbook: undeploy_cluster.yml 17 | -------------------------------------------------------------------------------- /charts/mce-cluster-build/templates/provider-trust-bundle.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.provider.providerCAs -}} 2 | apiVersion: v1 3 | kind: Secret 4 | type: Opaque 5 | metadata: 6 | name: {{ .Values.cluster.name }}-trust 7 | namespace: {{ .Values.cluster.name }} 8 | annotations: 9 | argocd.argoproj.io/sync-wave: '0' 10 | stringData: 11 | {{- if eq .Values.provider.type "OpenStack" }} 12 | ca.crt: | 13 | {{ else }} 14 | .cacert: | 15 | {{ end -}} 16 | {{ indent 4 .Values.provider.providerCAs }} 17 | {{ end }} 18 | -------------------------------------------------------------------------------- /charts/mce-cluster-build/templates/nmstate-configs.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.provider.infraenv.hostNetworkConfigs -}} 2 | --- 3 | {{ range $host, $netconf := .Values.provider.infraenv.hostNetworkConfigs }} 4 | apiVersion: agent-install.openshift.io/v1beta1 5 | kind: NMStateConfig 6 | metadata: 7 | namespace: {{ $.Values.cluster.name }} 8 | name: {{ $host }} 9 | labels: 10 | infraenvs.agent-install.openshift.io: {{ $.Values.cluster.name }} 11 | spec: 12 | {{- toYaml $netconf | nindent 2 }} 13 | --- 14 | {{ end }} 15 | {{- end -}} 16 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/cert-manager/subscription.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.certManager.enabled -}} 2 | apiVersion: operators.coreos.com/v1alpha1 3 | kind: Subscription 4 | metadata: 5 | name: openshift-cert-manager-operator 6 | namespace: cert-manager-operator 7 | annotations: 8 | argocd.argoproj.io/sync-wave: '-1' 9 | spec: 10 | channel: stable-v1 11 | installPlanApproval: Automatic 12 | name: openshift-cert-manager-operator 13 | source: redhat-operators 14 | sourceNamespace: openshift-marketplace 15 | {{ end }} 16 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/external-secrets/subscription.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.externalSecrets.enabled -}} 2 | apiVersion: operators.coreos.com/v1alpha1 3 | kind: Subscription 4 | metadata: 5 | name: external-secrets-operator 6 | namespace: external-secrets-operator 7 | annotations: 8 | argocd.argoproj.io/sync-wave: '-1' 9 | spec: 10 | channel: alpha 11 | installPlanApproval: Automatic 12 | name: external-secrets-operator 13 | source: community-operators 14 | sourceNamespace: openshift-marketplace 15 | {{ end }} 16 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/cert-manager/namespace.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.certManager.enabled -}} 2 | --- 3 | apiVersion: v1 4 | kind: Namespace 5 | metadata: 6 | name: cert-manager-operator 7 | labels: 8 | openshift.io/cluster-monitoring: 'true' 9 | annotations: 10 | argocd.argoproj.io/sync-wave: '-2' 11 | --- 12 | apiVersion: v1 13 | kind: Namespace 14 | metadata: 15 | name: cert-manager 16 | labels: 17 | openshift.io/cluster-monitoring: 'true' 18 | annotations: 19 | argocd.argoproj.io/sync-wave: '-2' 20 | 21 | {{ end }} 22 | -------------------------------------------------------------------------------- /charts/mce-cluster-build/templates/managed-cluster.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.cluster.importToHub -}} 2 | apiVersion: cluster.open-cluster-management.io/v1 3 | kind: ManagedCluster 4 | metadata: 5 | labels: 6 | cloud: {{ .Values.provider.type }} 7 | name: {{ .Values.cluster.name }} 8 | vendor: OpenShift 9 | spoke-gitops: 'true' 10 | name: {{ .Values.cluster.name }} 11 | annotations: 12 | argocd.argoproj.io/compare-options: IgnoreExtraneous 13 | argocd.argoproj.io/sync-wave: '1' 14 | spec: 15 | hubAcceptsClient: true 16 | {{ end }} 17 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/cert-manager/cluster-apiserver.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.certManager.enabled .Values.certManager.apiCert -}} 2 | apiVersion: config.openshift.io/v1 3 | kind: APIServer 4 | metadata: 5 | name: cluster 6 | annotations: 7 | argocd.argoproj.io/sync-wave: "3" 8 | spec: 9 | encryption: 10 | type: aescbc 11 | servingCerts: 12 | namedCertificates: 13 | - names: 14 | - api.{{ .Values.cluster.name }}.{{ .Values.cluster.baseDomain }} 15 | servingCertificate: 16 | name: acme-api 17 | {{ end }} 18 | -------------------------------------------------------------------------------- /charts/mce-cluster-build/templates/ssh-privatekey-vault.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: external-secrets.io/v1beta1 2 | kind: ExternalSecret 3 | metadata: 4 | name: {{ .Values.cluster.name }}-ssh-key 5 | namespace: {{ .Values.cluster.name }} 6 | annotations: 7 | argocd.argoproj.io/sync-wave: '0' 8 | spec: 9 | refreshInterval: 1h 10 | secretStoreRef: 11 | kind: ClusterSecretStore 12 | name: vault 13 | target: 14 | name: {{ .Values.cluster.name }}-ssh-key 15 | creationPolicy: Owner 16 | dataFrom: 17 | - extract: 18 | key: {{ .Values.cluster.sshKeyVault }} 19 | -------------------------------------------------------------------------------- /ansible/playbooks/testing/vault_lookup_test.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | gather_facts: true 3 | tasks: 4 | - name: Get Vault JWT 5 | no_log: true 6 | ansible.builtin.set_fact: 7 | vault_jwt: "{{ lookup('ansible.builtin.file', hashicorp_vault['jwt_location']) }}" 8 | - name: Dump test secret 9 | ansible.builtin.debug: 10 | msg: "{{ lookup('community.hashi_vault.hashi_vault', 'lab/rht-shared/data/test-openid-secret', auth_method='jwt', mount_point=hashicorp_vault['auth_mount'], role_id=hashicorp_vault['auth_role'], jwt=vault_jwt, url=hashicorp_vault['url']) }}" 11 | -------------------------------------------------------------------------------- /charts/mce-cluster-build/templates/pull-secret-vault.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: external-secrets.io/v1beta1 2 | kind: ExternalSecret 3 | metadata: 4 | name: {{ .Values.cluster.name }}-pull-secret 5 | namespace: {{ .Values.cluster.name }} 6 | annotations: 7 | argocd.argoproj.io/sync-wave: '0' 8 | spec: 9 | refreshInterval: 1h 10 | secretStoreRef: 11 | kind: ClusterSecretStore 12 | name: vault 13 | target: 14 | name: {{ .Values.cluster.name }}-pull-secret 15 | creationPolicy: Owner 16 | dataFrom: 17 | - extract: 18 | key: {{ .Values.cluster.pullSecretVault }} 19 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/cert-manager/clusterissuer.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.certManager.enabled }} 2 | apiVersion: cert-manager.io/v1 3 | kind: ClusterIssuer 4 | metadata: 5 | name: cluster-acme 6 | annotations: 7 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 8 | argocd.argoproj.io/sync-wave: "1" 9 | spec: 10 | acme: 11 | email: admin@signal9.gg 12 | privateKeySecretRef: 13 | name: acme-private-key 14 | server: {{ .Values.certManager.acmeBase }} 15 | solvers: 16 | {{ toYaml .Values.certManager.solvers | indent 6 }} 17 | {{ end }} 18 | -------------------------------------------------------------------------------- /ansible/roles/gitops_cluster_build/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for gitops_cluster_build 3 | # 4 | gitops_skip_push: false 5 | 6 | gitops_author_name: "Signal9 Ansible Automation" 7 | gitops_author_email: "aap@signal9.gg" 8 | 9 | # Can be changed to unprotect for certain delete workflows 10 | gitops_task: "build_or_destroy" 11 | 12 | cluster_special_feature: "" 13 | 14 | # When deleting a cluster, don't delete the spoke cluster gitops configs 15 | # This is useful for debugging and to avoid certain race 16 | # conditions on cluster deletion 17 | gitops_retain_cluster_configs: true 18 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/odf/default-sc.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.odfStorage.enabled .Values.odfStorage.external -}} 2 | kind: StorageClass 3 | apiVersion: storage.k8s.io/v1 4 | metadata: 5 | name: ocs-external-storagecluster-ceph-rbd 6 | annotations: 7 | argocd.argoproj.io/sync-wave: '3' 8 | argocd.argoproj.io/sync-options: ServerSideApply=true,Validate=false,SkipDryRunOnMissingResource=true 9 | storageclass.kubernetes.io/is-default-class: 'true' 10 | provisioner: openshift-storage.rbd.csi.ceph.com 11 | reclaimPolicy: Delete 12 | volumeBindingMode: Immediate 13 | {{- end -}} 14 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/rhacm-base/thanos-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: external-secrets.io/v1beta1 2 | kind: ExternalSecret 3 | metadata: 4 | name: thanos-object-storage 5 | namespace: open-cluster-management-observability 6 | annotations: 7 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 8 | argocd.argoproj.io/sync-wave: '1' 9 | spec: 10 | refreshInterval: 1h 11 | secretStoreRef: 12 | kind: ClusterSecretStore 13 | name: vault 14 | target: 15 | name: thanos-object-storage 16 | creationPolicy: Owner 17 | dataFrom: 18 | - extract: 19 | key: rhte-acm-thanos-config 20 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/aap-base/secret-key.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: external-secrets.io/v1beta1 2 | kind: ExternalSecret 3 | metadata: 4 | name: aap-secret-key 5 | namespace: aap 6 | annotations: 7 | argocd.argoproj.io/compare-options: IgnoreExtraneous 8 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 9 | argocd.argoproj.io/sync-wave: '1' 10 | spec: 11 | refreshInterval: 1h 12 | secretStoreRef: 13 | kind: ClusterSecretStore 14 | name: vault 15 | target: 16 | name: aap-secret-key 17 | creationPolicy: Owner 18 | dataFrom: 19 | - extract: 20 | key: rhte-aap-secret-key 21 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/aap-base/admin-password.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: external-secrets.io/v1beta1 2 | kind: ExternalSecret 3 | metadata: 4 | name: aap-admin-password 5 | namespace: aap 6 | annotations: 7 | argocd.argoproj.io/compare-options: IgnoreExtraneous 8 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 9 | argocd.argoproj.io/sync-wave: '1' 10 | spec: 11 | refreshInterval: 1h 12 | secretStoreRef: 13 | kind: ClusterSecretStore 14 | name: vault 15 | target: 16 | name: aap-admin-password 17 | creationPolicy: Owner 18 | dataFrom: 19 | - extract: 20 | key: rhte-aap-admin 21 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/rhacm-base/mch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: operator.open-cluster-management.io/v1 2 | kind: MultiClusterHub 3 | metadata: 4 | name: hub 5 | namespace: rhacm-hub 6 | annotations: 7 | argocd.argoproj.io/sync-wave: "2" 8 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 9 | spec: 10 | availabilityConfig: Basic 11 | ingress: 12 | sslCiphers: 13 | - ECDHE-ECDSA-AES256-GCM-SHA384 14 | - ECDHE-RSA-AES256-GCM-SHA384 15 | - ECDHE-ECDSA-CHACHA20-POLY1305 16 | - ECDHE-RSA-CHACHA20-POLY1305 17 | - ECDHE-ECDSA-AES128-GCM-SHA256 18 | - ECDHE-RSA-AES128-GCM-SHA256 19 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-mce-hub/live/mce/hive-imageset-app.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: hive-imagesets 5 | namespace: openshift-gitops 6 | annotations: 7 | argocd.argoproj.io/sync-wave: '3' 8 | spec: 9 | destination: 10 | namespace: openshift-gitops 11 | server: "https://kubernetes.default.svc" 12 | project: default 13 | syncPolicy: 14 | automated: {} 15 | source: 16 | repoURL: "https://github.com/stolostron/acm-hive-openshift-releases.git" 17 | path: "clusterImageSets/stable" 18 | targetRevision: "release-2.6" 19 | directory: 20 | recurse: true 21 | -------------------------------------------------------------------------------- /charts/mce-cluster-build/templates/install-config-vault.yaml: -------------------------------------------------------------------------------- 1 | {{- if eq .Values.provider.type "vSphere" -}} 2 | apiVersion: external-secrets.io/v1beta1 3 | kind: ExternalSecret 4 | metadata: 5 | name: {{ .Values.cluster.name }}-install-config 6 | namespace: {{ .Values.cluster.name }} 7 | annotations: 8 | argocd.argoproj.io/sync-wave: '0' 9 | spec: 10 | refreshInterval: 1h 11 | secretStoreRef: 12 | kind: ClusterSecretStore 13 | name: vault 14 | target: 15 | name: {{ .Values.cluster.name }}-install-config 16 | creationPolicy: Owner 17 | dataFrom: 18 | - extract: 19 | key: {{ .Values.provider.installConfigVault }} 20 | {{ end }} 21 | -------------------------------------------------------------------------------- /ansible/playbooks/testing/test_dns_records.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | gather_facts: false 3 | vars: 4 | cluster_platform: openstack 5 | cluster_name: dns-test 6 | internal_api_vip: 127.0.0.1 7 | internal_ingress_vip: 127.0.0.2 8 | external_api_vip: 127.0.0.3 9 | external_ingress_vip: 127.0.0.4 10 | tasks: 11 | - name: include resource_allocation role 12 | ansible.builtin.include_role: 13 | name: dns_config 14 | vars: 15 | cluster_state: present 16 | - name: include resource_allocation role 17 | ansible.builtin.include_role: 18 | name: dns_config 19 | vars: 20 | cluster_state: absent 21 | -------------------------------------------------------------------------------- /charts/mce-cluster-build/templates/provider-creds-vault.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.provider.providerCredsVault -}} 2 | apiVersion: external-secrets.io/v1beta1 3 | kind: ExternalSecret 4 | metadata: 5 | name: {{ .Values.cluster.name }}-provider-creds 6 | namespace: {{ .Values.cluster.name }} 7 | annotations: 8 | argocd.argoproj.io/sync-wave: '0' 9 | spec: 10 | refreshInterval: 1h 11 | secretStoreRef: 12 | kind: ClusterSecretStore 13 | name: vault 14 | target: 15 | name: {{ .Values.cluster.name }}-provider-creds 16 | creationPolicy: Owner 17 | dataFrom: 18 | - extract: 19 | key: {{ .Values.provider.providerCredsVault }} 20 | {{- end -}} 21 | -------------------------------------------------------------------------------- /ansible/playbooks/testing/test_sso_config.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | gather_facts: false 3 | vars: 4 | cluster_platform: openstack 5 | cluster_name: gitops-test-1 6 | cluster_size: small 7 | openstack_platform_config: "{{ platform_configs['openstack'] }}" 8 | cluster_protected: false 9 | cluster_image_set: img4.12.0-x86-64-appsub 10 | tasks: 11 | - name: include vault_config 12 | ansible.builtin.include_role: 13 | name: sso_client 14 | vars: 15 | cluster_state: present 16 | - name: include vault_config 17 | ansible.builtin.include_role: 18 | name: sso_client 19 | vars: 20 | cluster_state: absent 21 | -------------------------------------------------------------------------------- /ansible/playbooks/testing/test_vault_config.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | gather_facts: false 3 | vars: 4 | cluster_platform: openstack 5 | cluster_name: gitops-test-1 6 | cluster_size: small 7 | openstack_platform_config: "{{ platform_configs['openstack'] }}" 8 | cluster_protected: false 9 | cluster_image_set: img4.12.0-x86-64-appsub 10 | tasks: 11 | - name: include vault_config 12 | ansible.builtin.include_role: 13 | name: vault_config 14 | vars: 15 | cluster_state: present 16 | - name: include vault_config 17 | ansible.builtin.include_role: 18 | name: vault_config 19 | vars: 20 | cluster_state: absent 21 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/rhacm-base/mco-pull-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: external-secrets.io/v1beta1 2 | kind: ExternalSecret 3 | metadata: 4 | name: multiclusterhub-operator-pull-secret 5 | namespace: open-cluster-management-observability 6 | spec: 7 | refreshInterval: 1h 8 | secretStoreRef: 9 | kind: ClusterSecretStore 10 | name: vault 11 | target: 12 | name: multiclusterhub-operator-pull-secret 13 | template: 14 | type: kubernetes.io/dockerconfigjson 15 | data: 16 | .dockerconfigjson: "{{ .pullsecret | toString }}" 17 | creationPolicy: Owner 18 | data: 19 | - secretKey: pullsecret 20 | remoteRef: 21 | key: 'ocp-pull-secret' 22 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/rhacm-base/rhacm-operator.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: rhacm-hub 6 | spec: {} 7 | --- 8 | apiVersion: operators.coreos.com/v1 9 | kind: OperatorGroup 10 | metadata: 11 | name: rhacm-group 12 | namespace: rhacm-hub 13 | spec: 14 | targetNamespaces: 15 | - rhacm-hub 16 | --- 17 | apiVersion: operators.coreos.com/v1alpha1 18 | kind: Subscription 19 | metadata: 20 | name: acm-operator-subscription 21 | namespace: rhacm-hub 22 | spec: 23 | sourceNamespace: openshift-marketplace 24 | source: redhat-operators 25 | channel: release-2.6 26 | installPlanApproval: Automatic 27 | name: advanced-cluster-management 28 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-mce-hub/live/mce/agent-service-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: agent-install.openshift.io/v1beta1 2 | kind: AgentServiceConfig 3 | metadata: 4 | name: agent 5 | annotations: 6 | argocd.argoproj.io/sync-wave: '3' 7 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 8 | spec: 9 | databaseStorage: 10 | accessModes: 11 | - ReadWriteOnce 12 | resources: 13 | requests: 14 | storage: 50Gi 15 | filesystemStorage: 16 | accessModes: 17 | - ReadWriteOnce 18 | resources: 19 | requests: 20 | storage: 100Gi 21 | imageStorage: 22 | accessModes: 23 | - ReadWriteOnce 24 | resources: 25 | requests: 26 | storage: 100Gi 27 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/cert-manager/cert-manager-config.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.certManager.enabled -}} 2 | apiVersion: operator.openshift.io/v1alpha1 3 | kind: CertManager 4 | metadata: 5 | name: cluster 6 | annotations: 7 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 8 | argocd.argoproj.io/sync-wave: "0" 9 | spec: 10 | managementState: "Managed" 11 | unsupportedConfigOverrides: 12 | controller: 13 | args: 14 | - '--v=2' 15 | - '--cluster-resource-namespace=$(POD_NAMESPACE)' 16 | - '--leader-election-namespace=kube-system' 17 | - '--dns01-recursive-nameservers=8.8.8.8:53' 18 | - '--dns01-recursive-nameservers-only' 19 | {{ end }} 20 | -------------------------------------------------------------------------------- /ansible/roles/gitops_cluster_build/templates/base-config-app.yaml.j2: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: base-config-chart 5 | namespace: openshift-gitops 6 | spec: 7 | destination: 8 | namespace: openshift-gitops 9 | server: "https://kubernetes.default.svc" 10 | project: default 11 | syncPolicy: 12 | automated: {} 13 | retry: 14 | backoff: 15 | maxDuration: 1m 16 | limit: -1 17 | source: 18 | repoURL: "{{ gitops_repo_url }}" 19 | path: "charts/ocp-base-config" 20 | targetRevision: HEAD 21 | helm: 22 | valueFiles: 23 | - "../../argocd/clusters/managed-clusters/{{ cluster_name }}/helm-values/base-config-values.yaml" 24 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-mce-hub/live/mce/subscription.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: operators.coreos.com/v1 3 | kind: OperatorGroup 4 | metadata: 5 | name: mce-hub-group 6 | namespace: multicluster-engine 7 | annotations: 8 | argocd.argoproj.io/sync-wave: '1' 9 | spec: 10 | targetNamespaces: 11 | - multicluster-engine 12 | --- 13 | apiVersion: operators.coreos.com/v1alpha1 14 | kind: Subscription 15 | metadata: 16 | name: multicluster-engine 17 | namespace: multicluster-engine 18 | annotations: 19 | argocd.argoproj.io/sync-wave: '1' 20 | spec: 21 | sourceNamespace: openshift-marketplace 22 | source: redhat-operators 23 | channel: stable-2.2 24 | installPlanApproval: Automatic 25 | name: multicluster-engine 26 | 27 | -------------------------------------------------------------------------------- /argocd/install-gitops.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: operators.coreos.com/v1alpha1 3 | kind: Subscription 4 | metadata: 5 | name: openshift-gitops-operator 6 | namespace: openshift-operators 7 | spec: 8 | channel: gitops-1.7 9 | installPlanApproval: Automatic 10 | name: openshift-gitops-operator 11 | source: redhat-operators 12 | sourceNamespace: openshift-marketplace 13 | --- 14 | kind: ClusterRoleBinding 15 | apiVersion: rbac.authorization.k8s.io/v1 16 | metadata: 17 | name: gitops-cluster-admin 18 | subjects: 19 | - kind: ServiceAccount 20 | name: openshift-gitops-argocd-application-controller 21 | namespace: openshift-gitops 22 | roleRef: 23 | apiGroup: rbac.authorization.k8s.io 24 | kind: ClusterRole 25 | name: cluster-admin 26 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/monitoring/cluster-monitoring-config.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.monitoring.enabled -}} 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: cluster-monitoring-config 6 | namespace: openshift-monitoring 7 | data: 8 | config.yaml: | 9 | alertmanagerMain: 10 | volumeClaimTemplate: 11 | spec: 12 | storageClassName: {{ .Values.monitoring.storageClass }} 13 | resources: 14 | requests: 15 | storage: 10Gi 16 | prometheusK8s: 17 | retention: 7d 18 | volumeClaimTemplate: 19 | spec: 20 | storageClassName: {{ .Values.monitoring.storageClass }} 21 | resources: 22 | requests: 23 | storage: 50Gi 24 | {{ end }} 25 | -------------------------------------------------------------------------------- /argocd/clusters/managed-clusters/demo-feb9/live/base-configs/base-config-app.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: base-config-chart 5 | namespace: openshift-gitops 6 | spec: 7 | destination: 8 | namespace: openshift-gitops 9 | server: "https://kubernetes.default.svc" 10 | project: default 11 | syncPolicy: 12 | automated: {} 13 | retry: 14 | backoff: 15 | maxDuration: 1m 16 | limit: -1 17 | source: 18 | repoURL: "https://github.com/marbindrakon/signal9-lab-gitops.git" 19 | path: "charts/ocp-base-config" 20 | targetRevision: HEAD 21 | helm: 22 | valueFiles: 23 | - "../../argocd/clusters/managed-clusters/demo-feb9/helm-values/base-config-values.yaml" 24 | -------------------------------------------------------------------------------- /argocd/clusters/managed-clusters/demo-jun1/live/base-configs/base-config-app.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: base-config-chart 5 | namespace: openshift-gitops 6 | spec: 7 | destination: 8 | namespace: openshift-gitops 9 | server: "https://kubernetes.default.svc" 10 | project: default 11 | syncPolicy: 12 | automated: {} 13 | retry: 14 | backoff: 15 | maxDuration: 1m 16 | limit: -1 17 | source: 18 | repoURL: "https://github.com/marbindrakon/fleet-gitops-example.git" 19 | path: "charts/ocp-base-config" 20 | targetRevision: HEAD 21 | helm: 22 | valueFiles: 23 | - "../../argocd/clusters/managed-clusters/demo-jun1/helm-values/base-config-values.yaml" 24 | -------------------------------------------------------------------------------- /argocd/clusters/managed-clusters/demo-jun2/live/base-configs/base-config-app.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: base-config-chart 5 | namespace: openshift-gitops 6 | spec: 7 | destination: 8 | namespace: openshift-gitops 9 | server: "https://kubernetes.default.svc" 10 | project: default 11 | syncPolicy: 12 | automated: {} 13 | retry: 14 | backoff: 15 | maxDuration: 1m 16 | limit: -1 17 | source: 18 | repoURL: "https://github.com/marbindrakon/fleet-gitops-example.git" 19 | path: "charts/ocp-base-config" 20 | targetRevision: HEAD 21 | helm: 22 | valueFiles: 23 | - "../../argocd/clusters/managed-clusters/demo-jun2/helm-values/base-config-values.yaml" 24 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/timesync/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{- define "ocp-base-config.ptpKvmModprobe" -}} 2 | # Enable PTP KVM driver 3 | ptp_kvm 4 | {{- end -}} 5 | {{- define "ocp-base-config.chronyConfigData" -}} 6 | {{- if .Values.timesync.ptp.enabled -}} 7 | refclock PHC /dev/{{ .Values.timesync.ptp.device }} poll 3 dpoll -2 offset 0 stratum {{ .Values.timesync.ptp.sourceStratum }} 8 | {{ end }} 9 | {{ range .Values.timesync.ntpServers }} 10 | server {{ . }} iburst 11 | {{ end }} 12 | stratumweight 0 13 | driftfile /var/lib/chrony/drift 14 | rtcsync 15 | makestep 10 3 16 | bindcmdaddress 127.0.0.1 17 | bindcmdaddress ::1 18 | keyfile /etc/chrony.keys 19 | commandkey 1 20 | generatecommandkey 21 | noclientlog 22 | logchange 0.5 23 | logdir /var/log/chrony 24 | {{- end -}} 25 | -------------------------------------------------------------------------------- /ansible/playbooks/testing/test_gitops_create.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | gather_facts: false 3 | vars: 4 | cluster_platform: openstack 5 | cluster_name: gitops-test-1 6 | cluster_size: small 7 | cluster_state: present 8 | openstack_platform_config: "{{ platform_configs['openstack'] }}" 9 | cluster_protected: false 10 | cluster_image_set: img4.12.0-x86-64-appsub 11 | tasks: 12 | - name: include resource_allocation role 13 | ansible.builtin.include_role: 14 | name: resource_allocation 15 | 16 | - name: include dns role 17 | ansible.builtin.include_role: 18 | name: dns_config 19 | 20 | - name: include gitops_cluster_build role 21 | ansible.builtin.include_role: 22 | name: gitops_cluster_build 23 | -------------------------------------------------------------------------------- /ansible/playbooks/testing/test_gitops_destroy.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | gather_facts: false 3 | vars: 4 | cluster_platform: openstack 5 | cluster_name: gitops-test-1 6 | cluster_size: sandbox 7 | cluster_state: absent 8 | openstack_platform_config: "{{ platform_configs['openstack'] }}" 9 | cluster_protected: false 10 | cluster_image_set: img4.12.0-x86-64-appsub 11 | tasks: 12 | - name: include gitops_cluster_build role 13 | ansible.builtin.include_role: 14 | name: gitops_cluster_build 15 | 16 | - name: include resource_allocation role 17 | ansible.builtin.include_role: 18 | name: resource_allocation 19 | 20 | - name: include dns role 21 | ansible.builtin.include_role: 22 | name: dns_config 23 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/aap-base/rbac.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | kind: ClusterRole 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | metadata: 5 | name: aap-token-review 6 | rules: 7 | - verbs: 8 | - create 9 | apiGroups: 10 | - authentication.k8s.io 11 | resources: 12 | - tokenreviews 13 | - verbs: 14 | - create 15 | apiGroups: 16 | - authorization.k8s.io 17 | resources: 18 | - subjectaccessreviews 19 | --- 20 | kind: ClusterRoleBinding 21 | apiVersion: rbac.authorization.k8s.io/v1 22 | metadata: 23 | name: aap-token-review 24 | subjects: 25 | - kind: ServiceAccount 26 | name: acm-hub-aap 27 | namespace: aap 28 | roleRef: 29 | apiGroup: rbac.authorization.k8s.io 30 | kind: ClusterRole 31 | name: aap-token-review 32 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/cert-manager/external-secret.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.certManager.enabled .Values.certManager.externalSecret -}} 2 | apiVersion: external-secrets.io/v1beta1 3 | kind: ExternalSecret 4 | metadata: 5 | name: {{ .Values.certManager.externalSecret.name }} 6 | namespace: cert-manager 7 | annotations: 8 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 9 | argocd.argoproj.io/sync-wave: '1' 10 | spec: 11 | refreshInterval: 1h 12 | secretStoreRef: 13 | kind: ClusterSecretStore 14 | name: vault 15 | target: 16 | name: {{ .Values.certManager.externalSecret.name }} 17 | creationPolicy: Owner 18 | dataFrom: 19 | - extract: 20 | key: {{ .Values.certManager.externalSecret.vaultName }} 21 | {{ end }} 22 | -------------------------------------------------------------------------------- /charts/mce-cluster-build/templates/klusterlet-config.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.cluster.useACM -}} 2 | apiVersion: agent.open-cluster-management.io/v1 3 | kind: KlusterletAddonConfig 4 | metadata: 5 | name: {{ .Values.cluster.name }} 6 | namespace: {{ .Values.cluster.name }} 7 | annotations: 8 | argocd.argoproj.io/sync-wave: '1' 9 | spec: 10 | clusterName: {{ .Values.cluster.name }} 11 | clusterNamespace: {{ .Values.cluster.name }} 12 | clusterLabels: 13 | cloud: {{ .Values.provider.type }} 14 | vendor: OpenShift 15 | applicationManager: 16 | enabled: true 17 | policyController: 18 | enabled: true 19 | searchCollector: 20 | enabled: true 21 | certPolicyController: 22 | enabled: true 23 | iamPolicyController: 24 | enabled: true 25 | {{ end }} 26 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/auth/external-secret.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.auth.enabled .Values.auth.externalSecret -}} 2 | apiVersion: external-secrets.io/v1beta1 3 | kind: ExternalSecret 4 | metadata: 5 | name: {{ .Values.auth.externalSecret.name }} 6 | namespace: openshift-config 7 | annotations: 8 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 9 | argocd.argoproj.io/compare-options: IgnoreExtraneous 10 | argocd.argoproj.io/sync-wave: '1' 11 | spec: 12 | refreshInterval: 1h 13 | secretStoreRef: 14 | kind: ClusterSecretStore 15 | name: vault 16 | target: 17 | name: {{ .Values.auth.externalSecret.name }} 18 | creationPolicy: Owner 19 | dataFrom: 20 | - extract: 21 | key: {{ .Values.auth.externalSecret.vaultName }} 22 | {{ end }} 23 | -------------------------------------------------------------------------------- /ansible/roles/dns_config/tasks/providers/route53.yml: -------------------------------------------------------------------------------- 1 | - name: handle internal records 2 | amazon.aws.route53: 3 | state: "{{ cluster_state }}" 4 | zone: "{{ base_domain }}" 5 | record: "{{ item[0] }}.{{ base_domain }}" 6 | value: "{{ item[1] }}" 7 | type: A 8 | ttl: 1200 9 | loop: "{{ dns_internal_records }}" 10 | when: (not dns_split_horizon|bool) or dns_provider.value.split_horizon_internal|bool 11 | 12 | - name: handle external records 13 | amazon.aws.route53: 14 | state: "{{ cluster_state }}" 15 | zone: "{{ base_domain }}" 16 | record: "{{ item[0] }}.{{ base_domain }}" 17 | value: "{{ item[1] }}" 18 | type: A 19 | ttl: 1200 20 | loop: "{{ dns_external_records }}" 21 | when: dns_split_horizon|bool and (not dns_provider.value.split_horizon_internal|bool) 22 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/odf/external-secret.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.odfStorage.external .Values.odfStorage.externalSecret -}} 2 | apiVersion: external-secrets.io/v1beta1 3 | kind: ExternalSecret 4 | metadata: 5 | name: {{ .Values.odfStorage.externalSecret.name }} 6 | namespace: openshift-storage 7 | annotations: 8 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 9 | argocd.argoproj.io/compare-options: IgnoreExtraneous 10 | argocd.argoproj.io/sync-wave: '1' 11 | spec: 12 | refreshInterval: 1h 13 | secretStoreRef: 14 | kind: ClusterSecretStore 15 | name: vault 16 | target: 17 | name: {{ .Values.odfStorage.externalSecret.name }} 18 | creationPolicy: Orphan 19 | dataFrom: 20 | - extract: 21 | key: {{ .Values.odfStorage.externalSecret.vaultName }} 22 | {{- end -}} 23 | -------------------------------------------------------------------------------- /argocd/clusters/managed-clusters/demo-feb9/live/virt/operator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: openshift-cnv 5 | annotations: 6 | argocd.argoproj.io/sync-wave: "0" 7 | --- 8 | apiVersion: operators.coreos.com/v1 9 | kind: OperatorGroup 10 | metadata: 11 | name: kubevirt-hyperconverged-group 12 | namespace: openshift-cnv 13 | annotations: 14 | argocd.argoproj.io/sync-wave: "1" 15 | spec: 16 | targetNamespaces: 17 | - openshift-cnv 18 | --- 19 | apiVersion: operators.coreos.com/v1alpha1 20 | kind: Subscription 21 | metadata: 22 | name: hco-operatorhub 23 | namespace: openshift-cnv 24 | annotations: 25 | argocd.argoproj.io/sync-wave: "2" 26 | spec: 27 | source: redhat-operators 28 | sourceNamespace: openshift-marketplace 29 | name: kubevirt-hyperconverged 30 | channel: "stable" 31 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/external-secrets/cluster-issuer.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.externalSecrets.enabled -}} 2 | apiVersion: external-secrets.io/v1beta1 3 | kind: ClusterSecretStore 4 | metadata: 5 | name: vault 6 | annotations: 7 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 8 | argocd.argoproj.io/sync-wave: '1' 9 | spec: 10 | provider: 11 | vault: 12 | server: {{ .Values.externalSecrets.vaultBase }} 13 | path: {{ .Values.externalSecrets.secretBasePath }} 14 | version: "v2" 15 | auth: 16 | kubernetes: 17 | mountPath: {{ .Values.externalSecrets.vaultAuthPath }} 18 | role: "external-secrets-operator" 19 | serviceAccountRef: 20 | name: "external-secrets-operator" 21 | namespace: "external-secrets-operator" 22 | {{ end }} 23 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/auth/oauth-config.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.auth.enabled .Values.auth.externalSecret -}} 2 | apiVersion: config.openshift.io/v1 3 | kind: OAuth 4 | metadata: 5 | name: cluster 6 | annotations: 7 | argocd.argoproj.io/sync-wave: '1' 8 | spec: 9 | identityProviders: 10 | - mappingMethod: claim 11 | name: {{ .Values.auth.oidcDisplayName }} 12 | openID: 13 | claims: 14 | email: 15 | - email 16 | name: 17 | - name 18 | preferredUsername: 19 | - preferred_username 20 | - email 21 | groups: 22 | - groups 23 | clientID: {{ .Values.auth.oidcClientID }} 24 | clientSecret: 25 | name: {{ .Values.auth.externalSecret.name }} 26 | extraScopes: ["profile"] 27 | issuer: {{ .Values.auth.oidcIssuer }} 28 | type: OpenID 29 | {{ end }} 30 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/cluster-builds/demo-feb9.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: demo-feb9-deploy 5 | namespace: openshift-gitops 6 | finalizers: 7 | - resources-finalizer.argocd.argoproj.io 8 | spec: 9 | destination: 10 | namespace: openshift-gitops 11 | server: "https://kubernetes.default.svc" 12 | ignoreDifferences: 13 | - group: hive.openshift.io 14 | kind: ClusterDeployment 15 | jsonPointers: 16 | - /spec/installed 17 | project: default 18 | syncPolicy: 19 | automated: {} 20 | source: 21 | repoURL: "https://github.com/marbindrakon/signal9-lab-gitops.git" 22 | path: "charts/mce-cluster-build" 23 | targetRevision: HEAD 24 | helm: 25 | valueFiles: 26 | - "../../argocd/clusters/managed-clusters/demo-feb9/helm-values/build-values.yaml" 27 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/cert-manager/api-cert.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.certManager.enabled .Values.certManager.apiCert -}} 2 | apiVersion: cert-manager.io/v1 3 | kind: Certificate 4 | metadata: 5 | name: api-certificate 6 | namespace: openshift-config 7 | annotations: 8 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 9 | argocd.argoproj.io/sync-wave: "2" 10 | spec: 11 | secretName: acme-api 12 | duration: 2160h0m0s # 90d 13 | renewBefore: 360h0m0s # 15d 14 | subject: 15 | organizations: 16 | - "Signal9 Labs" 17 | privateKey: 18 | size: 4096 19 | algorithm: RSA 20 | encoding: PKCS1 21 | rotationPolicy: Always 22 | usages: 23 | - server auth 24 | - client auth 25 | dnsNames: 26 | - "api.{{ .Values.cluster.name }}.{{ .Values.cluster.baseDomain }}" 27 | issuerRef: 28 | name: cluster-acme 29 | kind: ClusterIssuer 30 | {{ end }} 31 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/cert-manager/apps-cert.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.certManager.enabled .Values.certManager.defaultIngressCert -}} 2 | apiVersion: cert-manager.io/v1 3 | kind: Certificate 4 | metadata: 5 | name: apps-certificate 6 | namespace: openshift-ingress 7 | annotations: 8 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 9 | argocd.argoproj.io/sync-wave: "2" 10 | spec: 11 | secretName: acme-apps 12 | duration: 2160h0m0s # 90d 13 | renewBefore: 360h0m0s # 15d 14 | subject: 15 | organizations: 16 | - "Signal9 Labs" 17 | privateKey: 18 | size: 4096 19 | algorithm: RSA 20 | encoding: PKCS1 21 | rotationPolicy: Always 22 | usages: 23 | - server auth 24 | - client auth 25 | dnsNames: 26 | - "*.apps.{{ .Values.cluster.name }}.{{ .Values.cluster.baseDomain }}" 27 | issuerRef: 28 | name: cluster-acme 29 | kind: ClusterIssuer 30 | {{ end }} 31 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/external-secrets/rbac.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.externalSecrets.enabled -}} 2 | --- 3 | kind: ClusterRole 4 | apiVersion: rbac.authorization.k8s.io/v1 5 | metadata: 6 | name: external-secrets-operator-token-review 7 | rules: 8 | - verbs: 9 | - create 10 | apiGroups: 11 | - authentication.k8s.io 12 | resources: 13 | - tokenreviews 14 | - verbs: 15 | - create 16 | apiGroups: 17 | - authorization.k8s.io 18 | resources: 19 | - subjectaccessreviews 20 | --- 21 | kind: ClusterRoleBinding 22 | apiVersion: rbac.authorization.k8s.io/v1 23 | metadata: 24 | name: external-secrets-operator-token-review 25 | subjects: 26 | - kind: ServiceAccount 27 | name: external-secrets-operator 28 | namespace: external-secrets-operator 29 | roleRef: 30 | apiGroup: rbac.authorization.k8s.io 31 | kind: ClusterRole 32 | name: external-secrets-operator-token-review 33 | {{ end }} 34 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/timesync/master-chrony-config.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.timesync.enabled -}} 2 | apiVersion: machineconfiguration.openshift.io/v1 3 | kind: MachineConfig 4 | metadata: 5 | labels: 6 | machineconfiguration.openshift.io/role: master 7 | name: 99-master-chrony-conf-override 8 | spec: 9 | config: 10 | ignition: 11 | version: 3.2.0 12 | storage: 13 | files: 14 | {{ if .Values.timesync.ptp.loadKvmModule }} 15 | - contents: 16 | source: data:text/plain;charset=utf-8;base64,{{ include "ocp-base-config.ptpKvmModprobe" . | b64enc }} 17 | mode: 420 18 | overwrite: true 19 | path: /etc/modules-load.d/ptp_kvm.conf 20 | {{ end }} 21 | - contents: 22 | source: data:text/plain;charset=utf-8;base64,{{ include "ocp-base-config.chronyConfigData" . | b64enc }} 23 | mode: 420 24 | overwrite: true 25 | path: /etc/chrony.conf 26 | {{- end -}} 27 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/timesync/worker-chrony-config.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.timesync.enabled -}} 2 | apiVersion: machineconfiguration.openshift.io/v1 3 | kind: MachineConfig 4 | metadata: 5 | labels: 6 | machineconfiguration.openshift.io/role: worker 7 | name: 99-worker-chrony-conf-override 8 | spec: 9 | config: 10 | ignition: 11 | version: 3.2.0 12 | storage: 13 | files: 14 | {{ if .Values.timesync.ptp.loadKvmModule }} 15 | - contents: 16 | source: data:text/plain;charset=utf-8;base64,{{ include "ocp-base-config.ptpKvmModprobe" . | b64enc }} 17 | mode: 420 18 | overwrite: true 19 | path: /etc/modules-load.d/ptp_kvm.conf 20 | {{ end }} 21 | - contents: 22 | source: data:text/plain;charset=utf-8;base64,{{ include "ocp-base-config.chronyConfigData" . | b64enc }} 23 | mode: 420 24 | overwrite: true 25 | path: /etc/chrony.conf 26 | {{- end -}} 27 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/gitops/cluster-argocd-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: ArgoCD 3 | metadata: 4 | name: openshift-gitops 5 | namespace: openshift-gitops 6 | annotations: 7 | argocd.argoproj.io/sync-options: ServerSideApply=true,Validate=false 8 | spec: 9 | resourceExclusions: | 10 | - apiGroups: 11 | - tekton.dev 12 | clusters: 13 | - '*' 14 | kinds: 15 | - TaskRun 16 | - PipelineRun 17 | - apiGroups: 18 | - internal.open-cluster-management.io 19 | clusters: 20 | - '*' 21 | kinds: 22 | - ManagedClusterInfo 23 | rbac: 24 | policy: | 25 | g, system:cluster-admins, role:admin 26 | g, cluster-admins, role:admin 27 | g, global-admins, role:admin 28 | scopes: '[groups]' 29 | server: 30 | insecure: true 31 | route: 32 | enabled: true 33 | tls: 34 | termination: edge 35 | insecureEdgeTerminationPolicy: Redirect 36 | -------------------------------------------------------------------------------- /ansible/roles/resource_allocation/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # cluster_platform must be set to openstack or infra_env_hybrid when using the main.yml entrypoint 3 | cluster_platform: "" 4 | cluster_name: "" 5 | # cluster_state should be present or absent 6 | cluster_state: present 7 | 8 | openstack_platform_config: 9 | # The external network where Floating IPs will be allocated 10 | vip_network: "" 11 | 12 | vsphere_platform_config: 13 | node_prefix: "" 14 | 15 | infra_env_hybrid_config: 16 | # Search for baremetal nodes in Netbox will be limited to this tag 17 | netbox_pool_tag: "openshift-pool" 18 | # Prefix for netbox tag applied to cluster nodes 19 | netbox_cluster_tag_prefix: "ocp-cluster-" 20 | # IP Prefixes in CIDR notation for allocating VIP and Node IPs in Netbox 21 | vip_prefix: "" 22 | node_prefix: "" 23 | storage_prefix: "" 24 | # Storage IPs will be allocated for any interface name appearing in this list 25 | storage_interface_names: [] 26 | -------------------------------------------------------------------------------- /ansible/roles/gitops_cluster_build/templates/cluster-deploy-app.yaml.j2: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: {{ cluster_name }}-deploy 5 | namespace: openshift-gitops 6 | {% if cluster_protected == False or gitops_task == "unprotect" %} 7 | finalizers: 8 | - resources-finalizer.argocd.argoproj.io 9 | {% endif %} 10 | spec: 11 | destination: 12 | namespace: openshift-gitops 13 | server: "https://kubernetes.default.svc" 14 | ignoreDifferences: 15 | - group: hive.openshift.io 16 | kind: ClusterDeployment 17 | jsonPointers: 18 | - /spec/installed 19 | project: default 20 | syncPolicy: 21 | automated: {} 22 | syncOptions: 23 | - RespectIgnoreDifferences=true 24 | source: 25 | repoURL: "{{ gitops_repo_url }}" 26 | path: "charts/mce-cluster-build" 27 | targetRevision: HEAD 28 | helm: 29 | valueFiles: 30 | - "../../argocd/clusters/managed-clusters/{{ cluster_name }}/helm-values/build-values.yaml" 31 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/odf/operator.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.odfStorage.enabled -}} 2 | --- 3 | apiVersion: v1 4 | kind: Namespace 5 | metadata: 6 | annotations: 7 | argocd.argoproj.io/sync-wave: '-1' 8 | labels: 9 | openshift.io/cluster-monitoring: "true" 10 | name: openshift-storage 11 | spec: {} 12 | --- 13 | apiVersion: operators.coreos.com/v1 14 | kind: OperatorGroup 15 | metadata: 16 | name: openshift-storage-operatorgroup 17 | namespace: openshift-storage 18 | annotations: 19 | argocd.argoproj.io/sync-wave: '0' 20 | spec: 21 | targetNamespaces: 22 | - openshift-storage 23 | --- 24 | apiVersion: operators.coreos.com/v1alpha1 25 | kind: Subscription 26 | metadata: 27 | name: odf-operator 28 | namespace: openshift-storage 29 | annotations: 30 | argocd.argoproj.io/sync-wave: '0' 31 | spec: 32 | channel: "stable-{{ .Values.odfStorage.version }}" 33 | installPlanApproval: Automatic 34 | name: odf-operator 35 | source: redhat-operators 36 | sourceNamespace: openshift-marketplace 37 | {{- end -}} 38 | -------------------------------------------------------------------------------- /ansible/roles/resource_allocation/README.md: -------------------------------------------------------------------------------- 1 | resource_allocation 2 | ========= 3 | 4 | This role encapsulates the resource allocation logic for OpenShift cluster provisioning. It is not intended to be reusable outside of this context. 5 | 6 | Depending on the target platform, this role will perform the following actions: 7 | 8 | * Allocate IP addresses from Netbox 9 | * Reserve baremetal nodes in Netbox 10 | * Allocate floating IP addresses in OpenStack 11 | 12 | Requirements 13 | ------------ 14 | 15 | This role requires the following collections and their Python dependencies: 16 | 17 | * openstack.cloud 18 | * netbox.netbox 19 | 20 | Role Variables 21 | -------------- 22 | 23 | A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. 24 | 25 | 26 | License 27 | ------- 28 | 29 | Apache 2.0 30 | -------------------------------------------------------------------------------- /ansible/playbooks/undeploy_cluster.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | gather_facts: false 3 | vars: 4 | cluster_state: absent 5 | tasks: 6 | - name: set platform config fact 7 | ansible.builtin.set_fact: 8 | "{{ cluster_platform }}_platform_config": "{{ platform_configs[cluster_platform] }}" 9 | 10 | - name: include vault_config role 11 | ansible.builtin.include_role: 12 | name: vault_config 13 | 14 | - name: include gitops_cluster_build role 15 | ansible.builtin.include_role: 16 | name: gitops_cluster_build 17 | 18 | - name: include sso_client role 19 | ansible.builtin.include_role: 20 | name: sso_client 21 | 22 | - name: include resource_allocation role 23 | ansible.builtin.include_role: 24 | name: resource_allocation 25 | 26 | - name: include dns role 27 | ansible.builtin.include_role: 28 | name: dns_config 29 | 30 | - hosts: loadbalancers 31 | gather_facts: true 32 | become: true 33 | vars: 34 | cluster_state: absent 35 | tasks: 36 | - name: include lb_config role 37 | ansible.builtin.include_role: 38 | name: lb_config 39 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/gitops/application-set.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: ApplicationSet 3 | metadata: 4 | name: cluster-configs 5 | namespace: openshift-gitops 6 | annotations: 7 | argocd.argoproj.io/sync-wave: '10' 8 | spec: 9 | generators: 10 | - git: 11 | repoURL: "{{ .Values.cluster.gitOpsRepo }}" 12 | revision: HEAD 13 | directories: 14 | - path: "{{ .Values.cluster.gitOpsBasePath }}/{{ .Values.cluster.name }}/live/*" 15 | - path: "{{ .Values.cluster.gitOpsBasePath }}/{{ .Values.cluster.name }}/live/base-configs" 16 | exclude: true 17 | template: 18 | metadata: 19 | name: '{{ "{{ path.basename }}" }}' 20 | finalizers: 21 | - resources-finalizer.argocd.argoproj.io 22 | spec: 23 | project: default 24 | syncPolicy: 25 | automated: 26 | prune: true 27 | allowEmpty: true 28 | destination: 29 | namespace: openshift-gitops 30 | server: "https://kubernetes.default.svc" 31 | source: 32 | repoURL: "{{ .Values.cluster.gitOpsRepo }}" 33 | targetRevision: HEAD 34 | path: '{{ "{{ path }}" }}' 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Deploying On-Prem OpenShift Fleets: From In-Box Tools to Zero-Touch with ACM and AAP 2 | 3 | This repository contains the demo code used for the talk *Deploying On-Prem 4 | OpenShift Fleets: From In-Box Tools to Zero-Touch with ACM and AAP* given at 5 | North America Tech Exchange 2023, an internal conference for Red Hat services 6 | associates and partners. The repository contains only public information. 7 | 8 | ## What's in the repo? 9 | 10 | The repo contains GitOps configurations and Helm charts that demonstrate 11 | deploying OpenShift Container Platform clusters through GitOps processes 12 | using OpenShift GitOps and the Multicluster Engine operator. 13 | 14 | The repo also contains further GitOps configuration and Ansible automation code 15 | for a further demo of an end-to-end automated process for self-service cluster 16 | provisioning driven by Red Hat Ansible Automation Platform (AAP) and Advanced 17 | Cluster Management for Kubernetes (ACM). 18 | 19 | ## Legal Stuff 20 | 21 | All protectable content in this repository is Copyright 2023 by Red Hat and is 22 | made available under the Apache License, Version 2.0. A complete copy of the 23 | license is available in the LICENSE file. 24 | -------------------------------------------------------------------------------- /ansible/roles/dns_config/tasks/providers/freeipa.yml: -------------------------------------------------------------------------------- 1 | - name: handle internal records 2 | freeipa.ansible_freeipa.ipadnsrecord: 3 | ipaadmin_principal: "{{ ipaadmin_principal }}" 4 | ipaadmin_password: "{{ ipaadmin_password | default(omit) }}" 5 | state: "{{ cluster_state }}" 6 | zone_name: "{{ base_domain }}" 7 | name: "{{ item[0] }}" 8 | record_value: "{{ item[1] }}" 9 | record_type: A 10 | record_ttl: 1200 11 | loop: "{{ dns_internal_records }}" 12 | when: (not dns_split_horizon|bool) or dns_provider.value.split_horizon_internal|bool 13 | delegate_to: "{{ groups['ipaservers'][0] }}" 14 | 15 | - name: handle external records 16 | freeipa.ansible_freeipa.ipadnsrecord: 17 | ipaadmin_principal: "{{ ipaadmin_principal }}" 18 | ipaadmin_password: "{{ ipaadmin_password | default(omit) }}" 19 | state: "{{ cluster_state }}" 20 | zone_name: "{{ base_domain }}" 21 | name: "{{ item[0] }}" 22 | record_value: "{{ item[1] }}" 23 | record_type: A 24 | record_ttl: 1200 25 | loop: "{{ dns_external_records }}" 26 | when: dns_split_horizon|bool and (not dns_provider.value.split_horizon_internal|bool) 27 | delegate_to: "{{ groups['ipaservers'][0] }}" 28 | -------------------------------------------------------------------------------- /ansible/playbooks/testing/netbox_test.yaml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | gather_facts: true 3 | tasks: 4 | - name: Obtain list of devices from NetBox 5 | set_fact: 6 | device_list: "{{ query('netbox.netbox.nb_lookup', 'devices', 7 | api_filter='status=staged') }}" 8 | - name: Get interfaces for device 9 | set_fact: 10 | "dev_{{ item.key }}_interfaces": "{{ query('netbox.netbox.nb_lookup', 'interfaces', api_filter='device=' + item.value.name) }}" 11 | loop: "{{ device_list }}" 12 | 13 | - name: Assign bond0 IP 14 | netbox.netbox.netbox_ip_address: 15 | state: present 16 | netbox_url: "{{ lookup('env', 'NETBOX_URL') }}" 17 | netbox_token: "{{ lookup('env', 'NETBOX_TOKEN') }}" 18 | data: 19 | prefix: 172.18.16.0/24 20 | assigned_object: 21 | name: bond0 22 | device: SL230-NODE-1 23 | 24 | - name: Assign bond1.19 IP 25 | netbox.netbox.netbox_ip_address: 26 | state: present 27 | netbox_url: "{{ lookup('env', 'NETBOX_URL') }}" 28 | netbox_token: "{{ lookup('env', 'NETBOX_TOKEN') }}" 29 | data: 30 | prefix: 172.18.19.0/24 31 | assigned_object: 32 | name: bond1.19 33 | device: SL230-NODE-1 34 | -------------------------------------------------------------------------------- /ansible/roles/dns_config/README.md: -------------------------------------------------------------------------------- 1 | dns_config 2 | ========= 3 | 4 | This role manages cluster DNS resources for OpenShift across one or more providers. It presently supports FreeIPA and Route53 providers. 5 | 6 | Requirements 7 | ------------ 8 | 9 | For FreeIPA, the freeipa.ansible_freeipa collection and dependencies are required. For Route53, the amazon.aws collection and dependencies are required. 10 | 11 | Role Variables 12 | -------------- 13 | 14 | This role expects the following variables: 15 | 16 | * cluster_name - Name of the cluster to be used in DNS records 17 | * cluster_state - Whether the cluster is should be present or absent 18 | * base_domain - The base domain for DNS records 19 | * external_api_vip - The virtual IP for the k8s API 20 | * external_ingress_vip - The virutal IP for the ingress controller 21 | * internal_api_vip - The internal virtual IP for the k8s API 22 | * internal_ingress_vip - The internal virutal IP for the ingress controller 23 | * loadbalancer_type - Can be external or internal. If external, api-int record will be created 24 | * enabled_dns_providers - Dictionary of enabled DNS providers and configuration options 25 | ** split_horizon_internal - If true, the internal VIP will be configured in DNS for this provider 26 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/aap-base/ca-bundle-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: app-ca-trust 5 | namespace: aap 6 | stringData: 7 | bundle-ca.crt: | 8 | -----BEGIN CERTIFICATE----- 9 | MIICkTCCAhagAwIBAgIUX1Cm8VWt4ki4+8XH7oKsYYKJM+QwCgYIKoZIzj0EAwIw 10 | dzELMAkGA1UEBhMCVVMxETAPBgNVBAgMCEFya2Fuc2FzMQ8wDQYDVQQHDAZSb2dl 11 | cnMxFTATBgNVBAoMDFNpZ25hbDkgTGFiczEMMAoGA1UECwwDWE5BMR8wHQYDVQQD 12 | DBZTaWduYWw5IFJvb3QgQXV0aG9yaXR5MB4XDTIxMDMwMTA0MDMwNFoXDTQxMDIy 13 | NDA0MDMwNFowdzELMAkGA1UEBhMCVVMxETAPBgNVBAgMCEFya2Fuc2FzMQ8wDQYD 14 | VQQHDAZSb2dlcnMxFTATBgNVBAoMDFNpZ25hbDkgTGFiczEMMAoGA1UECwwDWE5B 15 | MR8wHQYDVQQDDBZTaWduYWw5IFJvb3QgQXV0aG9yaXR5MHYwEAYHKoZIzj0CAQYF 16 | K4EEACIDYgAE5w5BHLiaagf5eSNkQYuDIdyWe7ULLY2z2qAP1fKXM+RrSHQQb5x1 17 | Q9+IhQRhf7exw/pJS5Vs1R8IyQ3B8r6xz885w6+Fk6iyMAlFn979RU6V5lbxMRGG 18 | Vxq/CEL/iorVo2MwYTAdBgNVHQ4EFgQUYfO+q+KnTtIDK5OFXsVZ/D0ziiUwHwYD 19 | VR0jBBgwFoAUYfO+q+KnTtIDK5OFXsVZ/D0ziiUwDwYDVR0TAQH/BAUwAwEB/zAO 20 | BgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwIDaQAwZgIxAJLOIPP9J1/mttvGdQtM 21 | Prnm+r+JzVu8vd0r2HxgwloEkElTr29S+DAAE8XlUpoXpQIxALEd+sYGr1qENJqr 22 | vHOvuo0diFSUxjvTjowus6kM6nZi1JR4rMycICsGgujg8zwVAw== 23 | -----END CERTIFICATE----- 24 | -------------------------------------------------------------------------------- /ansible/playbooks/testing/test_openstack_allocation.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | gather_facts: false 3 | vars: 4 | cluster_platform: openstack 5 | cluster_name: shift-stack-test 6 | openstack_platform_config: 7 | vip_network: lab-net 8 | tasks: 9 | - name: include resource_allocation role 10 | ansible.builtin.include_role: 11 | name: resource_allocation 12 | vars: 13 | cluster_state: present 14 | - name: debug internal VIPs 15 | ansible.builtin.debug: 16 | msg: "Internal: API: {{ internal_api_vip }} Ingess: {{ internal_ingress_vip }}" 17 | - name: debug external VIPs 18 | ansible.builtin.debug: 19 | msg: "External: API: {{ external_api_vip }} Ingess: {{ external_ingress_vip }}" 20 | - name: include resource_allocation role 21 | ansible.builtin.include_role: 22 | name: resource_allocation 23 | vars: 24 | cluster_state: absent 25 | - name: debug internal VIPs 26 | ansible.builtin.debug: 27 | msg: "Internal: API: {{ internal_api_vip }} Ingess: {{ internal_ingress_vip }}" 28 | - name: debug external VIPs 29 | ansible.builtin.debug: 30 | msg: "External: API: {{ external_api_vip }} Ingess: {{ external_ingress_vip }}" 31 | -------------------------------------------------------------------------------- /charts/mce-cluster-build/values.yaml: -------------------------------------------------------------------------------- 1 | cluster: 2 | name: ocp4 3 | baseDomain: lab.signal9.gg 4 | gitOpsRepo: https://github.com/marbindrakon/rhte-2023-fleet-gitops.git 5 | importToHub: true 6 | createGitopsManifestWorks: false 7 | useACM: false 8 | clusterImageSet: img4.11.17-x86-64-appsub 9 | releaseImage: null 10 | controlPlaneCount: 3 11 | workerCount: 3 12 | apiVIP: "" 13 | ingressVIP: "" 14 | pullSecretVault: "" 15 | trustedCAs: "" 16 | sshKeyVault: "" 17 | sshPubKey: "" 18 | dnsServers: [] 19 | 20 | provider: 21 | providerCredsVault: "" 22 | providerCAs: "" 23 | # Only used for vSphere 24 | installConfigVault: "" 25 | # Can be OpenStack, InfraEnv, or vSphere 26 | type: OpenStack 27 | vsphere: 28 | datacenter: "" 29 | cluster: "" 30 | defaultDatastore: "" 31 | network: "" 32 | folder: null 33 | vcenterHost: "" 34 | openstack: 35 | existingImage: null 36 | externalNetwork: "" 37 | computeAZs: [] 38 | controlPlaneFlavor: m1.xlarge 39 | workerFlavor: m1.large 40 | infraenv: 41 | networkType: static 42 | useExternalLB: true 43 | machineCIDR: "" 44 | ntpServers: 45 | - 172.18.0.79 46 | - 172.18.42.10 47 | - 172.18.42.11 48 | hostNetworkConfigs: {} 49 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-mce-hub/live/cluster-monitoring/cm-config.yaml: -------------------------------------------------------------------------------- 1 | kind: ConfigMap 2 | apiVersion: v1 3 | metadata: 4 | name: cluster-monitoring-config 5 | namespace: openshift-monitoring 6 | data: 7 | config.yaml: | 8 | alertmanagerMain: 9 | nodeSelector: null 10 | resources: null 11 | tolerations: null 12 | volumeClaimTemplate: 13 | metadata: {} 14 | spec: 15 | resources: 16 | requests: 17 | storage: 5Gi 18 | storageClassName: ocs-external-storagecluster-ceph-rbd 19 | status: {} 20 | enableUserWorkload: null 21 | grafana: null 22 | http: null 23 | k8sPrometheusAdapter: null 24 | kubeStateMetrics: null 25 | openshiftStateMetrics: null 26 | prometheusK8s: 27 | logLevel: "" 28 | nodeSelector: null 29 | remoteWrite: null 30 | resources: null 31 | retention: 7d 32 | tolerations: null 33 | volumeClaimTemplate: 34 | metadata: {} 35 | spec: 36 | resources: 37 | requests: 38 | storage: 50Gi 39 | storageClassName: ocs-external-storagecluster-ceph-rbd 40 | status: {} 41 | prometheusOperator: null 42 | telemeterClient: null 43 | thanosQuerier: null 44 | -------------------------------------------------------------------------------- /argocd/clusters/managed-clusters/demo-jun1/helm-values/base-config-values.yaml: -------------------------------------------------------------------------------- 1 | cluster: 2 | name: "demo-jun1" 3 | baseDomain: "lab.signal9.gg" 4 | gitOpsRepo: "https://github.com/marbindrakon/fleet-gitops-example.git" 5 | gitOpsBasePath: argocd/clusters/managed-clusters 6 | 7 | monitoring: 8 | enabled: true 9 | storageClass: standard-csi 10 | 11 | externalSecrets: 12 | vaultAuthPath: "k8s-mgd-demo-jun1" 13 | 14 | timesync: 15 | enabled: true 16 | ptp: 17 | enabled: true 18 | loadKvmModule: true 19 | ntpServers: [] 20 | 21 | auth: 22 | oidcClientID: "openshift" 23 | externalSecret: 24 | name: oauth-signal9-client-secret 25 | vaultName: signal9-openid 26 | 27 | certManager: 28 | externalSecret: 29 | name: route53-key 30 | vaultName: signal9-route53 31 | solvers: 32 | - http01: 33 | ingress: {} 34 | - dns01: 35 | route53: 36 | # Required prior to 1.9 when this can be moved to a 37 | # secret and pulled from vault like the secret key 38 | accessKeyID: AKIAR3Z7ELN7VLNNHZHZ 39 | region: us-east-1 40 | secretAccessKeySecretRef: 41 | key: secret-access-key 42 | name: route53-key 43 | selector: 44 | dnsZones: 45 | - lab.signal9.gg 46 | -------------------------------------------------------------------------------- /argocd/clusters/managed-clusters/demo-jun2/helm-values/base-config-values.yaml: -------------------------------------------------------------------------------- 1 | cluster: 2 | name: "demo-jun2" 3 | baseDomain: "lab.signal9.gg" 4 | gitOpsRepo: "https://github.com/marbindrakon/fleet-gitops-example.git" 5 | gitOpsBasePath: argocd/clusters/managed-clusters 6 | 7 | monitoring: 8 | enabled: true 9 | storageClass: standard-csi 10 | 11 | externalSecrets: 12 | vaultAuthPath: "k8s-mgd-demo-jun2" 13 | 14 | timesync: 15 | enabled: true 16 | ptp: 17 | enabled: true 18 | loadKvmModule: true 19 | ntpServers: [] 20 | 21 | auth: 22 | oidcClientID: "openshift" 23 | externalSecret: 24 | name: oauth-signal9-client-secret 25 | vaultName: signal9-openid 26 | 27 | certManager: 28 | externalSecret: 29 | name: route53-key 30 | vaultName: signal9-route53 31 | solvers: 32 | - http01: 33 | ingress: {} 34 | - dns01: 35 | route53: 36 | # Required prior to 1.9 when this can be moved to a 37 | # secret and pulled from vault like the secret key 38 | accessKeyID: AKIAR3Z7ELN7VLNNHZHZ 39 | region: us-east-1 40 | secretAccessKeySecretRef: 41 | key: secret-access-key 42 | name: route53-key 43 | selector: 44 | dnsZones: 45 | - lab.signal9.gg 46 | -------------------------------------------------------------------------------- /argocd/clusters/managed-clusters/demo-feb9/helm-values/base-config-values.yaml: -------------------------------------------------------------------------------- 1 | cluster: 2 | name: "demo-feb9" 3 | baseDomain: "lab.signal9.gg" 4 | gitOpsRepo: "https://github.com/marbindrakon/signal9-lab-gitops.git" 5 | gitOpsBasePath: argocd/clusters/managed-clusters 6 | 7 | monitoring: 8 | enabled: true 9 | storageClass: standard-csi 10 | 11 | externalSecrets: 12 | vaultAuthPath: "k8s-mgd-demo-feb9" 13 | 14 | timesync: 15 | enabled: true 16 | ptp: 17 | enabled: true 18 | loadKvmModule: true 19 | ntpServers: [] 20 | 21 | auth: 22 | oidcClientID: "demo-feb9-openshift" 23 | externalSecret: 24 | name: oauth-signal9-client-secret 25 | vaultName: demo-feb9-openid 26 | 27 | certManager: 28 | externalSecret: 29 | name: route53-key 30 | vaultName: signal9-route53 31 | solvers: 32 | - http01: 33 | ingress: {} 34 | - dns01: 35 | route53: 36 | # Required prior to 1.9 when this can be moved to a 37 | # secret and pulled from vault like the secret key 38 | accessKeyID: AKIAR3Z7ELN7VLNNHZHZ 39 | region: us-east-1 40 | secretAccessKeySecretRef: 41 | key: secret-access-key 42 | name: route53-key 43 | selector: 44 | dnsZones: 45 | - lab.signal9.gg 46 | -------------------------------------------------------------------------------- /charts/mce-cluster-build/templates/infra-env.yaml: -------------------------------------------------------------------------------- 1 | {{- if eq .Values.provider.type "InfraEnv" -}} 2 | apiVersion: agent-install.openshift.io/v1beta1 3 | kind: InfraEnv 4 | metadata: 5 | name: {{ .Values.cluster.name }} 6 | namespace: {{ .Values.cluster.name }} 7 | finalizers: 8 | - infraenv.agent-install.openshift.io/ai-deprovision 9 | annotations: 10 | argocd.argoproj.io/sync-wave: '0' 11 | labels: 12 | agentclusterinstalls.extensions.hive.openshift.io/location: {{ .Values.cluster.name }} 13 | networkType: {{ .Values.provider.infraenv.networkType }} 14 | spec: 15 | clusterRef: 16 | name: {{ .Values.cluster.name }} 17 | namespace: {{ .Values.cluster.name }} 18 | {{ if .Values.provider.infraenv.ntpServers }} 19 | additionalNTPSources: 20 | {{ range .Values.provider.infraenv.ntpServers }} 21 | - {{ . }} 22 | {{ end }} 23 | {{ end }} 24 | agentLabels: 25 | agentclusterinstalls.extensions.hive.openshift.io/location: {{ .Values.cluster.name }} 26 | cpuArchitecture: x86_64 27 | ipxeScriptType: DiscoveryImageAlways 28 | nmStateConfigLabelSelector: 29 | matchLabels: 30 | infraenvs.agent-install.openshift.io: {{ .Values.cluster.name }} 31 | pullSecretRef: 32 | name: {{ .Values.cluster.name }}-pull-secret 33 | sshAuthorizedKey: {{ .Values.cluster.sshPubKey }} 34 | {{- end -}} 35 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/external-secrets/operator-config.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.externalSecrets.enabled -}} 2 | apiVersion: operator.external-secrets.io/v1alpha1 3 | kind: OperatorConfig 4 | metadata: 5 | name: external-secrets-operator 6 | namespace: external-secrets-operator 7 | annotations: 8 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 9 | argocd.argoproj.io/sync-wave: '0' 10 | spec: 11 | # this must be set to false when using olm 12 | installCRDs: false 13 | webhook: 14 | securityContext: 15 | allowPrivilegeEscalation: false 16 | capabilities: 17 | drop: 18 | - ALL 19 | readOnlyRootFilesystem: true 20 | runAsNonRoot: true 21 | runAsUser: null 22 | seccompProfile: 23 | type: RuntimeDefault 24 | certController: 25 | securityContext: 26 | allowPrivilegeEscalation: false 27 | capabilities: 28 | drop: 29 | - ALL 30 | readOnlyRootFilesystem: true 31 | runAsNonRoot: true 32 | runAsUser: null 33 | seccompProfile: 34 | type: RuntimeDefault 35 | securityContext: 36 | allowPrivilegeEscalation: false 37 | capabilities: 38 | drop: 39 | - ALL 40 | readOnlyRootFilesystem: true 41 | runAsNonRoot: true 42 | runAsUser: null 43 | seccompProfile: 44 | type: RuntimeDefault 45 | {{ end }} 46 | -------------------------------------------------------------------------------- /charts/mce-cluster-build/templates/agent-cluster-install.yaml: -------------------------------------------------------------------------------- 1 | {{- if eq .Values.provider.type "InfraEnv" -}} 2 | apiVersion: extensions.hive.openshift.io/v1beta1 3 | kind: AgentClusterInstall 4 | metadata: 5 | name: {{ .Values.cluster.name }} 6 | namespace: {{ .Values.cluster.name }} 7 | finalizers: 8 | - agentclusterinstall.agent-install.openshift.io/ai-deprovision 9 | annotations: 10 | argocd.argoproj.io/sync-wave: '1' 11 | spec: 12 | clusterDeploymentRef: 13 | name: {{ .Values.cluster.name }} 14 | imageSetRef: 15 | {{ if .Values.cluster.clusterImageSet }} 16 | name: {{ .Values.cluster.clusterImageSet }} 17 | {{ else }} 18 | name: {{ .Values.cluster.name }}-custom 19 | {{ end }} 20 | {{ if not (eq .Values.provider.infraenv.useExternalLB true) }} 21 | apiVIP: {{ .Values.cluster.apiVIP }} 22 | ingressVIP: {{ .Values.cluster.ingressVIP }} 23 | {{ end }} 24 | networking: 25 | clusterNetwork: 26 | - cidr: 10.128.0.0/14 27 | hostPrefix: 23 28 | machineNetwork: 29 | - cidr: {{ .Values.provider.infraenv.machineCIDR }} 30 | serviceNetwork: 31 | - 172.30.0.0/16 32 | userManagedNetworking: {{ .Values.provider.infraenv.useExternalLB }} 33 | provisionRequirements: 34 | controlPlaneAgents: {{ .Values.cluster.controlPlaneCount }} 35 | {{ if .Values.cluster.workerCount }} 36 | workerAgents: {{ .Values.cluster.workerCount }} 37 | {{ end }} 38 | {{- end -}} 39 | -------------------------------------------------------------------------------- /ansible/roles/lb_config/README.md: -------------------------------------------------------------------------------- 1 | Role Name 2 | ========= 3 | 4 | A brief description of the role goes here. 5 | 6 | Requirements 7 | ------------ 8 | 9 | Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. 10 | 11 | Role Variables 12 | -------------- 13 | 14 | A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. 15 | 16 | Dependencies 17 | ------------ 18 | 19 | A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. 20 | 21 | Example Playbook 22 | ---------------- 23 | 24 | Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: 25 | 26 | - hosts: servers 27 | roles: 28 | - { role: username.rolename, x: 42 } 29 | 30 | License 31 | ------- 32 | 33 | BSD 34 | 35 | Author Information 36 | ------------------ 37 | 38 | An optional section for the role authors to include contact information, or a website (HTML is not allowed). 39 | -------------------------------------------------------------------------------- /ansible/roles/sso_client/README.md: -------------------------------------------------------------------------------- 1 | Role Name 2 | ========= 3 | 4 | A brief description of the role goes here. 5 | 6 | Requirements 7 | ------------ 8 | 9 | Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. 10 | 11 | Role Variables 12 | -------------- 13 | 14 | A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. 15 | 16 | Dependencies 17 | ------------ 18 | 19 | A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. 20 | 21 | Example Playbook 22 | ---------------- 23 | 24 | Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: 25 | 26 | - hosts: servers 27 | roles: 28 | - { role: username.rolename, x: 42 } 29 | 30 | License 31 | ------- 32 | 33 | BSD 34 | 35 | Author Information 36 | ------------------ 37 | 38 | An optional section for the role authors to include contact information, or a website (HTML is not allowed). 39 | -------------------------------------------------------------------------------- /ansible/roles/vault_config/README.md: -------------------------------------------------------------------------------- 1 | Role Name 2 | ========= 3 | 4 | A brief description of the role goes here. 5 | 6 | Requirements 7 | ------------ 8 | 9 | Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. 10 | 11 | Role Variables 12 | -------------- 13 | 14 | A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. 15 | 16 | Dependencies 17 | ------------ 18 | 19 | A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. 20 | 21 | Example Playbook 22 | ---------------- 23 | 24 | Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: 25 | 26 | - hosts: servers 27 | roles: 28 | - { role: username.rolename, x: 42 } 29 | 30 | License 31 | ------- 32 | 33 | BSD 34 | 35 | Author Information 36 | ------------------ 37 | 38 | An optional section for the role authors to include contact information, or a website (HTML is not allowed). 39 | -------------------------------------------------------------------------------- /ansible/playbooks/deploy_cluster.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | gather_facts: false 3 | vars: 4 | cluster_state: present 5 | tasks: 6 | - name: set platform config fact 7 | ansible.builtin.set_fact: 8 | "{{ cluster_platform }}_platform_config": "{{ platform_configs[cluster_platform] }}" 9 | 10 | - name: set cluster image set 11 | ansible.builtin.set_fact: 12 | cluster_image_set: "img{{ cluster_version }}-x86-64-appsub" 13 | 14 | - name: include resource_allocation role 15 | ansible.builtin.include_role: 16 | name: resource_allocation 17 | 18 | - hosts: loadbalancers 19 | gather_facts: true 20 | become: true 21 | vars: 22 | cluster_state: present 23 | tasks: 24 | - name: include lb_config role 25 | ansible.builtin.include_role: 26 | name: lb_config 27 | 28 | - hosts: localhost 29 | gather_facts: false 30 | vars: 31 | cluster_state: present 32 | tasks: 33 | - name: include dns role 34 | ansible.builtin.include_role: 35 | name: dns_config 36 | 37 | - name: include sso_client role 38 | ansible.builtin.include_role: 39 | name: sso_client 40 | 41 | - name: include gitops_cluster_build role 42 | ansible.builtin.include_role: 43 | name: gitops_cluster_build 44 | 45 | - name: wait two minutes because of secrets race condition 46 | ansible.builtin.pause: 47 | seconds: 120 48 | 49 | - name: include vault_config role 50 | ansible.builtin.include_role: 51 | name: vault_config 52 | -------------------------------------------------------------------------------- /ansible/playbooks/e2e-demo/snow_undeploy_cluster.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | gather_facts: false 3 | tasks: 4 | - name: update status in SNOW 5 | servicenow.itsm.api: 6 | resource: "{{ service_now['cluster_info_table'] }}" 7 | action: patch 8 | sys_id: "{{ snow_record_id }}" 9 | data: 10 | status: "Deprovisioning" 11 | 12 | - name: unprotect cluster since approval happened in SNOW 13 | ansible.builtin.include_role: 14 | name: gitops_cluster_build 15 | vars: 16 | gitops_task: unprotect 17 | cluster_state: unchanged 18 | when: cluster_protected == true 19 | 20 | - name: wait 30 seconds 21 | ansible.builtin.pause: 22 | seconds: 30 23 | when: cluster_protected == true 24 | 25 | - name: run cluster undeploy 26 | ansible.builtin.import_playbook: ../undeploy_cluster.yml 27 | 28 | - hosts: localhost 29 | gather_facts: false 30 | tasks: 31 | - name: wait up to one hour for cluster namespace to disappear 32 | kubernetes.core.k8s_info: 33 | api_version: v1 34 | kind: Namespace 35 | name: "{{ cluster_name }}" 36 | register: undeploy_ns_list 37 | until: undeploy_ns_list.resources is defined and undeploy_ns_list.resources | length == 0 38 | retries: 120 39 | delay: 30 40 | 41 | - name: delete cluster record in SNOW 42 | servicenow.itsm.api: 43 | resource: "{{ service_now['cluster_info_table'] }}" 44 | action: delete 45 | sys_id: "{{ snow_record_id }}" 46 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/aap-base/operator-sub.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: operators.coreos.com/v1 3 | kind: OperatorGroup 4 | metadata: 5 | name: ansible-automation-platform-operator 6 | namespace: aap 7 | annotations: 8 | argocd.argoproj.io/sync-wave: '1' 9 | spec: {} 10 | --- 11 | apiVersion: operators.coreos.com/v1alpha1 12 | kind: Subscription 13 | metadata: 14 | name: ansible-automation-platform 15 | namespace: aap 16 | annotations: 17 | argocd.argoproj.io/sync-wave: '1' 18 | spec: 19 | channel: 'stable-2.3-cluster-scoped' 20 | installPlanApproval: Automatic 21 | name: ansible-automation-platform-operator 22 | source: redhat-operators 23 | sourceNamespace: openshift-marketplace 24 | config: 25 | env: 26 | - name: RELATED_IMAGE_CONTROLLER_INIT_CONTAINER 27 | value: registry.redhat.io/ansible-automation-platform-23/ee-supported-rhel8@sha256:c1012c02b5e6a2d6130a2a903bed6290eacd25cf6aeb1cb68395a29f911d0b6f 28 | - name: RELATED_IMAGE_CONTROL_PLANE_EE 29 | value: registry.redhat.io/ansible-automation-platform-23/ee-supported-rhel8@sha256:c1012c02b5e6a2d6130a2a903bed6290eacd25cf6aeb1cb68395a29f911d0b6f 30 | - name: RELATED_IMAGE_EE_SUPPORTED 31 | value: registry.redhat.io/ansible-automation-platform-23/ee-supported-rhel8@sha256:c1012c02b5e6a2d6130a2a903bed6290eacd25cf6aeb1cb68395a29f911d0b6f 32 | - name: RELATED_IMAGE_EE_MINIMAL 33 | value: registry.redhat.io/ansible-automation-platform-23/ee-minimal-rhel8@sha256:5c520b468f7f423059363e4397927c2ace498bcdc658340619159fdaf0d4fc01 34 | -------------------------------------------------------------------------------- /ansible/roles/gitops_cluster_build/templates/base-config-values.yaml.j2: -------------------------------------------------------------------------------- 1 | cluster: 2 | name: "{{ cluster_name }}" 3 | baseDomain: "{{ base_domain }}" 4 | gitOpsRepo: "{{ gitops_repo_url }}" 5 | gitOpsBasePath: argocd/clusters/managed-clusters 6 | 7 | monitoring: 8 | {% if cluster_platform == "openstack" %} 9 | enabled: true 10 | storageClass: standard-csi 11 | {% else %} 12 | enabled: false 13 | {% endif %} 14 | 15 | externalSecrets: 16 | vaultAuthPath: "{{ hashicorp_vault['vault_managed_auth_name'] }}" 17 | 18 | timesync: 19 | enabled: true 20 | {% if cluster_platform == "openstack" %} 21 | ptp: 22 | enabled: true 23 | loadKvmModule: true 24 | ntpServers: [] 25 | {% else %} 26 | ntpServers: {{ cluster_ntp_sources }} 27 | {% endif %} 28 | 29 | auth: 30 | oidcClientID: "{{ cluster_sso['client_id'] }}" 31 | externalSecret: 32 | name: oauth-signal9-client-secret 33 | vaultName: {{ hashicorp_vault['cluster_secrets']['oidc'] }} 34 | 35 | certManager: 36 | externalSecret: 37 | name: route53-key 38 | vaultName: {{ hashicorp_vault['cluster_secrets']['cert-manager-dns'] }} 39 | solvers: 40 | - http01: 41 | ingress: {} 42 | - dns01: 43 | route53: 44 | # Required prior to 1.9 when this can be moved to a 45 | # secret and pulled from vault like the secret key 46 | accessKeyID: AKIAR3Z7ELN7VLNNHZHZ 47 | region: us-east-1 48 | secretAccessKeySecretRef: 49 | key: secret-access-key 50 | name: route53-key 51 | selector: 52 | dnsZones: 53 | - {{ base_domain }} 54 | -------------------------------------------------------------------------------- /ansible/roles/gitops_cluster_build/templates/vsphere-build-values.yaml.j2: -------------------------------------------------------------------------------- 1 | cluster: 2 | importToHub: true 3 | {% if hub_type == 'acm' %} 4 | useACM: true 5 | createGitopsManifestWorks: false 6 | {% else %} 7 | createGitopsManifestWorks: true 8 | {% endif %} 9 | name: {{ cluster_name }} 10 | baseDomain: {{ base_domain }} 11 | clusterImageSet: {{ cluster_image_set }} 12 | controlPlaneCount: {{ vsphere_platform_config['cluster_sizes'][cluster_size]['controller_count'] }} 13 | workerCount: {{ vsphere_platform_config['cluster_sizes'][cluster_size]['worker_count'] }} 14 | apiVIP: "{{ internal_api_vip }}" 15 | ingressVIP: "{{ internal_ingress_vip }}" 16 | pullSecretVault: "{{ hashicorp_vault['cluster_secrets']['pull-secret'] }}" 17 | trustedCAs: | 18 | {{ cluster_trust_bundle | indent(4) }} 19 | sshKeyVault: "{{ hashicorp_vault['cluster_secrets']['node-ssh'] }}" 20 | sshPubKey: "{{ cluster_ssh_pubkey }}" 21 | dnsServers: {{ cluster_dns_servers | to_json }} 22 | provider: 23 | installConfigVault: {{ hashicorp_vault['cluster_secrets']['install-config'] }} 24 | providerCredsVault: {{ hashicorp_vault['cluster_secrets']['vsphere-credentials'] }} 25 | providerCAs: | 26 | {{ vsphere_platform_config['platform_ca_bundle'] | indent(4) }} 27 | type: vSphere 28 | vsphere: 29 | datacenter: {{ vsphere_platform_config['datacenter'] }} 30 | cluster: {{ vsphere_platform_config['cluster'] }} 31 | defaultDatastore: {{ vsphere_platform_config['datastore'] }} 32 | network: {{ vsphere_platform_config['network'] }} 33 | folder: {{ vsphere_platform_config['folder'] | default("null") }} 34 | vcenterHost: {{ vsphere_platform_config['vcenter'] }} 35 | 36 | -------------------------------------------------------------------------------- /ansible/roles/dns_config/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: determine split horizon status 3 | ansible.builtin.set_fact: 4 | dns_split_horizon: '{{ enabled_dns_providers|length > 1 }}' 5 | 6 | - name: initialize records lists 7 | ansible.builtin.set_fact: 8 | dns_internal_records: [] 9 | dns_external_records: [] 10 | 11 | - name: construct dns names 12 | ansible.builtin.set_fact: 13 | dns_api_name: "api.{{ cluster_name }}" 14 | dns_ingress_name: "*.apps.{{ cluster_name }}" 15 | dns_int_api_name: "api-int.{{ cluster_name }}" 16 | 17 | - name: construct internal api record 18 | ansible.builtin.set_fact: 19 | dns_internal_records: '{{ dns_internal_records + [(dns_api_name, internal_api_vip)] }}' 20 | 21 | - name: construct internal api-int record 22 | ansible.builtin.set_fact: 23 | dns_internal_records: '{{ dns_internal_records + [(dns_int_api_name, internal_api_vip)] }}' 24 | when: loadbalancer_type == "external" 25 | 26 | - name: construct internal ingress record 27 | ansible.builtin.set_fact: 28 | dns_internal_records: '{{ dns_internal_records + [(dns_ingress_name, internal_ingress_vip)] }}' 29 | 30 | - name: construct external api record 31 | ansible.builtin.set_fact: 32 | dns_external_records: '{{ dns_external_records + [(dns_api_name, external_api_vip)] }}' 33 | when: (dns_split_horizon) 34 | 35 | - name: construct external ingress record 36 | ansible.builtin.set_fact: 37 | dns_external_records: '{{ dns_external_records + [(dns_ingress_name, external_ingress_vip)] }}' 38 | when: (dns_split_horizon) 39 | 40 | - name: execute dns provider logic 41 | ansible.builtin.include_tasks: "providers/{{ dns_provider.key }}.yml" 42 | loop_control: 43 | loop_var: dns_provider 44 | loop: "{{ enabled_dns_providers | dict2items }}" 45 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-mce-hub/live/base-config/base-config-app.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: base-config-chart 5 | namespace: openshift-gitops 6 | spec: 7 | destination: 8 | namespace: openshift-gitops 9 | server: "https://kubernetes.default.svc" 10 | project: default 11 | syncPolicy: 12 | automated: {} 13 | source: 14 | repoURL: "https://github.com/marbindrakon/fleet-gitops-example.git" 15 | path: "charts/ocp-base-config" 16 | targetRevision: HEAD 17 | helm: 18 | values: | 19 | cluster: 20 | name: rhte-mce-hub 21 | gitOpsRepo: "https://github.com/marbindrakon/fleet-gitops-example.git" 22 | baseDomain: lab.signal9.gg 23 | monitoring: 24 | enabled: false 25 | externalSecrets: 26 | vaultAuthPath: 'k8s-rhte-mce-hub' 27 | odfStorage: 28 | enabled: true 29 | external: true 30 | externalSecret: 31 | name: rook-ceph-external-cluster-details 32 | vaultName: rhte-mce-hub-rook-data 33 | network: 34 | hostRouting: true 35 | certManager: 36 | solvers: 37 | - http01: 38 | ingress: {} 39 | - dns01: 40 | route53: 41 | # Required prior to 1.9 when this can be moved to a 42 | # secret and pulled from vault like the secret key 43 | accessKeyID: AKIAR3Z7ELN7VLNNHZHZ 44 | region: us-east-1 45 | secretAccessKeySecretRef: 46 | key: secret-access-key 47 | name: route53-key 48 | selector: 49 | dnsZones: 50 | - signal9.gg 51 | - lab.signal9.gg 52 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/rhacm-base/gitops-integration.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: cluster.open-cluster-management.io/v1beta1 3 | kind: Placement 4 | metadata: 5 | name: all-openshift-clusters 6 | namespace: openshift-gitops 7 | annotations: 8 | argocd.argoproj.io/sync-wave: '3' 9 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 10 | spec: 11 | predicates: 12 | - requiredClusterSelector: 13 | labelSelector: 14 | matchExpressions: 15 | - key: vendor 16 | operator: "In" 17 | values: 18 | - OpenShift 19 | --- 20 | apiVersion: apps.open-cluster-management.io/v1beta1 21 | kind: GitOpsCluster 22 | metadata: 23 | name: argo-acm-importer 24 | namespace: openshift-gitops 25 | annotations: 26 | argocd.argoproj.io/sync-wave: '3' 27 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 28 | spec: 29 | argoServer: 30 | cluster: notused 31 | argoNamespace: openshift-gitops 32 | placementRef: 33 | kind: Placement 34 | apiVersion: cluster.open-cluster-management.io/v1beta1 35 | name: all-openshift-clusters 36 | namespace: openshift-gitops 37 | --- 38 | apiVersion: cluster.open-cluster-management.io/v1beta1 39 | kind: ManagedClusterSet 40 | metadata: 41 | name: all-openshift-clusters 42 | annotations: 43 | argocd.argoproj.io/sync-wave: '3' 44 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 45 | spec: {} 46 | --- 47 | apiVersion: cluster.open-cluster-management.io/v1beta1 48 | kind: ManagedClusterSetBinding 49 | metadata: 50 | name: all-openshift-clusters 51 | namespace: openshift-gitops 52 | annotations: 53 | argocd.argoproj.io/sync-wave: '3' 54 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 55 | spec: 56 | clusterSet: all-openshift-clusters 57 | -------------------------------------------------------------------------------- /charts/ocp-base-config/values.yaml: -------------------------------------------------------------------------------- 1 | cluster: 2 | name: rhte-acm-hub 3 | baseDomain: lab.signal9.gg 4 | gitOpsRepo: https://github.com/marbindrakon/rhte-2023-fleet-gitops.git 5 | gitOpsBasePath: argocd/clusters 6 | trustedCABundle: "" 7 | 8 | externalSecrets: 9 | enabled: true 10 | vaultBase: 'https://vault.lab.signal9.gg' 11 | vaultAuthPath: 'k8s-ocp' 12 | secretBasePath: lab/rht-shared 13 | 14 | certManager: 15 | enabled: true 16 | apiCert: true 17 | defaultIngressCert: true 18 | acmeBase: 'https://acme-v02.api.letsencrypt.org/directory' 19 | externalSecret: 20 | name: route53-key 21 | vaultName: signal9-route53 22 | solvers: 23 | - http01: 24 | ingress: {} 25 | - dns01: 26 | route53: 27 | accessKeyID: REDACTED 28 | region: us-east-1 29 | secretAccessKeySecretRef: 30 | key: secret-access-key 31 | name: route53-key 32 | selector: 33 | dnsZones: 34 | - signal9.gg 35 | - lab.signal9.gg 36 | 37 | monitoring: 38 | enabled: true 39 | storageClass: standard 40 | 41 | network: 42 | hostRouting: false 43 | 44 | odfStorage: 45 | enabled: false 46 | version: '4.11' 47 | external: false 48 | externalSecret: 49 | name: rook-ceph-external-cluster-details 50 | vaultName: rhte-acm-hub-rook-data 51 | 52 | auth: 53 | enabled: true 54 | oidcDisplayName: Signal9-RHT 55 | oidcClientID: openshift 56 | oidcIssuer: https://login.home.signal9.gg/auth/realms/Signal9-RHT 57 | externalSecret: 58 | name: oauth-signal9-client-secret 59 | vaultName: signal9-openid 60 | 61 | timesync: 62 | enabled: true 63 | ptp: 64 | enabled: false 65 | loadKvmModule: false 66 | device: 'ptp_kvm' 67 | sourceStratum: 2 68 | ntpServers: 69 | - 172.18.0.79 70 | - 172.18.42.10 71 | - 172.18.42.11 72 | -------------------------------------------------------------------------------- /ansible/roles/sso_client/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: your name 3 | description: your role description 4 | company: your company (optional) 5 | 6 | # If the issue tracker for your role is not on github, uncomment the 7 | # next line and provide a value 8 | # issue_tracker_url: http://example.com/issue/tracker 9 | 10 | # Choose a valid license ID from https://spdx.org - some suggested licenses: 11 | # - BSD-3-Clause (default) 12 | # - MIT 13 | # - GPL-2.0-or-later 14 | # - GPL-3.0-only 15 | # - Apache-2.0 16 | # - CC-BY-4.0 17 | license: license (GPL-2.0-or-later, MIT, etc) 18 | 19 | min_ansible_version: 2.1 20 | 21 | # If this a Container Enabled role, provide the minimum Ansible Container version. 22 | # min_ansible_container_version: 23 | 24 | # 25 | # Provide a list of supported platforms, and for each platform a list of versions. 26 | # If you don't wish to enumerate all versions for a particular platform, use 'all'. 27 | # To view available platforms and versions (or releases), visit: 28 | # https://galaxy.ansible.com/api/v1/platforms/ 29 | # 30 | # platforms: 31 | # - name: Fedora 32 | # versions: 33 | # - all 34 | # - 25 35 | # - name: SomePlatform 36 | # versions: 37 | # - all 38 | # - 1.0 39 | # - 7 40 | # - 99.99 41 | 42 | galaxy_tags: [] 43 | # List tags for your role here, one per line. A tag is a keyword that describes 44 | # and categorizes the role. Users find roles by searching for tags. Be sure to 45 | # remove the '[]' above, if you add tags to this list. 46 | # 47 | # NOTE: A tag is limited to a single word comprised of alphanumeric characters. 48 | # Maximum 20 tags per role. 49 | 50 | dependencies: [] 51 | # List your role dependencies here, one per line. Be sure to remove the '[]' above, 52 | # if you add dependencies to this list. 53 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/aap-base/aap-controller.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: automationcontroller.ansible.com/v1beta1 3 | kind: AutomationController 4 | metadata: 5 | name: acm-hub-aap 6 | namespace: aap 7 | annotations: 8 | argocd.argoproj.io/sync-wave: '2' 9 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 10 | spec: 11 | create_preload_data: false 12 | route_tls_termination_mechanism: Edge 13 | ingress_type: route 14 | service_type: ClusterIP 15 | garbage_collect_secrets: false 16 | image_pull_policy: IfNotPresent 17 | projects_storage_size: 12Gi 18 | task_privileged: false 19 | projects_storage_access_mode: ReadWriteMany 20 | projects_persistence: true 21 | projects_use_existing_claim: _No_ 22 | projects_storage_class: ocs-external-storagecluster-cephfs 23 | replicas: 1 24 | admin_user: admin 25 | admin_email: admin@signal9.gg 26 | admin_password_secret: aap-admin-password 27 | secret_key_secret: aap-secret-key 28 | bundle_cacert_secret: app-ca-trust 29 | route_host: aap.apps.rhte-acm-hub.lab.signal9.gg 30 | hostname: aap.apps.rhte-acm-hub.lab.signal9.gg 31 | # Customize EE images due to pull error 32 | control_plane_ee_image: registry.redhat.io/ansible-automation-platform-23/ee-supported-rhel8@sha256:c1012c02b5e6a2d6130a2a903bed6290eacd25cf6aeb1cb68395a29f911d0b6f 33 | ee_images: 34 | - name: supported-ee 35 | image: registry.redhat.io/ansible-automation-platform-23/ee-supported-rhel8@sha256:c1012c02b5e6a2d6130a2a903bed6290eacd25cf6aeb1cb68395a29f911d0b6f 36 | - name: supported-minimal 37 | image: registry.redhat.io/ansible-automation-platform-23/ee-minimal-rhel8@sha256:5c520b468f7f423059363e4397927c2ace498bcdc658340619159fdaf0d4fc01 38 | - name: supported-2.9 39 | image: registry.redhat.io/ansible-automation-platform-23/ee-29-rhel8@sha256:3414db39974a6ae20dd7947f18ab9072d69d9d6877aa4d0e0c0bd3e1ada295a7 40 | -------------------------------------------------------------------------------- /ansible/roles/gitops_cluster_build/templates/openstack-build-values.yaml.j2: -------------------------------------------------------------------------------- 1 | cluster: 2 | importToHub: true 3 | {% if hub_type == 'acm' %} 4 | useACM: true 5 | createGitopsManifestWorks: false 6 | {% else %} 7 | createGitopsManifestWorks: true 8 | {% endif %} 9 | name: {{ cluster_name }} 10 | baseDomain: {{ base_domain }} 11 | clusterImageSet: {{ cluster_image_set }} 12 | controlPlaneCount: {{ openstack_platform_config['cluster_sizes'][cluster_size]['controller_count'] }} 13 | workerCount: {{ openstack_platform_config['cluster_sizes'][cluster_size]['worker_count'] }} 14 | apiVIP: "{{ internal_api_vip }}" 15 | ingressVIP: "{{ internal_ingress_vip }}" 16 | pullSecretVault: "{{ hashicorp_vault['cluster_secrets']['pull-secret'] }}" 17 | trustedCAs: | 18 | {{ cluster_trust_bundle | indent(4) }} 19 | sshKeyVault: "{{ hashicorp_vault['cluster_secrets']['node-ssh'] }}" 20 | sshPubKey: "{{ cluster_ssh_pubkey }}" 21 | dnsServers: {{ cluster_dns_servers | to_json }} 22 | provider: 23 | providerCredsVault: {{ hashicorp_vault['cluster_secrets']['openstack-cloud'] }} 24 | providerCAs: | 25 | {{ openstack_platform_config['platform_ca_bundle'] | indent(4) }} 26 | type: OpenStack 27 | openstack: 28 | {% if openstack_platform_config['use_existing_image'] == True %} 29 | existingImage: {{ openstack_platform_config['glance_image'] }} 30 | {% endif %} 31 | externalNetwork: {{ openstack_platform_config['vip_network'] }} 32 | computeAZs: null 33 | {% if 'gpu' in cluster_special_feature|lower and cluster_size == 'sandbox' %} 34 | controlPlaneFlavor: {{ openstack_platform_config['cluster_sizes'][cluster_size]['gpu_flavor'] }} 35 | {% else %} 36 | {% endif %} 37 | {% if 'gpu' in cluster_special_feature|lower %} 38 | workerFlavor: {{ openstack_platform_config['cluster_sizes'][cluster_size]['gpu_flavor'] }} 39 | {% else %} 40 | workerFlavor: {{ openstack_platform_config['cluster_sizes'][cluster_size]['worker_flavor'] }} 41 | {% endif %} 42 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/cluster-monitoring/cm-config.yaml: -------------------------------------------------------------------------------- 1 | kind: ConfigMap 2 | apiVersion: v1 3 | metadata: 4 | name: cluster-monitoring-config 5 | namespace: openshift-monitoring 6 | data: 7 | config.yaml: | 8 | alertmanagerMain: 9 | nodeSelector: null 10 | resources: null 11 | tolerations: null 12 | volumeClaimTemplate: 13 | metadata: {} 14 | spec: 15 | resources: 16 | requests: 17 | storage: 5Gi 18 | storageClassName: ocs-external-storagecluster-ceph-rbd 19 | status: {} 20 | enableUserWorkload: null 21 | grafana: null 22 | http: null 23 | k8sPrometheusAdapter: null 24 | kubeStateMetrics: null 25 | openshiftStateMetrics: null 26 | prometheusK8s: 27 | additionalAlertManagerConfigs: 28 | - apiVersion: v2 29 | bearerToken: 30 | key: token 31 | name: observability-alertmanager-accessor 32 | pathPrefix: / 33 | scheme: https 34 | staticConfigs: 35 | - alertmanager-open-cluster-management-observability.apps.rhte-acm-hub.lab.signal9.gg 36 | tlsConfig: 37 | ServerName: "" 38 | ca: 39 | key: service-ca.crt 40 | name: hub-alertmanager-router-ca 41 | insecureSkipVerify: false 42 | externalLabels: 43 | cluster: 2752f03d-ff94-4931-af6b-c98a27d97cd8 44 | managed_cluster: 2752f03d-ff94-4931-af6b-c98a27d97cd8 45 | logLevel: "" 46 | nodeSelector: null 47 | remoteWrite: null 48 | resources: null 49 | retention: 7d 50 | tolerations: null 51 | volumeClaimTemplate: 52 | metadata: {} 53 | spec: 54 | resources: 55 | requests: 56 | storage: 50Gi 57 | storageClassName: ocs-external-storagecluster-ceph-rbd 58 | status: {} 59 | prometheusOperator: null 60 | telemeterClient: null 61 | thanosQuerier: null 62 | -------------------------------------------------------------------------------- /charts/ocp-base-config/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "ocp-base-config.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "ocp-base-config.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "ocp-base-config.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "ocp-base-config.labels" -}} 37 | helm.sh/chart: {{ include "ocp-base-config.chart" . }} 38 | {{ include "ocp-base-config.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "ocp-base-config.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "ocp-base-config.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | {{- end }} 52 | 53 | {{/* 54 | Create the name of the service account to use 55 | */}} 56 | {{- define "ocp-base-config.serviceAccountName" -}} 57 | {{- if .Values.serviceAccount.create }} 58 | {{- default (include "ocp-base-config.fullname" .) .Values.serviceAccount.name }} 59 | {{- else }} 60 | {{- default "default" .Values.serviceAccount.name }} 61 | {{- end }} 62 | {{- end }} 63 | -------------------------------------------------------------------------------- /charts/mce-cluster-build/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "ocp-base-config.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "ocp-base-config.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "ocp-base-config.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "ocp-base-config.labels" -}} 37 | helm.sh/chart: {{ include "ocp-base-config.chart" . }} 38 | {{ include "ocp-base-config.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "ocp-base-config.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "ocp-base-config.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | {{- end }} 52 | 53 | {{/* 54 | Create the name of the service account to use 55 | */}} 56 | {{- define "ocp-base-config.serviceAccountName" -}} 57 | {{- if .Values.serviceAccount.create }} 58 | {{- default (include "ocp-base-config.fullname" .) .Values.serviceAccount.name }} 59 | {{- else }} 60 | {{- default "default" .Values.serviceAccount.name }} 61 | {{- end }} 62 | {{- end }} 63 | -------------------------------------------------------------------------------- /charts/mce-cluster-build/templates/gitops-manifestwork.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.cluster.createGitopsManifestWorks -}} 2 | apiVersion: work.open-cluster-management.io/v1 3 | kind: ManifestWork 4 | metadata: 5 | namespace: {{ .Values.cluster.name }} 6 | name: gitops-onboarding 7 | spec: 8 | workload: 9 | manifests: 10 | - apiVersion: operators.coreos.com/v1alpha1 11 | kind: Subscription 12 | metadata: 13 | name: openshift-gitops-operator 14 | namespace: openshift-operators 15 | spec: 16 | channel: gitops-1.7 17 | installPlanApproval: Automatic 18 | name: openshift-gitops-operator 19 | source: redhat-operators 20 | sourceNamespace: openshift-marketplace 21 | - kind: ClusterRoleBinding 22 | apiVersion: rbac.authorization.k8s.io/v1 23 | metadata: 24 | name: gitops-cluster-admin 25 | subjects: 26 | - kind: ServiceAccount 27 | name: openshift-gitops-argocd-application-controller 28 | namespace: openshift-gitops 29 | roleRef: 30 | apiGroup: rbac.authorization.k8s.io 31 | kind: ClusterRole 32 | name: cluster-admin 33 | - apiVersion: argoproj.io/v1alpha1 34 | kind: ApplicationSet 35 | metadata: 36 | name: cluster-base-configs 37 | namespace: openshift-gitops 38 | spec: 39 | generators: 40 | - git: 41 | repoURL: "{{ .Values.cluster.gitOpsRepo }}" 42 | revision: HEAD 43 | directories: 44 | - path: argocd/clusters/managed-clusters/{{ .Values.cluster.name }}/live/base-configs 45 | template: 46 | metadata: 47 | name: '{{ "{{ path.basename }}" }}' 48 | spec: 49 | project: default 50 | syncPolicy: 51 | automated: {} 52 | destination: 53 | namespace: openshift-gitops 54 | server: "https://kubernetes.default.svc" 55 | source: 56 | repoURL: "{{ .Values.cluster.gitOpsRepo }}" 57 | targetRevision: HEAD 58 | path: '{{ "{{ path }}" }}' 59 | {{ end }} 60 | -------------------------------------------------------------------------------- /ansible/playbooks/e2e-demo/snow_deploy_cluster.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | gather_facts: false 3 | tasks: 4 | - name: auto platform - set platform based for gpu 5 | ansible.builtin.set_fact: 6 | cluster_platform: openstack 7 | when: snow_cluster_platform == "auto" and cluster_special_feature == "gpu" 8 | 9 | - name: auto platform - set platform based for virt 10 | ansible.builtin.set_fact: 11 | cluster_platform: infra_env_hybrid 12 | when: snow_cluster_platform == "auto" and cluster_special_feature == "virtualization" 13 | 14 | - name: auto platform - default to openstack 15 | ansible.builtin.set_fact: 16 | cluster_platform: openstack 17 | when: snow_cluster_platform == "auto" and cluster_special_feature not in ["gpu", "virtualization"] 18 | 19 | - name: set cluster_platform based on non-auto snow_cluster_platform 20 | ansible.builtin.set_fact: 21 | cluster_platform: "{{ snow_cluster_platform }}" 22 | when: snow_cluster_platform != "auto" 23 | 24 | - name: update platform in SNOW 25 | servicenow.itsm.api: 26 | resource: "{{ service_now['cluster_info_table'] }}" 27 | action: patch 28 | sys_id: "{{ snow_record_id }}" 29 | data: 30 | platform: "{{ cluster_platform }}" 31 | 32 | - name: run cluster deployment 33 | ansible.builtin.import_playbook: ../deploy_cluster.yml 34 | 35 | - hosts: localhost 36 | gather_facts: false 37 | tasks: 38 | - name: wait up to one hour for ManagedClusterAvailable 39 | kubernetes.core.k8s_info: 40 | api_version: cluster.open-cluster-management.io/v1 41 | kind: ManagedCluster 42 | name: "{{ cluster_name }}" 43 | wait_condition: 44 | type: ManagedClusterConditionAvailable 45 | status: "True" 46 | reason: "ManagedClusterAvailable" 47 | wait: true 48 | wait_sleep: 45 49 | wait_timeout: 3600 50 | 51 | - name: update cluster status and console url in SNOW 52 | servicenow.itsm.api: 53 | resource: "{{ service_now['cluster_info_table'] }}" 54 | action: patch 55 | sys_id: "{{ snow_record_id }}" 56 | data: 57 | status: "Running" 58 | console_url: "https://console-openshift-console.apps.{{ cluster_name }}.{{ base_domain }}" 59 | -------------------------------------------------------------------------------- /ansible/roles/gitops_cluster_build/templates/vsphere-install-config.yaml.j2: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | metadata: 3 | name: {{ cluster_name }} 4 | baseDomain: {{ base_domain }} 5 | 6 | controlPlane: 7 | hyperthreading: Enabled 8 | name: master 9 | replicas: {{ vsphere_platform_config['cluster_sizes'][cluster_size]['controller_count'] }} 10 | platform: 11 | vsphere: 12 | cpus: {{ vsphere_platform_config['cluster_sizes'][cluster_size]['controller_vcpu'] }} 13 | coresPerSocket: 2 14 | memoryMB: {{ vsphere_platform_config['cluster_sizes'][cluster_size]['controller_ram'] }} 15 | osDisk: 16 | diskSizeGB: {{ vsphere_platform_config['cluster_sizes'][cluster_size]['controller_disk'] }} 17 | compute: 18 | - hyperthreading: Enabled 19 | name: worker 20 | replicas: {{ vsphere_platform_config['cluster_sizes'][cluster_size]['worker_count'] }} 21 | platform: 22 | vsphere: 23 | cpus: {{ vsphere_platform_config['cluster_sizes'][cluster_size]['worker_vcpu'] }} 24 | coresPerSocket: 2 25 | memoryMB: {{ vsphere_platform_config['cluster_sizes'][cluster_size]['worker_ram'] }} 26 | osDisk: 27 | diskSizeGB: {{ vsphere_platform_config['cluster_sizes'][cluster_size]['worker_disk'] }} 28 | 29 | networking: 30 | networkType: OVNKubernetes 31 | clusterNetwork: 32 | - cidr: 10.128.0.0/14 33 | hostPrefix: 23 34 | machineNetwork: 35 | - cidr: {{ vsphere_platform_config['node_prefix'] }} 36 | serviceNetwork: 37 | - 172.30.0.0/16 38 | 39 | platform: 40 | vsphere: 41 | username: "{{ lookup('env', 'VMWARE_USER') }}" 42 | password: "{{ lookup('env', 'VMWARE_PASSWORD') }}" 43 | apiVIP: {{ internal_api_vip }} 44 | ingressVIP: {{ internal_ingress_vip }} 45 | vCenter: {{ vsphere_platform_config['vcenter'] }} 46 | diskType: {{ vsphere_platform_config['disk_type'] }} 47 | datacenter: {{ vsphere_platform_config['datacenter'] }} 48 | cluster: {{ vsphere_platform_config['cluster'] }} 49 | defaultDatastore: {{ vsphere_platform_config['datastore'] }} 50 | network: {{ vsphere_platform_config['network'] }} 51 | {% if vsphere_platform_config.get('folder', None) %} 52 | folder: {{ vsphere_platform_config['folder'] | default("null") }} 53 | {% endif %} 54 | 55 | additionalTrustBundle: | 56 | {{ cluster_trust_bundle | indent(2) }} 57 | 58 | pullSecret: "" 59 | sshKey: "{{ cluster_ssh_pubkey }}" 60 | -------------------------------------------------------------------------------- /charts/mce-cluster-build/templates/install-config-secret.yaml: -------------------------------------------------------------------------------- 1 | {{- if not (has .Values.provider.type (list "InfraEnv" "vSphere")) -}} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: {{ .Values.cluster.name }}-install-config 6 | namespace: {{ .Values.cluster.name }} 7 | annotations: 8 | argocd.argoproj.io/sync-wave: '0' 9 | type: Opaque 10 | stringData: 11 | install-config.yaml: | 12 | apiVersion: v1 13 | metadata: 14 | name: {{ .Values.cluster.name }} 15 | baseDomain: {{ .Values.cluster.baseDomain }} 16 | {{ if .Values.cluster.sshPubKey }} 17 | sshKey: {{ .Values.cluster.sshPubKey }} 18 | {{ end }} 19 | controlPlane: 20 | hyperthreading: Enabled 21 | name: master 22 | replicas: {{ .Values.cluster.controlPlaneCount }} 23 | platform: 24 | {{ if eq .Values.provider.type "OpenStack" }} 25 | openstack: 26 | type: {{ .Values.provider.openstack.controlPlaneFlavor }} 27 | {{ if .Values.provider.openstack.computeAZs }} 28 | zones: {{ toRawJson .Values.provider.openstack.computeAZs }} 29 | {{ end }} 30 | {{ end }} 31 | compute: 32 | - hyperthreading: Enabled 33 | name: 'worker' 34 | replicas: {{ .Values.cluster.workerCount }} 35 | platform: 36 | {{ if eq .Values.provider.type "OpenStack" }} 37 | openstack: 38 | type: {{ .Values.provider.openstack.workerFlavor }} 39 | {{ if .Values.provider.openstack.computeAZs }} 40 | zones: {{ toRawJson .Values.provider.openstack.computeAZs }} 41 | {{ end }} 42 | {{ end }} 43 | networking: 44 | networkType: OVNKubernetes 45 | clusterNetwork: 46 | - cidr: 10.128.0.0/14 47 | hostPrefix: 23 48 | machineNetwork: 49 | - cidr: 10.0.1.0/24 50 | serviceNetwork: 51 | - 172.30.0.0/16 52 | platform: 53 | {{ if eq .Values.provider.type "OpenStack" }} 54 | openstack: 55 | {{ if .Values.provider.openstack.existingImage }} 56 | clusterOSImage: {{ .Values.provider.openstack.existingImage }} 57 | {{ end }} 58 | cloud: openstack 59 | externalNetwork: {{ .Values.provider.openstack.externalNetwork }} 60 | lbFloatingIP: {{ .Values.cluster.apiVIP }} 61 | ingressFloatingIP: {{ .Values.cluster.ingressVIP }} 62 | apiVIP: 10.0.1.5 63 | ingressVIP: 10.0.1.7 64 | externalDNS: {{ toRawJson .Values.cluster.dnsServers }} 65 | {{ end }} 66 | {{- end -}} 67 | -------------------------------------------------------------------------------- /charts/mce-cluster-build/templates/cluster-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: hive.openshift.io/v1 2 | kind: ClusterDeployment 3 | metadata: 4 | name: {{ .Values.cluster.name }} 5 | namespace: {{ .Values.cluster.name }} 6 | labels: 7 | cloud: {{ .Values.provider.type }} 8 | vendor: 'OpenShift' 9 | annotations: 10 | argocd.argoproj.io/sync-wave: '1' 11 | spec: 12 | {{ if eq .Values.provider.type "InfraEnv" }} 13 | clusterInstallRef: 14 | group: extensions.hive.openshift.io 15 | kind: AgentClusterInstall 16 | name: {{ .Values.cluster.name }} 17 | version: v1beta1 18 | {{ end }} 19 | baseDomain: {{ .Values.cluster.baseDomain }} 20 | clusterName: {{ .Values.cluster.name }} 21 | controlPlaneConfig: 22 | servingCertificates: {} 23 | installAttemptsLimit: 3 24 | installed: false 25 | platform: 26 | {{ if eq .Values.provider.type "InfraEnv" }} 27 | agentBareMetal: 28 | agentSelector: 29 | matchLabels: 30 | agentclusterinstalls.extensions.hive.openshift.io/location: {{ .Values.cluster.name }} 31 | {{ end }} 32 | {{ if eq .Values.provider.type "vSphere" }} 33 | vsphere: 34 | certificatesSecretRef: 35 | name: {{ .Values.cluster.name }}-trust 36 | cluster: {{ .Values.provider.vsphere.cluster }} 37 | credentialsSecretRef: 38 | name: {{ .Values.cluster.name }}-provider-creds 39 | datacenter: {{ .Values.provider.vsphere.datacenter }} 40 | defaultDatastore: {{ .Values.provider.vsphere.defaultDatastore }} 41 | network: {{ .Values.provider.vsphere.network }} 42 | vCenter: {{ .Values.provider.vsphere.vcenterHost }} 43 | {{ if .Values.provider.vsphere.folder }} 44 | folder: {{ .Values.provider.vsphere.folder }} 45 | {{ end }} 46 | {{ end }} 47 | {{ if eq .Values.provider.type "OpenStack" }} 48 | openstack: 49 | certificatesSecretRef: 50 | name: {{ .Values.cluster.name }}-trust 51 | credentialsSecretRef: 52 | name: {{ .Values.cluster.name }}-provider-creds 53 | cloud: openstack 54 | {{ end }} 55 | {{ if not (eq .Values.provider.type "InfraEnv") }} 56 | provisioning: 57 | installConfigSecretRef: 58 | name: {{ .Values.cluster.name }}-install-config 59 | sshPrivateKeySecretRef: 60 | name: {{ .Values.cluster.name }}-ssh-key 61 | {{ if .Values.cluster.clusterImageSet }} 62 | imageSetRef: 63 | name: {{ .Values.cluster.clusterImageSet }} 64 | {{ end }} 65 | {{ if .Values.cluster.releaseImage }} 66 | releaseImage: {{ .Values.cluster.releaseImage }} 67 | {{ end }} 68 | {{ end }} 69 | pullSecretRef: 70 | name: {{ .Values.cluster.name }}-pull-secret 71 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/rhacm-base/mco.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: observability.open-cluster-management.io/v1beta2 2 | kind: MultiClusterObservability 3 | metadata: 4 | name: observability 5 | annotations: 6 | argocd.argoproj.io/sync-wave: "3" 7 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 8 | spec: 9 | enableDownsampling: true 10 | advanced: 11 | retentionConfig: 12 | blockDuration: 3h 13 | deleteDelay: 50h 14 | retentionInLocal: 5d 15 | retentionResolution1h: 31d 16 | retentionResolution5m: 15d 17 | retentionResolutionRaw: 6d 18 | observatoriumAPI: 19 | resources: 20 | limits: 21 | memory: 1Gi 22 | replicas: 1 23 | queryFrontend: 24 | resources: 25 | limits: 26 | memory: 1Gi 27 | replicas: 1 28 | query: 29 | resources: 30 | limits: 31 | memory: 1Gi 32 | replicas: 1 33 | compact: 34 | resources: 35 | limits: 36 | memory: 2Gi 37 | receive: 38 | resources: 39 | limits: 40 | memory: 4Gi 41 | replicas: 1 42 | rule: 43 | resources: 44 | limits: 45 | memory: 1Gi 46 | replicas: 1 47 | store: 48 | resources: 49 | limits: 50 | memory: 2Gi 51 | replicas: 1 52 | storeMemcached: 53 | resources: 54 | limits: 55 | memory: 2Gi 56 | replicas: 1 57 | memoryLimitMb: 2048 58 | maxItemSize: 2m 59 | connectionLimit: 2048 60 | queryFrontendMemcached: 61 | resources: 62 | limits: 63 | memory: 2Gi 64 | replicas: 1 65 | memoryLimitMb: 2048 66 | maxItemSize: 2m 67 | connectionLimit: 2048 68 | grafana: 69 | replicas: 1 70 | resources: 71 | limits: 72 | memory: 1Gi 73 | alertmanager: 74 | replicas: 1 75 | resources: 76 | limits: 77 | memory: 400Mi 78 | rbacQueryProxy: 79 | replicas: 1 80 | resources: 81 | limits: 82 | memory: 200Mi 83 | nodeSelector: 84 | kubernetes.io/os: linux 85 | observabilityAddonSpec: 86 | enableMetrics: true 87 | interval: 30 88 | resources: 89 | limits: 90 | memory: 700Mi 91 | requests: 92 | cpu: 10m 93 | memory: 100Mi 94 | storageConfig: 95 | alertmanagerStorageSize: 1Gi 96 | compactStorageSize: 50Gi 97 | metricObjectStorage: 98 | key: thanos.yaml 99 | name: thanos-object-storage 100 | receiveStorageSize: 50Gi 101 | ruleStorageSize: 1Gi 102 | storageClass: ocs-external-storagecluster-ceph-rbd 103 | storeStorageSize: 5Gi 104 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/base-config/base-config-app.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: base-config-chart 5 | namespace: openshift-gitops 6 | spec: 7 | destination: 8 | namespace: openshift-gitops 9 | server: "https://kubernetes.default.svc" 10 | project: default 11 | syncPolicy: 12 | automated: {} 13 | source: 14 | repoURL: "https://github.com/marbindrakon/signal9-lab-gitops.git" 15 | path: "charts/ocp-base-config" 16 | targetRevision: HEAD 17 | helm: 18 | values: | 19 | cluster: 20 | name: rhte-acm-hub 21 | baseDomain: lab.signal9.gg 22 | gitOpsRepo: "https://github.com/marbindrakon/signal9-lab-gitops.git" 23 | trustedCABundle: | 24 | -----BEGIN CERTIFICATE----- 25 | MIICkTCCAhagAwIBAgIUX1Cm8VWt4ki4+8XH7oKsYYKJM+QwCgYIKoZIzj0EAwIw 26 | dzELMAkGA1UEBhMCVVMxETAPBgNVBAgMCEFya2Fuc2FzMQ8wDQYDVQQHDAZSb2dl 27 | cnMxFTATBgNVBAoMDFNpZ25hbDkgTGFiczEMMAoGA1UECwwDWE5BMR8wHQYDVQQD 28 | DBZTaWduYWw5IFJvb3QgQXV0aG9yaXR5MB4XDTIxMDMwMTA0MDMwNFoXDTQxMDIy 29 | NDA0MDMwNFowdzELMAkGA1UEBhMCVVMxETAPBgNVBAgMCEFya2Fuc2FzMQ8wDQYD 30 | VQQHDAZSb2dlcnMxFTATBgNVBAoMDFNpZ25hbDkgTGFiczEMMAoGA1UECwwDWE5B 31 | MR8wHQYDVQQDDBZTaWduYWw5IFJvb3QgQXV0aG9yaXR5MHYwEAYHKoZIzj0CAQYF 32 | K4EEACIDYgAE5w5BHLiaagf5eSNkQYuDIdyWe7ULLY2z2qAP1fKXM+RrSHQQb5x1 33 | Q9+IhQRhf7exw/pJS5Vs1R8IyQ3B8r6xz885w6+Fk6iyMAlFn979RU6V5lbxMRGG 34 | Vxq/CEL/iorVo2MwYTAdBgNVHQ4EFgQUYfO+q+KnTtIDK5OFXsVZ/D0ziiUwHwYD 35 | VR0jBBgwFoAUYfO+q+KnTtIDK5OFXsVZ/D0ziiUwDwYDVR0TAQH/BAUwAwEB/zAO 36 | BgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwIDaQAwZgIxAJLOIPP9J1/mttvGdQtM 37 | Prnm+r+JzVu8vd0r2HxgwloEkElTr29S+DAAE8XlUpoXpQIxALEd+sYGr1qENJqr 38 | vHOvuo0diFSUxjvTjowus6kM6nZi1JR4rMycICsGgujg8zwVAw== 39 | -----END CERTIFICATE----- 40 | monitoring: 41 | enabled: false 42 | externalSecrets: 43 | vaultAuthPath: 'k8s-rhte-acm-hub' 44 | odfStorage: 45 | enabled: true 46 | external: true 47 | network: 48 | hostRouting: true 49 | certManager: 50 | solvers: 51 | - http01: 52 | ingress: {} 53 | - dns01: 54 | route53: 55 | # Required prior to 1.9 when this can be moved to a 56 | # secret and pulled from vault like the secret key 57 | accessKeyID: AKIAR3Z7ELN7VLNNHZHZ 58 | region: us-east-1 59 | secretAccessKeySecretRef: 60 | key: secret-access-key 61 | name: route53-key 62 | selector: 63 | dnsZones: 64 | - signal9.gg 65 | - lab.signal9.gg 66 | -------------------------------------------------------------------------------- /ansible/roles/sso_client/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: read serviceaccount token 3 | no_log: true 4 | ansible.builtin.set_fact: 5 | vault_jwt: "{{ lookup('ansible.builtin.file', hashicorp_vault['jwt_location']) }}" 6 | when: vault_jwt is not defined 7 | 8 | - name: ensure sso client state 9 | community.general.keycloak_client: 10 | auth_keycloak_url: "{{ cluster_sso['sso_url'] }}" 11 | auth_realm: "{{ cluster_sso['admin_realm'] }}" 12 | auth_username: "{{ sso_admin_user }}" 13 | auth_password: "{{ sso_admin_password }}" 14 | client_id: "{{ cluster_sso['client_id'] }}" 15 | public_client: false 16 | client_authenticator_type: client-secret 17 | protocol: openid-connect 18 | enabled: true 19 | realm: "{{ cluster_sso['client_realm'] }}" 20 | redirect_uris: 21 | - "https://oauth-openshift.apps.{{ cluster_name }}.{{ base_domain }}/oauth2callback/{{ cluster_sso['console_sso_label'] }}" 22 | protocol_mappers: 23 | - name: "client roles" 24 | consentRequired: false 25 | protocol: "openid-connect" 26 | protocolMapper: "oidc-usermodel-client-role-mapper" 27 | config: 28 | access.token.claim: true 29 | claim.name: groups 30 | id.token.claim: true 31 | jsonType.label: String 32 | multivalued: true 33 | usermodel.clientRoleMapping.clientId: "{{ cluster_sso['role_source_client'] }}" 34 | state: "{{ cluster_state }}" 35 | 36 | - name: get client secret for client 37 | community.general.keycloak_clientsecret_info: 38 | auth_keycloak_url: "{{ cluster_sso['sso_url'] }}" 39 | auth_realm: "{{ cluster_sso['admin_realm'] }}" 40 | auth_username: "{{ sso_admin_user }}" 41 | auth_password: "{{ sso_admin_password }}" 42 | client_id: "{{ cluster_sso['client_id'] }}" 43 | realm: "{{ cluster_sso['client_realm'] }}" 44 | no_log: true 45 | register: sso_client_secret_resp 46 | when: cluster_state == "present" 47 | 48 | - name: write client secret to vault 49 | community.hashi_vault.vault_write: 50 | url: "{{ hashicorp_vault['url'] }}" 51 | auth_method: jwt 52 | mount_point: "{{ hashicorp_vault['auth_mount'] }}" 53 | role_id: "{{ hashicorp_vault['auth_role'] }}" 54 | jwt: "{{ vault_jwt }}" 55 | path: "{{ hashicorp_vault['secret_base_path'] }}/data/{{ hashicorp_vault['cluster_secrets']['oidc'] }}" 56 | data: 57 | data: 58 | clientSecret: "{{ sso_client_secret_resp.clientsecret_info.value }}" 59 | no_log: true 60 | when: cluster_state == "present" 61 | 62 | - name: delete client secret from vault 63 | community.hashi_vault.vault_delete: 64 | url: "{{ hashicorp_vault['url'] }}" 65 | auth_method: jwt 66 | mount_point: "{{ hashicorp_vault['auth_mount'] }}" 67 | role_id: "{{ hashicorp_vault['auth_role'] }}" 68 | jwt: "{{ vault_jwt }}" 69 | path: "{{ hashicorp_vault['secret_base_path'] }}/data/{{ hashicorp_vault['cluster_secrets']['oidc'] }}" 70 | no_log: true 71 | when: cluster_state == "absent" 72 | -------------------------------------------------------------------------------- /ansible/roles/resource_allocation/tasks/providers/openstack.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Allocate FIPs using openstack CLI until openstack.cloud.floating_ip 3 | # supports creating a FIP without a server reference 4 | 5 | - name: check for existing api fip 6 | ansible.builtin.command: 7 | cmd: /usr/local/bin/openstack floating ip list --os-cloud devstack -f json --tags "{{ cluster_name|quote }}-api" 8 | register: api_fip_query 9 | 10 | - name: check for existing ingress fip 11 | ansible.builtin.command: 12 | cmd: /usr/local/bin/openstack floating ip list --os-cloud devstack -f json --tags "{{ cluster_name|quote }}-ingress" 13 | register: ingress_fip_query 14 | 15 | - name: parse existing floating ip queries 16 | set_fact: 17 | openstack_existing_api_fip: "{{ api_fip_query.stdout | from_json }}" 18 | openstack_existing_ingress_fip: "{{ ingress_fip_query.stdout | from_json }}" 19 | 20 | - name: return existing api fip 21 | set_fact: 22 | internal_api_vip: "{{ openstack_existing_api_fip[0]['Floating IP Address'] }}" 23 | when: (openstack_existing_api_fip) 24 | 25 | - name: return existing ingress fip 26 | set_fact: 27 | internal_ingress_vip: "{{ openstack_existing_ingress_fip[0]['Floating IP Address'] }}" 28 | when: (openstack_existing_ingress_fip) 29 | 30 | - name: allocate api floating ip 31 | ansible.builtin.command: 32 | cmd: /usr/local/bin/openstack floating ip create --os-cloud devstack -f value -c floating_ip_address --tag "{{ cluster_name|quote }}-api" "{{ openstack_platform_config['vip_network']|quote }}" 33 | register: api_fip_cmd 34 | when: cluster_state == "present" and not (openstack_existing_api_fip) 35 | 36 | - name: allocate ingress floating ip 37 | ansible.builtin.command: 38 | cmd: /usr/local/bin/openstack floating ip create --os-cloud devstack -f value -c floating_ip_address --tag "{{ cluster_name|quote }}-ingress" "{{ openstack_platform_config['vip_network']|quote }}" 39 | register: ingress_fip_cmd 40 | when: cluster_state == "present" and not (openstack_existing_ingress_fip) 41 | 42 | - name: return new api fip 43 | set_fact: 44 | internal_api_vip: "{{ api_fip_cmd.stdout }}" 45 | when: cluster_state == "present" and not (openstack_existing_api_fip) 46 | 47 | - name: return new ingress fip 48 | set_fact: 49 | internal_ingress_vip: "{{ ingress_fip_cmd.stdout }}" 50 | when: cluster_state == "present" and not (openstack_existing_ingress_fip) 51 | 52 | - name: delete api fip 53 | ansible.builtin.command: 54 | cmd: /usr/local/bin/openstack floating ip delete --os-cloud devstack "{{ fip_to_delete['ID'] | quote }}" 55 | when: cluster_state == "absent" and (openstack_existing_api_fip) 56 | loop_control: 57 | loop_var: fip_to_delete 58 | loop: "{{ openstack_existing_api_fip }}" 59 | 60 | - name: delete ingress fip 61 | ansible.builtin.command: 62 | cmd: /usr/local/bin/openstack floating ip delete --os-cloud devstack "{{ fip_to_delete['ID'] | quote }}" 63 | when: cluster_state == "absent" and (openstack_existing_ingress_fip) 64 | loop_control: 65 | loop_var: fip_to_delete 66 | loop: "{{ openstack_existing_ingress_fip }}" 67 | 68 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/rhacm-base/hive-ca-bundle.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: signal9-ca-bundle 5 | namespace: hive 6 | annotations: 7 | argocd.argoproj.io/sync-wave: '3' 8 | stringData: 9 | ca.crt: | 10 | -----BEGIN CERTIFICATE----- 11 | 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 40 | -----END CERTIFICATE----- 41 | -----BEGIN CERTIFICATE----- 42 | MIICkTCCAhagAwIBAgIUX1Cm8VWt4ki4+8XH7oKsYYKJM+QwCgYIKoZIzj0EAwIw 43 | dzELMAkGA1UEBhMCVVMxETAPBgNVBAgMCEFya2Fuc2FzMQ8wDQYDVQQHDAZSb2dl 44 | cnMxFTATBgNVBAoMDFNpZ25hbDkgTGFiczEMMAoGA1UECwwDWE5BMR8wHQYDVQQD 45 | DBZTaWduYWw5IFJvb3QgQXV0aG9yaXR5MB4XDTIxMDMwMTA0MDMwNFoXDTQxMDIy 46 | NDA0MDMwNFowdzELMAkGA1UEBhMCVVMxETAPBgNVBAgMCEFya2Fuc2FzMQ8wDQYD 47 | VQQHDAZSb2dlcnMxFTATBgNVBAoMDFNpZ25hbDkgTGFiczEMMAoGA1UECwwDWE5B 48 | MR8wHQYDVQQDDBZTaWduYWw5IFJvb3QgQXV0aG9yaXR5MHYwEAYHKoZIzj0CAQYF 49 | K4EEACIDYgAE5w5BHLiaagf5eSNkQYuDIdyWe7ULLY2z2qAP1fKXM+RrSHQQb5x1 50 | Q9+IhQRhf7exw/pJS5Vs1R8IyQ3B8r6xz885w6+Fk6iyMAlFn979RU6V5lbxMRGG 51 | Vxq/CEL/iorVo2MwYTAdBgNVHQ4EFgQUYfO+q+KnTtIDK5OFXsVZ/D0ziiUwHwYD 52 | VR0jBBgwFoAUYfO+q+KnTtIDK5OFXsVZ/D0ziiUwDwYDVR0TAQH/BAUwAwEB/zAO 53 | BgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwIDaQAwZgIxAJLOIPP9J1/mttvGdQtM 54 | Prnm+r+JzVu8vd0r2HxgwloEkElTr29S+DAAE8XlUpoXpQIxALEd+sYGr1qENJqr 55 | vHOvuo0diFSUxjvTjowus6kM6nZi1JR4rMycICsGgujg8zwVAw== 56 | -----END CERTIFICATE----- 57 | -------------------------------------------------------------------------------- /ansible/roles/resource_allocation/tasks/providers/vsphere.yml: -------------------------------------------------------------------------------- 1 | - name: query existing internal VIPs 2 | ansible.builtin.set_fact: 3 | nb_existing_int_api_query: "{{ query('netbox.netbox.nb_lookup', 'ip-addresses', api_filter='description=' + cluster_name + '-Internal-API') | items2dict}}" 4 | nb_existing_int_ingress_query: "{{ query('netbox.netbox.nb_lookup', 'ip-addresses', api_filter='description=' + cluster_name + '-Internal-Ingress') | items2dict }}" 5 | 6 | - name: set internal API VIP based on existing records 7 | ansible.builtin.set_fact: 8 | internal_api_vip: "{{ nb_existing_int_api_query.values() | map(attribute='address') | first | ansible.netcommon.ipaddr('address') }}" 9 | internal_api_cidr: "{{ nb_existing_int_api_query.values() | map(attribute='address') | first }}" 10 | when: 11 | - nb_existing_int_api_query is defined 12 | - nb_existing_int_api_query | length > 0 13 | 14 | - name: set internal ingress VIP based on existing records 15 | ansible.builtin.set_fact: 16 | internal_ingress_vip: "{{ nb_existing_int_ingress_query.values() | map(attribute='address') | first | ansible.netcommon.ipaddr('address') }}" 17 | internal_ingress_cidr: "{{ nb_existing_int_ingress_query.values() | map(attribute='address') | first }}" 18 | when: 19 | - nb_existing_int_ingress_query is defined 20 | - nb_existing_int_ingress_query | length > 0 21 | 22 | - name: allocate internal API VIP 23 | netbox.netbox.netbox_ip_address: 24 | netbox_url: "{{ lookup('env', 'NETBOX_URL') }}" 25 | netbox_token: "{{ lookup('env', 'NETBOX_TOKEN') }}" 26 | state: new 27 | data: 28 | prefix: "{{ vsphere_platform_config['node_prefix'] }}" 29 | role: VIP 30 | dns_name: "api.{{ cluster_name }}.{{ base_domain }}" 31 | description: "{{ cluster_name }}-Internal-API" 32 | register: nb_internal_api_create 33 | when: 34 | - loadbalancer_type == "internal" or expose_internal_loadbalancers|bool 35 | - cluster_state == "present" 36 | - internal_api_vip is not defined 37 | 38 | - name: set internal API VIP based on new record 39 | ansible.builtin.set_fact: 40 | internal_api_vip: "{{ nb_internal_api_create.ip_address.address | ansible.netcommon.ipaddr('address') }}" 41 | internal_api_cidr: "{{ nb_internal_api_create.ip_address.address }}" 42 | when: 43 | - internal_api_vip is not defined 44 | - nb_internal_api_create is defined 45 | - nb_internal_api_create.ip_address is defined 46 | 47 | - name: allocate internal ingress VIP 48 | netbox.netbox.netbox_ip_address: 49 | netbox_url: "{{ lookup('env', 'NETBOX_URL') }}" 50 | netbox_token: "{{ lookup('env', 'NETBOX_TOKEN') }}" 51 | state: new 52 | data: 53 | prefix: "{{ vsphere_platform_config['node_prefix'] }}" 54 | role: VIP 55 | dns_name: "apps.{{ cluster_name }}.{{ base_domain }}" 56 | description: "{{ cluster_name }}-Internal-Ingress" 57 | register: nb_internal_ingress_create 58 | when: 59 | - cluster_state == "present" 60 | - internal_ingress_vip is not defined 61 | 62 | - name: set internal ingress VIP based on new record 63 | set_fact: 64 | internal_ingress_vip: "{{ nb_internal_ingress_create.ip_address.address | ansible.netcommon.ipaddr('address') }}" 65 | internal_ingress_cidr: "{{ nb_internal_ingress_create.ip_address.address }}" 66 | when: 67 | - internal_ingress_vip is not defined 68 | - nb_internal_ingress_create is defined 69 | - nb_internal_ingress_create.ip_address is defined 70 | 71 | - name: deallocate internal API VIP 72 | netbox.netbox.netbox_ip_address: 73 | netbox_url: "{{ lookup('env', 'NETBOX_URL') }}" 74 | netbox_token: "{{ lookup('env', 'NETBOX_TOKEN') }}" 75 | state: absent 76 | data: 77 | address: "{{ internal_api_cidr }}" 78 | register: nb_internal_api_create 79 | when: 80 | - cluster_state == "absent" 81 | - internal_api_vip is defined 82 | 83 | - name: deallocate internal ingress VIP 84 | netbox.netbox.netbox_ip_address: 85 | netbox_url: "{{ lookup('env', 'NETBOX_URL') }}" 86 | netbox_token: "{{ lookup('env', 'NETBOX_TOKEN') }}" 87 | state: absent 88 | data: 89 | address: "{{ internal_ingress_cidr }}" 90 | register: nb_internal_ingress_create 91 | when: 92 | - cluster_state == "absent" 93 | - internal_ingress_vip is defined 94 | -------------------------------------------------------------------------------- /ansible/roles/vault_config/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: read serviceaccount token 3 | no_log: true 4 | ansible.builtin.set_fact: 5 | vault_jwt: "{{ lookup('ansible.builtin.file', hashicorp_vault['jwt_location']) }}" 6 | 7 | - name: list enabled auth methods 8 | community.hashi_vault.vault_read: 9 | url: "{{ hashicorp_vault['url'] }}" 10 | auth_method: jwt 11 | mount_point: "{{ hashicorp_vault['auth_mount'] }}" 12 | role_id: "{{ hashicorp_vault['auth_role'] }}" 13 | jwt: "{{ vault_jwt }}" 14 | path: "sys/auth" 15 | failed_when: vault_existing_auth_raw.data is not defined and "doesn't seem to exist" not in vault_existing_auth_raw.msg 16 | register: vault_existing_auth_raw 17 | 18 | - name: save existing auth method 19 | ansible.builtin.set_fact: 20 | vault_existing_auth: "{{ vault_existing_auth_raw.data.get(hashicorp_vault['vault_managed_auth_name'] +'/', {}) }}" 21 | 22 | - name: create k8s auth method 23 | block: 24 | - name: Get kubeconfig secret 25 | kubernetes.core.k8s_info: 26 | api_version: v1 27 | kind: Secret 28 | namespace: "{{ cluster_name }}" 29 | label_selectors: 30 | - "hive.openshift.io/secret-type=kubeconfig" 31 | wait: true 32 | wait_sleep: 10 33 | wait_timeout: 1200 34 | register: kubeconfig_secret 35 | until: kubeconfig_secret.resources | length > 0 36 | retries: 120 37 | delay: 10 38 | no_log: true 39 | 40 | - name: load cluster kubeconfig 41 | ansible.builtin.set_fact: 42 | cluster_kubeconfig: "{{ kubeconfig_secret.resources.0.data.kubeconfig | b64decode | from_yaml }}" 43 | no_log: true 44 | 45 | - name: extract initial api ca bundle and combine with inventory 46 | ansible.builtin.set_fact: 47 | vault_k8s_ca_bundle: | 48 | {{ cluster_kubeconfig['clusters'][0]['cluster']['certificate-authority-data'] | b64decode }} 49 | {{ cluster_trust_bundle }} 50 | 51 | - name: write k8s auth method to vault 52 | community.hashi_vault.vault_write: 53 | url: "{{ hashicorp_vault['url'] }}" 54 | auth_method: jwt 55 | mount_point: "{{ hashicorp_vault['auth_mount'] }}" 56 | role_id: "{{ hashicorp_vault['auth_role'] }}" 57 | jwt: "{{ vault_jwt }}" 58 | path: "sys/auth/{{ hashicorp_vault['vault_managed_auth_name'] }}" 59 | data: 60 | type: kubernetes 61 | kubernetes_host: "https://api.{{ cluster_name }}.{{ base_domain }}:6443" 62 | kubernetes_ca_cert: "{{ vault_k8s_ca_bundle }}" 63 | disable_local_ca_jwt: true 64 | disable_iss_validation: true 65 | 66 | - name: write k8s auth method config to vault 67 | community.hashi_vault.vault_write: 68 | url: "{{ hashicorp_vault['url'] }}" 69 | auth_method: jwt 70 | mount_point: "{{ hashicorp_vault['auth_mount'] }}" 71 | role_id: "{{ hashicorp_vault['auth_role'] }}" 72 | jwt: "{{ vault_jwt }}" 73 | path: "auth/{{ hashicorp_vault['vault_managed_auth_name'] }}/config" 74 | data: 75 | kubernetes_host: "https://api.{{ cluster_name }}.{{ base_domain }}:6443" 76 | kubernetes_ca_cert: "{{ vault_k8s_ca_bundle }}" 77 | disable_local_ca_jwt: true 78 | disable_iss_validation: true 79 | 80 | - name: write external-secrets-operator role to vault 81 | community.hashi_vault.vault_write: 82 | url: "{{ hashicorp_vault['url'] }}" 83 | auth_method: jwt 84 | mount_point: "{{ hashicorp_vault['auth_mount'] }}" 85 | role_id: "{{ hashicorp_vault['auth_role'] }}" 86 | jwt: "{{ vault_jwt }}" 87 | path: "auth/{{ hashicorp_vault['vault_managed_auth_name'] }}/role/external-secrets-operator" 88 | data: 89 | alias_name_source: serviceaccount_uid 90 | bound_service_account_names: 91 | - external-secrets-operator 92 | bound_service_account_namespaces: 93 | - external-secrets-operator 94 | token_policies: 95 | - "{{ hashicorp_vault['cluster_policy'] }}" 96 | 97 | when: cluster_state == "present" and not (vault_existing_auth) 98 | 99 | - name: remove auth method 100 | community.hashi_vault.vault_delete: 101 | url: "{{ hashicorp_vault['url'] }}" 102 | auth_method: jwt 103 | mount_point: "{{ hashicorp_vault['auth_mount'] }}" 104 | role_id: "{{ hashicorp_vault['auth_role'] }}" 105 | jwt: "{{ vault_jwt }}" 106 | path: "sys/auth/{{ hashicorp_vault['vault_managed_auth_name'] }}" 107 | when: cluster_state == "absent" and (vault_existing_auth) 108 | 109 | -------------------------------------------------------------------------------- /ansible/roles/resource_allocation/tasks/external_vips.yml: -------------------------------------------------------------------------------- 1 | - name: set external VIPs for shared frontend 2 | ansible.builtin.set_fact: 3 | external_api_vip: "{{ loadbalancer_api_shared_vip }}" 4 | external_ingress_vip: "{{ loadbalancer_ingress_shared_vip }}" 5 | when: 6 | - loadbalancer_type == "external" or expose_internal_loadbalancers|bool 7 | - loadbalancer_frontend_mode == "shared" 8 | 9 | - name: query existing external VIPs 10 | ansible.builtin.set_fact: 11 | nb_existing_ext_api_query: "{{ query('netbox.netbox.nb_lookup', 'ip-addresses', api_filter='description=' + cluster_name + '-External-API') | items2dict}}" 12 | nb_existing_ext_ingress_query: "{{ query('netbox.netbox.nb_lookup', 'ip-addresses', api_filter='description=' + cluster_name + '-External-Ingress') | items2dict }}" 13 | when: 14 | - loadbalancer_type == "external" or expose_internal_loadbalancers|bool 15 | - loadbalancer_frontend_mode == "dedicated" 16 | 17 | - name: set external API VIP based on existing records 18 | ansible.builtin.set_fact: 19 | external_api_vip: "{{ nb_existing_ext_api_query.values() | map(attribute='address') | first | ansible.netcommon.ipaddr('address') }}" 20 | external_api_cidr: "{{ nb_existing_ext_api_query.values() | map(attribute='address') | first }}" 21 | when: 22 | - nb_existing_ext_api_query is defined 23 | - nb_existing_ext_api_query | length > 0 24 | 25 | - name: set external ingress VIP based on existing records 26 | ansible.builtin.set_fact: 27 | external_ingress_vip: "{{ nb_existing_ext_ingress_query.values() | map(attribute='address') | first | ansible.netcommon.ipaddr('address') }}" 28 | external_ingress_cidr: "{{ nb_existing_ext_ingress_query.values() | map(attribute='address') | first }}" 29 | when: 30 | - nb_existing_ext_ingress_query is defined 31 | - nb_existing_ext_ingress_query | length > 0 32 | 33 | - name: allocate external API VIP 34 | netbox.netbox.netbox_ip_address: 35 | netbox_url: "{{ lookup('env', 'NETBOX_URL') }}" 36 | netbox_token: "{{ lookup('env', 'NETBOX_TOKEN') }}" 37 | state: new 38 | data: 39 | prefix: "{{ external_vip_prefix }}" 40 | role: VIP 41 | dns_name: "api.{{ cluster_name }}.{{ base_domain }}" 42 | description: "{{ cluster_name }}-External-API" 43 | register: nb_external_api_create 44 | when: 45 | - loadbalancer_type == "external" or expose_internal_loadbalancers|bool 46 | - loadbalancer_frontend_mode == "dedicated" 47 | - cluster_state == "present" 48 | - external_api_vip is not defined 49 | 50 | - name: set external API VIP based on new record 51 | ansible.builtin.set_fact: 52 | external_api_vip: "{{ nb_external_api_create.ip_address.address | ansible.netcommon.ipaddr('address') }}" 53 | external_api_cidr: "{{ nb_external_api_create.ip_address.address }}" 54 | when: 55 | - external_api_vip is not defined 56 | - nb_external_api_create is defined 57 | - nb_external_api_create.ip_address is defined 58 | 59 | - name: allocate external ingress VIP 60 | netbox.netbox.netbox_ip_address: 61 | netbox_url: "{{ lookup('env', 'NETBOX_URL') }}" 62 | netbox_token: "{{ lookup('env', 'NETBOX_TOKEN') }}" 63 | state: new 64 | data: 65 | prefix: "{{ external_vip_prefix }}" 66 | role: VIP 67 | dns_name: "apps.{{ cluster_name }}.{{ base_domain }}" 68 | description: "{{ cluster_name }}-External-Ingress" 69 | register: nb_external_ingress_create 70 | when: 71 | - loadbalancer_type == "external" or expose_internal_loadbalancers|bool 72 | - loadbalancer_frontend_mode == "dedicated" 73 | - cluster_state == "present" 74 | - external_ingress_vip is not defined 75 | 76 | - name: set external ingress VIP based on new record 77 | set_fact: 78 | external_ingress_vip: "{{ nb_external_ingress_create.ip_address.address | ansible.netcommon.ipaddr('address') }}" 79 | external_ingress_cidr: "{{ nb_external_ingress_create.ip_address.address }}" 80 | when: 81 | - external_ingress_vip is not defined 82 | - nb_external_ingress_create is defined 83 | - nb_external_ingress_create.ip_address is defined 84 | 85 | - name: deallocate external API VIP 86 | netbox.netbox.netbox_ip_address: 87 | netbox_url: "{{ lookup('env', 'NETBOX_URL') }}" 88 | netbox_token: "{{ lookup('env', 'NETBOX_TOKEN') }}" 89 | state: absent 90 | data: 91 | address: "{{ external_api_cidr }}" 92 | register: nb_external_api_create 93 | when: 94 | - loadbalancer_type == "external" or expose_internal_loadbalancers|bool 95 | - loadbalancer_frontend_mode == "dedicated" 96 | - cluster_state == "absent" 97 | - external_api_vip is defined 98 | 99 | - name: deallocate external ingress VIP 100 | netbox.netbox.netbox_ip_address: 101 | netbox_url: "{{ lookup('env', 'NETBOX_URL') }}" 102 | netbox_token: "{{ lookup('env', 'NETBOX_TOKEN') }}" 103 | state: absent 104 | data: 105 | address: "{{ external_ingress_cidr }}" 106 | register: nb_external_ingress_create 107 | when: 108 | - loadbalancer_type == "external" or expose_internal_loadbalancers|bool 109 | - loadbalancer_frontend_mode == "dedicated" 110 | - cluster_state == "absent" 111 | - external_ingress_vip is defined 112 | -------------------------------------------------------------------------------- /argocd/clusters/rhte-acm-hub/live/rhacm-policies/install-gitops.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy.open-cluster-management.io/v1 2 | kind: Policy 3 | metadata: 4 | name: policy-managed-gitops 5 | namespace: rhacm-hub 6 | annotations: 7 | argocd.argoproj.io/compare-options: IgnoreExtraneous 8 | policy.open-cluster-management.io/standards: NIST SP 800-53 9 | policy.open-cluster-management.io/categories: CM Configuration Management 10 | policy.open-cluster-management.io/controls: CM-2 Baseline Configuration 11 | spec: 12 | remediationAction: enforce 13 | disabled: false 14 | policy-templates: 15 | - objectDefinition: 16 | apiVersion: policy.open-cluster-management.io/v1 17 | kind: ConfigurationPolicy 18 | metadata: 19 | name: policy-managed-argocd-subscription 20 | spec: 21 | remediationAction: enforce 22 | severity: low 23 | namespaceSelector: 24 | exclude: 25 | - kube-* 26 | include: 27 | - default 28 | object-templates: 29 | - complianceType: musthave 30 | objectDefinition: 31 | apiVersion: operators.coreos.com/v1alpha1 32 | kind: Subscription 33 | metadata: 34 | name: openshift-gitops-operator 35 | namespace: openshift-operators 36 | spec: 37 | channel: gitops-1.7 38 | installPlanApproval: Automatic 39 | name: openshift-gitops-operator 40 | source: redhat-operators 41 | sourceNamespace: openshift-marketplace 42 | - objectDefinition: 43 | apiVersion: policy.open-cluster-management.io/v1 44 | kind: ConfigurationPolicy 45 | metadata: 46 | name: policy-managed-argocd-clusterrolebinding 47 | spec: 48 | remediationAction: enforce 49 | severity: low 50 | namespaceSelector: 51 | exclude: 52 | - kube-* 53 | include: 54 | - default 55 | object-templates: 56 | - complianceType: musthave 57 | objectDefinition: 58 | kind: ClusterRoleBinding 59 | apiVersion: rbac.authorization.k8s.io/v1 60 | metadata: 61 | name: gitops-cluster-admin 62 | subjects: 63 | - kind: ServiceAccount 64 | name: openshift-gitops-argocd-application-controller 65 | namespace: openshift-gitops 66 | roleRef: 67 | apiGroup: rbac.authorization.k8s.io 68 | kind: ClusterRole 69 | name: cluster-admin 70 | - objectDefinition: 71 | apiVersion: policy.open-cluster-management.io/v1 72 | kind: ConfigurationPolicy 73 | metadata: 74 | name: policy-cluster-configs-appset 75 | spec: 76 | remediationAction: enforce 77 | severity: low 78 | namespaceSelector: 79 | exclude: 80 | - kube-* 81 | include: 82 | - openshift-gitops 83 | object-templates: 84 | - complianceType: musthave 85 | objectDefinition: 86 | apiVersion: argoproj.io/v1alpha1 87 | kind: ApplicationSet 88 | metadata: 89 | name: cluster-base-configs 90 | namespace: openshift-gitops 91 | spec: 92 | generators: 93 | - git: 94 | repoURL: "https://github.com/marbindrakon/signal9-lab-gitops.git" 95 | revision: HEAD 96 | directories: 97 | - path: argocd/clusters/managed-clusters/{{hub .ManagedClusterName hub}}/live/base-configs 98 | template: 99 | metadata: 100 | name: '{{ "{{ path.basename }}" }}' 101 | spec: 102 | project: default 103 | syncPolicy: 104 | automated: {} 105 | destination: 106 | namespace: openshift-gitops 107 | server: "https://kubernetes.default.svc" 108 | source: 109 | repoURL: "https://github.com/marbindrakon/signal9-lab-gitops.git" 110 | targetRevision: HEAD 111 | path: '{{ "{{ path }}" }}' 112 | --- 113 | apiVersion: policy.open-cluster-management.io/v1 114 | kind: PlacementBinding 115 | metadata: 116 | name: binding-policy-managed-gitops 117 | namespace: rhacm-hub 118 | placementRef: 119 | name: placement-policy-managed-gitops 120 | kind: PlacementRule 121 | apiGroup: apps.open-cluster-management.io 122 | subjects: 123 | - name: policy-managed-gitops 124 | kind: Policy 125 | apiGroup: policy.open-cluster-management.io 126 | --- 127 | apiVersion: apps.open-cluster-management.io/v1 128 | kind: PlacementRule 129 | metadata: 130 | name: placement-policy-managed-gitops 131 | namespace: rhacm-hub 132 | spec: 133 | clusterConditions: 134 | - status: "True" 135 | type: ManagedClusterConditionAvailable 136 | clusterSelector: 137 | matchExpressions: 138 | - { key: spoke-gitops, operator: In, values: ["true"] } 139 | -------------------------------------------------------------------------------- /ansible/roles/gitops_cluster_build/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # tasks file for gitops_cluster_build 3 | - name: write install config to vault for vsphere 4 | community.hashi_vault.vault_write: 5 | url: "{{ hashicorp_vault['url'] }}" 6 | auth_method: jwt 7 | mount_point: "{{ hashicorp_vault['auth_mount'] }}" 8 | role_id: "{{ hashicorp_vault['auth_role'] }}" 9 | jwt: "{{ vault_jwt }}" 10 | path: "{{ hashicorp_vault['secret_base_path'] }}/data/{{ hashicorp_vault['cluster_secrets']['install-config'] }}" 11 | data: 12 | data: 13 | install-config.yaml: "{{ lookup('template', 'vsphere-install-config.yaml.j2') }}" 14 | no_log: true 15 | when: cluster_state == "present" and cluster_platform == "vsphere" 16 | 17 | - name: create temporary directory for gitops repo 18 | ansible.builtin.tempfile: 19 | state: directory 20 | suffix: gitops 21 | register: gitops_temp_dir 22 | 23 | - name: clone gitops repository to temporary directory 24 | ansible.builtin.git: 25 | repo: "{{ gitops_repo_url_authed }}" 26 | dest: "{{ gitops_temp_dir.path }}" 27 | no_log: true 28 | 29 | - name: set git user name 30 | ansible.builtin.command: 31 | chdir: "{{ gitops_temp_dir.path }}" 32 | cmd: "/usr/bin/git config user.name '{{ gitops_author_name }}'" 33 | 34 | - name: set git user email 35 | ansible.builtin.command: 36 | chdir: "{{ gitops_temp_dir.path }}" 37 | cmd: "/usr/bin/git config user.email '{{ gitops_author_email }}'" 38 | 39 | - name: create new cluster directories 40 | ansible.builtin.file: 41 | state: directory 42 | path: "{{ gitops_temp_dir.path }}/{{ item }}" 43 | loop: 44 | - "argocd/clusters/managed-clusters/{{ cluster_name }}/live/base-configs" 45 | - "argocd/clusters/managed-clusters/{{ cluster_name }}/helm-values" 46 | when: cluster_state == "present" 47 | 48 | - name: template cluster deployment 49 | ansible.builtin.template: 50 | src: "cluster-deploy-app.yaml.j2" 51 | dest: "{{ gitops_temp_dir.path }}/{{ cluster_builds_dir }}/{{ cluster_name }}.yaml" 52 | when: cluster_state == "present" or gitops_task == "unprotect" 53 | 54 | - name: template cluster deployment values 55 | ansible.builtin.template: 56 | src: "{{ cluster_platform }}-build-values.yaml.j2" 57 | dest: "{{ gitops_temp_dir.path }}/argocd/clusters/managed-clusters/{{ cluster_name }}/helm-values/build-values.yaml" 58 | when: cluster_state == "present" 59 | 60 | - name: template base config 61 | ansible.builtin.template: 62 | src: "base-config-app.yaml.j2" 63 | dest: "{{ gitops_temp_dir.path }}/argocd/clusters/managed-clusters/{{ cluster_name }}/live/base-configs/base-config-app.yaml" 64 | when: cluster_state == "present" 65 | 66 | - name: template base config values 67 | ansible.builtin.template: 68 | src: "base-config-values.yaml.j2" 69 | dest: "{{ gitops_temp_dir.path }}/argocd/clusters/managed-clusters/{{ cluster_name }}/helm-values/base-config-values.yaml" 70 | when: cluster_state == "present" 71 | 72 | - name: run git add for new files 73 | ansible.builtin.command: 74 | cmd: "/usr/bin/git add {{ item }}" 75 | chdir: "{{ gitops_temp_dir.path }}" 76 | loop: 77 | - "argocd/clusters/managed-clusters/{{ cluster_name }}" 78 | - "{{ cluster_builds_dir }}" 79 | when: cluster_state == "present" 80 | 81 | - name: delete cluster gitops configs (retain cluster configs) 82 | ansible.builtin.command: 83 | cmd: "/usr/bin/git rm -r {{ item }}" 84 | chdir: "{{ gitops_temp_dir.path }}" 85 | removes: "{{ gitops_temp_dir.path }}/{{ item }}" 86 | loop: 87 | - "{{ cluster_builds_dir }}/{{ cluster_name }}.yaml" 88 | when: cluster_state == "absent" and gitops_retain_cluster_configs == true 89 | 90 | - name: delete cluster gitops configs (destroy cluster configs) 91 | ansible.builtin.command: 92 | cmd: "/usr/bin/git rm -r {{ item }}" 93 | chdir: "{{ gitops_temp_dir.path }}" 94 | removes: "{{ gitops_temp_dir.path }}/{{ item }}" 95 | loop: 96 | - "argocd/clusters/managed-clusters/{{ cluster_name }}" 97 | - "{{ cluster_builds_dir }}/{{ cluster_name }}.yaml" 98 | when: cluster_state == "absent" and gitops_retain_cluster_configs == false 99 | 100 | - name: commit changes 101 | ansible.builtin.command: 102 | cmd: '/usr/bin/git commit -a -m "Configure cluster {{ cluster_name }} via Ansible"' 103 | chdir: "{{ gitops_temp_dir.path }}" 104 | register: git_out 105 | failed_when: not "nothing to commit, working tree clean" in git_out.stdout_lines and git_out.rc != 0 106 | changed_when: not "nothing to commit, working tree clean" in git_out.stdout_lines 107 | 108 | - name: push changes 109 | ansible.builtin.command: 110 | cmd: "/usr/bin/git push" 111 | chdir: "{{ gitops_temp_dir.path }}" 112 | when: git_out.changed and not gitops_skip_push 113 | 114 | - name: delete temporary directory 115 | ansible.builtin.file: 116 | path: "{{ gitops_temp_dir.path }}" 117 | state: absent 118 | 119 | - name: delete install config from vault for vsphere 120 | community.hashi_vault.vault_delete: 121 | url: "{{ hashicorp_vault['url'] }}" 122 | auth_method: jwt 123 | mount_point: "{{ hashicorp_vault['auth_mount'] }}" 124 | role_id: "{{ hashicorp_vault['auth_role'] }}" 125 | jwt: "{{ vault_jwt }}" 126 | path: "{{ hashicorp_vault['secret_base_path'] }}/data/{{ hashicorp_vault['cluster_secrets']['install-config'] }}" 127 | no_log: true 128 | when: cluster_state == "absent" and cluster_platform == "vsphere" 129 | -------------------------------------------------------------------------------- /argocd/clusters/managed-clusters/demo-feb9/helm-values/build-values.yaml: -------------------------------------------------------------------------------- 1 | cluster: 2 | importToHub: true 3 | useACM: true 4 | createGitopsManifestWorks: false 5 | name: demo-feb9 6 | baseDomain: lab.signal9.gg 7 | clusterImageSet: img4.12.1-x86-64-appsub 8 | controlPlaneCount: 3 9 | workerCount: 3 10 | apiVIP: "172.18.104.160" 11 | ingressVIP: "172.18.104.155" 12 | pullSecretVault: "ocp-pull-secret" 13 | trustedCAs: | 14 | -----BEGIN CERTIFICATE----- 15 | MIICkTCCAhagAwIBAgIUX1Cm8VWt4ki4+8XH7oKsYYKJM+QwCgYIKoZIzj0EAwIw 16 | dzELMAkGA1UEBhMCVVMxETAPBgNVBAgMCEFya2Fuc2FzMQ8wDQYDVQQHDAZSb2dl 17 | cnMxFTATBgNVBAoMDFNpZ25hbDkgTGFiczEMMAoGA1UECwwDWE5BMR8wHQYDVQQD 18 | DBZTaWduYWw5IFJvb3QgQXV0aG9yaXR5MB4XDTIxMDMwMTA0MDMwNFoXDTQxMDIy 19 | NDA0MDMwNFowdzELMAkGA1UEBhMCVVMxETAPBgNVBAgMCEFya2Fuc2FzMQ8wDQYD 20 | VQQHDAZSb2dlcnMxFTATBgNVBAoMDFNpZ25hbDkgTGFiczEMMAoGA1UECwwDWE5B 21 | MR8wHQYDVQQDDBZTaWduYWw5IFJvb3QgQXV0aG9yaXR5MHYwEAYHKoZIzj0CAQYF 22 | K4EEACIDYgAE5w5BHLiaagf5eSNkQYuDIdyWe7ULLY2z2qAP1fKXM+RrSHQQb5x1 23 | Q9+IhQRhf7exw/pJS5Vs1R8IyQ3B8r6xz885w6+Fk6iyMAlFn979RU6V5lbxMRGG 24 | Vxq/CEL/iorVo2MwYTAdBgNVHQ4EFgQUYfO+q+KnTtIDK5OFXsVZ/D0ziiUwHwYD 25 | VR0jBBgwFoAUYfO+q+KnTtIDK5OFXsVZ/D0ziiUwDwYDVR0TAQH/BAUwAwEB/zAO 26 | BgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwIDaQAwZgIxAJLOIPP9J1/mttvGdQtM 27 | Prnm+r+JzVu8vd0r2HxgwloEkElTr29S+DAAE8XlUpoXpQIxALEd+sYGr1qENJqr 28 | vHOvuo0diFSUxjvTjowus6kM6nZi1JR4rMycICsGgujg8zwVAw== 29 | -----END CERTIFICATE----- 30 | -----BEGIN CERTIFICATE----- 31 | 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 60 | -----END CERTIFICATE----- 61 | 62 | sshKeyVault: "rhte-cluster-ssh-key" 63 | sshPubKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDgvctEXuDg84taMVkL+cD8ny5F6f0+mYsMfTYa48SdBhU9nwB/W4/7vmTMNASWf0urWSDl4YtzSrsca5I1v8VA1LLdqSWD/bFPlLNRtZ4wTKidk9uk1uP5JyeYUpLB31Sq5P7cyzKcd8OaHgDgzPSk0nZIcrcU/hdO/A0UcMGEFZ4fDuMAVhHdjto7k4rQbyAZtsdkfDbex14wiNNy4bHeQxECV644+GAPy7xXDUT4j/AF1ud7sXTq1hnlIc12FtaIQZ3WGX69Om3Qv5XJL3mdYafX721xEIdyX+U8obr+dc2E7TtLxcrHCb8Rqko6rvy8YLLPx+2Dj4ypuDZCmS/3vWQ50kEwRsWze20z835cJEodNS5wo0RanrrGgCGRMlMi9xNofBWnvpr7VCBXgywPN2JmfDwDcurBvJ++L8ednadGI7Xqp8Q17LIM9b8ag92GeZ86ycmaVJUKCb5DRScMsn6UCC9QBL2I9pP+GKDNzjGFTXga+WSU0vhE5Jsng1c= rhte-demo@ocp-ansible-bastion.lab.signal9.gg" 64 | dnsServers: ["172.18.42.10", "172.18.42.11"] 65 | provider: 66 | providerCredsVault: opensnack-cloud-config 67 | providerCAs: | 68 | -----BEGIN CERTIFICATE----- 69 | MIICkTCCAhagAwIBAgIUX1Cm8VWt4ki4+8XH7oKsYYKJM+QwCgYIKoZIzj0EAwIw 70 | dzELMAkGA1UEBhMCVVMxETAPBgNVBAgMCEFya2Fuc2FzMQ8wDQYDVQQHDAZSb2dl 71 | cnMxFTATBgNVBAoMDFNpZ25hbDkgTGFiczEMMAoGA1UECwwDWE5BMR8wHQYDVQQD 72 | DBZTaWduYWw5IFJvb3QgQXV0aG9yaXR5MB4XDTIxMDMwMTA0MDMwNFoXDTQxMDIy 73 | NDA0MDMwNFowdzELMAkGA1UEBhMCVVMxETAPBgNVBAgMCEFya2Fuc2FzMQ8wDQYD 74 | VQQHDAZSb2dlcnMxFTATBgNVBAoMDFNpZ25hbDkgTGFiczEMMAoGA1UECwwDWE5B 75 | MR8wHQYDVQQDDBZTaWduYWw5IFJvb3QgQXV0aG9yaXR5MHYwEAYHKoZIzj0CAQYF 76 | K4EEACIDYgAE5w5BHLiaagf5eSNkQYuDIdyWe7ULLY2z2qAP1fKXM+RrSHQQb5x1 77 | Q9+IhQRhf7exw/pJS5Vs1R8IyQ3B8r6xz885w6+Fk6iyMAlFn979RU6V5lbxMRGG 78 | Vxq/CEL/iorVo2MwYTAdBgNVHQ4EFgQUYfO+q+KnTtIDK5OFXsVZ/D0ziiUwHwYD 79 | VR0jBBgwFoAUYfO+q+KnTtIDK5OFXsVZ/D0ziiUwDwYDVR0TAQH/BAUwAwEB/zAO 80 | BgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwIDaQAwZgIxAJLOIPP9J1/mttvGdQtM 81 | Prnm+r+JzVu8vd0r2HxgwloEkElTr29S+DAAE8XlUpoXpQIxALEd+sYGr1qENJqr 82 | vHOvuo0diFSUxjvTjowus6kM6nZi1JR4rMycICsGgujg8zwVAw== 83 | -----END CERTIFICATE----- 84 | -----BEGIN CERTIFICATE----- 85 | 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 114 | -----END CERTIFICATE----- 115 | 116 | type: OpenStack 117 | openstack: 118 | existingImage: rhcos-4.12.0 119 | externalNetwork: lab-net 120 | computeAZs: null 121 | workerFlavor: m1.large 122 | -------------------------------------------------------------------------------- /argocd/clusters/managed-clusters/demo-jun1/helm-values/build-values.yaml: -------------------------------------------------------------------------------- 1 | cluster: 2 | importToHub: true 3 | useACM: false 4 | createGitopsManifestWorks: true 5 | name: demo-jun1 6 | baseDomain: lab.signal9.gg 7 | clusterImageSet: img4.12.18-x86-64-appsub 8 | controlPlaneCount: 3 9 | workerCount: 3 10 | apiVIP: "172.18.104.180" 11 | ingressVIP: "172.18.104.52" 12 | pullSecretVault: "ocp-pull-secret" 13 | trustedCAs: | 14 | -----BEGIN CERTIFICATE----- 15 | MIICkTCCAhagAwIBAgIUX1Cm8VWt4ki4+8XH7oKsYYKJM+QwCgYIKoZIzj0EAwIw 16 | dzELMAkGA1UEBhMCVVMxETAPBgNVBAgMCEFya2Fuc2FzMQ8wDQYDVQQHDAZSb2dl 17 | cnMxFTATBgNVBAoMDFNpZ25hbDkgTGFiczEMMAoGA1UECwwDWE5BMR8wHQYDVQQD 18 | DBZTaWduYWw5IFJvb3QgQXV0aG9yaXR5MB4XDTIxMDMwMTA0MDMwNFoXDTQxMDIy 19 | NDA0MDMwNFowdzELMAkGA1UEBhMCVVMxETAPBgNVBAgMCEFya2Fuc2FzMQ8wDQYD 20 | VQQHDAZSb2dlcnMxFTATBgNVBAoMDFNpZ25hbDkgTGFiczEMMAoGA1UECwwDWE5B 21 | MR8wHQYDVQQDDBZTaWduYWw5IFJvb3QgQXV0aG9yaXR5MHYwEAYHKoZIzj0CAQYF 22 | K4EEACIDYgAE5w5BHLiaagf5eSNkQYuDIdyWe7ULLY2z2qAP1fKXM+RrSHQQb5x1 23 | Q9+IhQRhf7exw/pJS5Vs1R8IyQ3B8r6xz885w6+Fk6iyMAlFn979RU6V5lbxMRGG 24 | Vxq/CEL/iorVo2MwYTAdBgNVHQ4EFgQUYfO+q+KnTtIDK5OFXsVZ/D0ziiUwHwYD 25 | VR0jBBgwFoAUYfO+q+KnTtIDK5OFXsVZ/D0ziiUwDwYDVR0TAQH/BAUwAwEB/zAO 26 | BgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwIDaQAwZgIxAJLOIPP9J1/mttvGdQtM 27 | Prnm+r+JzVu8vd0r2HxgwloEkElTr29S+DAAE8XlUpoXpQIxALEd+sYGr1qENJqr 28 | vHOvuo0diFSUxjvTjowus6kM6nZi1JR4rMycICsGgujg8zwVAw== 29 | -----END CERTIFICATE----- 30 | -----BEGIN CERTIFICATE----- 31 | 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 60 | -----END CERTIFICATE----- 61 | 62 | sshKeyVault: "rhte-cluster-ssh-key" 63 | sshPubKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDgvctEXuDg84taMVkL+cD8ny5F6f0+mYsMfTYa48SdBhU9nwB/W4/7vmTMNASWf0urWSDl4YtzSrsca5I1v8VA1LLdqSWD/bFPlLNRtZ4wTKidk9uk1uP5JyeYUpLB31Sq5P7cyzKcd8OaHgDgzPSk0nZIcrcU/hdO/A0UcMGEFZ4fDuMAVhHdjto7k4rQbyAZtsdkfDbex14wiNNy4bHeQxECV644+GAPy7xXDUT4j/AF1ud7sXTq1hnlIc12FtaIQZ3WGX69Om3Qv5XJL3mdYafX721xEIdyX+U8obr+dc2E7TtLxcrHCb8Rqko6rvy8YLLPx+2Dj4ypuDZCmS/3vWQ50kEwRsWze20z835cJEodNS5wo0RanrrGgCGRMlMi9xNofBWnvpr7VCBXgywPN2JmfDwDcurBvJ++L8ednadGI7Xqp8Q17LIM9b8ag92GeZ86ycmaVJUKCb5DRScMsn6UCC9QBL2I9pP+GKDNzjGFTXga+WSU0vhE5Jsng1c= rhte-demo@ocp-ansible-bastion.lab.signal9.gg" 64 | dnsServers: ["172.18.42.10", "172.18.42.11"] 65 | provider: 66 | providerCredsVault: opensnack-cloud-config 67 | providerCAs: | 68 | -----BEGIN CERTIFICATE----- 69 | MIICkTCCAhagAwIBAgIUX1Cm8VWt4ki4+8XH7oKsYYKJM+QwCgYIKoZIzj0EAwIw 70 | dzELMAkGA1UEBhMCVVMxETAPBgNVBAgMCEFya2Fuc2FzMQ8wDQYDVQQHDAZSb2dl 71 | cnMxFTATBgNVBAoMDFNpZ25hbDkgTGFiczEMMAoGA1UECwwDWE5BMR8wHQYDVQQD 72 | DBZTaWduYWw5IFJvb3QgQXV0aG9yaXR5MB4XDTIxMDMwMTA0MDMwNFoXDTQxMDIy 73 | NDA0MDMwNFowdzELMAkGA1UEBhMCVVMxETAPBgNVBAgMCEFya2Fuc2FzMQ8wDQYD 74 | VQQHDAZSb2dlcnMxFTATBgNVBAoMDFNpZ25hbDkgTGFiczEMMAoGA1UECwwDWE5B 75 | MR8wHQYDVQQDDBZTaWduYWw5IFJvb3QgQXV0aG9yaXR5MHYwEAYHKoZIzj0CAQYF 76 | K4EEACIDYgAE5w5BHLiaagf5eSNkQYuDIdyWe7ULLY2z2qAP1fKXM+RrSHQQb5x1 77 | Q9+IhQRhf7exw/pJS5Vs1R8IyQ3B8r6xz885w6+Fk6iyMAlFn979RU6V5lbxMRGG 78 | Vxq/CEL/iorVo2MwYTAdBgNVHQ4EFgQUYfO+q+KnTtIDK5OFXsVZ/D0ziiUwHwYD 79 | VR0jBBgwFoAUYfO+q+KnTtIDK5OFXsVZ/D0ziiUwDwYDVR0TAQH/BAUwAwEB/zAO 80 | BgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwIDaQAwZgIxAJLOIPP9J1/mttvGdQtM 81 | Prnm+r+JzVu8vd0r2HxgwloEkElTr29S+DAAE8XlUpoXpQIxALEd+sYGr1qENJqr 82 | vHOvuo0diFSUxjvTjowus6kM6nZi1JR4rMycICsGgujg8zwVAw== 83 | -----END CERTIFICATE----- 84 | -----BEGIN CERTIFICATE----- 85 | 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 114 | -----END CERTIFICATE----- 115 | 116 | type: OpenStack 117 | openstack: 118 | existingImage: rhcos-4.12.17 119 | externalNetwork: lab-net 120 | computeAZs: null 121 | workerFlavor: m1.large 122 | -------------------------------------------------------------------------------- /argocd/clusters/managed-clusters/demo-jun2/helm-values/build-values.yaml: -------------------------------------------------------------------------------- 1 | cluster: 2 | importToHub: true 3 | useACM: false 4 | createGitopsManifestWorks: true 5 | name: demo-jun2 6 | baseDomain: lab.signal9.gg 7 | clusterImageSet: img4.12.18-x86-64-appsub 8 | controlPlaneCount: 3 9 | workerCount: 3 10 | apiVIP: "172.18.104.100" 11 | ingressVIP: "172.18.104.113" 12 | pullSecretVault: "ocp-pull-secret" 13 | trustedCAs: | 14 | -----BEGIN CERTIFICATE----- 15 | MIICkTCCAhagAwIBAgIUX1Cm8VWt4ki4+8XH7oKsYYKJM+QwCgYIKoZIzj0EAwIw 16 | dzELMAkGA1UEBhMCVVMxETAPBgNVBAgMCEFya2Fuc2FzMQ8wDQYDVQQHDAZSb2dl 17 | cnMxFTATBgNVBAoMDFNpZ25hbDkgTGFiczEMMAoGA1UECwwDWE5BMR8wHQYDVQQD 18 | DBZTaWduYWw5IFJvb3QgQXV0aG9yaXR5MB4XDTIxMDMwMTA0MDMwNFoXDTQxMDIy 19 | NDA0MDMwNFowdzELMAkGA1UEBhMCVVMxETAPBgNVBAgMCEFya2Fuc2FzMQ8wDQYD 20 | VQQHDAZSb2dlcnMxFTATBgNVBAoMDFNpZ25hbDkgTGFiczEMMAoGA1UECwwDWE5B 21 | MR8wHQYDVQQDDBZTaWduYWw5IFJvb3QgQXV0aG9yaXR5MHYwEAYHKoZIzj0CAQYF 22 | K4EEACIDYgAE5w5BHLiaagf5eSNkQYuDIdyWe7ULLY2z2qAP1fKXM+RrSHQQb5x1 23 | Q9+IhQRhf7exw/pJS5Vs1R8IyQ3B8r6xz885w6+Fk6iyMAlFn979RU6V5lbxMRGG 24 | Vxq/CEL/iorVo2MwYTAdBgNVHQ4EFgQUYfO+q+KnTtIDK5OFXsVZ/D0ziiUwHwYD 25 | VR0jBBgwFoAUYfO+q+KnTtIDK5OFXsVZ/D0ziiUwDwYDVR0TAQH/BAUwAwEB/zAO 26 | BgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwIDaQAwZgIxAJLOIPP9J1/mttvGdQtM 27 | Prnm+r+JzVu8vd0r2HxgwloEkElTr29S+DAAE8XlUpoXpQIxALEd+sYGr1qENJqr 28 | vHOvuo0diFSUxjvTjowus6kM6nZi1JR4rMycICsGgujg8zwVAw== 29 | -----END CERTIFICATE----- 30 | -----BEGIN CERTIFICATE----- 31 | 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 60 | -----END CERTIFICATE----- 61 | 62 | sshKeyVault: "rhte-cluster-ssh-key" 63 | sshPubKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDgvctEXuDg84taMVkL+cD8ny5F6f0+mYsMfTYa48SdBhU9nwB/W4/7vmTMNASWf0urWSDl4YtzSrsca5I1v8VA1LLdqSWD/bFPlLNRtZ4wTKidk9uk1uP5JyeYUpLB31Sq5P7cyzKcd8OaHgDgzPSk0nZIcrcU/hdO/A0UcMGEFZ4fDuMAVhHdjto7k4rQbyAZtsdkfDbex14wiNNy4bHeQxECV644+GAPy7xXDUT4j/AF1ud7sXTq1hnlIc12FtaIQZ3WGX69Om3Qv5XJL3mdYafX721xEIdyX+U8obr+dc2E7TtLxcrHCb8Rqko6rvy8YLLPx+2Dj4ypuDZCmS/3vWQ50kEwRsWze20z835cJEodNS5wo0RanrrGgCGRMlMi9xNofBWnvpr7VCBXgywPN2JmfDwDcurBvJ++L8ednadGI7Xqp8Q17LIM9b8ag92GeZ86ycmaVJUKCb5DRScMsn6UCC9QBL2I9pP+GKDNzjGFTXga+WSU0vhE5Jsng1c= rhte-demo@ocp-ansible-bastion.lab.signal9.gg" 64 | dnsServers: ["172.18.42.10", "172.18.42.11"] 65 | provider: 66 | providerCredsVault: opensnack-cloud-config 67 | providerCAs: | 68 | -----BEGIN CERTIFICATE----- 69 | MIICkTCCAhagAwIBAgIUX1Cm8VWt4ki4+8XH7oKsYYKJM+QwCgYIKoZIzj0EAwIw 70 | dzELMAkGA1UEBhMCVVMxETAPBgNVBAgMCEFya2Fuc2FzMQ8wDQYDVQQHDAZSb2dl 71 | cnMxFTATBgNVBAoMDFNpZ25hbDkgTGFiczEMMAoGA1UECwwDWE5BMR8wHQYDVQQD 72 | DBZTaWduYWw5IFJvb3QgQXV0aG9yaXR5MB4XDTIxMDMwMTA0MDMwNFoXDTQxMDIy 73 | NDA0MDMwNFowdzELMAkGA1UEBhMCVVMxETAPBgNVBAgMCEFya2Fuc2FzMQ8wDQYD 74 | VQQHDAZSb2dlcnMxFTATBgNVBAoMDFNpZ25hbDkgTGFiczEMMAoGA1UECwwDWE5B 75 | MR8wHQYDVQQDDBZTaWduYWw5IFJvb3QgQXV0aG9yaXR5MHYwEAYHKoZIzj0CAQYF 76 | K4EEACIDYgAE5w5BHLiaagf5eSNkQYuDIdyWe7ULLY2z2qAP1fKXM+RrSHQQb5x1 77 | Q9+IhQRhf7exw/pJS5Vs1R8IyQ3B8r6xz885w6+Fk6iyMAlFn979RU6V5lbxMRGG 78 | Vxq/CEL/iorVo2MwYTAdBgNVHQ4EFgQUYfO+q+KnTtIDK5OFXsVZ/D0ziiUwHwYD 79 | VR0jBBgwFoAUYfO+q+KnTtIDK5OFXsVZ/D0ziiUwDwYDVR0TAQH/BAUwAwEB/zAO 80 | BgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwIDaQAwZgIxAJLOIPP9J1/mttvGdQtM 81 | Prnm+r+JzVu8vd0r2HxgwloEkElTr29S+DAAE8XlUpoXpQIxALEd+sYGr1qENJqr 82 | vHOvuo0diFSUxjvTjowus6kM6nZi1JR4rMycICsGgujg8zwVAw== 83 | -----END CERTIFICATE----- 84 | -----BEGIN CERTIFICATE----- 85 | MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw 86 | TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh 87 | cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 88 | WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu 89 | ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY 90 | MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc 91 | h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ 92 | 0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U 93 | A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW 94 | T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH 95 | B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC 96 | B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv 97 | KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn 98 | OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn 99 | jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw 100 | qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI 101 | rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV 102 | HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq 103 | hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL 104 | ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ 105 | 3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK 106 | NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 107 | ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur 108 | TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC 109 | jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc 110 | oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq 111 | 4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA 112 | mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d 113 | emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= 114 | -----END CERTIFICATE----- 115 | 116 | type: OpenStack 117 | openstack: 118 | existingImage: rhcos-4.12.17 119 | externalNetwork: lab-net 120 | computeAZs: null 121 | workerFlavor: m1.large 122 | -------------------------------------------------------------------------------- /ansible/roles/lb_config/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: register vip facts on loadbalancer hosts 3 | ansible.builtin.set_fact: 4 | external_api_vip: "{{ hostvars['localhost']['external_api_vip'] | default(omit) }}" 5 | internal_api_vip: "{{ hostvars['localhost']['internal_api_vip'] | default(omit) }}" 6 | external_ingress_vip: "{{ hostvars['localhost']['external_ingress_vip'] | default(omit) }}" 7 | internal_ingress_vip: "{{ hostvars['localhost']['internal_ingress_vip'] | default(omit) }}" 8 | 9 | - name: handle external shared frontend config 10 | block: 11 | - name: ensure api acl 12 | ansible.builtin.lineinfile: 13 | path: /etc/haproxy/haproxy.cfg 14 | search_string: "use_backend be-{{ cluster_name }}-api if { req_ssl_sni -i api.{{ cluster_name}}.{{ base_domain}} }" 15 | line: " use_backend be-{{ cluster_name }}-api if { req_ssl_sni -i api.{{ cluster_name}}.{{ base_domain}} }" 16 | insertbefore: "default_backend be-ocp-api" 17 | state: "{{ cluster_state }}" 18 | notify: "reload haproxy" 19 | when: loadbalancer_type == "external" or expose_internal_loadbalancers == true 20 | 21 | - name: ensure api-int acl when not using internal LB 22 | ansible.builtin.lineinfile: 23 | path: /etc/haproxy/haproxy.cfg 24 | search_string: "use_backend be-{{ cluster_name }}-api if { req_ssl_sni -i api-int.{{ cluster_name}}.{{ base_domain}} }" 25 | line: " use_backend be-{{ cluster_name }}-api if { req_ssl_sni -i api-int.{{ cluster_name}}.{{ base_domain}} }" 26 | insertbefore: "default_backend be-ocp-api" 27 | state: "{{ cluster_state }}" 28 | notify: "reload haproxy" 29 | when: loadbalancer_type == "external" 30 | 31 | - name: ensure machineapi acl when not using internal LB 32 | ansible.builtin.lineinfile: 33 | path: /etc/haproxy/haproxy.cfg 34 | search_string: "use_backend be-{{ cluster_name }}-machineapi if { req_ssl_sni -m end {{ cluster_name}}.{{ base_domain}} }" 35 | line: " use_backend be-{{ cluster_name }}-machineapi if { req_ssl_sni -m end {{ cluster_name}}.{{ base_domain}} }" 36 | insertbefore: "default_backend be-ocp5-machineapi" 37 | state: "{{ cluster_state }}" 38 | notify: "reload haproxy" 39 | when: loadbalancer_type == "external" 40 | 41 | - name: ensure ingress https acl 42 | ansible.builtin.lineinfile: 43 | path: /etc/haproxy/haproxy.cfg 44 | search_string: "use_backend be-{{ cluster_name }}-https if { req_ssl_sni -m end apps.{{ cluster_name}}.{{ base_domain}} }" 45 | line: " use_backend be-{{ cluster_name }}-https if { req_ssl_sni -m end apps.{{ cluster_name}}.{{ base_domain}} }" 46 | insertbefore: '^.*default_backend be-ocp-https$' 47 | state: "{{ cluster_state }}" 48 | notify: "reload haproxy" 49 | when: loadbalancer_type == "external" or expose_internal_loadbalancers == true 50 | 51 | - name: ensure ingress http acl 52 | ansible.builtin.lineinfile: 53 | path: /etc/haproxy/haproxy.cfg 54 | search_string: "use_backend be-{{ cluster_name }}-http if { hdr_sub(host) -i {{ cluster_name}}.{{ base_domain}} }" 55 | line: " use_backend be-{{ cluster_name }}-http if { hdr_sub(host) -i {{ cluster_name}}.{{ base_domain}} }" 56 | insertbefore: '^.*default_backend be-ocp-http$' 57 | state: "{{ cluster_state }}" 58 | notify: "reload haproxy" 59 | when: loadbalancer_type == "external" or expose_internal_loadbalancers == true 60 | 61 | when: loadbalancer_frontend_mode == "shared" 62 | 63 | - name: handle dedicated frontend config 64 | block: 65 | - name: ensure api frontend 66 | ansible.builtin.blockinfile: 67 | path: /etc/haproxy/haproxy.cfg 68 | marker: '# {mark} {{ cluster_name|upper }} API FRONTEND' 69 | block: | 70 | frontend fe-{{ cluster_name }}-api 71 | bind {{ external_api_vip }}:6443 72 | timeout client 10m 73 | tcp-request inspect-delay 5s 74 | tcp-request content accept if { req_ssl_hello_type 1 } 75 | mode tcp 76 | option tcplog 77 | default_backend be-{{ cluster_name }}-api 78 | state: "{{ cluster_state }}" 79 | notify: "reload haproxy" 80 | 81 | - name: ensure machineapi frontend 82 | ansible.builtin.blockinfile: 83 | path: /etc/haproxy/haproxy.cfg 84 | marker: '# {mark} {{ cluster_name|upper }} MACHINEAPI FRONTEND' 85 | block: | 86 | frontend fe-{{ cluster_name }}-api 87 | bind {{ external_api_vip }}:22623 88 | timeout client 10m 89 | tcp-request inspect-delay 5s 90 | tcp-request content accept if { req_ssl_hello_type 1 } 91 | mode tcp 92 | option tcplog 93 | default_backend be-{{ cluster_name }}-machineapi 94 | state: "{{ cluster_state }}" 95 | notify: "reload haproxy" 96 | 97 | - name: ensure http frontend 98 | ansible.builtin.blockinfile: 99 | path: /etc/haproxy/haproxy.cfg 100 | marker: '# {mark} {{ cluster_name|upper }} HTTP FRONTEND' 101 | block: | 102 | frontend fe-{{ cluster_name }}-http 103 | bind {{ external_ingress_vip }}:80 104 | default_backend be-{{ cluster_name }}-http 105 | state: "{{ cluster_state }}" 106 | notify: "reload haproxy" 107 | 108 | - name: ensure https frontend 109 | ansible.builtin.blockinfile: 110 | path: /etc/haproxy/haproxy.cfg 111 | marker: '# {mark} {{ cluster_name|upper }} HTTPS FRONTEND' 112 | block: | 113 | frontend fe-{{ cluster_name }}-https 114 | bind {{ external_ingress_vip }}:443 115 | timeout client 10m 116 | tcp-request inspect-delay 5s 117 | tcp-request content accept if { req_ssl_hello_type 1 } 118 | mode tcp 119 | option tcplog 120 | default_backend be-{{ cluster_name }}-https 121 | state: "{{ cluster_state }}" 122 | notify: "reload haproxy" 123 | 124 | - name: add loopback interface IP addresses 125 | ansible.builtin.command: 126 | cmd: "/sbin/ip addr add {{ item }}/32 dev lo" 127 | when: 128 | - cluster_state == 'present' 129 | - item not in ansible_lo['ipv4'] | map('address') 130 | 131 | - name: remove loopback interface IP addresses 132 | ansible.builtin.command: 133 | cmd: "/sbin/ip addr del {{ item }}/32 dev lo" 134 | when: 135 | - cluster_state == 'absent' 136 | - item in ansible_lo['ipv4'] | map('address') 137 | 138 | when: loadbalancer_frontend_mode == "dedicated" 139 | 140 | - name: handle backend definitions 141 | block: 142 | - name: handle api backend for external LB 143 | ansible.builtin.blockinfile: 144 | path: /etc/haproxy/haproxy.cfg 145 | marker: '# {mark} {{ cluster_name|upper }} API BACKEND' 146 | block: | 147 | backend be-{{ cluster_name }}-api 148 | mode tcp 149 | timeout server 10m 150 | {% for host in cluster_hosts.get('control-plane', []) %} 151 | server {{ host.name }} {{ host.ip_address }}:6443 check 152 | {% endfor %} 153 | backend be-{{ cluster_name }}-machineapi 154 | mode tcp 155 | timeout server 10m 156 | {% for host in cluster_hosts.get('control-plane', []) %} 157 | server {{ host.name }} {{ host.ip_address }}:22623 check 158 | {% endfor %} 159 | state: "{{ cluster_state }}" 160 | notify: "reload haproxy" 161 | when: loadbalancer_type == "external" 162 | 163 | - name: handle api backend for exposed internal LB 164 | ansible.builtin.blockinfile: 165 | path: /etc/haproxy/haproxy.cfg 166 | marker: '# {mark} {{ cluster_name|upper }} API BACKEND' 167 | block: | 168 | backend be-{{ cluster_name }}-api 169 | mode tcp 170 | timeout server 10m 171 | server {{ cluster_name }}-vip {{ internal_api_vip }}:6443 check 172 | state: "{{ cluster_state }}" 173 | notify: "reload haproxy" 174 | when: loadbalancer_type == "internal" and expose_internal_loadbalancers == true 175 | 176 | - name: handle ingress backends for external LB 177 | ansible.builtin.blockinfile: 178 | path: /etc/haproxy/haproxy.cfg 179 | marker: '# {mark} {{ cluster_name|upper }} INGRESS BACKEND' 180 | block: | 181 | backend be-{{ cluster_name }}-https 182 | mode tcp 183 | {% for host in cluster_hosts.get('worker', []) %} 184 | server {{ host.name }} {{ host.ip_address }}:443 check 185 | {% endfor %} 186 | 187 | backend be-{{ cluster_name }}-http 188 | {% for host in cluster_hosts.get('worker', []) %} 189 | server {{ host.name }} {{ host.ip_address }}:80 check 190 | {% endfor %} 191 | state: "{{ cluster_state }}" 192 | notify: "reload haproxy" 193 | when: loadbalancer_type == "external" 194 | 195 | - name: handle ingress backends for exposed internal LB 196 | ansible.builtin.blockinfile: 197 | path: /etc/haproxy/haproxy.cfg 198 | marker: '# {mark} {{ cluster_name|upper }} INGRESS BACKEND' 199 | block: | 200 | backend be-{{ cluster_name }}-https 201 | mode tcp 202 | server {{ cluster_name }}-vip {{ internal_ingress_vip }}:443 check 203 | 204 | backend be-{{ cluster_name }}-http 205 | server {{ cluster_name }}-vip {{ internal_ingress_vip }}:80 check 206 | state: "{{ cluster_state }}" 207 | notify: "reload haproxy" 208 | when: loadbalancer_type == "internal" and expose_internal_loadbalancers == true 209 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | 204 | --------------------------------------------------------------------------------