summaryrefslogtreecommitdiffstats
path: root/roles/openshift_facts
diff options
context:
space:
mode:
Diffstat (limited to 'roles/openshift_facts')
-rwxr-xr-xroles/openshift_facts/library/openshift_facts.py214
-rw-r--r--roles/openshift_facts/tasks/main.yml5
2 files changed, 205 insertions, 14 deletions
diff --git a/roles/openshift_facts/library/openshift_facts.py b/roles/openshift_facts/library/openshift_facts.py
index 3570de693..ae530eadd 100755
--- a/roles/openshift_facts/library/openshift_facts.py
+++ b/roles/openshift_facts/library/openshift_facts.py
@@ -20,8 +20,29 @@ EXAMPLES = '''
import ConfigParser
import copy
import os
+import StringIO
+import yaml
from distutils.util import strtobool
+from distutils.version import LooseVersion
+import struct
+import socket
+def first_ip(network):
+ """ Return the first IPv4 address in network
+
+ Args:
+ network (str): network in CIDR format
+ Returns:
+ str: first IPv4 address
+ """
+ def atoi(addr):
+ return struct.unpack("!I", socket.inet_aton(addr))[0]
+ def itoa(addr):
+ return socket.inet_ntoa(struct.pack("!I", addr))
+
+ (address, netmask) = network.split('/')
+ netmask_i = (0xffffffff << (32 - atoi(netmask))) & 0xffffffff
+ return itoa((atoi(address) & netmask_i) + 1)
def hostname_valid(hostname):
""" Test if specified hostname should be considered valid
@@ -305,6 +326,23 @@ def set_fluentd_facts_if_unset(facts):
facts['common']['use_fluentd'] = use_fluentd
return facts
+def set_flannel_facts_if_unset(facts):
+ """ Set flannel facts if not already present in facts dict
+ dict: the facts dict updated with the flannel facts if
+ missing
+ Args:
+ facts (dict): existing facts
+ Returns:
+ dict: the facts dict updated with the flannel
+ facts if they were not already present
+
+ """
+ if 'common' in facts:
+ if 'use_flannel' not in facts['common']:
+ use_flannel = False
+ facts['common']['use_flannel'] = use_flannel
+ return facts
+
def set_node_schedulability(facts):
""" Set schedulable facts if not already present in facts dict
Args:
@@ -362,6 +400,33 @@ def set_metrics_facts_if_unset(facts):
facts['common']['use_cluster_metrics'] = use_cluster_metrics
return facts
+def set_project_cfg_facts_if_unset(facts):
+ """ Set Project Configuration facts if not already present in facts dict
+ dict:
+ Args:
+ facts (dict): existing facts
+ Returns:
+ dict: the facts dict updated with the generated Project Configuration
+ facts if they were not already present
+
+ """
+
+ config = {
+ 'default_node_selector': '',
+ 'project_request_message': '',
+ 'project_request_template': '',
+ 'mcs_allocator_range': 's0:/2',
+ 'mcs_labels_per_project': 5,
+ 'uid_allocator_range': '1000000000-1999999999/10000'
+ }
+
+ if 'master' in facts:
+ for key, value in config.items():
+ if key not in facts['master']:
+ facts['master'][key] = value
+
+ return facts
+
def set_identity_providers_if_unset(facts):
""" Set identity_providers fact if not already present in facts dict
@@ -378,7 +443,7 @@ def set_identity_providers_if_unset(facts):
name='allow_all', challenge=True, login=True,
kind='AllowAllPasswordIdentityProvider'
)
- if deployment_type == 'enterprise':
+ if deployment_type in ['enterprise', 'atomic-enterprise', 'openshift-enterprise']:
identity_provider = dict(
name='deny_all', challenge=True, login=True,
kind='DenyAllPasswordIdentityProvider'
@@ -455,24 +520,84 @@ def set_aggregate_facts(facts):
dict: the facts dict updated with aggregated facts
"""
all_hostnames = set()
+ internal_hostnames = set()
if 'common' in facts:
all_hostnames.add(facts['common']['hostname'])
all_hostnames.add(facts['common']['public_hostname'])
+ all_hostnames.add(facts['common']['ip'])
+ all_hostnames.add(facts['common']['public_ip'])
+
+ internal_hostnames.add(facts['common']['hostname'])
+ internal_hostnames.add(facts['common']['ip'])
if 'master' in facts:
+ # FIXME: not sure why but facts['dns']['domain'] fails
+ cluster_domain = 'cluster.local'
if 'cluster_hostname' in facts['master']:
all_hostnames.add(facts['master']['cluster_hostname'])
if 'cluster_public_hostname' in facts['master']:
all_hostnames.add(facts['master']['cluster_public_hostname'])
+ svc_names = ['openshift', 'openshift.default', 'openshift.default.svc',
+ 'openshift.default.svc.' + cluster_domain, 'kubernetes', 'kubernetes.default',
+ 'kubernetes.default.svc', 'kubernetes.default.svc.' + cluster_domain]
+ all_hostnames.update(svc_names)
+ internal_hostnames.update(svc_names)
+ first_svc_ip = first_ip(facts['master']['portal_net'])
+ all_hostnames.add(first_svc_ip)
+ internal_hostnames.add(first_svc_ip)
facts['common']['all_hostnames'] = list(all_hostnames)
+ facts['common']['internal_hostnames'] = list(internal_hostnames)
return facts
+
+def set_etcd_facts_if_unset(facts):
+ """
+ If using embedded etcd, loads the data directory from master-config.yaml.
+
+ If using standalone etcd, loads ETCD_DATA_DIR from etcd.conf.
+
+ If anything goes wrong parsing these, the fact will not be set.
+ """
+ if 'etcd' in facts:
+ if 'master' in facts and facts['master']['embedded_etcd']:
+ try:
+ # Parse master config to find actual etcd data dir:
+ master_cfg_path = os.path.join(facts['common']['config_base'],
+ 'master/master-config.yaml')
+ master_cfg_f = open(master_cfg_path, 'r')
+ config = yaml.safe_load(master_cfg_f.read())
+ master_cfg_f.close()
+
+ facts['etcd']['etcd_data_dir'] = \
+ config['etcdConfig']['storageDirectory']
+ # We don't want exceptions bubbling up here:
+ # pylint: disable=broad-except
+ except Exception:
+ pass
+ else:
+ # Read ETCD_DATA_DIR from /etc/etcd/etcd.conf:
+ try:
+ # Add a fake section for parsing:
+ ini_str = '[root]\n' + open('/etc/etcd/etcd.conf', 'r').read()
+ ini_fp = StringIO.StringIO(ini_str)
+ config = ConfigParser.RawConfigParser()
+ config.readfp(ini_fp)
+ etcd_data_dir = config.get('root', 'ETCD_DATA_DIR')
+ if etcd_data_dir.startswith('"') and etcd_data_dir.endswith('"'):
+ etcd_data_dir = etcd_data_dir[1:-1]
+ facts['etcd']['etcd_data_dir'] = etcd_data_dir
+ # We don't want exceptions bubbling up here:
+ # pylint: disable=broad-except
+ except Exception:
+ pass
+ return facts
+
def set_deployment_facts_if_unset(facts):
""" Set Facts that vary based on deployment_type. This currently
includes common.service_type, common.config_base, master.registry_url,
- node.registry_url
+ node.registry_url, node.storage_plugin_deps
Args:
facts (dict): existing facts
@@ -480,8 +605,9 @@ def set_deployment_facts_if_unset(facts):
dict: the facts dict updated with the generated deployment_type
facts
"""
- # Perhaps re-factor this as a map?
- # pylint: disable=too-many-branches
+ # disabled to avoid breaking up facts related to deployment type into
+ # multiple methods for now.
+ # pylint: disable=too-many-statements, too-many-branches
if 'common' in facts:
deployment_type = facts['common']['deployment_type']
if 'service_type' not in facts['common']:
@@ -495,13 +621,18 @@ def set_deployment_facts_if_unset(facts):
config_base = '/etc/origin'
if deployment_type in ['enterprise', 'online']:
config_base = '/etc/openshift'
+ # Handle upgrade scenarios when symlinks don't yet exist:
+ if not os.path.exists(config_base) and os.path.exists('/etc/openshift'):
+ config_base = '/etc/openshift'
facts['common']['config_base'] = config_base
if 'data_dir' not in facts['common']:
data_dir = '/var/lib/origin'
if deployment_type in ['enterprise', 'online']:
data_dir = '/var/lib/openshift'
+ # Handle upgrade scenarios when symlinks don't yet exist:
+ if not os.path.exists(data_dir) and os.path.exists('/var/lib/openshift'):
+ data_dir = '/var/lib/openshift'
facts['common']['data_dir'] = data_dir
- facts['common']['version'] = get_openshift_version()
for role in ('master', 'node'):
if role in facts:
@@ -514,14 +645,55 @@ def set_deployment_facts_if_unset(facts):
registry_url = 'aep3/aep-${component}:${version}'
facts[role]['registry_url'] = registry_url
+ if 'master' in facts:
+ deployment_type = facts['common']['deployment_type']
+ openshift_features = ['Builder', 'S2IBuilder', 'WebConsole']
+ if 'disabled_features' in facts['master']:
+ if deployment_type == 'atomic-enterprise':
+ curr_disabled_features = set(facts['master']['disabled_features'])
+ facts['master']['disabled_features'] = list(curr_disabled_features.union(openshift_features))
+ else:
+ if deployment_type == 'atomic-enterprise':
+ facts['master']['disabled_features'] = openshift_features
+
+ if 'node' in facts:
+ deployment_type = facts['common']['deployment_type']
+ if 'storage_plugin_deps' not in facts['node']:
+ if deployment_type in ['openshift-enterprise', 'atomic-enterprise']:
+ facts['node']['storage_plugin_deps'] = ['ceph', 'glusterfs']
+ else:
+ facts['node']['storage_plugin_deps'] = []
+
return facts
+def set_version_facts_if_unset(facts):
+ """ Set version facts. This currently includes common.version and
+ common.version_greater_than_3_1_or_1_1.
-def set_sdn_facts_if_unset(facts):
+ Args:
+ facts (dict): existing facts
+ Returns:
+ dict: the facts dict updated with version facts.
+ """
+ if 'common' in facts:
+ deployment_type = facts['common']['deployment_type']
+ facts['common']['version'] = version = get_openshift_version()
+ if version is not None:
+ if deployment_type == 'origin':
+ version_gt_3_1_or_1_1 = LooseVersion(version) > LooseVersion('1.0.6')
+ else:
+ version_gt_3_1_or_1_1 = LooseVersion(version) > LooseVersion('3.0.2.900')
+ else:
+ version_gt_3_1_or_1_1 = True
+ facts['common']['version_greater_than_3_1_or_1_1'] = version_gt_3_1_or_1_1
+ return facts
+
+def set_sdn_facts_if_unset(facts, system_facts):
""" Set sdn facts if not already present in facts dict
Args:
facts (dict): existing facts
+ system_facts (dict): ansible_facts
Returns:
dict: the facts dict updated with the generated sdn facts if they
were not already present
@@ -540,9 +712,18 @@ def set_sdn_facts_if_unset(facts):
if 'sdn_host_subnet_length' not in facts['master']:
facts['master']['sdn_host_subnet_length'] = '8'
- if 'node' in facts:
- if 'sdn_mtu' not in facts['node']:
- facts['node']['sdn_mtu'] = '1450'
+ if 'node' in facts and 'sdn_mtu' not in facts['node']:
+ node_ip = facts['common']['ip']
+
+ # default MTU if interface MTU cannot be detected
+ facts['node']['sdn_mtu'] = '1450'
+
+ for val in system_facts.itervalues():
+ if isinstance(val, dict) and 'mtu' in val:
+ mtu = val['mtu']
+
+ if 'ipv4' in val and val['ipv4'].get('address') == node_ip:
+ facts['node']['sdn_mtu'] = str(mtu - 50)
return facts
@@ -632,7 +813,7 @@ def get_openshift_version():
Returns:
version: the current openshift version
"""
- version = ''
+ version = None
if os.path.isfile('/usr/bin/openshift'):
_, output, _ = module.run_command(['/usr/bin/openshift', 'version'])
@@ -775,7 +956,7 @@ class OpenShiftFacts(object):
Raises:
OpenShiftFactsUnsupportedRoleError:
"""
- known_roles = ['common', 'master', 'node', 'master_sdn', 'node_sdn', 'dns']
+ known_roles = ['common', 'master', 'node', 'master_sdn', 'node_sdn', 'dns', 'etcd']
def __init__(self, role, filename, local_facts):
self.changed = False
@@ -807,14 +988,18 @@ class OpenShiftFacts(object):
facts = merge_facts(facts, local_facts)
facts['current_config'] = get_current_config(facts)
facts = set_url_facts_if_unset(facts)
+ facts = set_project_cfg_facts_if_unset(facts)
facts = set_fluentd_facts_if_unset(facts)
+ facts = set_flannel_facts_if_unset(facts)
facts = set_node_schedulability(facts)
facts = set_master_selectors(facts)
facts = set_metrics_facts_if_unset(facts)
facts = set_identity_providers_if_unset(facts)
- facts = set_sdn_facts_if_unset(facts)
+ facts = set_sdn_facts_if_unset(facts, self.system_facts)
facts = set_deployment_facts_if_unset(facts)
+ facts = set_version_facts_if_unset(facts)
facts = set_aggregate_facts(facts)
+ facts = set_etcd_facts_if_unset(facts)
return dict(openshift=facts)
def get_defaults(self, roles):
@@ -853,11 +1038,12 @@ class OpenShiftFacts(object):
session_name='ssn', session_secrets_file='',
access_token_max_seconds=86400,
auth_token_max_seconds=500,
- oauth_grant_method='auto', cluster_defer_ha=False)
+ oauth_grant_method='auto')
defaults['master'] = master
if 'node' in roles:
- node = dict(labels={}, annotations={}, portal_net='172.30.0.0/16')
+ node = dict(labels={}, annotations={}, portal_net='172.30.0.0/16',
+ iptables_sync_period='5s')
defaults['node'] = node
return defaults
diff --git a/roles/openshift_facts/tasks/main.yml b/roles/openshift_facts/tasks/main.yml
index 6301d4fc0..913f0dc78 100644
--- a/roles/openshift_facts/tasks/main.yml
+++ b/roles/openshift_facts/tasks/main.yml
@@ -6,5 +6,10 @@
- ansible_version | version_compare('1.9.0', 'ne')
- ansible_version | version_compare('1.9.0.1', 'ne')
+- name: Ensure PyYaml is installed
+ yum: pkg={{ item }} state=installed
+ with_items:
+ - PyYAML
+
- name: Gather Cluster facts
openshift_facts: