Add openstack integration to skydive
This change will enable neutron network awareness and set the auth-backend to to use keystone when `skydive_openstack_enabled` is set to true. Options have been added to allow users to customize the deployment, all of which have been documented in the default/main.yml file. Change-Id: Iab958c0631c7c396d218d8fb6302db03e5d9a5a6 Signed-off-by: Kevin Carter <kevin.carter@rackspace.com> Signed-off-by: Kevin Carter <kevin@cloudnull.com>
This commit is contained in:

committed by
Kevin Carter

parent
b6bf88b7d9
commit
1fa93b1d8c
@@ -134,7 +134,7 @@ openstack-ansible -i /opt/openstack-ansible/inventory/dynamic_inventory.py \
|
||||
More on using overlay inventories can be seen in the `overlay-inventory`
|
||||
directory.
|
||||
|
||||
##### Configuration | Haproxy
|
||||
##### Configuration | Haproxy (frontend)
|
||||
|
||||
The example overlay inventory contains a section for general haproxy
|
||||
configuration which exposes the skydive UI internally.
|
||||
@@ -170,12 +170,27 @@ This config will provide access to the web UI for both **skydive** and
|
||||
* **Skydive** runs on port `8082`
|
||||
* **Traefik** runs on port `8090`
|
||||
|
||||
##### OpenStack Integration
|
||||
|
||||
Skydive can be configured to work with OpenStack. For this to work a
|
||||
`clouds.yaml` must be present on one of the nodes used within the deployment;
|
||||
the path is typically to the clouds config is typically
|
||||
`$HOME/.config/openstack/clouds.yaml`. The playbooks will use the
|
||||
`clouds.yaml` file to read nessisary credentials used to create a new users
|
||||
and roles to be used with `skydive` and to enable neutron probes within the
|
||||
`skydive` agent.
|
||||
|
||||
When OpenStack integration is enabled, all authentication will be done through
|
||||
keystone. User access to the skydive UI will be restricted to only users that
|
||||
have the skydive role assigned to them.
|
||||
|
||||
All available options for the OpenStack integration can be found in the
|
||||
`defaults/main.yml` file.
|
||||
|
||||
### Validating the skydive installation
|
||||
|
||||
Post-deployment, the skydive installation can be validated by simply running
|
||||
the `validateSkydive.yml` playbook.
|
||||
|
||||
TODOs:
|
||||
[] Setup cert based agent/server auth
|
||||
[] Add OpenStack integration
|
||||
[] Document OpenStack integration, what it adds to the admin service
|
||||
- [] Setup cert based agent/server auth
|
||||
|
@@ -37,6 +37,7 @@
|
||||
patterns: "*skydive*"
|
||||
register: files_to_copy
|
||||
delegate_to: "{{ skydive_staging_node }}"
|
||||
run_once: true
|
||||
become: false
|
||||
- name: Install built skydive
|
||||
copy:
|
||||
@@ -55,6 +56,7 @@
|
||||
dest: "/tmp/skydive/{{ ansible_architecture }}/{{ skydive_binary_url | basename }}"
|
||||
mode: '0755'
|
||||
delegate_to: "{{ skydive_staging_node }}"
|
||||
run_once: true
|
||||
become: false
|
||||
- name: Install binary skydive
|
||||
copy:
|
||||
@@ -91,6 +93,7 @@
|
||||
patterns: "*traefik*"
|
||||
register: files_to_copy
|
||||
delegate_to: "{{ traefik_staging_node }}"
|
||||
run_once: true
|
||||
become: false
|
||||
- name: Install built traefik
|
||||
copy:
|
||||
@@ -109,6 +112,7 @@
|
||||
dest: "/tmp/traefik/{{ ansible_architecture }}/{{ traefik_binary_url | basename }}"
|
||||
mode: '0755'
|
||||
delegate_to: "{{ traefik_staging_node }}"
|
||||
run_once: true
|
||||
become: false
|
||||
- name: Install binary traefik
|
||||
copy:
|
||||
|
@@ -108,32 +108,23 @@ skydive_basic_auth_file: /var/lib/skydive/skydive.secret
|
||||
skydive_basic_auth_users: {}
|
||||
|
||||
# Skydive openstack setup
|
||||
skydive_os_service_username: "{{ skydive_username }}.service"
|
||||
skydive_os_service_password: "{{ skydive_password }}"
|
||||
skydive_os_service_tenant_name: service
|
||||
skydive_os_service_domain_name: Default
|
||||
skydive_os_service_region_name: RegionOne
|
||||
skydive_os_service_endpoint_type: internal
|
||||
skydive_os_service_insecure: true
|
||||
|
||||
skydive_os_auth_url: null
|
||||
skydive_auth_os_tenant_name: "{{ skydive_username }}"
|
||||
skydive_auth_os_domain_name: Default
|
||||
skydive_auth_os_domain_id: default
|
||||
skydive_auth_os_user_role: admin
|
||||
## These options are normally undefined, if undefined the value will be pulled from the local clouds.yml.
|
||||
skydive_openstack_enabled: false
|
||||
# skydive_os_auth_url: http://localhost:5000/v3
|
||||
# skydive_os_region_name: RegionOne
|
||||
# skydive_os_endpoint_type: public
|
||||
|
||||
|
||||
os_auth_url:
|
||||
os_username:
|
||||
os_password:
|
||||
os_tenant_name: admin
|
||||
os_user_domain_name: Default
|
||||
os_project_domain_name: Default
|
||||
os_identity_api_version: 3
|
||||
|
||||
# Role of the user created that will be used for the probe
|
||||
# authentication
|
||||
skydive_os_cloud: default
|
||||
skydive_os_cloud_file: "{{ ansible_env.HOME }}/.config/openstack/clouds.yaml"
|
||||
skydive_os_domain_name: Default
|
||||
skydive_os_project_name: "{{ skydive_username }}"
|
||||
skydive_os_user_name: "{{ skydive_username }}"
|
||||
skydive_os_user_role: admin
|
||||
skydive_os_service_user: "{{ skydive_username }}.service"
|
||||
skydive_os_service_user_role: admin
|
||||
skydive_os_service_password: "{{ skydive_password }}"
|
||||
skydive_os_service_insecure: true
|
||||
|
||||
|
||||
# Configuration overrides can be set using a config template.
|
||||
|
@@ -68,4 +68,31 @@
|
||||
tags:
|
||||
- package_install
|
||||
|
||||
- name: Check for openstack deployment
|
||||
block:
|
||||
- name: Slurp clouds file
|
||||
slurp:
|
||||
src: "{{ skydive_os_cloud_file }}"
|
||||
register: clouds_file
|
||||
|
||||
- name: Enable OpenStack integration
|
||||
set_fact:
|
||||
clouds_yaml: "{{ clouds_file['content'] | b64decode | from_yaml }}"
|
||||
skydive_auth_type: mykeystone
|
||||
skydive_openstack_enabled: true
|
||||
run_once: true
|
||||
delegate_to: "{{ item }}"
|
||||
delegate_facts: true
|
||||
with_items: "{{ ansible_play_hosts }}"
|
||||
|
||||
- include_tasks: skydive_keystone.yml
|
||||
run_once: true
|
||||
rescue:
|
||||
- name: Notice
|
||||
debug:
|
||||
msg: >-
|
||||
OpenStack setup is not possible, running in without it.
|
||||
when:
|
||||
- not (skydive_openstack_enabled | bool)
|
||||
|
||||
- include_tasks: skydive_setup.yml
|
||||
|
131
skydive/roles/skydive_common/tasks/skydive_keystone.yml
Normal file
131
skydive/roles/skydive_common/tasks/skydive_keystone.yml
Normal file
@@ -0,0 +1,131 @@
|
||||
---
|
||||
# Copyright 2019, Rackspace US, 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: Check credentials and clouds data
|
||||
fail:
|
||||
msg: >-
|
||||
The following variable "{{ item.default }}" is undefined and no known value was defined
|
||||
in the "{{ skydive_os_cloud_file }}" file.
|
||||
when:
|
||||
- hostvars[inventory_hostname][item.default] is undefined
|
||||
- clouds_yaml['clouds'] is undefined
|
||||
- clouds_yaml['clouds'][skydive_os_cloud] is undefined
|
||||
- clouds_yaml['clouds'][skydive_os_cloud]['auth'] is undefined
|
||||
- clouds_yaml['clouds'][skydive_os_cloud]['auth'][item.cfg] is undefined
|
||||
with_items:
|
||||
- default: "skydive_os_auth_url"
|
||||
cfg: "auth_url"
|
||||
|
||||
- name: Create skydive venv
|
||||
command: "/usr/bin/virtualenv --no-site-packages --no-setuptools /opt/skydive"
|
||||
args:
|
||||
creates: /opt/skydive/bin/pip
|
||||
|
||||
- name: Setup skydive venv
|
||||
pip:
|
||||
name:
|
||||
- pip
|
||||
- setuptools
|
||||
extra_args: "-U"
|
||||
virtualenv: /opt/skydive
|
||||
|
||||
- name: Ensure the openstacksdk is installed
|
||||
pip:
|
||||
name:
|
||||
- openstacksdk
|
||||
extra_args: "-U"
|
||||
virtualenv: /opt/skydive
|
||||
|
||||
- name: Capture current ansible python interpreter
|
||||
set_fact:
|
||||
old_ansible_python_interpreter: "{{ ansible_python_interpreter | default('/usr/bin/python') }}"
|
||||
|
||||
- name: Set ansible python interpreter to skydive venv
|
||||
set_fact:
|
||||
ansible_python_interpreter: "/opt/skydive/bin/python"
|
||||
|
||||
- name: Add skydive project
|
||||
os_project:
|
||||
cloud: "{{ skydive_os_cloud }}"
|
||||
state: present
|
||||
name: "{{ skydive_os_project_name }}"
|
||||
description: "Skydive admin project"
|
||||
domain_id: "{{ skydive_os_domain_name }}"
|
||||
verify: "{{ not (skydive_os_service_insecure | bool) }}"
|
||||
enabled: true
|
||||
register: keystone_api
|
||||
until: keystone_api is success
|
||||
retries: 5
|
||||
delay: 10
|
||||
|
||||
- name: Add skydive user
|
||||
os_user:
|
||||
cloud: "{{ skydive_os_cloud }}"
|
||||
state: present
|
||||
name: "{{ skydive_os_user_name }}"
|
||||
password: "{{ skydive_password }}"
|
||||
update_password: on_create
|
||||
domain: "{{ skydive_os_domain_name }}"
|
||||
default_project: "{{ skydive_os_project_name }}"
|
||||
verify: "{{ not (skydive_os_service_insecure | bool) }}"
|
||||
enabled: true
|
||||
register: keystone_api
|
||||
until: keystone_api is success
|
||||
retries: 5
|
||||
delay: 10
|
||||
|
||||
- name: Assign skydive user role
|
||||
os_user_role:
|
||||
cloud: "{{ skydive_os_cloud }}"
|
||||
state: present
|
||||
user: "{{ skydive_os_user_name }}"
|
||||
role: "{{ skydive_os_user_role }}"
|
||||
project: "{{ skydive_os_project_name }}"
|
||||
verify: "{{ not (skydive_os_service_insecure | bool) }}"
|
||||
register: keystone_api
|
||||
until: keystone_api is success
|
||||
retries: 5
|
||||
delay: 10
|
||||
|
||||
- name: Add skydive service user
|
||||
os_user:
|
||||
cloud: "{{ skydive_os_cloud }}"
|
||||
state: present
|
||||
name: "{{ skydive_os_service_user }}"
|
||||
password: "{{ skydive_os_service_password }}"
|
||||
domain: "{{ skydive_os_domain_name }}"
|
||||
default_project: "{{ skydive_os_project_name }}"
|
||||
verify: "{{ not (skydive_os_service_insecure | bool) }}"
|
||||
register: keystone_api
|
||||
until: keystone_api is success
|
||||
retries: 5
|
||||
delay: 10
|
||||
|
||||
- name: Assign skydive service user role
|
||||
os_user_role:
|
||||
cloud: "{{ skydive_os_cloud }}"
|
||||
state: present
|
||||
user: "{{ skydive_os_service_user }}"
|
||||
role: "{{ skydive_os_service_user_role }}"
|
||||
project: "{{ skydive_os_project_name }}"
|
||||
verify: "{{ not (skydive_os_service_insecure | bool) }}"
|
||||
register: keystone_api
|
||||
until: keystone_api is success
|
||||
retries: 5
|
||||
delay: 10
|
||||
|
||||
- name: Reset ansible python
|
||||
set_fact:
|
||||
ansible_python_interpreter: "{{ old_ansible_python_interpreter }}"
|
@@ -43,7 +43,7 @@ http:
|
||||
# queue_size: 10000
|
||||
|
||||
# enable write compression
|
||||
# enable_write_compression: true
|
||||
enable_write_compression: true
|
||||
|
||||
{% if inventory_hostname in groups['skydive_analyzers'] %}
|
||||
analyzer:
|
||||
@@ -191,47 +191,50 @@ agent:
|
||||
# Probes used to capture topology information like interfaces,
|
||||
# bridges, namespaces, etc...
|
||||
# Available: ovsdb, docker, neutron, opencontrail, socketinfo, lxd, lldp
|
||||
{% if skydive_docker_exists | bool %}
|
||||
{% set _ = skydive_probes.append('docker') %}
|
||||
{% endif %}
|
||||
{% if skydive_ovs_db_exists | bool %}
|
||||
{% set _ = skydive_probes.append('ovsdb') %}
|
||||
{% endif %}
|
||||
{% if skydive_docker_exists | bool %}
|
||||
{% set _ = skydive_probes.append('docker') %}
|
||||
{% endif %}
|
||||
{% if skydive_ovs_db_exists | bool %}
|
||||
{% set _ = skydive_probes.append('ovsdb') %}
|
||||
{% endif %}
|
||||
{% if skydive_openstack_enabled | bool %}
|
||||
{% set _ = skydive_probes.append('neutron') %}
|
||||
{% endif %}
|
||||
probes: {{ skydive_probes | to_json }}
|
||||
|
||||
netlink:
|
||||
# delay in seconds between two metric updates
|
||||
# metrics_update: 30
|
||||
metrics_update: 30
|
||||
|
||||
{% if skydive_openstack_enabled | bool %}
|
||||
# Define OpenStack Neutron credentials and the enpoint type
|
||||
# used by the neutron probe
|
||||
neutron:
|
||||
# auth_url:
|
||||
# username: neutron
|
||||
# password: secret
|
||||
# tenant_name: service
|
||||
# region_name: RegionOne
|
||||
# domain_name: Default
|
||||
# ssl_insecure: false
|
||||
|
||||
# The endpoint_type value must be 'public', 'internal' or 'admin'
|
||||
# endpoint_type: public
|
||||
auth_url: {{ skydive_os_auth_url | default(clouds_yaml['clouds'][skydive_os_cloud]['auth']['auth_url']) }}
|
||||
username: {{ skydive_os_service_user }}
|
||||
password: {{ skydive_os_service_password }}
|
||||
tenant_name: {{ skydive_os_project_name }}
|
||||
region_name: {{ skydive_os_region_name | default(clouds_yaml['clouds'][skydive_os_cloud]['region_name']) }}
|
||||
domain_name: {{ skydive_os_domain_name }}
|
||||
ssl_insecure: {{ not (skydive_os_service_insecure | bool) }}
|
||||
endpoint_type: {{ skydive_os_endpoint_type | default(clouds_yaml['clouds'][skydive_os_cloud]['interface']) }}
|
||||
{% endif %}
|
||||
|
||||
lldp:
|
||||
# Interfaces to listen for LLDP frames. If no list is specified,
|
||||
# use all interfaces
|
||||
interfaces:
|
||||
|
||||
{% if skydive_libvirt_exists | bool %}
|
||||
{% if skydive_libvirt_exists | bool %}
|
||||
libvirt:
|
||||
url: qemu:///system
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if skydive_runc_exists | bool %}
|
||||
{% if skydive_runc_exists | bool %}
|
||||
runc:
|
||||
run_path:
|
||||
- /var/run/runc
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
capture:
|
||||
# Period in second to get capture stats from the probe. Note this
|
||||
@@ -239,7 +242,6 @@ agent:
|
||||
|
||||
metadata:
|
||||
# info: This is compute node
|
||||
{% endif %}
|
||||
|
||||
dpdk:
|
||||
# DPDK port listening flows from
|
||||
@@ -253,6 +255,7 @@ dpdk:
|
||||
# debug message every n seconds
|
||||
# debug: 1
|
||||
|
||||
{% if skydive_ovs_db_exists | bool %}
|
||||
sflow:
|
||||
# Default listening address is 127.0.0.1
|
||||
# bind_address: 127.0.0.1
|
||||
@@ -262,7 +265,6 @@ sflow:
|
||||
# port_min: 6345
|
||||
# port_max: 6355
|
||||
|
||||
{% if skydive_ovs_db_exists | bool %}
|
||||
ovs:
|
||||
# ovsdb connection, Format supported :
|
||||
# * addr:port
|
||||
@@ -299,12 +301,12 @@ ovs:
|
||||
address:
|
||||
# Map translating bridge names into URL for remote connection
|
||||
# - bridge: ssl:xxx.yyy.zzz.ttt:port
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if skydive_docker_exists | bool %}
|
||||
{% if skydive_docker_exists | bool %}
|
||||
docker:
|
||||
url: unix://{{ skydive_docker_socket }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
netns:
|
||||
# allow to specify where the netns probe is watching network namespace
|
||||
@@ -319,7 +321,9 @@ opencontrail:
|
||||
|
||||
# UDP dest port for MPLS traffic
|
||||
# mpls_udp_port: 51234
|
||||
{% endif %}
|
||||
|
||||
{% if inventory_hostname in groups['skydive_analyzers'] %}
|
||||
storage:
|
||||
# Elasticsearch backend information.
|
||||
myelasticsearch:
|
||||
@@ -351,6 +355,7 @@ storage:
|
||||
# Memory backend
|
||||
mymemory:
|
||||
# driver: memory
|
||||
{% endif %}
|
||||
|
||||
logging:
|
||||
# level: INFO
|
||||
@@ -383,19 +388,22 @@ auth:
|
||||
# user1: secret1
|
||||
# user2: secret2
|
||||
|
||||
{% if skydive_openstack_enabled | bool %}
|
||||
mykeystone:
|
||||
# Define a basic auth authentication backend
|
||||
type: keystone
|
||||
auth_url: {{ skydive_os_auth_url }}
|
||||
auth_url: {{ skydive_os_auth_url | default(clouds_yaml['clouds'][skydive_os_cloud]['auth']['auth_url']) }}
|
||||
|
||||
# define the tenant and the domain that the users have to belong to
|
||||
tenant_name: {{ skydive_auth_os_tenant_name }}
|
||||
domain_name: {{ skydive_auth_os_domain_name }}
|
||||
tenant_name: {{ skydive_os_project_name }}
|
||||
domain_name: {{ skydive_os_domain_name }}
|
||||
|
||||
# define which role an authenticated user will have. Only used for API authentication.
|
||||
# two roles are predefined, admin and guest.
|
||||
role: {{ skydive_auth_os_user_role }}
|
||||
role: {{ skydive_os_user_role }}
|
||||
{% endif %}
|
||||
|
||||
{% if inventory_hostname in groups['skydive_analyzers'] %}
|
||||
etcd:
|
||||
# server parameters
|
||||
# when 'embedded' is set to true, the analyzer will start an embedded etcd server
|
||||
@@ -410,25 +418,27 @@ etcd:
|
||||
# data_dir: /var/lib/skydive/etcd
|
||||
|
||||
# client parameters
|
||||
{% if skydive_etcd_servers %}
|
||||
{% if skydive_etcd_servers %}
|
||||
servers: {{ skydive_etcd_servers | to_json }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
# name to use for clustering, by default it is set to the host id
|
||||
name: {{ inventory_hostname }}
|
||||
|
||||
# list of peers for etcd clustering between analyzers
|
||||
# each entry is composed of the peer name and the endpoints for this peer
|
||||
{% set peers = {} %}
|
||||
{% for node in groups['skydive_analyzers'] %}
|
||||
{% if node in ansible_play_hosts %}
|
||||
{% set _ansible_interface_name = hostvars[node]['skydive_network_device'] | default(hostvars[node]['ansible_default_ipv4']['interface']) | replace('-', '_') %}
|
||||
{% set _ = peers.__setitem__(inventory_hostname, 'http://' ~ (hostvars[node]['skydive_bind_address'] | default(hostvars[node]["ansible_" ~ _ansible_interface_name]['ipv4']['address'])) ~ ':' ~ skydive_etcd_port) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% set peers = {} %}
|
||||
{% for node in groups['skydive_analyzers'] %}
|
||||
{% if node in ansible_play_hosts %}
|
||||
{% set _ansible_interface_name = hostvars[node]['skydive_network_device'] | default(hostvars[node]['ansible_default_ipv4']['interface']) | replace('-', '_') %}
|
||||
{% set _ = peers.__setitem__(inventory_hostname, 'http://' ~ (hostvars[node]['skydive_bind_address'] | default(hostvars[node]["ansible_" ~ _ansible_interface_name]['ipv4']['address'])) ~ ':' ~ skydive_etcd_port) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
peers: {{ skydive_etcd_peers | default(peers) | to_json }}
|
||||
|
||||
# client_timeout: 5
|
||||
{% endif %}
|
||||
|
||||
{% if inventory_hostname in groups['skydive_agents'] %}
|
||||
flow:
|
||||
# Without any new packets, a flow expires after flow.expire
|
||||
# seconds
|
||||
@@ -455,6 +465,7 @@ flow:
|
||||
# 1194: OPENVPN
|
||||
udp:
|
||||
# 1194: OPENVPN
|
||||
{% endif %}
|
||||
|
||||
ui:
|
||||
# Specify the extra assets folder. Javascript and CSS files present in this
|
||||
|
Reference in New Issue
Block a user