diff options
-rw-r--r-- | inventory/byo/hosts.aep.example | 16 | ||||
-rw-r--r-- | inventory/byo/hosts.origin.example | 16 | ||||
-rw-r--r-- | inventory/byo/hosts.ose.example | 16 | ||||
-rw-r--r-- | playbooks/common/openshift-cluster/upgrades/v3_1_minor/upgrade.yml | 4 | ||||
-rw-r--r-- | playbooks/common/openshift-master/config.yml | 5 | ||||
-rw-r--r-- | playbooks/common/openshift-node/config.yml | 4 | ||||
-rw-r--r-- | roles/lib_dyn/library/dyn_record.py | 164 | ||||
-rw-r--r-- | roles/openshift_master/tasks/main.yml | 2 | ||||
-rw-r--r-- | roles/os_reboot_server/tasks/main.yaml | 16 | ||||
-rw-r--r-- | roles/os_update_latest/tasks/main.yml | 5 | ||||
-rw-r--r-- | roles/os_utils/tasks/main.yaml | 17 |
11 files changed, 203 insertions, 62 deletions
diff --git a/inventory/byo/hosts.aep.example b/inventory/byo/hosts.aep.example index 8cd4caac4..637f13be6 100644 --- a/inventory/byo/hosts.aep.example +++ b/inventory/byo/hosts.aep.example @@ -132,7 +132,7 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', #osm_api_server_args={'max-requests-inflight': ['400']} # default subdomain to use for exposed routes -#osm_default_subdomain=apps.test.example.com +#openshift_master_default_subdomain=apps.test.example.com # additional cors origins #osm_custom_cors_origins=['foo.example.com', 'bar.example.com'] @@ -157,6 +157,20 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', # Disable the OpenShift SDN plugin # openshift_use_openshift_sdn=False +# Configure SDN cluster network CIDR block. This network block should +# be a private block and should not conflict with existing network +# blocks in your infrastructure that pods may require access to. +# Can not be changed after deployment. +#osm_cluster_network_cidr=10.1.0.0/16 + +# Configure number of bits to allocate to each host’s subnet e.g. 8 +# would mean a /24 network on the host. +#osm_host_subnet_length=8 + +# Configure master API and console ports. +#openshift_master_api_port=8443 +#openshift_master_console_port=8443 + # set RPM version for debugging purposes #openshift_pkg_version=-3.1.0.0 diff --git a/inventory/byo/hosts.origin.example b/inventory/byo/hosts.origin.example index fffdcaab4..c30f65f9f 100644 --- a/inventory/byo/hosts.origin.example +++ b/inventory/byo/hosts.origin.example @@ -137,7 +137,7 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', #osm_api_server_args={'max-requests-inflight': ['400']} # default subdomain to use for exposed routes -#osm_default_subdomain=apps.test.example.com +#openshift_master_default_subdomain=apps.test.example.com # additional cors origins #osm_custom_cors_origins=['foo.example.com', 'bar.example.com'] @@ -162,6 +162,20 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', # Disable the OpenShift SDN plugin # openshift_use_openshift_sdn=False +# Configure SDN cluster network CIDR block. This network block should +# be a private block and should not conflict with existing network +# blocks in your infrastructure that pods may require access to. +# Can not be changed after deployment. +#osm_cluster_network_cidr=10.1.0.0/16 + +# Configure number of bits to allocate to each host’s subnet e.g. 8 +# would mean a /24 network on the host. +#osm_host_subnet_length=8 + +# Configure master API and console ports. +#openshift_master_api_port=8443 +#openshift_master_console_port=8443 + # set RPM version for debugging purposes #openshift_pkg_version=-1.1 diff --git a/inventory/byo/hosts.ose.example b/inventory/byo/hosts.ose.example index 233c1c8e2..b51569e68 100644 --- a/inventory/byo/hosts.ose.example +++ b/inventory/byo/hosts.ose.example @@ -133,7 +133,7 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', #osm_api_server_args={'max-requests-inflight': ['400']} # default subdomain to use for exposed routes -#osm_default_subdomain=apps.test.example.com +#openshift_master_default_subdomain=apps.test.example.com # additional cors origins #osm_custom_cors_origins=['foo.example.com', 'bar.example.com'] @@ -158,6 +158,20 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', # Disable the OpenShift SDN plugin # openshift_use_openshift_sdn=False +# Configure SDN cluster network CIDR block. This network block should +# be a private block and should not conflict with existing network +# blocks in your infrastructure that pods may require access to. +# Can not be changed after deployment. +#osm_cluster_network_cidr=10.1.0.0/16 + +# Configure number of bits to allocate to each host’s subnet e.g. 8 +# would mean a /24 network on the host. +#osm_host_subnet_length=8 + +# Configure master API and console ports. +#openshift_master_api_port=8443 +#openshift_master_console_port=8443 + # set RPM version for debugging purposes #openshift_pkg_version=-3.1.0.0 diff --git a/playbooks/common/openshift-cluster/upgrades/v3_1_minor/upgrade.yml b/playbooks/common/openshift-cluster/upgrades/v3_1_minor/upgrade.yml index dbf746f12..54bb251f7 100644 --- a/playbooks/common/openshift-cluster/upgrades/v3_1_minor/upgrade.yml +++ b/playbooks/common/openshift-cluster/upgrades/v3_1_minor/upgrade.yml @@ -13,10 +13,11 @@ tasks: - name: Upgrade master packages command: "{{ ansible_pkg_mgr}} update -y {{ openshift.common.service_type }}-master{{ openshift_version }}" + when: not openshift.common.is_containerized | bool - name: Ensure python-yaml present for config upgrade action: "{{ ansible_pkg_mgr }} name=PyYAML state=present" - when: not openshift.common.is_atomic | bool + when: not openshift.common.is_containerized | bool # Currently 3.1.1 does not have any new configuration settings # @@ -63,6 +64,7 @@ tasks: - name: Upgrade node packages command: "{{ ansible_pkg_mgr }} update -y {{ openshift.common.service_type }}-node{{ openshift_version }}" + when: not openshift.common.is_containerized | bool - name: Restart node service service: name="{{ openshift.common.service_type }}-node" state=restarted diff --git a/playbooks/common/openshift-master/config.yml b/playbooks/common/openshift-master/config.yml index b9d595576..acd2f5b11 100644 --- a/playbooks/common/openshift-master/config.yml +++ b/playbooks/common/openshift-master/config.yml @@ -28,6 +28,11 @@ | default([])) | oo_collect('openshift.common.hostname') | default(none, true) }}" + + - set_fact: + openshift_master_debug_level: "{{ lookup('oo_option', 'openshift_master_debug_level') | default(openshift.common.debug_level, true) }}" + when: openshift_master_debug_level is not defined + roles: - openshift_facts post_tasks: diff --git a/playbooks/common/openshift-node/config.yml b/playbooks/common/openshift-node/config.yml index 56d30e9b9..7edea9160 100644 --- a/playbooks/common/openshift-node/config.yml +++ b/playbooks/common/openshift-node/config.yml @@ -1,6 +1,10 @@ --- - name: Gather and set facts for node hosts hosts: oo_nodes_to_config + pre_tasks: + - set_fact: + openshift_node_debug_level: "{{ lookup('oo_option', 'openshift_node_debug_level') | default(openshift.common.debug_level, true) }}" + when: openshift_node_debug_level is not defined roles: - openshift_facts tasks: diff --git a/roles/lib_dyn/library/dyn_record.py b/roles/lib_dyn/library/dyn_record.py index 7b80064f4..42d970060 100644 --- a/roles/lib_dyn/library/dyn_record.py +++ b/roles/lib_dyn/library/dyn_record.py @@ -13,6 +13,7 @@ # 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. +# pylint: disable=too-many-branches '''Ansible module to manage records in the Dyn Managed DNS service''' DOCUMENTATION = ''' --- @@ -84,9 +85,18 @@ options: description: - 'Record's "Time to live". Number of seconds the record remains cached' - 'in DNS servers or c(0) to use the default TTL for the zone.' + - 'This option is mutually exclusive with use_zone_ttl' required: false default: 0 + use_zone_ttl: + description: + - 'Use the DYN Zone's Default TTL' + - 'This option is mutually exclusive with record_ttl' + required: false + default: false + mutually exclusive with: record_ttl + notes: - The module makes a broad assumption that there will be only one record per "node" (FQDN). - This module returns record(s) in the "result" element when 'state' is set to 'present'. This value can be be registered and used in your playbooks. @@ -96,18 +106,28 @@ author: "Russell Harrison" ''' EXAMPLES = ''' +# Attempting to cname www.example.com to web1.example.com +- name: Update CNAME record + dyn_record: + state: present + record_fqdn: www.example.com + zone: example.com + record_type: CNAME + record_value: web1.example.com + record_ttl: 7200 + +# Use the zones default TTL - name: Update CNAME record - local_action: - module: dyn_record + dyn_record: state: present record_fqdn: www.example.com zone: example.com record_type: CNAME record_value: web1.example.com + use_zone_ttl: true - name: Update A record - local_action: - module: dyn_record + dyn_record: state: present record_fqdn: web1.example.com zone: example.com @@ -144,7 +164,10 @@ def get_record_type(record_key): return record_key.replace('_records', '').upper() def get_record_key(record_type): - '''Get the key to look up records in the dictionary returned from get_any_records.''' + '''Get the key to look up records in the dictionary returned from get_any_records. + example: + 'cname_records' + ''' return record_type.lower() + '_records' def get_any_records(module, node): @@ -166,14 +189,41 @@ def get_any_records(module, node): def get_record_values(records): '''Get the record values for each record returned by get_any_records.''' - # This simply returns the values from a dictionary of record objects + # This simply returns the values from a record ret_dict = {} for key in records.keys(): record_type = get_record_type(key) - record_value_param = RECORD_PARAMS[record_type]['value_param'] - ret_dict[key] = [getattr(elem, record_value_param) for elem in records[key]] + params = [RECORD_PARAMS[record_type]['value_param'], 'ttl', 'zone', 'fqdn'] + ret_dict[key] = [] + properties = {} + for elem in records[key]: + for param in params: + properties[param] = getattr(elem, param) + ret_dict[key].append(properties) + return ret_dict +def compare_record_values(record_type_key, user_record_value, dyn_values): + ''' Verify the user record_value exists in dyn''' + rtype = get_record_type(record_type_key) + for record in dyn_values[record_type_key]: + if user_record_value in record[RECORD_PARAMS[rtype]['value_param']]: + return True + + return False + +def compare_record_ttl(record_type_key, user_record_value, dyn_values, user_param_ttl): + ''' Verify the ttls match for the record''' + rtype = get_record_type(record_type_key) + for record in dyn_values[record_type_key]: + # find the right record + if user_record_value in record[RECORD_PARAMS[rtype]['value_param']]: + # Compare ttls from the records + if int(record['ttl']) == user_param_ttl: + return True + + return False + def main(): '''Ansible module for managing Dyn DNS records.''' module = AnsibleModule( @@ -187,16 +237,20 @@ def main(): record_type=dict(required=False, type='str', choices=[ 'A', 'AAAA', 'CNAME', 'PTR', 'TXT']), record_value=dict(required=False, type='str'), - record_ttl=dict(required=False, default=0, type='int'), + record_ttl=dict(required=False, default=None, type='int'), + use_zone_ttl=dict(required=False, default=False), ), required_together=( ['record_fqdn', 'record_value', 'record_ttl', 'record_type'] - ) + ), + mutually_exclusive=[('record_ttl', 'use_zone_ttl')] ) if IMPORT_ERROR: - module.fail_json(msg="Unable to import dyn module: https://pypi.python.org/pypi/dyn", - error=IMPORT_ERROR) + module.fail_json(msg="Unable to import dyn module: https://pypi.python.org/pypi/dyn", error=IMPORT_ERROR) + + if module.params['record_ttl'] != None and int(module.params['record_ttl']) <= 0: + module.fail_json(msg="Invalid Value for record TTL") # Start the Dyn session try: @@ -204,22 +258,16 @@ def main(): module.params['user_name'], module.params['user_password']) except dyn.tm.errors.DynectAuthError as error: - module.fail_json(msg='Unable to authenticate with Dyn', - error=str(error)) + module.fail_json(msg='Unable to authenticate with Dyn', error=str(error)) # Retrieve zone object try: dyn_zone = Zone(module.params['zone']) except dyn.tm.errors.DynectGetError as error: if 'No such zone' in str(error): - module.fail_json( - msg="Not a valid zone for this account", - zone=module.params['zone'] - ) + module.fail_json(msg="Not a valid zone for this account", zone=module.params['zone']) else: - module.fail_json(msg="Unable to retrieve zone", - error=str(error)) - + module.fail_json(msg="Unable to retrieve zone", error=str(error)) # To retrieve the node object we need to remove the zone name from the FQDN dyn_node_name = module.params['record_fqdn'].replace('.' + module.params['zone'], '') @@ -233,27 +281,46 @@ def main(): # All states will need a list of the exiting records for the zone. dyn_node_records = get_any_records(module, dyn_node) + dyn_values = get_record_values(dyn_node_records) + if module.params['state'] == 'list': - module.exit_json(changed=False, - records=get_record_values( - dyn_node_records, - )) + module.exit_json(changed=False, dyn_records=dyn_values) - if module.params['state'] == 'present': + elif module.params['state'] == 'absent': + # If there are any records present we'll want to delete the node. + if dyn_node_records: + dyn_node.delete() + + # Publish the zone since we've modified it. + dyn_zone.publish() + + module.exit_json(changed=True, msg="Removed node %s from zone %s" % (dyn_node_name, module.params['zone'])) + + module.exit_json(changed=False) + + elif module.params['state'] == 'present': + + # configure the TTL variable: + # if use_zone_ttl, use the default TTL of the account. + # if TTL == None, don't check it, set it as 0 (api default) + # if TTL > 0, ensure this TTL is set + if module.params['use_zone_ttl']: + user_param_ttl = dyn_zone.ttl + elif not module.params['record_ttl']: + user_param_ttl = 0 + else: + user_param_ttl = module.params['record_ttl'] # First get a list of existing records for the node - values = get_record_values(dyn_node_records) - value_key = get_record_key(module.params['record_type']) - param_value = module.params['record_value'] + record_type_key = get_record_key(module.params['record_type']) + user_record_value = module.params['record_value'] # Check to see if the record is already in place before doing anything. - if (dyn_node_records and - dyn_node_records[value_key][0].ttl == module.params['record_ttl'] and - (param_value in values[value_key] or - param_value + '.' in values[value_key])): - - module.exit_json(changed=False) + if dyn_node_records and compare_record_values(record_type_key, user_record_value, dyn_values): + if user_param_ttl == 0 or \ + compare_record_ttl(record_type_key, user_record_value, dyn_values, user_param_ttl): + module.exit_json(changed=False, dyn_record=dyn_values) # Working on the assumption that there is only one record per # node we will first delete the node if there are any records before @@ -262,27 +329,20 @@ def main(): dyn_node.delete() # Now lets create the correct node entry. - dyn_zone.add_record(dyn_node_name, - module.params['record_type'], - module.params['record_value'], - module.params['record_ttl'] - ) + record = dyn_zone.add_record(dyn_node_name, + module.params['record_type'], + module.params['record_value'], + user_param_ttl + ) # Now publish the zone since we've updated it. dyn_zone.publish() - module.exit_json(changed=True, - msg="Created node %s in zone %s" % (dyn_node_name, module.params['zone'])) - if module.params['state'] == 'absent': - # If there are any records present we'll want to delete the node. - if dyn_node_records: - dyn_node.delete() - # Publish the zone since we've modified it. - dyn_zone.publish() - module.exit_json(changed=True, - msg="Removed node %s from zone %s" % (dyn_node_name, module.params['zone'])) - else: - module.exit_json(changed=False) + rmsg = "Created node [%s] " % dyn_node_name + rmsg += "in zone: [%s]" % module.params['zone'] + module.exit_json(changed=True, msg=rmsg, dyn_record=get_record_values({record_type_key: [record]})) + + module.fail_json(msg="Unknown state: [%s]" % module.params['state']) # Ansible tends to need a wild card import so we'll use it here # pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, locally-disabled diff --git a/roles/openshift_master/tasks/main.yml b/roles/openshift_master/tasks/main.yml index dd66eeebb..a37f5b4bb 100644 --- a/roles/openshift_master/tasks/main.yml +++ b/roles/openshift_master/tasks/main.yml @@ -70,7 +70,7 @@ oauth_grant_method: "{{ openshift_master_oauth_grant_method | default(None) }}" sdn_cluster_network_cidr: "{{ osm_cluster_network_cidr | default(None) }}" sdn_host_subnet_length: "{{ osm_host_subnet_length | default(None) }}" - default_subdomain: "{{ osm_default_subdomain | default(None) }}" + default_subdomain: "{{ openshift_master_default_subdomain | default(osm_default_subdomain) | default(None) }}" custom_cors_origins: "{{ osm_custom_cors_origins | default(None) }}" default_node_selector: "{{ osm_default_node_selector | default(None) }}" project_request_message: "{{ osm_project_request_message | default(None) }}" diff --git a/roles/os_reboot_server/tasks/main.yaml b/roles/os_reboot_server/tasks/main.yaml new file mode 100644 index 000000000..581ed3e0a --- /dev/null +++ b/roles/os_reboot_server/tasks/main.yaml @@ -0,0 +1,16 @@ +--- +# Role to reboot a server +- name: Restart server + shell: sleep 2 && shutdown -r now "Ansible updates triggered" + async: 1 + poll: 0 + ignore_errors: true + +- name: Wait for server to restart + local_action: + module: wait_for + host={{ ansible_ssh_host }} + port=22 + delay=3 + timeout=300 + sudo: false diff --git a/roles/os_update_latest/tasks/main.yml b/roles/os_update_latest/tasks/main.yml index 2400164fa..ff2b52275 100644 --- a/roles/os_update_latest/tasks/main.yml +++ b/roles/os_update_latest/tasks/main.yml @@ -1,8 +1,3 @@ --- -- fail: - msg: "Update is not yet supported by this playbook on atomic hosts" - when: openshift.common.is_containerized | bool - - name: Update all packages action: "{{ ansible_pkg_mgr }} name=* state=latest" - when: not openshift.common.is_containerized | bool
\ No newline at end of file diff --git a/roles/os_utils/tasks/main.yaml b/roles/os_utils/tasks/main.yaml new file mode 100644 index 000000000..346f6566f --- /dev/null +++ b/roles/os_utils/tasks/main.yaml @@ -0,0 +1,17 @@ +--- +# Utility packages that make things helpful + +- name: Install useful rpm packages + action: "{{ ansible_pkg_mgr }} name={{ item }} state=present" + with_items: + - wget + - git + - net-tools + - bind-utils + - iptables-services + - bridge-utils + - bash-completion + - atop + - htop + - ack + - telnet |