Add role to add ipa services for tls-everywhere

This role adds required IPA services given the server metadata
and registers the base host as an ipa client.
To be used when novajoin is not available, that is:
 * in the standalone node (to be used in TLS Everywhere CI),
 * when using pre-provisioned nodes.

This commit also ensure we don't attempt to register a server/host
that's already enrolled.

This code requires the ansible-freeipa package to be installed.

Co-Authored-By: Grzegorz Grasza <xek@redhat.com>
Change-Id: Ie7fa5e1e83a3b015fd1e86c4666ace575e99833e
This commit is contained in:
Ade Lee 2019-10-29 12:11:49 -04:00 committed by Grzegorz Grasza
parent a3d1af2413
commit 771fc31828
23 changed files with 916 additions and 62 deletions

View File

@ -1,3 +1,4 @@
ansible
docker
molecule>=3.0,<3.1
testinfra

View File

@ -17,6 +17,9 @@ whitelist_externals =
tox
[testenv:molecule]
setenv =
ANSIBLE_FILTER_PLUGINS={toxinidir}/tripleo_ipa/ansible_plugins/filter
ANSIBLE_ROLES_PATH={toxinidir}/tripleo_ipa/roles.galaxy:{toxinidir}/tripleo_ipa/roles
deps =
-r {toxinidir}/molecule-requirements.txt
changedir = {toxinidir}/tripleo_ipa

View File

@ -1,2 +0,0 @@
---
# defaults file for tripleo_ipa

View File

@ -1,2 +0,0 @@
---
# handlers file for tripleo_ipa

View File

@ -1,45 +0,0 @@
galaxy_info:
author: OpenStack
description: This role is used to integrate TripleO with FreeIPA.
company: Red Hat
# If the issue tracker for your role is not on github, uncomment the
# next line and provide a value
# issue_tracker_url: http://example.com/issue/tracker
# Choose a valid license ID from https://spdx.org - some suggested licenses:
# - BSD-3-Clause (default)
# - MIT
# - GPL-2.0-or-later
# - GPL-3.0-only
# - Apache-2.0
# - CC-BY-4.0
license: Apache-2.0
min_ansible_version: 2.9
# If this a Container Enabled role, provide the minimum Ansible Container version.
# min_ansible_container_version:
#
# Provide a list of supported platforms, and for each platform a list of versions.
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
# To view available platforms and versions (or releases), visit:
# https://galaxy.ansible.com/api/v1/platforms/
#
platforms:
- name: CentOS
versions:
- 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.

View File

@ -0,0 +1,37 @@
# Molecule managed
# Copyright 2020 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
{% if item.registry is defined %}
FROM {{ item.registry.url }}/{{ item.image }}
{% else %}
FROM {{ item.image }}
{% endif %}
RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates && apt-get clean; \
elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash {{ item.pkg_extras | default('') }} && dnf clean all; \
elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl python-setuptools bash {{ item.pkg_extras | default('') }} && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \
elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml {{ item.pkg_extras | default('') }} && zypper clean -a; \
elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates {{ item.pkg_extras | default('') }}; \
elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates {{ item.pkg_extras | default('') }} && xbps-remove -O; fi
{% for pkg in item.easy_install | default([]) %}
# install pip for centos where there is no python-pip rpm in default repos
RUN easy_install {{ pkg }}
{% endfor %}
CMD ["/sbin/init"]

View File

