Add support for generation of SSH keypairs

If operator needs to enter guest agent instance for troubleshooting,
they need to create a keypair, upload it as Trove user specifically,
create a security group and define it's UUID in trove.conf

This process is quite cumbersome and time consuming, thus this
patch implements mentioned fuctionality and can be enabled
with a single variable.

Process is alike to what we have and been using for Octavia for a while.

Change-Id: I29984c565c808bca79ef39a02e79d9b015a70786
This commit is contained in:
Dmitriy Rabotyagov
2025-06-02 21:07:21 +02:00
parent 46862920df
commit 3035e25333
6 changed files with 117 additions and 40 deletions

View File

@@ -256,6 +256,22 @@ trove_guestagent_images: []
trove_guest_auth_url: "{{ keystone_service_publicurl }}"
trove_guest_swift_url: "{{ trove_service_publicuri_proto }}://{{ external_lb_vip_address }}:{{ swift_proxy_port }}/v1/AUTH_"
trove_resources_deploy_host: localhost
trove_resources_deploy_python_interpreter: "{{ ansible_playbook_python }}"
trove_guest_ssh_enabled: false
trove_guest_ssh_key_manage: true
trove_guest_ssh_key_name: trove_guestagent_key
trove_guest_ssh_key_dir: "{{ openstack_ssh_keypairs_dir | default(lookup('env', 'HOME') ~ '/.ssh') }}"
trove_guest_ssh_key_comment: "Generated-By-OpenStack-Ansible"
# Options: ssh, pkcs1 and pkcs8
trove_guest_ssh_key_format: ssh
# Options: rsa, dsa, rsa1, ecdsa, ed25519
trove_guest_ssh_key_type: rsa
trove_guest_ssh_key_size: 4096
# Security group which will allow SSH connections
trove_guest_ssh_security_group_name: trove_guest_management
trove_guest_ssh_security_group_extra_rules: []
trove_swift_enabled: >-
{{
(groups['swift_all'] is defined and groups['swift_all'] | length > 0) or

View File

@@ -0,0 +1,8 @@
---
features:
- |
Implemented SSH keypair generation for Trove Guest Agent. When
``trove_guest_ssh_enabled`` is set to True, role will perform SSH
keypair generation and upload to Nova. With that, a security group
will be created and added to the ``management_security_groups``
which will allow SSH traffic on dbaas network.

View File

@@ -158,6 +158,44 @@
tags:
- trove-install
- name: Including osa.service_setup role
ansible.builtin.include_role:
name: openstack.osa.service_setup
apply:
tags:
- trove-install
- common-service
vars:
_project_name: "{{ trove_service_project_name }}"
_project_domain: "{{ trove_service_project_domain_id }}"
_service_adminuri_insecure: "{{ keystone_service_adminuri_insecure }}"
_service_setup_host: "{{ trove_service_setup_host }}"
_service_setup_host_python_interpreter: "{{ trove_service_setup_host_python_interpreter }}"
_service_in_ldap: "{{ trove_service_in_ldap }}"
_service_project_name: "{{ trove_service_project_name }}"
_service_region: "{{ trove_service_region }}"
_service_users:
- name: "{{ trove_service_user_name }}"
password: "{{ trove_service_password }}"
role: "{{ trove_service_admin_role_names }}"
_service_endpoints:
- service: "{{ trove_service_name }}"
interface: "public"
url: "{{ trove_service_publicurl }}"
- service: "{{ trove_service_name }}"
interface: "internal"
url: "{{ trove_service_internalurl }}"
- service: "{{ trove_service_name }}"
interface: "admin"
url: "{{ trove_service_adminurl }}"
_service_catalog:
- name: "{{ trove_service_name }}"
type: "{{ trove_service_type }}"
description: "{{ trove_service_description }}"
when: _trove_is_first_play_host
tags:
- always
- name: Including trove_resources tasks
ansible.builtin.include_tasks: trove_resources.yml
when:
@@ -221,44 +259,6 @@
- trove-config
- uwsgi
- name: Including osa.service_setup role
ansible.builtin.include_role:
name: openstack.osa.service_setup
apply:
tags:
- trove-install
- common-service
vars:
_project_name: "{{ trove_service_project_name }}"
_project_domain: "{{ trove_service_project_domain_id }}"
_service_adminuri_insecure: "{{ keystone_service_adminuri_insecure }}"
_service_setup_host: "{{ trove_service_setup_host }}"
_service_setup_host_python_interpreter: "{{ trove_service_setup_host_python_interpreter }}"
_service_in_ldap: "{{ trove_service_in_ldap }}"
_service_project_name: "{{ trove_service_project_name }}"
_service_region: "{{ trove_service_region }}"
_service_users:
- name: "{{ trove_service_user_name }}"
password: "{{ trove_service_password }}"
role: "{{ trove_service_admin_role_names }}"
_service_endpoints:
- service: "{{ trove_service_name }}"
interface: "public"
url: "{{ trove_service_publicurl }}"
- service: "{{ trove_service_name }}"
interface: "internal"
url: "{{ trove_service_internalurl }}"
- service: "{{ trove_service_name }}"
interface: "admin"
url: "{{ trove_service_adminurl }}"
_service_catalog:
- name: "{{ trove_service_name }}"
type: "{{ trove_service_type }}"
description: "{{ trove_service_description }}"
when: _trove_is_first_play_host
tags:
- always
- name: Importing trove_db_sync tasks
ansible.builtin.import_tasks: trove_db_sync.yml
when: _trove_conductor_is_first_play_host

View File

@@ -19,6 +19,23 @@
vars:
openstack_resources_setup_host: "{{ trove_service_setup_host }}"
openstack_resources_python_interpreter: "{{ trove_service_setup_host_python_interpreter }}"
openstack_resources_deploy_host: "{{ trove_resources_deploy_host }}"
openstack_resources_deploy_python_interpreter: "{{ trove_resources_deploy_python_interpreter }}"
_keypairs:
- name: "{{ trove_guest_ssh_key_name }}"
path: "{{ trove_guest_ssh_key_dir }}/{{ trove_guest_ssh_key_name }}"
state: "{{ (trove_guest_ssh_enabled | bool) | ternary('present', 'absent') }}"
private_key_format: "{{ trove_guest_ssh_key_format }}"
size: "{{ trove_guest_ssh_key_size }}"
comment: "{{ trove_guest_ssh_key_comment }}"
type: "{{ trove_guest_ssh_key_type }}"
auth:
auth_url: "{{ keystone_service_adminurl }}"
username: "{{ trove_service_user_name }}"
password: "{{ trove_service_password }}"
project_name: "{{ trove_service_project_name }}"
user_domain_name: "{{ trove_service_user_domain_id }}"
project_domain_name: "{{ trove_service_project_domain_id }}"
_network_resources:
- name: "{{ trove_service_net_name }}"
network_type: "{{ trove_service_net_type }}"
@@ -31,7 +48,20 @@
dhcp: "{{ trove_service_net_dhcp }}"
allocation_start: "{{ trove_service_net_allocation_pool_start | default(omit) }}"
allocation_end: "{{ trove_service_net_allocation_pool_end | default(omit) }}"
_security_groups:
- name: "{{ trove_guest_ssh_security_group_name }}"
description: "security group for octavia amphora"
project: "{{ trove_service_project_name }}"
security_group_rules:
- protocol: tcp
port_range_min: 22
port_range_max: 22
remote_ip_prefix: "{{ trove_service_net_subnet_cidr }}"
openstack_resources_network:
networks: "{{ trove_service_net_setup | ternary(_network_resources, []) }}"
security_groups: "{{ (trove_guest_ssh_enabled) | ternary(_security_groups + trove_guest_ssh_security_group_extra_rules, []) }}"
openstack_resources_image:
images: "{{ _trove_glance_images_compat }}"
openstack_resources_compute:
keypairs: "{{ (trove_guest_ssh_key_manage | bool) | ternary(_keypairs, {}) }}"

View File

@@ -42,3 +42,22 @@
ansible.builtin.set_fact:
trove_service_net_id: "{{ _get_trove_service_net.networks[0].id }}"
run_once: true
- name: Register created security group
run_once: true
when:
- trove_guest_ssh_enabled
block:
- name: Get trove guestagent SSH security group ID
openstack.cloud.security_group_info:
cloud: default
validate_certs: "{{ trove_service_net_validate_certs }}"
wait: true
endpoint_type: "{{ trove_service_net_endpoint_type }}"
name: "{{ trove_guest_ssh_security_group_name }}"
register: _get_trove_security_group
- name: Save security group as fact
ansible.builtin.set_fact:
trove_guest_ssh_security_group_id: "{{ _get_trove_security_group.security_groups[0].id | default('') }}"

View File

@@ -59,8 +59,12 @@ management_networks = {{ trove_service_net_id }}
neutron_endpoint_type = {{ trove_service_neutron_endpoint_type }}
neutron_service_type = network
{% if trove_management_security_groups | length > 0 %}
management_security_groups = {{ trove_management_security_groups | join(',') }}
{% set _enabled_security_groups = trove_management_security_groups %}
{% if trove_guest_ssh_enabled %}
{% set _ = _enabled_security_groups.append(trove_guest_ssh_security_group_id) %}
{% endif %}
{% if _enabled_security_groups | length > 0 %}
management_security_groups = {{ _enabled_security_groups | join(',') }}
{% endif %}
{% if trove_swift_enabled is defined %}