summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrenton Leanhardt <bleanhar@redhat.com>2016-04-20 10:07:27 -0400
committerBrenton Leanhardt <bleanhar@redhat.com>2016-04-20 10:07:27 -0400
commit3fccdb3e55a89597270e4ee2d9cdaf9dd66cb341 (patch)
tree36eaafd964e7a96f7f0d4272d3cc77d29272a52c
parent1f490c2374038669df3d2bfcb01af54361f8907e (diff)
parentbc11db0c73554be36b4196993d39a35cecbbd25b (diff)
downloadopenshift-3fccdb3e55a89597270e4ee2d9cdaf9dd66cb341.tar.gz
openshift-3fccdb3e55a89597270e4ee2d9cdaf9dd66cb341.tar.bz2
openshift-3fccdb3e55a89597270e4ee2d9cdaf9dd66cb341.tar.xz
openshift-3fccdb3e55a89597270e4ee2d9cdaf9dd66cb341.zip
Merge pull request #1588 from sdodson/cluster-dns
Cluster dns provided by dnsmasq
-rw-r--r--filter_plugins/openshift_node.py43
-rw-r--r--inventory/byo/hosts.aep.example6
-rw-r--r--inventory/byo/hosts.origin.example6
-rw-r--r--inventory/byo/hosts.ose.example6
-rw-r--r--playbooks/adhoc/uninstall.yml5
-rw-r--r--playbooks/common/openshift-master/config.yml1
-rw-r--r--roles/flannel_register/README.md2
-rw-r--r--roles/flannel_register/defaults/main.yaml2
-rw-r--r--roles/openshift_common/README.md1
-rw-r--r--roles/openshift_common/tasks/main.yml2
-rwxr-xr-xroles/openshift_facts/library/openshift_facts.py68
-rw-r--r--roles/openshift_master/defaults/main.yml8
-rw-r--r--roles/openshift_master/templates/master.yaml.v1.j24
-rw-r--r--roles/openshift_master_facts/tasks/main.yml2
-rw-r--r--roles/openshift_node/meta/main.yml3
-rw-r--r--roles/openshift_node/tasks/main.yml8
-rw-r--r--roles/openshift_node/templates/node.yaml.v1.j24
-rwxr-xr-xroles/openshift_node_dnsmasq/files/networkmanager/99-origin-dns.sh55
-rw-r--r--roles/openshift_node_dnsmasq/handlers/main.yml5
-rw-r--r--roles/openshift_node_dnsmasq/meta/main.yml15
-rw-r--r--roles/openshift_node_dnsmasq/tasks/main.yml27
-rw-r--r--roles/openshift_node_dnsmasq/tasks/network-manager.yml9
-rw-r--r--roles/openshift_node_dnsmasq/tasks/no-network-manager.yml2
-rw-r--r--roles/openshift_node_dnsmasq/templates/origin-dns.conf.j24
24 files changed, 264 insertions, 24 deletions
diff --git a/filter_plugins/openshift_node.py b/filter_plugins/openshift_node.py
new file mode 100644
index 000000000..4ef92ba03
--- /dev/null
+++ b/filter_plugins/openshift_node.py
@@ -0,0 +1,43 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# vim: expandtab:tabstop=4:shiftwidth=4
+'''
+Custom filters for use in openshift-node
+'''
+from ansible import errors
+
+class FilterModule(object):
+ ''' Custom ansible filters for use by openshift_node role'''
+
+ @staticmethod
+ def get_dns_ip(openshift_dns_ip, hostvars):
+ ''' Navigates the complicated logic of when to set dnsIP
+
+ In all situations if they've set openshift_dns_ip use that
+ For 1.0/3.0 installs we use the openshift_master_cluster_vip, openshift_node_first_master_ip, else None
+ For 1.1/3.1 installs we use openshift_master_cluster_vip, else None (product will use kube svc ip)
+ For 1.2/3.2+ installs we set to the node's default interface ip
+ '''
+
+ if not issubclass(type(hostvars), dict):
+ raise errors.AnsibleFilterError("|failed expects hostvars is a dict")
+
+ # We always use what they've specified if they've specified a value
+ if openshift_dns_ip != None:
+ return openshift_dns_ip
+
+ if bool(hostvars['openshift']['common']['version_gte_3_2_or_1_2']):
+ return hostvars['ansible_default_ipv4']['address']
+ elif bool(hostvars['openshift']['common']['version_gte_3_1_or_1_1']):
+ if 'openshift_master_cluster_vip' in hostvars:
+ return hostvars['openshift_master_cluster_vip']
+ else:
+ if 'openshift_master_cluster_vip' in hostvars:
+ return hostvars['openshift_master_cluster_vip']
+ elif 'openshift_node_first_master_ip' in hostvars:
+ return hostvars['openshift_node_first_master_ip']
+ return None
+
+ def filters(self):
+ ''' returns a mapping of filters to methods '''
+ return {'get_dns_ip': self.get_dns_ip}
diff --git a/inventory/byo/hosts.aep.example b/inventory/byo/hosts.aep.example
index 62891e6c3..c3f551401 100644
--- a/inventory/byo/hosts.aep.example
+++ b/inventory/byo/hosts.aep.example
@@ -336,6 +336,12 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true',
# Setting this variable to true will override that check.
#openshift_override_hostname_check=true
+# Configure dnsmasq for cluster dns, switch the host's local resolver to use dnsmasq
+# and configure node's dnsIP to point at the node's local dnsmasq instance. Defaults
+# to True for Origin 1.2 and OSE 3.2. False for 1.1 / 3.1 installs, this cannot
+# be used with 1.0 and 3.0.
+# openshift_node_dnsmasq=False
+
# host group for masters
[masters]
aep3-master[1:3]-ansible.test.example.com
diff --git a/inventory/byo/hosts.origin.example b/inventory/byo/hosts.origin.example
index 1f13aade6..caed1c6a1 100644
--- a/inventory/byo/hosts.origin.example
+++ b/inventory/byo/hosts.origin.example
@@ -341,6 +341,12 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true',
# Setting this variable to true will override that check.
#openshift_override_hostname_check=true
+# Configure dnsmasq for cluster dns, switch the host's local resolver to use dnsmasq
+# and configure node's dnsIP to point at the node's local dnsmasq instance. Defaults
+# to True for Origin 1.2 and OSE 3.2. False for 1.1 / 3.1 installs, this cannot
+# be used with 1.0 and 3.0.
+# openshift_node_dnsmasq=False
+
# host group for masters
[masters]
ose3-master[1:3]-ansible.test.example.com
diff --git a/inventory/byo/hosts.ose.example b/inventory/byo/hosts.ose.example
index 2386eb236..557e7d8aa 100644
--- a/inventory/byo/hosts.ose.example
+++ b/inventory/byo/hosts.ose.example
@@ -337,6 +337,12 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true',
# Setting this variable to true will override that check.
#openshift_override_hostname_check=true
+# Configure dnsmasq for cluster dns, switch the host's local resolver to use dnsmasq
+# and configure node's dnsIP to point at the node's local dnsmasq instance. Defaults
+# to True for Origin 1.2 and OSE 3.2. False for 1.1 / 3.1 installs, this cannot
+# be used with 1.0 and 3.0.
+# openshift_node_dnsmasq=False
+
# host group for masters
[masters]
ose3-master[1:3]-ansible.test.example.com
diff --git a/playbooks/adhoc/uninstall.yml b/playbooks/adhoc/uninstall.yml
index 8fb515982..b9c2a2714 100644
--- a/playbooks/adhoc/uninstall.yml
+++ b/playbooks/adhoc/uninstall.yml
@@ -232,6 +232,9 @@
- /usr/local/bin/oadm
- /usr/local/bin/oc
- /usr/local/bin/kubectl
+ - /etc/NetworkManager/dispatcher.d/99-origin-dns.sh
+ - /etc/dnsmasq.d/origin-dns.conf
+ - /etc/dnsmasq.d/origin-upstream-dns.conf
# Since we are potentially removing the systemd unit files for separated
# master-api and master-controllers services, so we need to reload the
@@ -244,3 +247,5 @@
tasks:
- name: restart docker
service: name=docker state=restarted
+ - name: restart NetworkManager
+ service: name=NetworkManager state=restarted
diff --git a/playbooks/common/openshift-master/config.yml b/playbooks/common/openshift-master/config.yml
index f1eaf8e16..620c4ea7c 100644
--- a/playbooks/common/openshift-master/config.yml
+++ b/playbooks/common/openshift-master/config.yml
@@ -53,7 +53,6 @@
console_url: "{{ openshift_master_console_url | default(None) }}"
console_use_ssl: "{{ openshift_master_console_use_ssl | default(None) }}"
public_console_url: "{{ openshift_master_public_console_url | default(None) }}"
- portal_net: "{{ openshift_master_portal_net | default(None) }}"
ha: "{{ openshift_master_ha | default(groups.oo_masters | length > 1) }}"
master_count: "{{ openshift_master_count | default(groups.oo_masters | length) }}"
- openshift_facts:
diff --git a/roles/flannel_register/README.md b/roles/flannel_register/README.md
index ba7541ab1..623c4c7cf 100644
--- a/roles/flannel_register/README.md
+++ b/roles/flannel_register/README.md
@@ -14,7 +14,7 @@ Role Variables
| Name | Default value | Description |
|---------------------|----------------------------------------------------|-------------------------------------------------|
-| flannel_network | {{ openshift.master.portal_net }} or 172.16.1.1/16 | interface to use for inter-host communication |
+| flannel_network | {{ openshift.common.portal_net }} or 172.16.1.1/16 | interface to use for inter-host communication |
| flannel_min_network | {{ min_network }} or 172.16.5.0 | beginning of IP range for the subnet allocation |
| flannel_subnet_len | /openshift.com/network | size of the subnet allocated to each host |
| flannel_etcd_key | /openshift.com/network | etcd prefix |
diff --git a/roles/flannel_register/defaults/main.yaml b/roles/flannel_register/defaults/main.yaml
index 269d1a17c..b1279aa88 100644
--- a/roles/flannel_register/defaults/main.yaml
+++ b/roles/flannel_register/defaults/main.yaml
@@ -1,5 +1,5 @@
---
-flannel_network: "{{ openshift.master.portal_net | default('172.30.0.0/16', true) }}"
+flannel_network: "{{ openshift.common.portal_net | default('172.30.0.0/16', true) }}"
flannel_min_network: 172.30.5.0
flannel_subnet_len: 24
flannel_etcd_key: /openshift.com/network
diff --git a/roles/openshift_common/README.md b/roles/openshift_common/README.md
index 87306d4a6..2a271854b 100644
--- a/roles/openshift_common/README.md
+++ b/roles/openshift_common/README.md
@@ -20,6 +20,7 @@ Role Variables
| openshift_ip | UNDEF | Internal IP address to use for this host |
| openshift_public_hostname | UNDEF | Public hostname to use for this host |
| openshift_public_ip | UNDEF | Public IP address to use for this host |
+| openshift_portal_net | UNDEF | Service IP CIDR |
Dependencies
------------
diff --git a/roles/openshift_common/tasks/main.yml b/roles/openshift_common/tasks/main.yml
index eda43b9f8..d5166b52e 100644
--- a/roles/openshift_common/tasks/main.yml
+++ b/roles/openshift_common/tasks/main.yml
@@ -27,6 +27,8 @@
use_nuage: "{{ openshift_use_nuage | default(None) }}"
use_manageiq: "{{ openshift_use_manageiq | default(None) }}"
data_dir: "{{ openshift_data_dir | default(None) }}"
+ portal_net: "{{ openshift_portal_net | default(openshift_master_portal_net) | default(None) }}"
+ use_dnsmasq: "{{ openshift_use_dnsmasq | default(None) }}"
# Using oo_image_tag_to_rpm_version here is a workaround for how
# openshift_version is set. That value is computed based on either RPM
diff --git a/roles/openshift_facts/library/openshift_facts.py b/roles/openshift_facts/library/openshift_facts.py
index 9218e12ae..3bdad1175 100755
--- a/roles/openshift_facts/library/openshift_facts.py
+++ b/roles/openshift_facts/library/openshift_facts.py
@@ -58,10 +58,44 @@ def migrate_docker_facts(facts):
facts['docker']['hosted_registry_network'] = facts['node'].pop('portal_net')
return facts
+# TODO: We should add a generic migration function that takes source and destination
+# paths and does the right thing rather than one function for common, one for node, etc.
+def migrate_common_facts(facts):
+ """ Migrate facts from various roles into common """
+ params = {
+ 'node': ('portal_net'),
+ 'master': ('portal_net')
+ }
+ if 'common' not in facts:
+ facts['common'] = {}
+ for role in params.keys():
+ if role in facts:
+ for param in params[role]:
+ if param in facts[role]:
+ facts['common'][param] = facts[role].pop(param)
+ return facts
+
+def migrate_node_facts(facts):
+ """ Migrate facts from various roles into node """
+ params = {
+ 'common': ('dns_ip'),
+ }
+ if 'node' not in facts:
+ facts['node'] = {}
+ for role in params.keys():
+ if role in facts:
+ for param in params[role]:
+ if param in facts[role]:
+ facts['node'][param] = facts[role].pop(param)
+ return facts
+
def migrate_local_facts(facts):
""" Apply migrations of local facts """
migrated_facts = copy.deepcopy(facts)
- return migrate_docker_facts(migrated_facts)
+ migrated_facts = migrate_docker_facts(migrated_facts)
+ migrated_facts = migrate_common_facts(migrated_facts)
+ migrated_facts = migrate_node_facts(migrated_facts)
+ return migrated_facts
def migrate_hosted_facts(facts):
""" Apply migrations for master facts """
@@ -448,6 +482,27 @@ def set_metrics_facts_if_unset(facts):
facts['common']['use_cluster_metrics'] = use_cluster_metrics
return facts
+def set_dnsmasq_facts_if_unset(facts):
+ """ Set dnsmasq facts if not already present in facts
+ Args:
+ facts (dict) existing facts
+ Returns:
+ facts (dict) updated facts with values set if not previously set
+ """
+
+ if 'common' in facts:
+ if 'use_dnsmasq' not in facts['common'] and facts['common']['version_gte_3_2_or_1_2']:
+ facts['common']['use_dnsmasq'] = True
+ else:
+ facts['common']['use_dnsmasq'] = False
+ if 'master' in facts and 'dns_port' not in facts['master']:
+ if facts['common']['use_dnsmasq']:
+ facts['master']['dns_port'] = 8053
+ else:
+ facts['master']['dns_port'] = 53
+
+ return facts
+
def set_project_cfg_facts_if_unset(facts):
""" Set Project Configuration facts if not already present in facts dict
dict:
@@ -586,11 +641,13 @@ def set_aggregate_facts(facts):
"""
all_hostnames = set()
internal_hostnames = set()
+ kube_svc_ip = first_ip(facts['common']['portal_net'])
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'])
+ facts['common']['kube_svc_ip'] = kube_svc_ip
internal_hostnames.add(facts['common']['hostname'])
internal_hostnames.add(facts['common']['ip'])
@@ -607,9 +664,8 @@ def set_aggregate_facts(facts):
'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)
+ all_hostnames.add(kube_svc_ip)
+ internal_hostnames.add(kube_svc_ip)
facts['common']['all_hostnames'] = list(all_hostnames)
facts['common']['internal_hostnames'] = list(internal_hostnames)
@@ -1490,6 +1546,7 @@ class OpenShiftFacts(object):
facts = build_controller_args(facts)
facts = build_api_server_args(facts)
facts = set_version_facts_if_unset(facts)
+ facts = set_dnsmasq_facts_if_unset(facts)
facts = set_manageiq_facts_if_unset(facts)
facts = set_aggregate_facts(facts)
facts = set_etcd_facts_if_unset(facts)
@@ -1519,6 +1576,7 @@ class OpenShiftFacts(object):
deployment_type=deployment_type,
hostname=hostname,
public_hostname=hostname,
+ portal_net='172.30.0.0/16',
client_binary='oc', admin_binary='oadm',
dns_domain='cluster.local',
install_examples=True,
@@ -1546,7 +1604,7 @@ class OpenShiftFacts(object):
etcd_hosts='', etcd_port='4001',
portal_net='172.30.0.0/16',
embedded_etcd=True, embedded_kube=True,
- embedded_dns=True, dns_port='53',
+ embedded_dns=True,
bind_addr='0.0.0.0',
session_max_seconds=3600,
session_name='ssn',
diff --git a/roles/openshift_master/defaults/main.yml b/roles/openshift_master/defaults/main.yml
index 6bf28ff2b..09bde6002 100644
--- a/roles/openshift_master/defaults/main.yml
+++ b/roles/openshift_master/defaults/main.yml
@@ -9,10 +9,10 @@ os_firewall_allow:
port: "{{ openshift.master.api_port }}/tcp"
- service: api controllers https
port: "{{ openshift.master.controllers_port }}/tcp"
-- service: dns tcp
- port: 53/tcp
-- service: dns udp
- port: 53/udp
+- service: skydns tcp
+ port: "{{ openshift.master.dns_port }}/tcp"
+- service: skydns udp
+ port: "{{ openshift.master.dns_port }}/udp"
- service: Fluentd td-agent tcp
port: 24224/tcp
- service: Fluentd td-agent udp
diff --git a/roles/openshift_master/templates/master.yaml.v1.j2 b/roles/openshift_master/templates/master.yaml.v1.j2
index 1009aa318..979b428bf 100644
--- a/roles/openshift_master/templates/master.yaml.v1.j2
+++ b/roles/openshift_master/templates/master.yaml.v1.j2
@@ -123,7 +123,7 @@ kubernetesMasterConfig:
keyFile: master.proxy-client.key
schedulerConfigFile: {{ openshift_master_scheduler_conf }}
servicesNodePortRange: ""
- servicesSubnet: {{ openshift.master.portal_net }}
+ servicesSubnet: {{ openshift.common.portal_net }}
staticNodeNames: {{ openshift_node_ips | default([], true) }}
{% endif %}
masterClients:
@@ -138,7 +138,7 @@ networkConfig:
networkPluginName: {{ openshift.common.sdn_network_plugin_name }}
{% endif %}
# serviceNetworkCIDR must match kubernetesMasterConfig.servicesSubnet
- serviceNetworkCIDR: {{ openshift.master.portal_net }}
+ serviceNetworkCIDR: {{ openshift.common.portal_net }}
oauthConfig:
{% if 'oauth_always_show_provider_selection' in openshift.master %}
alwaysShowProviderSelection: {{ openshift.master.oauth_always_show_provider_selection }}
diff --git a/roles/openshift_master_facts/tasks/main.yml b/roles/openshift_master_facts/tasks/main.yml
index 4d7c04065..e3be12182 100644
--- a/roles/openshift_master_facts/tasks/main.yml
+++ b/roles/openshift_master_facts/tasks/main.yml
@@ -30,10 +30,10 @@
embedded_etcd: "{{ openshift_master_embedded_etcd | default(None) }}"
embedded_kube: "{{ openshift_master_embedded_kube | default(None) }}"
embedded_dns: "{{ openshift_master_embedded_dns | default(None) }}"
+ # defaults to 8053 when using dnsmasq in 1.2/3.2
dns_port: "{{ openshift_master_dns_port | default(None) }}"
bind_addr: "{{ openshift_master_bind_addr | default(None) }}"
pod_eviction_timeout: "{{ openshift_master_pod_eviction_timeout | default(None) }}"
- portal_net: "{{ openshift_master_portal_net | default(None) }}"
session_max_seconds: "{{ openshift_master_session_max_seconds | default(None) }}"
session_name: "{{ openshift_master_session_name | default(None) }}"
session_secrets_file: "{{ openshift_master_session_secrets_file | default(None) }}"
diff --git a/roles/openshift_node/meta/main.yml b/roles/openshift_node/meta/main.yml
index 84ba9ac2e..ca0c332ea 100644
--- a/roles/openshift_node/meta/main.yml
+++ b/roles/openshift_node/meta/main.yml
@@ -15,3 +15,6 @@ dependencies:
- role: openshift_docker
- role: openshift_cloud_provider
- role: openshift_common
+- role: openshift_node_dnsmasq
+ when: openshift.common.use_dnsmasq
+
diff --git a/roles/openshift_node/tasks/main.yml b/roles/openshift_node/tasks/main.yml
index 8987e0191..06fde88af 100644
--- a/roles/openshift_node/tasks/main.yml
+++ b/roles/openshift_node/tasks/main.yml
@@ -9,13 +9,6 @@
role: "{{ item.role }}"
local_facts: "{{ item.local_facts }}"
with_items:
- - role: common
- local_facts:
- # TODO: Replace this with a lookup or filter plugin.
- # TODO: Move this to the node role
- dns_ip: "{{ openshift_dns_ip
- | default(openshift_master_cluster_vip
- | default(None if openshift.common.version_gte_3_1_or_1_1 | bool else openshift_node_first_master_ip | default(None, true), true), true) }}"
- role: node
local_facts:
annotations: "{{ openshift_node_annotations | default(none) }}"
@@ -32,6 +25,7 @@
ovs_image: "{{ osn_ovs_image | default(None) }}"
proxy_mode: "{{ openshift_node_proxy_mode | default('iptables') }}"
local_quota_per_fsgroup: "{{ openshift_node_local_quota_per_fsgroup | default(None) }}"
+ dns_ip: "{{ openshift_dns_ip | default(none) | get_dns_ip(hostvars[inventory_hostname])}}"
# We have to add tuned-profiles in the same transaction otherwise we run into depsolving
# problems because the rpms don't pin the version properly. This was fixed in 3.1 packaging.
diff --git a/roles/openshift_node/templates/node.yaml.v1.j2 b/roles/openshift_node/templates/node.yaml.v1.j2
index 28cb1ea26..9ba1a01dd 100644
--- a/roles/openshift_node/templates/node.yaml.v1.j2
+++ b/roles/openshift_node/templates/node.yaml.v1.j2
@@ -1,8 +1,8 @@
allowDisabledDocker: false
apiVersion: v1
dnsDomain: {{ openshift.common.dns_domain }}
-{% if 'dns_ip' in openshift.common %}
-dnsIP: {{ openshift.common.dns_ip }}
+{% if 'dns_ip' in openshift.node %}
+dnsIP: {{ openshift.node.dns_ip }}
{% endif %}
dockerConfig:
execHandlerName: ""
diff --git a/roles/openshift_node_dnsmasq/files/networkmanager/99-origin-dns.sh b/roles/openshift_node_dnsmasq/files/networkmanager/99-origin-dns.sh
new file mode 100755
index 000000000..51e0751e9
--- /dev/null
+++ b/roles/openshift_node_dnsmasq/files/networkmanager/99-origin-dns.sh
@@ -0,0 +1,55 @@
+#!/bin/bash -x
+
+# This NetworkManager dispatcher script replicates the functionality of
+# NetworkManager's dns=dnsmasq however, rather than hardcoding the listening
+# address and /etc/resolv.conf to 127.0.0.1 it pulls the IP address from the
+# interface that owns the default route. This enables us to then configure pods
+# to use this IP address as their only resolver, where as using 127.0.0.1 inside
+# a pod would fail.
+#
+# To use this,
+# Drop this script in /etc/NetworkManager/dispatcher.d/
+# systemctl restart NetworkManager
+# Configure node-config.yaml to set dnsIP: to the ip address of this
+# node
+#
+# Test it:
+# host kubernetes.default.svc.cluster.local
+# host google.com
+#
+# TODO: I think this would be easy to add as a config option in NetworkManager
+# natively, look at hacking that up
+
+cd /etc/sysconfig/network-scripts
+. ./network-functions
+
+[ -f ../network ] && . ../network
+
+if [[ $2 =~ ^(up|dhcp4-change)$ ]]; then
+ # couldn't find an existing method to determine if the interface owns the
+ # default route
+ def_route=$(/sbin/ip route list match 0.0.0.0/0 | awk '{print $3 }')
+ def_route_int=$(/sbin/ip route get to ${def_route} | awk '{print $3}')
+ def_route_ip=$(/sbin/ip route get to ${def_route} | awk '{print $5}')
+ if [[ ${DEVICE_IFACE} == ${def_route_int} ]]; then
+ if [ ! -f /etc/dnsmasq.d/origin-dns.conf ]; then
+ cat << EOF > /etc/dnsmasq.d/origin-dns.conf
+strict-order
+no-resolv
+domain-needed
+server=/cluster.local/172.30.0.1
+server=/30.172.in-addr.arpa/172.30.0.1
+EOF
+ fi
+ # zero out our upstream servers list and feed it into dnsmasq
+ echo '' > /etc/dnsmasq.d/origin-upstream-dns.conf
+ for ns in ${DHCP4_DOMAIN_NAME_SERVERS}; do
+ echo "server=${ns}" >> /etc/dnsmasq.d/origin-upstream-dns.conf
+ done
+ echo "listen-address=${def_route_ip}" >> /etc/dnsmasq.d/origin-upstream-dns.conf
+ systemctl restart dnsmasq
+
+ sed -i 's/^nameserver.*$/nameserver '"${def_route_ip}"'/g' /etc/resolv.conf
+ echo "# nameserver updated by /etc/NetworkManager/dispatcher.d/99-origin-dns.sh" >> /etc/resolv.conf
+ fi
+fi
diff --git a/roles/openshift_node_dnsmasq/handlers/main.yml b/roles/openshift_node_dnsmasq/handlers/main.yml
new file mode 100644
index 000000000..7e9e4d299
--- /dev/null
+++ b/roles/openshift_node_dnsmasq/handlers/main.yml
@@ -0,0 +1,5 @@
+---
+- name: restart NetworkManager
+ service:
+ name: NetworkManager
+ state: restarted
diff --git a/roles/openshift_node_dnsmasq/meta/main.yml b/roles/openshift_node_dnsmasq/meta/main.yml
new file mode 100644
index 000000000..c83d64ae4
--- /dev/null
+++ b/roles/openshift_node_dnsmasq/meta/main.yml
@@ -0,0 +1,15 @@
+---
+galaxy_info:
+ author: Scott Dodson
+ description: OpenShift Node DNSMasq support
+ company: Red Hat, Inc.
+ license: Apache License, Version 2.0
+ min_ansible_version: 1.7
+ platforms:
+ - name: EL
+ versions:
+ - 7
+ categories:
+ - cloud
+dependencies:
+- role: openshift_common
diff --git a/roles/openshift_node_dnsmasq/tasks/main.yml b/roles/openshift_node_dnsmasq/tasks/main.yml
new file mode 100644
index 000000000..4cb24469d
--- /dev/null
+++ b/roles/openshift_node_dnsmasq/tasks/main.yml
@@ -0,0 +1,27 @@
+---
+- name: Check for NetworkManager service
+ command: >
+ systemctl show NetworkManager
+ register: nm_show
+
+- name: Set fact using_network_manager
+ set_fact:
+ network_manager_active: "{{ True if 'ActiveState=active' in nm_show.stdout else False }}"
+
+- name: Install dnsmasq
+ action: "{{ ansible_pkg_mgr }} name=dnsmasq state=installed"
+ when: not openshift.common.is_atomic | bool
+
+- name: Install dnsmasq configuration
+ template:
+ src: origin-dns.conf.j2
+ dest: /etc/dnsmasq.d/origin-dns.conf
+
+# Dynamic NetworkManager based dispatcher
+- include: ./network-manager.yml
+ when: network_manager_active | bool
+
+# Relies on ansible in order to configure static config
+- include: ./no-network-manager.yml
+ when: not network_manager_active | bool
+
diff --git a/roles/openshift_node_dnsmasq/tasks/network-manager.yml b/roles/openshift_node_dnsmasq/tasks/network-manager.yml
new file mode 100644
index 000000000..dddcfc9da
--- /dev/null
+++ b/roles/openshift_node_dnsmasq/tasks/network-manager.yml
@@ -0,0 +1,9 @@
+---
+- name: Install network manager dispatch script
+ copy:
+ src: networkmanager/99-origin-dns.sh
+ dest: /etc/NetworkManager/dispatcher.d/
+ mode: 0755
+ notify: restart NetworkManager
+
+- meta: flush_handlers
diff --git a/roles/openshift_node_dnsmasq/tasks/no-network-manager.yml b/roles/openshift_node_dnsmasq/tasks/no-network-manager.yml
new file mode 100644
index 000000000..cda90bd10
--- /dev/null
+++ b/roles/openshift_node_dnsmasq/tasks/no-network-manager.yml
@@ -0,0 +1,2 @@
+---
+- fail: msg="Not implemented" \ No newline at end of file
diff --git a/roles/openshift_node_dnsmasq/templates/origin-dns.conf.j2 b/roles/openshift_node_dnsmasq/templates/origin-dns.conf.j2
new file mode 100644
index 000000000..1753bb821
--- /dev/null
+++ b/roles/openshift_node_dnsmasq/templates/origin-dns.conf.j2
@@ -0,0 +1,4 @@
+strict-order
+no-resolv
+domain-needed
+server=/{{ openshift.common.dns_domain }}/{{ openshift.common.kube_svc_ip }}