@ -1,7 +1,143 @@
---
- name: Converge
# Copyright 2020 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
- name: Setup server
hosts: all
vars:
ipa_domain: example.test
ipa_server_ip: 172.18.0.22
ipa_server_user: admin
ipa_server_password: password123
ipa_server_hostname: ipa.example.test
undercloud_fqdn: test-0.example.test
tasks:
- name: "Include tripleo_ipa"
- name: install python urllib gssapi
pip:
name: urllib_gssapi
- name: install ipa client
package:
name: ipa-client
state: present
- name: set resolv.conf to point to the ipa server
shell:
cmd: cat > /etc/resolv.conf
stdin: |
search {{ ipa_domain }}
nameserver {{ ipa_server_ip }}
- name: Set fqdn in /etc/hosts
shell:
cmd: cat > /etc/hosts
- name: Set fqdn in /etc/hosts
shell:
cmd: cat > /etc/hosts
stdin: |
127.0.0.1 test-0.example.test test-0 localhost localhost.localdomain
- name: enroll the server as an ipa client using admin creds
shell: |
ipa-client-install -U \
--server "{{ ipa_server_hostname }}" \
--domain "{{ ipa_domain }}" \
--realm "{{ ipa_domain | upper }}" \
--principal "{{ ipa_server_user }}" \
--password "{{ ipa_server_password }}" \
--no-ntp --force-join --no-nisdomain
args:
creates: /etc/ipa/default.conf
# we need this keytab for operations that we cannot do yet with ansible
- name: kinit to get admin creds
command: kinit "{{ ipa_server_user }}"
args:
stdin: "{{ ipa_server_password }}"
- name: Ensure "tripleo-admin" group exists
group:
name: tripleo-admin
state: present
- name: create users, perms, get keytab
include_role:
name: "tripleo_ipa"
name: tripleo_ipa_setup
apply:
environment:
IPA_USER: "{{ ipa_server_user }}"
IPA_HOST: "{{ ipa_server_hostname }}"
IPA_PASS: "{{ ipa_server_password }}"
- name: Converge - add host and relevant services
hosts: all
vars:
tripleo_ipa_enroll_base_server: true
tripleo_ipa_base_server_fqdn: test-0.example.test
tripleo_ipa_base_server_short_name: test-0
tripleo_ipa_base_server_domain: example.test
tripleo_ipa_delegate_server: localhost
tripleo_ipa_server_metadata: |
{
"compact_service_HTTP": [
"ctlplane",
"storage",
"storagemgmt",
"internalapi",
"external"
],
"compact_service_haproxy": [
"ctlplane",
"storage",
"storagemgmt",
"internalapi"
],
"compact_service_libvirt-vnc": [
"internalapi"
],
"compact_service_mysql": [
"internalapi"
],
"compact_service_neutron_ovn": [
"internalapi"
],
"compact_service_novnc-proxy": [
"internalapi"
],
"compact_service_ovn_controller": [
"internalapi"
],
"compact_service_ovn_dbs": [
"internalapi"
],
"compact_service_rabbitmq": [
"internalapi"
],
"compact_service_redis": [
"internalapi"
],
"managed_service_haproxyctlplane": "haproxy/test-0.ctlplane.example.test",
"managed_service_haproxyexternal": "haproxy/test-0.example.test",
"managed_service_haproxyinternal_api": "haproxy/test-0.internalapi.example.test",
"managed_service_haproxystorage": "haproxy/test-0.storage.example.test",
"managed_service_haproxystorage_mgmt": "haproxy/test-0.storagemgmt.example.test",
"managed_service_mysqlinternal_api": "mysql/test-0.internalapi.example.test",
"managed_service_ovn_dbsinternal_api": "ovn_dbs/test-0.internalapi.example.test",
"managed_service_redisinternal_api": "redis/test-0.internalapi.example.test"
}
roles:
- name: tripleo_ipa_registration
environment:
IPA_USER: admin
IPA_HOST: ipa.example.test
IPA_PASS: password123

View File

@ -1,13 +1,46 @@
---
dependency:
name: galaxy
driver:
name: docker
log: true
platforms:
- name: instance
image: docker.io/pycontribs/centos:7
pre_build_image: true
- name: centos7
hostname: test-0.example.test
image: centos:7
security_opts:
- seccomp=unconfined
command: /sbin/init
tmpfs:
- /run
- /tmp
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
dockerfile: Dockerfile
network_mode: host
easy_install:
- pip
environment: &env
http_proxy: "{{ lookup('env', 'http_proxy') }}"
https_proxy: "{{ lookup('env', 'https_proxy') }}"
provisioner:
name: ansible
log: true
env:
ANSIBLE_STDOUT_CALLBACK: yaml
ANSIBLE_ROLES_PATH: "${ANSIBLE_ROLES_PATH:-/usr/share/ansible/roles}:${HOME}/zuul-jobs/roles"
ANSIBLE_LIBRARY: "${ANSIBLE_LIBRARY:-/usr/share/ansible/plugins/modules}"
ANSIBLE_FILTER_PLUGINS: "${ANSIBLE_FILTER_PLUGINS:-/usr/share/ansible/plugins/filter}"
scenario:
test_sequence:
- destroy
- create
- prepare
- converge
- verify
- destroy
verifier:
name: ansible
name: testinfra

