Skip to content
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

create content_view_promotion role #1216

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 127 additions & 0 deletions roles/content_view_promote/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
theforeman.foreman.content_view_promote
=========

A role for automating the staging/promotion of Foreman Content-Views through various Organizations and LifeCycle Environemnts.

Requirements
------------

This role requires the theforeman.foreman module collection.

Role Variables
--------------

The primary dictionary is the organizations dictionary, which is formatted as such:
```
organizations:
bmarlow marked this conversation as resolved.
Show resolved Hide resolved
org1:
lifecycle_environments:
- "Dev"
- "QA"
- "Prod"
content_views:
- "content-view1"
- "content-view2"
org2:
lifecycle_environments:
- "Dev2"
- "QA2"
- "Prod2"
content_views:
- "content-view3"
- "content-view4"
```

This can run against multiple organizations/lifecycle_environments/content-views or selected subsets.

For example, if the previously mentioned dictionary describes *ALL* of my Foreman environment, but I only want to promote the 'Prod' lifecycle_environment in the content-view 'content-view1' in organization 'org', my dictionary would look like this:
```
organizations:
org1:
lifecycle_environments:
- "Prod"
content_views:
- "content-view1"
```
Items not described in the inventory will not be affected (the exception being Library when a new content_view_version needs to be published).

Dependencies
------------

You need a Foreman user with admin access to the Organizations, Lifecycle_Environments, and Content_Views you wish to interact with.

By default, the role will require a valid SSL certificate installed on your Foreman server that the ansible client can trace trust to. To disable that update the 'FOREMAN_VALIDATE_CERTS' variable in defaults/main.yml.

For example, to disable certificate checking you would update the variable as such:
```
FOREMAN_VALIDATE_CERTS: false
```

Example Playbook
----------------

The role can be instantiated quite simply, all of the decision making is handled by the variables previously set:

```
---
- name: "Run the content_view_promotion Role"
hosts: all
tasks:
- name: "Run the content_view_promotion Role"
include_role:
name: theforeman.foreman.content_view_promotion
```
For example:

Promoting Lifecycle Environments:
```
organizations:
org1:
lifecycle_environments:
- "Dev"
- "QA"
- "Prod"
content_views:
- "content-view1"
- "content-view2"
```

The role would promote the Dev, QA and Prod Lifecycle Environments up one version level for both content-view1 and content-view2.
Rolling back Lifecycle Environments to the previous version:
```
organizations:
org1:
lifecycle_environments:
- "Dev"
- "QA"
- "Prod"
content_views:
- "content-view1"
- "content-view2"
```

The role would take the Dev, QA and Prod Lifecycle Environments to Content-View version N+1. If, prior to role runtime, the versions were: Prod=10, QA=11, and Dev=12, the result at the end of the run would be: Prod=10, QA=11, and Dev=12.

To perform actions across multiple Organizations:
```
organizations:
org1:
lifecycle_environments:
- "Dev"
- "QA"
- "Prod"
content_views:
- "content-view1"
- "content-view2"
org2:
lifecycle_environments:
- "LCE1"
- "LCE2"
content_views:
- "org2_content-view"
```

Notes
----------------

When there isn't a new version of the Content-View to promote to, a new version of the Content-View will be published automatically. Be aware that publishing new versions on a large Content-View can take a long time- you may need to adjust your Ansible job timeouts accordingly.
5 changes: 5 additions & 0 deletions roles/content_view_promote/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
# defaults file for content_view_promote
publish_only: false
rollback: false
FOREMAN_VALIDATE_CERTS: true
21 changes: 21 additions & 0 deletions roles/content_view_promote/meta/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
galaxy_info:
author: Brandon Marlow
description: A role for promoting content views
company: Red Hat
license: BSD-3-Clause

min_ansible_version: "2.9"

galaxy_tags:
- satellite
- katello
- foreman
- theforeman
- update
- content-view
- lifecycle
- patch
- patching

collections:
- theforeman.foreman
7 changes: 7 additions & 0 deletions roles/content_view_promote/tasks/content-view.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
- name: "Promote Content-Views"
include_tasks: promote.yml
loop: "{{ organization.value.content_views }}"
loop_control:
loop_var: content_view
when: rollback == False
6 changes: 6 additions & 0 deletions roles/content_view_promote/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
- name: "Run Content-View Role"
include_tasks: content-view.yml
with_dict: "{{ organizations }}"
loop_control:
loop_var: organization
87 changes: 87 additions & 0 deletions roles/content_view_promote/tasks/promote.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
---
# get data on the current content-view
- name: "Gather Data For Current Content-View From Foreman"
theforeman.foreman.resource_info:
username: "{{ foreman_user }}"
password: "{{ foreman_password }}"
server_url: "{{ foreman_server_url }}"
organization: "{{ organization.key }}"
resource: content_views
search: name = "{{ content_view }}"
validate_certs: false
register: content_view_data

# get data on the current content-view version
- name: "Gather Data For Current Content-View Versions From Foreman"
theforeman.foreman.resource_info:
username: "{{ foreman_user }}"
password: "{{ foreman_password }}"
server_url: "{{ foreman_server_url }}"
organization: "{{ organization.key }}"
resource: content_view_versions
params:
content_view_id: "{{ content_view_data.resources[0].id }}"
register: version_information

# creates a dictionary with data formatted as such {'Prod':'11.0'}
- name: "Build Dictionary With Lifecycle Envrionment And Version Number"
set_fact:
environments: "{{ environments | default({}) | combine ({item[1].name : item[0].name.split()[-1]}) }}"
with_subelements:
- "{{ version_information.resources }}"
- environments

# create list of content-view versions
- name: "Build List of All Versions of Content-View"
set_fact:
cv_versions: "{{ cv_versions | default([]) + [item.major] }}"
with_items: "{{ version_information.resources }}"

# set the highest version to zero so that we don't use previous Content-View settings
- name: "Set Highest Version to 0"
set_fact:
highest_version: 0

# set highest number
- name: "Set the Highest Version of the Content-View Currently Available"
set_fact:
highest_version: "{{ cv_versions | max }}"

# add one to each of the version numbers
- name: "Update Facts With Incremented Content-View Version Numbers"
set_fact:
new_environments: "{{ new_environments | default({}) | combine ({item.key: item.value|int + 1.0 }) }} "
with_dict: "{{ environments }}"

- name: "Check if publishing new version of Content-View is necessary"
set_fact:
publish_true: true
with_dict: "{{ new_environments }}"
when: item.value | int > highest_version | int

# only publish new view if necessary (when the current view is at or above library)
- name: "Publish new version of Content-View"
bmarlow marked this conversation as resolved.
Show resolved Hide resolved
theforeman.foreman.content_view_version:
username: "{{ foreman_user }}"
password: "{{ foreman_password }}"
server_url: "{{ foreman_server_url }}"
organization: "{{ organization.key }}"
content_view: "{{ content_view }}"
when: publish_true | default(false)

# only promote environments defined in the vars
- name: "Promote Environments to Version N+1"
theforeman.foreman.content_view_version:
username: "{{ foreman_user }}"
password: "{{ foreman_password }}"
server_url: "{{ foreman_server_url }}"
organization: "{{ organization.key }}"
content_view: "{{ content_view }}"
# dictionaries aren't ordered and Foreman doesn't want you promoting things out of order
# but we're promoting them all so we just override that behavior
force_promote: true
lifecycle_environments: "{{ item.key }}"
version: "{{ item.value }}"
with_dict: "{{ new_environments }}"
when: item.key in organization.value.lifecycle_environments