-
Notifications
You must be signed in to change notification settings - Fork 148
Add edpm_ssh_info role for retrieving EDPM SSH connectivity information #3650
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -370,6 +370,7 @@ networkattachmentdefinition | |
| networkconfig | ||
| networkmanager | ||
| networktype | ||
| networker | ||
| nfs | ||
| nftables | ||
| nhc | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,150 @@ | ||
| # edpm_ssh_info | ||
|
|
||
| This Ansible role retrieves EDPM (External Data Plane Management) SSH connectivity information. | ||
|
|
||
| ## Description | ||
|
|
||
| The role performs the following tasks: | ||
|
|
||
| 1. Queries OpenShift for OpenStackDataPlaneNodeSet resources | ||
| 2. Retrieves the dataplane SSH private key from OpenShift secrets (if not already present locally) | ||
| 3. Extracts compute node names and their control plane IP addresses | ||
| 4. Returns all information in a structured format for use in subsequent plays | ||
|
|
||
| ## Requirements | ||
|
|
||
| - Ansible collection `kubernetes.core` must be installed | ||
| - Ansible collection `community.okd` must be installed | ||
| - Valid kubeconfig file at `{{ ansible_user_dir }}/.kube/config` | ||
| - Access to the OpenShift/Kubernetes namespace containing EDPM resources | ||
| - Appropriate permissions to read OpenStackDataPlaneNodeSet resources and secrets | ||
|
|
||
| ## Variables | ||
|
|
||
| ### Role Variables | ||
|
|
||
| | Variable | Default | Description | | ||
| |----------|---------|-------------| | ||
| | `cifmw_edpm_ssh_info_openstack_namespace` | `openstack` | OpenShift namespace where EDPM resources are deployed | | ||
| | `cifmw_edpm_ssh_info_kubeconfig_path` | `{{ ansible_user_dir }}/.kube/config` | Path to kubeconfig file | | ||
| | `cifmw_edpm_ssh_info_oc_auth_required` | `true` | Whether to authenticate to OpenShift cluster before querying resources | | ||
| | `cifmw_edpm_ssh_info_oc_username` | `kubeadmin` | OpenShift username for authentication | | ||
| | `cifmw_edpm_ssh_info_oc_password_file` | `{{ ansible_user_dir }}/.kube/kubeadmin-password` | Path to file containing OpenShift password | | ||
| | `cifmw_edpm_ssh_info_oc_api_url` | `https://api.ocp.openstack.lab:6443/` | OpenShift API URL | | ||
| | `cifmw_edpm_ssh_info_oc_validate_certs` | `false` | Whether to validate SSL certificates when connecting to OpenShift API | | ||
| | `cifmw_edpm_ssh_info_node_prefix` | `compute-` | Node name prefix to filter (e.g., 'compute-', 'networker-') | | ||
| | `cifmw_edpm_ssh_info_ssh_secret_name` | `dataplane-ansible-ssh-private-key-secret` | Name of the secret containing SSH private key | | ||
| | `cifmw_edpm_ssh_info_ssh_key_path` | `{{ ansible_user_dir }}/.ssh/compute_id` | Destination path for SSH private key | | ||
|
|
||
| ## Output | ||
|
|
||
| ### Facts Set | ||
|
|
||
| The role sets a fact named `cifmw_edpm_ssh_info` with the following structure: | ||
|
|
||
| ```yaml | ||
| cifmw_edpm_ssh_info: | ||
| ssh_key_path: "/path/to/ssh/key" | ||
| nodes: | ||
| - name: compute-0 | ||
| host: 192.168.122.100 | ||
| - name: compute-1 | ||
| host: 192.168.122.101 | ||
| ``` | ||
|
|
||
| **Fields:** | ||
| - `ssh_key_path` (string): Path to the SSH private key file | ||
| - `nodes` (list): List of discovered dataplane nodes | ||
| - `name` (string): Node name (e.g., "compute-0") | ||
| - `host` (string): Control plane IP address | ||
|
|
||
| ## Usage | ||
|
|
||
| ### Basic Usage (with defaults) | ||
|
|
||
| ```yaml | ||
| - name: Get EDPM SSH information | ||
| hosts: localhost | ||
| gather_facts: false | ||
| tasks: | ||
| - name: Retrieve dataplane info | ||
| ansible.builtin.include_role: | ||
| name: edpm_ssh_info | ||
|
|
||
| - name: Display discovered nodes | ||
| ansible.builtin.debug: | ||
| msg: "Found {{ cifmw_edpm_ssh_info.nodes | length }} nodes" | ||
| ``` | ||
|
|
||
| ### Custom Configuration | ||
|
|
||
| ```yaml | ||
| - name: Get EDPM SSH information | ||
| hosts: localhost | ||
| gather_facts: false | ||
| tasks: | ||
| - name: Retrieve dataplane info | ||
| ansible.builtin.include_role: | ||
| name: edpm_ssh_info | ||
| vars: | ||
| cifmw_edpm_ssh_info_openstack_namespace: my-openstack | ||
| cifmw_edpm_ssh_info_node_prefix: networker- | ||
| cifmw_edpm_ssh_info_ssh_key_path: /custom/path/to/key | ||
| ``` | ||
|
|
||
| ### Custom Password File | ||
|
|
||
| ```yaml | ||
| - name: Get EDPM SSH information with custom password file | ||
| hosts: localhost | ||
| gather_facts: false | ||
| tasks: | ||
| - name: Retrieve dataplane info | ||
| ansible.builtin.include_role: | ||
| name: edpm_ssh_info | ||
| vars: | ||
| cifmw_edpm_ssh_info_oc_password_file: /custom/path/to/password-file | ||
| ``` | ||
|
|
||
| ### Using with Dynamic Inventory | ||
|
|
||
| ```yaml | ||
| - name: Get EDPM SSH information | ||
| hosts: localhost | ||
| gather_facts: false | ||
| tasks: | ||
| - name: Retrieve dataplane info | ||
| ansible.builtin.include_role: | ||
| name: edpm_ssh_info | ||
|
|
||
| - name: Add nodes to inventory | ||
| hosts: localhost | ||
| gather_facts: false | ||
| tasks: | ||
| - name: Add compute nodes to dynamic inventory | ||
| ansible.builtin.add_host: | ||
| name: "{{ item.name }}" | ||
| ansible_host: "{{ item.host }}" | ||
| ansible_ssh_private_key_file: "{{ cifmw_edpm_ssh_info.ssh_key_path }}" | ||
| groups: | ||
| - compute_nodes | ||
| loop: "{{ cifmw_edpm_ssh_info.nodes }}" | ||
|
|
||
| - name: Configure compute nodes | ||
| hosts: compute_nodes | ||
| tasks: | ||
| - name: Run configuration tasks | ||
| ansible.builtin.debug: | ||
| msg: "Configuring {{ inventory_hostname }}" | ||
| ``` | ||
|
|
||
| ## Notes | ||
|
|
||
| - If your kubeconfig is already authenticated, set `cifmw_edpm_ssh_info_oc_auth_required: false` to skip the `oc login` step | ||
| - The OpenShift password is read from the file specified in `cifmw_edpm_ssh_info_oc_password_file` (defaults to `~/.kube/kubeadmin-password`) | ||
| - You can set a custom password file path via `cifmw_edpm_ssh_info_oc_password_file` if your password is stored elsewhere | ||
| - The role will fail if no OpenStackDataPlaneNodeSet resources are found | ||
| - SSH key retrieval is skipped if the key file already exists at the destination path | ||
| - SSH key is saved with `0600` permissions for security | ||
| - The role is idempotent - it can be run multiple times safely | ||
| - Only nodes matching the specified prefix and having a control plane IP are included | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| --- | ||
| # OpenShift/Kubernetes namespace for EDPM resources | ||
| cifmw_edpm_ssh_info_openstack_namespace: openstack | ||
|
|
||
| # Kubeconfig file path | ||
| cifmw_edpm_ssh_info_kubeconfig_path: "{{ ansible_user_dir }}/.kube/config" | ||
|
|
||
| # OpenShift authentication required | ||
| cifmw_edpm_ssh_info_oc_auth_required: true | ||
|
|
||
| # OpenShift login credentials | ||
| cifmw_edpm_ssh_info_oc_username: kubeadmin | ||
| cifmw_edpm_ssh_info_oc_password_file: "{{ ansible_user_dir }}/.kube/kubeadmin-password" | ||
| cifmw_edpm_ssh_info_oc_api_url: https://api.ocp.openstack.lab:6443/ | ||
| cifmw_edpm_ssh_info_oc_validate_certs: false | ||
|
|
||
| # Node name prefix to filter (e.g., 'compute-', 'networker-') | ||
| cifmw_edpm_ssh_info_node_prefix: compute- | ||
|
|
||
| # SSH private key retrieval settings | ||
| cifmw_edpm_ssh_info_ssh_secret_name: dataplane-ansible-ssh-private-key-secret | ||
| cifmw_edpm_ssh_info_ssh_key_path: "{{ ansible_user_dir }}/.ssh/compute_id" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| --- | ||
| collections: | ||
| - kubernetes.core | ||
| - community.okd |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| --- | ||
| - name: Read OpenShift password from file | ||
| ansible.builtin.slurp: | ||
| src: "{{ cifmw_edpm_ssh_info_oc_password_file }}" | ||
| register: _oc_password_content | ||
| no_log: "{{ cifmw_nolog | default(true) | bool }}" | ||
| when: cifmw_edpm_ssh_info_oc_auth_required | ||
|
|
||
| - name: Authenticate to OpenShift cluster | ||
| community.okd.openshift_auth: | ||
| host: "{{ cifmw_edpm_ssh_info_oc_api_url }}" | ||
| username: "{{ cifmw_edpm_ssh_info_oc_username }}" | ||
| password: "{{ _oc_password_content.content | b64decode | trim }}" | ||
| validate_certs: "{{ cifmw_edpm_ssh_info_oc_validate_certs }}" | ||
| register: _openshift_auth_result | ||
| no_log: "{{ cifmw_nolog | default(true) | bool }}" | ||
| when: cifmw_edpm_ssh_info_oc_auth_required | ||
|
|
||
| - name: Get OpenShift DataPlane NodeSets | ||
| kubernetes.core.k8s_info: | ||
| api_version: dataplane.openstack.org/v1beta1 | ||
| kind: OpenStackDataPlaneNodeSet | ||
| namespace: "{{ cifmw_edpm_ssh_info_openstack_namespace }}" | ||
| host: "{{ cifmw_edpm_ssh_info_oc_api_url if cifmw_edpm_ssh_info_oc_auth_required else omit }}" | ||
| api_key: "{{ _openshift_auth_result.openshift_auth.api_key if cifmw_edpm_ssh_info_oc_auth_required else omit }}" | ||
| kubeconfig: "{{ cifmw_edpm_ssh_info_kubeconfig_path if not cifmw_edpm_ssh_info_oc_auth_required else omit }}" | ||
| validate_certs: "{{ cifmw_edpm_ssh_info_oc_validate_certs }}" | ||
| register: osdpns_info | ||
| failed_when: osdpns_info.resources | length == 0 | ||
|
|
||
| - name: Check if SSH private key already exists | ||
| ansible.builtin.stat: | ||
| path: "{{ cifmw_edpm_ssh_info_ssh_key_path }}" | ||
| register: ssh_key_stat | ||
|
|
||
| - name: Retrieve SSH private key from OpenShift | ||
| when: not ssh_key_stat.stat.exists | ||
| block: | ||
| - name: Get dataplane SSH secret from OpenShift | ||
| kubernetes.core.k8s_info: | ||
| api_version: v1 | ||
| kind: Secret | ||
| name: "{{ cifmw_edpm_ssh_info_ssh_secret_name }}" | ||
| namespace: "{{ cifmw_edpm_ssh_info_openstack_namespace }}" | ||
| host: "{{ cifmw_edpm_ssh_info_oc_api_url if cifmw_edpm_ssh_info_oc_auth_required else omit }}" | ||
| api_key: "{{ _openshift_auth_result.openshift_auth.api_key if cifmw_edpm_ssh_info_oc_auth_required else omit }}" | ||
| kubeconfig: "{{ cifmw_edpm_ssh_info_kubeconfig_path if not cifmw_edpm_ssh_info_oc_auth_required else omit }}" | ||
| validate_certs: "{{ cifmw_edpm_ssh_info_oc_validate_certs }}" | ||
| register: secret_info | ||
| failed_when: secret_info.resources | length == 0 | ||
|
|
||
| - name: Ensure SSH directory exists | ||
| ansible.builtin.file: | ||
| path: "{{ cifmw_edpm_ssh_info_ssh_key_path | dirname }}" | ||
| state: directory | ||
| mode: '0700' | ||
|
|
||
| - name: Save SSH private key | ||
evallesp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ansible.builtin.copy: | ||
| content: "{{ secret_info.resources[0].data['ssh-privatekey'] | b64decode }}" | ||
| dest: "{{ cifmw_edpm_ssh_info_ssh_key_path }}" | ||
| mode: '0600' | ||
| no_log: "{{ cifmw_nolog | default(true) | bool }}" | ||
|
|
||
| - name: Build dataplane information with nodes and SSH key | ||
| ansible.builtin.set_fact: | ||
| cifmw_edpm_ssh_info: | ||
| ssh_key_path: "{{ cifmw_edpm_ssh_info_ssh_key_path }}" | ||
| nodes: >- | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: consider to change variable name to something different, that would be helpful to recognize place, where it has been set.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm a bit confused by this comment.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with you @michburk, considering that @danpawlik also approved it, could you approve it too? |
||
| {%- set nodes = [] -%} | ||
| {%- for nodeset in osdpns_info.resources -%} | ||
| {%- if nodeset.status.allHostnames is defined and nodeset.status.allIPs is defined -%} | ||
| {%- for fqdn in nodeset.status.allHostnames.keys() -%} | ||
| {%- set node_name = fqdn.split('.')[0] -%} | ||
| {%- if node_name.startswith(cifmw_edpm_ssh_info_node_prefix) and fqdn in nodeset.status.allIPs -%} | ||
| {%- set ctlplane_ip = nodeset.status.allIPs[fqdn].ctlplane | default(None) -%} | ||
| {%- if ctlplane_ip -%} | ||
| {%- set _ = nodes.append({'name': node_name, 'host': ctlplane_ip}) -%} | ||
| {%- endif -%} | ||
| {%- endif -%} | ||
| {%- endfor -%} | ||
| {%- endif -%} | ||
| {%- endfor -%} | ||
| {{ nodes }} | ||
Uh oh!
There was an error while loading. Please reload this page.