View File

@ -0,0 +1,74 @@
---
# Copyright 2020 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
- hosts: localhost
connection: local
tasks:
- name: set facts for domains
set_fact:
domain: example.test
ipa_password: password123
- name: Download FreeIPA Container
docker_image:
name: freeipa/freeipa-server:fedora-28
source: pull
- name: Make IPA data dir
file:
path: /tmp/ipa-data
state: directory
- name: Toggle SELinux boolean
seboolean:
name: container_manage_cgroup
state: true
persistent: true
become: true
- name: Remove any old IPA container
docker_container:
name: freeipa-server-container
state: absent
- name: Create network
docker_network:
name: ipa_network
ipam_config:
- subnet: 172.18.0.0/16
- name: Configure FreeIPA
shell: >
docker run --name freeipa-server-container
--sysctl net.ipv6.conf.lo.disable_ipv6=0
--security-opt seccomp=unconfined
--net ipa_network --ip 172.18.0.22
-e IPA_SERVER_IP={{ ansible_default_ipv4.address | default('127.0.0.1') }}
-e PASSWORD={{ ipa_password }}
-h ipa.{{ domain }}
--read-only --tmpfs /run --tmpfs /tmp
-v /sys/fs/cgroup:/sys/fs/cgroup:ro
-v /tmp/ipa-data:/data:Z freeipa/freeipa-server:fedora-28 exit-on-finished
-U -r {{ domain | upper }} --setup-dns --no-reverse --no-ntp
--forwarder={{ unbound_primary_nameserver_v4 | default('1.1.1.1') }}
--forwarder={{ unbound_secondary_nameserver_v4 | default('8.8.8.8') }} &
- name: Wait for FreeIPA server install
wait_for:
path: "/tmp/ipa-data/var/log/ipaserver-install.log"
search_regex: "(INFO The ipa-server-install command was successful|ERROR The ipa-server-install command failed)"
timeout: 900
become: true

View File

