Skip to content

Commit

Permalink
merge ansible role octavia_preconf as per jira OSPC-189 (#653)
Browse files Browse the repository at this point in the history
* merge ansible role octavia_preconf as per jira OSPC-189

Signed-off-by: puni4220 <[email protected]>

* remove tests directory from the octavia_preconf role and enclose variable names in double quotes in shell scripts

Signed-off-by: puni4220 <[email protected]>

* resolve ansible linting issues as per the last report Jan 24th

Signed-off-by: puni4220 <[email protected]>

* disable shellcheck for cat command in shell script

* fix training whitespace issues

---------

Signed-off-by: puni4220 <[email protected]>
  • Loading branch information
puni4220 authored Jan 24, 2025
1 parent 61c7700 commit ed56490
Show file tree
Hide file tree
Showing 18 changed files with 983 additions and 0 deletions.
85 changes: 85 additions & 0 deletions ansible/roles/octavia_preconf/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
## octavia_preconf

This is a role for performing the pre-requisite tasks to enable amphora provider for octavia for example creating a network and a subnet for amphorae, uploading the image to glance, creating ssh keys etc. This is mainly intended for running octavia in a k8s environment

## Requirements

These are the requirements to run this role:
1. This role needs to be run on any of the nodes which has access to the openstack public endpoints
2. This role also needs access to the k8s cluster as it tries to create "octavia-certs" secret in the openstack namespace to it needs access to kubectl utility
3. It is recommended to create a virtual environment to run this role; steps will be shared below

## Creating a virtual environment

1. Install the required packages for creating the virutal environment with python:
```
root@saturn-c1:~# apt-get install python3-venv python3-pip
```
2. Create the virtual environment:
```
root@saturn-c1:~# mkdir -p ~/.venvs
root@saturn-c1:~# python3 -m venv --system-site-packages ~/.venvs/octavia_preconf
```
3. Install the required dependencies for the virtual environment:
```
root@saturn-c1:~# source .venvs/octavia_preconf/bin/activate
(octavia_preconf) root@saturn-c1:~#
(octavia_preconf) root@saturn-c1:~# pip install --upgrade pip
(octavia_preconf) root@saturn-c1:~# pip install "ansible>=2.9" "openstacksdk>=1.0.0" "python-openstackclient==6.2.0"
```
4. Download the kubectl binary and copy the kubeconfig from one of the k8s master nodes:
```
(octavia_preconf) root@saturn-c1:~# curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
(octavia_preconf) root@saturn-c1:~# install -o root -g root -m 0755 kubectl /root/.venvs/octavia_preconf/bin
(octavia_preconf) root@saturn-c1:~# mkdir ~/.kube
(octavia_preconf) root@saturn-c1:~# mv config ~/.kube/
```
note that the kubeconfig in this step has been copied from the master node and it should be modified accordingly

## Role Variables

+ The available variables can be found in the defaults/main.yml file
+ The role variables can be used to modify
+ quota values for cores, RAM, security groups, security group rules, server groups and others
+ lb-mgmt-subet cidr, pool and gateway
+ whether ssh should be enabled for amphora
+ Validity and other certificate parameters \
Refer to the role defaults for more detail

## Dependencies

The role has no external dependencies; only the steps shared above for creating the virutal environment are required

## Example Playbook

The role needs keystone admin credentials; they can be provided as environment variables \
This is an example playbook for running the role:

```
(octavia_preconf) root@saturn-c1:~# cat octavia-preconf-main.yaml
- name: Pre-requisites for enabling amphora provider in octavia
hosts: localhost
environment:
OS_ENDPOINT_TYPE: publicURL
OS_INTERFACE: publicURL
OS_USERNAME: 'admin'
OS_PASSWORD: 'XXXXX'
OS_PROJECT_NAME: 'admin'
OS_TENANT_NAME: 'admin'
OS_AUTH_TYPE: password
OS_AUTH_URL: 'https://keystone.lab.local/v3'
OS_USER_DOMAIN_NAME: 'default'
OS_PROJECT_DOMAIN_NAME: 'default'
OS_REGION_NAME: 'RegionOne'
OS_IDENTITY_API_VERSION: 3
OS_AUTH_VERSION: 3
NOVA_ENDPOINT_TYPE: publicURL
roles:
- /root/octavia_preconf
```

These are the required environment variables for the role; must be modified accordingly. The keystone admin password can be obtained from k8s as below:
```
(octavia_preconf) root@saturn-c1:~# kubectl get secret -n openstack keystone-admin -o jsonpath='{ .data.password }' | base64 -d
```
76 changes: 76 additions & 0 deletions ansible/roles/octavia_preconf/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
# defaults file for octavia_preconf

# these are the defaults for quotas
num_amphora_instances: 100
num_amphora_cores: "{{ (num_amphora_instances|int)*2 }}" # 2 cores for each amphora
amphora_ram_mb: "{{ (num_amphora_instances|int)*1024 }}" # 1G of ram for each amphora
num_amphora_ports: "{{ (num_amphora_instances|int)*5 }}" # considering 5 ports for amphora instance
octavia_num_secgroup: "{{ (num_amphora_instances|int)*1.5|int|abs }}" # average 3 listeners per lb
octavia_num_secgroup_rule: "{{ (octavia_num_secgroup|int)*5 }}" # considering 5 secgroup rules per sec group
num_amphora_server_groups: "{{ ((num_amphora_instances|int)*0.5)|int|abs }}" # 2 amphora per group for active/passive
num_amphora_server_group_member: 20

# these are the defaults for lb-mgmt-net
#lb_mgmt_net_physical_net
lb_mgmt_net_type: geneve
#lb_mgmt_net_segmentation_id

# these are the defaults for lb-mgmt-subnet
lb_mgmt_subnet_cidr: '172.16.29.0/24'
lb_mgmt_subnet_pool_start: '172.16.29.2'
lb_mgmt_subnet_pool_end: '172.16.29.254'
lb_mgmt_subnet_gateway: '172.16.29.1'

# these are the defaults for security groups
amphora_icmp_enabled: true
amphora_ssh_enabled: true
lb_health_mgr_secgrp_name: "lb-health-mgr-secgroup"
lb_mgmt_secgrp_name: "lb-mgmt-secgroup"

# these are the defaults for the flavor, image and ssh keypair
amphora_ssh_key_name: amphora-ssh-key
amphora_flavor_name: m1.amphora
amphora_image_version: focal
amphora_image_name: amphora-ubuntu-{{ amphora_image_version }}

# these are the defaults for certs
octavia_create_certs: true
octavia_certs_dir: "{{ lookup('env', 'HOME') }}/octavia_certs"
octavia_cert_key_bits: 4096
octavia_key_type: "RSA"
octavia_key_passwd: 'not-secure-passphrase'

octavia_server_ca_subj: '/C=US/ST=Texas/L=Local/O=RPC/OU=Racklab/CN=ServerRootCA'
octavia_client_ca_subj: '/C=US/ST=Texas/L=Local/O=RPC/OU=Racklab/CN=ClientRootCA'

# CA and client cert and key files
octavia_serverca_privkey: "{{ octavia_certs_dir }}/private/serverca.key.pem"
octavia_server_ca_cert: "{{ octavia_certs_dir }}/certs/serverca.cert.pem"

octavia_clientca_privkey: "{{ octavia_certs_dir }}/private/clientca.key.pem"
octavia_client_ca_cert: "{{ octavia_certs_dir }}/certs/clientca.cert.pem"

octavia_client_csr: "{{ octavia_certs_dir }}/csr/client.csr.pem"
octavia_client_key: "{{ octavia_certs_dir }}/private/client.key.pem"
octavia_client_cert: "{{ octavia_certs_dir }}/certs/client.cert.pem"
octavia_client_key_cert: "{{ octavia_certs_dir }}/private/client-key-and-cert.pem"

octavia_ca_valid_period: 1096 # about 3 years


octavia_client_key_bits: 2048

# Client CSR
client_cert_CN: "OctaviaController"
client_cert_CT: "US"
client_cert_ST: "Texas"
client_cert_LN: "Local"
client_cert_ORG: "RPC"
client_cert_OU: "Rackerlab"

# Client cert validity (in days)
octavia_client_cert_valid_period: 1096

# octavia helm values for amphora provider
octavia_helm_values_file: "{{ lookup('env', 'HOME') }}/octavia_amphora_provider.yaml"
34 changes: 34 additions & 0 deletions ansible/roles/octavia_preconf/files/create_health_mgr_ports.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/bash

# We need to create the ports with shell scripts
# the ansible module currently doesn't provide
# --host argument

set -xe

# Obtain the network_id and secgroup_id from and
# cloud name from ansible task
NET_ID=$1
SECGRP_ID=$2
CLOUD_NAME=$3

export OS_CLOUD=$CLOUD_NAME

# Obtain the list of kubernetes nodes with
# "openstack-control-plane=enabled" label
CONTROLLER_IP_PORT_LIST=''
CTRLS=$(kubectl get nodes -l openstack-control-plane=enabled -o name | awk -F"/" '{print $2}')
for node in $CTRLS
do
node_short=$(echo "$node" | awk -F"." '{print $1}')
PORTNAME=octavia-health-manager-port-$node_short
PORT_ID=$(openstack port create "$PORTNAME" --security-group "$SECGRP_ID" --device-owner Octavia:health-mgr --host="$node" -c id -f value --network "$NET_ID")
IP=$(openstack port show "$PORT_ID" -c fixed_ips -f yaml | grep ip_address | awk -F':' '{print $2}')
if [ -z "$CONTROLLER_IP_PORT_LIST" ]; then
CONTROLLER_IP_PORT_LIST=$IP:5555
else
CONTROLLER_IP_PORT_LIST=$CONTROLLER_IP_PORT_LIST,$IP:5555
fi
done

echo "$CONTROLLER_IP_PORT_LIST" > /tmp/octavia_hm_controller_ip_port_list
34 changes: 34 additions & 0 deletions ansible/roles/octavia_preconf/files/create_k8s_secret.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/bash

# obtain the values for cert and keys
# from the ansible tasks; these will
# then be used to create the secret

set -xe

SERVER_CA=$1
SERVER_CA_KEY=$2
CLIENT_CA=$3
CLIENT_KEY_CERT=$4

function encod_base64()
{
local file_path=$1
# shellcheck disable=SC2002
cat "$file_path" | base64 -w0 | tr -d '\n'
}

cat <<EOF> /tmp/k8s_secret.yml
---
apiVersion: v1
kind: Secret
metadata:
name: octavia-certs
namespace: openstack
type: Opaque
data:
server_ca.cert.pem: $(encod_base64 "$SERVER_CA")
server_ca.key.pem: $(encod_base64 "$SERVER_CA_KEY")
client_ca.cert.pem: $(encod_base64 "$CLIENT_CA")
client.key-and-cert.pem: $(encod_base64 "$CLIENT_KEY_CERT")
EOF
2 changes: 2 additions & 0 deletions ansible/roles/octavia_preconf/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
# handlers file for octavia_preconf
16 changes: 16 additions & 0 deletions ansible/roles/octavia_preconf/meta/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
galaxy_info:
author: Punit Shankar Kundal
description: Create the required pre-requisite resources for enabling amphora provider in Octavia
company: Rackspace Technology
license: Apache-2.0
min_ansible_version: 2.15.8
galaxy_tags: []
# List tags for your role here, one per line. A tag is a keyword that describes
# and categorizes the role. Users find roles by searching for tags. Be sure to
# remove the '[]' above, if you add tags to this list.
#
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
# Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.
43 changes: 43 additions & 0 deletions ansible/roles/octavia_preconf/tasks/admin_tenant_quota_setup.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
# This tasks modifies the quotas for the admin tenant to
# more suitable defaults as the resources for amphora
# provider are created in the "admin" tenant by default
- name: Fetch the current quotas for the admin tenant
openstack.cloud.quota:
name: "{{ admin_project_name | default('admin') }}"
interface: public
register: _current_admin_quota

- name: Display the current quota values for the admin tenant
debug:
msg:
- "Current quota value for instances: {{ _current_admin_quota.quotas.compute.instances }}; New quota value for instances: {{ num_amphora_instances }}"
- "Current quota value for cores: {{ _current_admin_quota.quotas.compute.cores }}; New quota value for cores: {{ num_amphora_cores }}"
- "Current quota value for server_groups: {{ _current_admin_quota.quotas.compute.server_groups }}; New quota value for server_groups: {{ num_amphora_server_groups }}"
- "Current quota value for ram(MB): {{ _current_admin_quota.quotas.compute.ram }}; New quota value for ram(MB): {{ amphora_ram_mb }}"
- "Current quota value for ports: {{ _current_admin_quota.quotas.network.ports }}; New quota value for ports: {{ num_amphora_ports }}"
- "Current quota value for security_groups: {{ _current_admin_quota.quotas.network.security_groups }}; New quota value for security_groups: {{ octavia_num_secgroup }}"
- "Current quota value for security_group_rules: {{ _current_admin_quota.quotas.network.security_group_rules }}; New quota value for security_group_rules: {{ octavia_num_secgroup_rule }}"
- "Current quota value for server_group_members: {{ _current_admin_quota.quotas.compute.server_group_members }}; New quota value for server_group_members: {{ num_amphora_server_group_member }}"

- name: modify the quotas for the admin tenant to suit to production environments
block:
- openstack.cloud.quota:
name: "{{ admin_project_name | default('admin') }}"
instances: "{{ num_amphora_instances }}"
cores: "{{ num_amphora_cores }}"
server_groups: "{{ num_amphora_server_groups }}"
ram: "{{ amphora_ram_mb }}"
port: "{{ num_amphora_ports }}"
security_group: "{{ octavia_num_secgroup }}"
security_group_rule: "{{ octavia_num_secgroup_rule }}"
server_group_members: "{{ num_amphora_server_group_member }}"
interface: public
rescue:
- debug:
msg: "WARNING: Failed to modify admin tenant quotas! trying to reset to defaults; please review the ansible error logs"
- name: set the quota to defaults for the admin tenant
openstack.cloud.quota:
state: absent
name: "{{ admin_project_name | default('admin') }}"
interface: public
44 changes: 44 additions & 0 deletions ansible/roles/octavia_preconf/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
# tasks file for octavia_preconf

- name: import tasks for modifying the admin tenant quotas
import_tasks: admin_tenant_quota_setup.yml
tags:
- always

- name: import tasks to create lb-mgmt-net for amphora
import_tasks: octavia_lb_net_setup.yml
tags:
- always

- name: import tasks to create sec groups for amphora and health manager ports
import_tasks: octavia_sec_group.yml
tags:
- always

- name: import tasks to create health mgr ports
import_tasks: octavia_health_mgr_ports.yml
tags:
- always

- name: import tasks to create amphora image, flavor and ssh keypair
import_tasks: octavia_amphora_keypair_image_flavor.yml
tags:
- always

- name: import tasks to create cert directories
import_tasks: octavia_cert_dir_setup.yml
tags:
- octavia_certs
when: octavia_create_certs

- name: import tasks to create octavia certs
import_tasks: octavia_cert.yml
tags:
- octavia_certs
when: octavia_create_certs

- name: import tasks to create helm values file for amphora provider
import_tasks: octavia_helm_amphorae_values.yml
tags:
- always
Loading

0 comments on commit ed56490

Please sign in to comment.