diff --git a/.gitignore b/.gitignore index 6ecee48..3c03b19 100644 --- a/.gitignore +++ b/.gitignore @@ -133,3 +133,6 @@ dmypy.json # Prevent manifest file upload aap_manifest.zip + +# Prevent pull_secret.txt file upload +pull_secret.txt diff --git a/ansible/hcp-manifests.yml b/ansible/hcp-manifests.yml new file mode 100644 index 0000000..8e81d5a --- /dev/null +++ b/ansible/hcp-manifests.yml @@ -0,0 +1,15 @@ +--- +# Playbook to create manifests for a Hosted Control Plane deployed by MCE +# +# Example Usage: +# +# time ansible-playbook -i -i ../jetlag/ansible/inventory/cloud30.local ansible/hcp-manifests.yml +# + +- name: Create manifests for an hcp cluster deployed by MCE + hosts: bastion + gather_facts: false + vars_files: + - vars/all.yml + roles: + - hcp-create-manifests diff --git a/ansible/roles/hcp-create-manifests/defaults/main.yml b/ansible/roles/hcp-create-manifests/defaults/main.yml new file mode 100644 index 0000000..bb4d903 --- /dev/null +++ b/ansible/roles/hcp-create-manifests/defaults/main.yml @@ -0,0 +1,40 @@ +--- +# hcp-create-manifests default vars + +hv_vm_manifests_directory: /root/hv-vm + +hcp_namespace: clusters + +# Must match DNS records +hcp_cluster_name: standard-00001 + +# Provide pull-secret for connected manifests +hcp_pull_secret: "{{ lookup('file', '../pull_secret.txt') }}" + +# SSH key that will be able to access booted HCP worker machines +ssh_public_key_file: ~/.ssh/id_rsa.pub + +# OCP version for the hosted cluster +hcp_release_image: quay.io/openshift-release-dev/ocp-release:4.17.25-x86_64 + +# Starting count of Hosted Cluster worker replicas +hcp_nodepool_replicas: 1 + +hcp_nodeselectors: +- 'node-role.kubernetes.io/hcp: ""' + +hcp_tolerations: +- effect: NoExecute + key: node-role.kubernetes.io/hcp + value: reserved +- effect: NoSchedule + key: node-role.kubernetes.io/hcp + value: reserved + +hcp_etcd_storageclass: localstorage-sc + +hcp_vm_offset: 8 + +# sushy emulator bmc username/password +bmc_username_base64: "{{ 'redhat' | b64encode }}" +bmc_password_base64: "{{ 'password' | b64encode }}" diff --git a/ansible/roles/hcp-create-manifests/tasks/main.yml b/ansible/roles/hcp-create-manifests/tasks/main.yml new file mode 100644 index 0000000..05dfabc --- /dev/null +++ b/ansible/roles/hcp-create-manifests/tasks/main.yml @@ -0,0 +1,32 @@ +--- +# hcp-create-manifests tasks + +- name: Create directories for hv-vm HCP manifests on bastion + file: + path: "{{ item.dir }}" + state: directory + loop: + - dir: "{{ hv_vm_manifests_directory }}/" + - dir: "{{ hv_vm_manifests_directory }}/hcp" + +- name: Template a manifest per hv-vm on bastion as a SNO + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + loop: + - src: 01-namespace.yml.j2 + dest: "{{ hv_vm_manifests_directory }}/hcp/01-namespace.yml" + - src: 02-secret-ps.yml.j2 + dest: "{{ hv_vm_manifests_directory }}/hcp/02-secret-ps.yml" + - src: 03-secret-ssh.yml.j2 + dest: "{{ hv_vm_manifests_directory }}/hcp/03-secret-ssh.yml" + - src: 04-hostedcluster.yml.j2 + dest: "{{ hv_vm_manifests_directory }}/hcp/04-hostedcluster.yml" + - src: 05-nodepool.yml.j2 + dest: "{{ hv_vm_manifests_directory }}/hcp/05-nodepool.yml" + - src: 06-nmstateconfig.yml.j2 + dest: "{{ hv_vm_manifests_directory }}/hcp/06-nmstateconfig.yml" + - src: 07-infraenv.yml.j2 + dest: "{{ hv_vm_manifests_directory }}/hcp/07-infraenv.yml" + - src: 08-bmh.yml.j2 + dest: "{{ hv_vm_manifests_directory }}/hcp/08-bmh.yml" diff --git a/ansible/roles/hcp-create-manifests/templates/01-namespace.yml.j2 b/ansible/roles/hcp-create-manifests/templates/01-namespace.yml.j2 new file mode 100644 index 0000000..abd425f --- /dev/null +++ b/ansible/roles/hcp-create-manifests/templates/01-namespace.yml.j2 @@ -0,0 +1,18 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: {{ hcp_namespace }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: capi-provider-role + namespace: {{ hcp_namespace }} +rules: +- apiGroups: + - agent-install.openshift.io + resources: + - agents + verbs: + - '*' diff --git a/ansible/roles/hcp-create-manifests/templates/02-secret-ps.yml.j2 b/ansible/roles/hcp-create-manifests/templates/02-secret-ps.yml.j2 new file mode 100644 index 0000000..92763c2 --- /dev/null +++ b/ansible/roles/hcp-create-manifests/templates/02-secret-ps.yml.j2 @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ hcp_cluster_name }}-pull-secret + namespace: {{ hcp_namespace }} +Type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ hcp_pull_secret | to_json | b64encode }} diff --git a/ansible/roles/hcp-create-manifests/templates/03-secret-ssh.yml.j2 b/ansible/roles/hcp-create-manifests/templates/03-secret-ssh.yml.j2 new file mode 100644 index 0000000..a620e75 --- /dev/null +++ b/ansible/roles/hcp-create-manifests/templates/03-secret-ssh.yml.j2 @@ -0,0 +1,8 @@ +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ hcp_cluster_name }}-ssh-key + namespace: {{ hcp_namespace }} +stringData: + id_rsa.pub: {{ lookup('file', ssh_public_key_file) }} diff --git a/ansible/roles/hcp-create-manifests/templates/04-hostedcluster.yml.j2 b/ansible/roles/hcp-create-manifests/templates/04-hostedcluster.yml.j2 new file mode 100644 index 0000000..9e1e881 --- /dev/null +++ b/ansible/roles/hcp-create-manifests/templates/04-hostedcluster.yml.j2 @@ -0,0 +1,71 @@ +--- +apiVersion: hypershift.openshift.io/v1beta1 +kind: HostedCluster +metadata: + name: {{ hcp_cluster_name }} + namespace: {{ hcp_namespace }} +spec: +{% if hcp_nodeselectors | length > 0 %} + nodeSelector: +{% for nodeselector in hcp_nodeselectors %} + {{ nodeselector }} +{% endfor %} +{% endif %} +{% if hcp_tolerations | length > 0 %} + tolerations: +{% for toleration in hcp_tolerations %} + - {{ toleration }} +{% endfor %} +{% endif %} + etcd: + managementType: Managed + managed: + storage: + type: PersistentVolume + persistentVolume: + storageClassName: {{ hcp_etcd_storageclass }} + release: + image: {{ hcp_release_image }} + pullSecret: + name: {{ hcp_cluster_name }}-pull-secret + sshKey: + name: {{ hcp_cluster_name }}-ssh-key + networking: + machineNetwork: + - cidr: "{{ hostvars[groups['hv_vm'][0]]['machine_network'] }}" + networkType: OVNKubernetes + serviceNetwork: + - cidr: "172.31.0.0/16" + platform: + agent: + agentNamespace: {{ hcp_namespace }} + type: Agent + infraID: {{ hcp_cluster_name }} + dns: + baseDomain: {{ hostvars[groups['hv_vm'][0]]['base_domain'] }} + services: + - service: APIServer + servicePublishingStrategy: + nodePort: + address: api.{{ hcp_cluster_name }}.{{ hostvars[groups['hv_vm'][0]]['base_domain'] }} + type: NodePort + - service: OAuthServer + servicePublishingStrategy: + nodePort: + address: api.{{ hcp_cluster_name }}.{{ hostvars[groups['hv_vm'][0]]['base_domain'] }} + type: NodePort + - service: OIDC + servicePublishingStrategy: + # nodePort: + # address: api.{{ hcp_cluster_name }}.{{ hostvars[groups['hv_vm'][0]]['base_domain'] }} + type: None + - service: Konnectivity + servicePublishingStrategy: + nodePort: + address: api.{{ hcp_cluster_name }}.{{ hostvars[groups['hv_vm'][0]]['base_domain'] }} + type: NodePort + - service: Ignition + servicePublishingStrategy: + nodePort: + address: api.{{ hcp_cluster_name }}.{{ hostvars[groups['hv_vm'][0]]['base_domain'] }} + type: NodePort diff --git a/ansible/roles/hcp-create-manifests/templates/05-nodepool.yml.j2 b/ansible/roles/hcp-create-manifests/templates/05-nodepool.yml.j2 new file mode 100644 index 0000000..2789e0c --- /dev/null +++ b/ansible/roles/hcp-create-manifests/templates/05-nodepool.yml.j2 @@ -0,0 +1,16 @@ +--- +apiVersion: hypershift.openshift.io/v1beta1 +kind: NodePool +metadata: + name: {{ hcp_cluster_name }}-workers + namespace: {{ hcp_namespace }} +spec: + clusterName: {{ hcp_cluster_name }} + replicas: {{ hcp_nodepool_replicas }} + management: + autoRepair: false + upgradeType: InPlace + platform: + type: Agent + release: + image: {{ hcp_release_image }} diff --git a/ansible/roles/hcp-create-manifests/templates/06-nmstateconfig.yml.j2 b/ansible/roles/hcp-create-manifests/templates/06-nmstateconfig.yml.j2 new file mode 100644 index 0000000..cfbba00 --- /dev/null +++ b/ansible/roles/hcp-create-manifests/templates/06-nmstateconfig.yml.j2 @@ -0,0 +1,36 @@ +{% for vm in groups['hv_vm'][hcp_vm_offset:] %} +--- +apiVersion: agent-install.openshift.io/v1beta1 +kind: NMStateConfig +metadata: + name: {{ vm }} + namespace: {{ hcp_namespace }} + labels: + cluster: {{ hcp_cluster_name }} +spec: + config: + interfaces: + - name: enp1s0 + type: ethernet + state: up + ipv4: + enabled: true + dhcp: false + address: + - ip: {{ hostvars[vm]['ip'] }} + prefix-length: {{ hostvars[vm]['network_prefix'] }} + dns-resolver: + config: + server: + - {{ hostvars[vm]['gateway'] }} + routes: + config: + - destination: 0.0.0.0/0 + metric: 1 + next-hop-address: {{ hostvars[vm]['gateway'] }} + next-hop-interface: enp1s0 + table-id: 254 + interfaces: + - name: enp1s0 + macAddress: {{ hostvars[vm]['mac_address'] }} +{% endfor %} diff --git a/ansible/roles/hcp-create-manifests/templates/07-infraenv.yml.j2 b/ansible/roles/hcp-create-manifests/templates/07-infraenv.yml.j2 new file mode 100644 index 0000000..43186b7 --- /dev/null +++ b/ansible/roles/hcp-create-manifests/templates/07-infraenv.yml.j2 @@ -0,0 +1,15 @@ +--- +apiVersion: agent-install.openshift.io/v1beta1 +kind: InfraEnv +metadata: + name: {{ hcp_cluster_name }} + namespace: {{ hcp_namespace }} +spec: + additionalNTPSources: + - {{ hostvars[groups['hv_vm'][0]]['hv_ip'] }} + pullSecretRef: + name: {{ hcp_cluster_name }}-pull-secret + sshAuthorizedKey: {{ lookup('file', ssh_public_key_file) }} + nmStateConfigLabelSelector: + matchLabels: + cluster: {{ hcp_cluster_name }} diff --git a/ansible/roles/hcp-create-manifests/templates/08-bmh.yml.j2 b/ansible/roles/hcp-create-manifests/templates/08-bmh.yml.j2 new file mode 100644 index 0000000..c9c4e58 --- /dev/null +++ b/ansible/roles/hcp-create-manifests/templates/08-bmh.yml.j2 @@ -0,0 +1,32 @@ +{% for vm in groups['hv_vm'][hcp_vm_offset:] %} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ vm }}-bmc-secret + namespace: {{ hcp_namespace }} +type: Opaque +data: + password: {{ bmc_password_base64 }} + username: {{ bmc_username_base64 }} +--- +apiVersion: metal3.io/v1alpha1 +kind: BareMetalHost +metadata: + name: {{ vm }} + namespace: {{ hcp_namespace }} + annotations: + inspect.metal3.io: disabled + bmac.agent-install.openshift.io/hostname: "{{ vm }}" + labels: + infraenvs.agent-install.openshift.io: "{{ hcp_cluster_name }}" +spec: + bootMode: "UEFI" + bmc: + address: redfish-virtualmedia+http://{{ hostvars[vm]['hv_ip'] }}:9000/redfish/v1/Systems/{{ hostvars[vm]['domain_uuid'] }} + disableCertificateVerification: true + credentialsName: {{ vm }}-bmc-secret + bootMACAddress: {{ hostvars[vm]['mac_address'] }} + automatedCleaningMode: disabled + online: true +{% endfor %}