@ -0,0 +1,168 @@
import os
import pytest
import testinfra
import testinfra.utils.ansible_runner
inventory = os.environ['MOLECULE_INVENTORY_FILE']
testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
inventory).get_hosts('all')
def setup_module(module):
for host in testinfra_hosts:
testinfra.get_host('ansible://' + host,
ansible_inventory=inventory
).check_output('echo password123 | kinit admin')
def teardown_module(module):
for host in testinfra_hosts:
testinfra.get_host('ansible://' + host,
ansible_inventory=inventory
).check_output('kdestroy')
@pytest.mark.parametrize('pkg', [
'ipa-client',
])
def test_pkg(host, pkg):
package = host.package(pkg)
assert package.is_installed
@pytest.mark.parametrize('svc', [
'dbus',
'sssd',
])
def test_svc(host, svc):
service = host.service(svc)
assert service.is_running
assert service.is_enabled
@pytest.mark.parametrize('file, content', [
("/etc/ipa/default.conf", "ipa.example.test"),
("/etc/hosts", "test-0.example.test"),
("/etc/resolv.conf", "172.18.0.22"),
("/etc/novajoin/krb5.keytab", "test-0.example.test"),
])
def test_files(host, file, content):
file = host.file(file)
assert file.exists
assert file.contains(content)
@pytest.mark.parametrize('perm', [
{'name': 'Modify host password', 'right': "write",
'type': "host", 'attrs': "userpassword"},
{'name': 'Write host certificate', 'right': "write",
'type': "host", 'attrs': "usercertificate"},
{'name': 'Modify host userclass', 'right': "write",
'type': "host", 'attrs': "userclass"},
{'name': 'Modify service managedBy attribute', 'right': "write",
'type': "service", 'attrs': "managedby"},
])
def test_permissions(host, perm):
result = host.check_output('ipa permission-find "{name}"'.format(**perm))
assert '1 permission matched' in result
assert 'Granted rights: {right}'.format(**perm) in result
assert 'Type: {type}'.format(**perm) in result
assert 'Effective attributes: {attrs}'.format(**perm) in result
@pytest.mark.parametrize('pri', [
'Nova Host Management',
])
def test_privilages(host, pri):
result = host.check_output('ipa privilege-find "{}"'.format(pri))
assert '1 privilege matched' in result
assert 'Privilege name: {}'.format(pri) in result
assert 'Description: {}'.format(pri) in result
def test_privilege_permissions(host):
pri = 'Nova Host Management'
perms = [
'System: add hosts',
'System: remove hosts',
'Modify host password',
'Modify host userclass',
'System: Modify hosts',
'Modify service managedBy attribute',
'System: Add krbPrincipalName to a Host',
'System: Add Services',
'System: Remove Services',
'Revoke certificate',
'System: manage host keytab',
'System: Manage host certificates',
'System: modify services',
'System: manage service keytab',
'System: read dns entries',
'System: remove dns entries',
'System: add dns entries',
'System: update dns entries',
'Retrieve Certificates from the CA',
]
result = host.check_output('ipa privilege-show "{}"'.format(pri))
assert 'Privilege name: {}'.format(pri) in result
for perm in perms:
assert perm.lower() in result.lower()
def test_role(host):
role = 'Nova Host Manager'
pri = 'Nova Host Management'
result = host.check_output('ipa role-show "{}"'.format(role))
assert 'Role name: {}'.format(role) in result
assert 'Description: {}'.format(role) in result
assert 'Privileges: {}'.format(pri) in result
assert 'Member services: nova/test-0.example.test@EXAMPLE.TEST' in result
@pytest.mark.parametrize('name', [
'test-0.example.test',
'test-0.ctlplane.example.test',
'test-0.external.example.test',
'test-0.internalapi.example.test',
'test-0.storage.example.test',
'test-0.storagemgmt.example.test',
])
def test_hosts(host, name):
result = host.check_output('ipa host-find {}'.format(name))
assert '1 host matched' in result
@pytest.mark.parametrize('service, subhost', [
('HTTP', 'ctlplane'),
('HTTP', 'external'),
('HTTP', 'internalapi'),
('HTTP', 'storage'),
('HTTP', 'storagemgmt'),
('haproxy', 'ctlplane'),
('haproxy', 'internalapi'),
('haproxy', 'storage'),
('haproxy', 'storagemgmt'),
('libvirt-vnc', 'internalapi'),
('mysql', 'internalapi'),
('neutron_ovn', 'internalapi'),
('novnc-proxy', 'internalapi'),
('ovn_controller', 'internalapi'),
('ovn_dbs', 'internalapi'),
('rabbitmq', 'internalapi'),
('redis', 'internalapi'),
])
def test_services(host, service, subhost):
result = host.check_output(
'ipa service-show {}/test-0.{}.example.test@EXAMPLE.TEST'.format(
service, subhost))
assert 'Principal name: {}/test-0.{}.example.test@EXAMPLE.TEST'.format(
service, subhost) in result
assert 'Principal alias: {}/test-0.{}.example.test@EXAMPLE.TEST'.format(
service, subhost) in result
'Roles: Nova Host Manager' in result
assert 'Managed by: test-0.{}.example.test, test-0.example.test'.format(
subhost) in result

View File

@ -0,0 +1,23 @@
---
# Copyright 2020 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# All variables intended for modification should place placed in this file.
# All variables within this role should have a prefix of "tripleo_ipa"
# enroll base server
tripleo_ipa_enroll_base_server: false

View File

@ -0,0 +1,44 @@
---
# Copyright 2020 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
galaxy_info:
author: OpenStack
description: TripleO OpenStack Role -- tripleo_ipa_registration
company: Red Hat
license: Apache-2.0
min_ansible_version: 2.7
#
# Provide a list of supported platforms, and for each platform a list of versions.
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
# To view available platforms and versions (or releases), visit:
# https://galaxy.ansible.com/api/v1/platforms/
#
platforms:
- name: Fedora
versions:
- 28
- name: CentOS
versions:
- 7
galaxy_tags:
- tripleo
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.
dependencies: []

View File

@ -0,0 +1,63 @@
---
# Copyright 2020 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# This role adds a host and its required sub-hosts and services to
# FreeIPA as defined in the ServerMetadata.
#
# The following variables are required:
# - tripleo_ipa_enroll_base_server (True if base server must be enrolled)
# - tripleo_ipa_base_server_fqdn (FQDN of base host eg. controller-0.example.com)
# - tripleo_ipa_base_server_otp (OTP for enrollment, only required if enroll_server is True)
# - tripleo_ipa_delegate_server (Server for OTP delegation, only required if enroll_server is True)
# - tripleo_ipa_server_metadata (server metadata, which includes required services)
- name: set main facts
set_fact:
base_server_fqdn: "{{ tripleo_ipa_base_server_fqdn }}"
base_server_short_name: "{{ tripleo_ipa_base_server_fqdn.split('.')[0] }}"
base_server_domain: "{{ tripleo_ipa_base_server_fqdn.split('.', 1)[1] }}"
enroll_base_server: "{{ tripleo_ipa_enroll_base_server }}"
- name: add main host to IPA with OTP
when: enroll_base_server|bool
block:
- name: get host raw data and keytab info
command: "ipa host-show --raw --all {{ base_server_fqdn }}"
register: host_raw_data
changed_when: false
failed_when: false
- name: confirm that host is not already registered with current keytab
when: '"has_keytab: TRUE" not in host_raw_data.stdout'
block:
- name: add new host with random otp
ipa_host:
fqdn: "{{ base_server_fqdn }}"
random_password: true
force: true
register: ipa_host
ignore_errors: true
- name: set otp as a host fact
set_fact:
ipa_host_otp: "{{ ipa_host.host.randompassword | default(omit) }}"
no_log: true
delegate_facts: true
delegate_to: "{{ tripleo_ipa_delegate_server }}"
- name: add required services
include: services.yml
loop: "{{ tripleo_ipa_server_metadata | from_json | parse_service_metadata(base_server_fqdn) }}"

View File

@ -0,0 +1,55 @@
---
# Copyright 2020 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# The tasks in this file perform the registration process for a service.
#
# The following variable are required:
# - {item} : which is an ordered tuple of the form:
# -- { sub_host, service }
#
# An example of this is:
# { "controller-5.storagemgmt.example.com", "haproxy" }
#
# At this time, the final value in the tuple is unused.
- name: set variables
set_fact:
sub_host: "{{ item.0 }}"
service: "{{ item.1 }}"
- name: add sub_host
ipa_host:
fqdn: "{{ sub_host }}"
force: true
state: present
validate_certs: false
- name: add service
ipa_service:
name: "{{ service }}/{{ sub_host }}"
force: true
state: present
validate_certs: false
register: my_service
- name: add host to managed_hosts if needed
when: base_server_fqdn not in my_service['host']['managedby_host']
ipa_service:
name: "{{ service }}/{{ sub_host }}"
force: true
state: present
hosts: "{{ my_service['host']['managedby_host'] + [ base_server_fqdn ] }}"
validate_certs: false

View File

@ -0,0 +1,44 @@
---
# Copyright 2020 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
galaxy_info:
author: OpenStack
description: TripleO-IPA Role -- tripleo_ipa_setup
company: Red Hat
license: Apache-2.0
min_ansible_version: 2.7
#
# Provide a list of supported platforms, and for each platform a list of versions.
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
# To view available platforms and versions (or releases), visit:
# https://galaxy.ansible.com/api/v1/platforms/
#
platforms:
- name: Fedora
versions:
- 28
- name: CentOS
versions:
- 7
galaxy_tags:
- tripleo
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.
dependencies: []

View File

@ -0,0 +1,39 @@
---
# Copyright 2020 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# This playbook creates the nova user and adds it to the Nova Host Manager IPA
# role. This needs to be executed by a user that has permissions to add services
# and to add them to roles.
#
- name: set nova service user facts
set_fact:
nova_service: "nova/{{ undercloud_fqdn }}"
- name: add nova service
ipa_service:
name: "{{ nova_service }}"
state: present
force: true
- name: add Nova Host Manager role
ipa_role:
name: Nova Host Manager
description: Nova Host Manager
privilege:
- Nova Host Management
service:
- "{{ nova_service }}"

View File

@ -0,0 +1,44 @@
---
# Copyright 2020 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# This role is supposed to be run on the undercloud. In this role,
# we retrieve a keytab for the previously created nova user/service.
# The undercloud is assumed to be enrolled as an ipa client
#
- name: set keytab permissions facts
set_fact:
nova_service: "nova/{{ undercloud_fqdn }}"
nova_keytab: "/etc/novajoin/krb5.keytab"
nova_keytab_group: "tripleo-admin"
- name: add directory for keytab
file:
path: "/etc/novajoin"
state: directory
mode: '0755'
- name: get a keytab for the novajoin service
shell: |
ipa-getkeytab \
-p "{{ nova_service }}" \
-k "{{ nova_keytab }}"
- name: chgrp and chmod the keytab
file:
path: "{{ nova_keytab }}"
group: "{{ nova_keytab_group }}"
mode: "g+r"

View File

@ -0,0 +1,23 @@
---
# Copyright 2019 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
- name: create ipa_user_role
include: setup.yml
- name: create ipa_user for this undercloud
include: add_ipa_user.yml
- name: get keytab for this user
include: get_ipa_user_keytab.yml

View File

@ -0,0 +1,84 @@
---
# Copyright 2020 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# This playbook adds the privileges and IPA role needed to do the things that
# tripleo wants to do in FreeIPA to add hosts and services. The operations in
# this playbook likely need admin privileges and should be executed on an
# IPA client.
#
- name: set keytab permissions facts
set_fact:
novajoin_perms:
- {name: 'Modify host password', right: "write", type: "host", attrs: "userpassword"}
- {name: 'Write host certificate', right: "write", type: "host", attrs: "usercertificate"}
- {name: 'Modify host userclass', right: "write", type: "host", attrs: "userclass"}
- {name: 'Modify service managedBy attribute', right: "write", type: "service", attrs: "managedby"}
novajoin_privilege_perms:
- 'System: add hosts'
- 'System: remove hosts'
- 'Modify host password'
- 'Modify host userclass'
- 'System: Modify hosts'
- 'Modify service managedBy attribute'
- 'System: Add krbPrincipalName to a Host'
- 'System: Add Services'
- 'System: Remove Services'
- 'Revoke certificate'
- 'System: manage host keytab'
- 'System: Manage host certificates'
- 'System: modify services'
- 'System: manage service keytab'
- 'System: read dns entries'
- 'System: remove dns entries'
- 'System: add dns entries'
- 'System: update dns entries'
- 'Retrieve Certificates from the CA'
# unfortunately we don't have ansible module yet to create perms
- name: add nova host managedment permissions
shell: |
ipa permission-find "{{ item.name }}"
if [ $? -ne 0 ]; then
ipa permission-add "{{ item.name }}" --right "{{ item.right }}" \
--type "{{ item.type }}" --attrs "{{ item.attrs }}"
fi
loop: "{{ novajoin_perms|flatten(levels=1) }}"
# unfortunately we don't have ansible module yet to create privileges
- name: add Nova Host privilege
shell: |
ipa privilege-find 'Nova Host Management'
if [ $? -ne 0 ]; then
ipa privilege-add --desc='Nova Host Management' 'Nova Host Management'
fi
- name: add permissions to the Nova Host privilege
shell: |
ipa privilege-add-permission 'Nova Host Management' \
--permission "{{ item }}"
register: add_perm_command
failed_when:
- add_perm_command.rc !=0
- '"This entry is already a member" not in add_perm_command.stdout'
loop: "{{ novajoin_privilege_perms|flatten(levels=1) }}"
- name: add Nova Host Manager role
ipa_role:
name: Nova Host Manager
description: Nova Host Manager
privilege:
- Nova Host Management

View File

@ -1,2 +0,0 @@
---
# tasks file for tripleo_ipa

View File

@ -1,2 +0,0 @@
---
# vars file for tripleo_ipa

View File

@ -10,5 +10,7 @@
- zuul.d/playbooks/pre.yml
run:
- zuul.d/playbooks/run.yml
post-run:
- zuul.d/playbooks/post.yml
timeout: 1800
voting: true

34
zuul.d/playbooks/post.yml Normal file
View File

@ -0,0 +1,34 @@
---
# Copyright 2020 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
- name: TripleO IPA Post
hosts: all
tasks:
- name: Make ipaserver-install log readable
file:
path: "/tmp/ipa-data/var/log/ipaserver-install.log"
mode: 0644
become: true
failed_when: false
- name: Collect ipaserver-install logs
synchronize:
dest: "{{ zuul.executor.log_root }}"
mode: pull
src: "/tmp/ipa-data/var/log/ipaserver-install.log"
verify_host: true
failed_when: false