diff options
Diffstat (limited to 'roles')
20 files changed, 342 insertions, 150 deletions
diff --git a/roles/docker_storage/README.md b/roles/docker_storage/README.md deleted file mode 100644 index bf0158623..000000000 --- a/roles/docker_storage/README.md +++ /dev/null @@ -1,39 +0,0 @@ -docker_storage -========= - -Configure docker_storage options ------------- - -None - -Role Variables --------------- - -None - -Dependencies ------------- - -None - -Example Playbook ----------------- - -Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: - - - hosts: servers - roles: - - { role/docker_storage: - - key: df.fs - value: xfs - } - -License -------- - -ASL 2.0 - -Author Information ------------------- - -OpenShift operations, Red Hat, Inc diff --git a/roles/docker_storage/defaults/main.yml b/roles/docker_storage/defaults/main.yml deleted file mode 100644 index ed97d539c..000000000 --- a/roles/docker_storage/defaults/main.yml +++ /dev/null @@ -1 +0,0 @@ ---- diff --git a/roles/docker_storage/handlers/main.yml b/roles/docker_storage/handlers/main.yml deleted file mode 100644 index ed97d539c..000000000 --- a/roles/docker_storage/handlers/main.yml +++ /dev/null @@ -1 +0,0 @@ ---- diff --git a/roles/docker_storage/meta/main.yml b/roles/docker_storage/meta/main.yml deleted file mode 100644 index f5b2d53cb..000000000 --- a/roles/docker_storage/meta/main.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -galaxy_info: - author: OpenShift - description: Setup docker_storage options - company: Red Hat, Inc - license: ASL 2.0 - min_ansible_version: 1.2 -dependencies: -- docker diff --git a/roles/docker_storage/tasks/main.yml b/roles/docker_storage/tasks/main.yml deleted file mode 100644 index 48a3fc208..000000000 --- a/roles/docker_storage/tasks/main.yml +++ /dev/null @@ -1,37 +0,0 @@ ---- -- lvg: - pvs: "{{ dst_device }}" - vg: "{{ dst_vg }}" - register: dst_lvg - -- lvol: - lv: data - vg: "{{ dst_vg }}" - size: 95%VG - register: dst_lvol_data - -- lvol: - lv: metadata - vg: "{{ dst_vg }}" - size: 5%VG - register: dst_lvol_metadata - - -- name: Update docker_storage options - lineinfile: - dest: /etc/sysconfig/docker-storage - backrefs: yes - regexp: "^(DOCKER_STORAGE_OPTIONS=)" - line: '\1 --storage-opt {{ dst_options | oo_combine_key_value("=") | join(" --storage-opt ") }}' - when: dst_options is defined and dst_options | length > 0 - register: dst_config - - -- name: Reload systemd units - command: systemctl daemon-reload - notify: - - restart docker - when: dst_config | changed or - dst_lvg | changed or - dst_lvol_data | changed or - dst_lvol_metadata | changed diff --git a/roles/docker_storage/vars/main.yml b/roles/docker_storage/vars/main.yml deleted file mode 100644 index ed97d539c..000000000 --- a/roles/docker_storage/vars/main.yml +++ /dev/null @@ -1 +0,0 @@ ---- diff --git a/roles/docker_storage_setup/README.md b/roles/docker_storage_setup/README.md new file mode 100644 index 000000000..6039b349a --- /dev/null +++ b/roles/docker_storage_setup/README.md @@ -0,0 +1,42 @@ +docker_storage_setup +========= +This role coverts docker to go from loopback to direct-lvm (the Red Hat recommended way to run docker). + +It requires the block device to be already provisioned and attached to the host. + + Notes: + * This is NOT idempotent. Conversion needs to be done for it to be idempotent + * This will remove /var/lib/docker! + * You will need to re-deploy docker images + +Configure docker_storage_setup +------------ + +None + +Role Variables +-------------- + +dss_docker_device: defaults to /dev/xvdb + +Dependencies +------------ + +None + +Example Playbook +---------------- + + - hosts: servers + roles: + - { role/docker_storage_setup, dss_docker_device: '/dev/xvdb' } + +License +------- + +ASL 2.0 + +Author Information +------------------ + +OpenShift operations, Red Hat, Inc diff --git a/roles/docker_storage_setup/defaults/main.yml b/roles/docker_storage_setup/defaults/main.yml new file mode 100644 index 000000000..5013aba97 --- /dev/null +++ b/roles/docker_storage_setup/defaults/main.yml @@ -0,0 +1,2 @@ +--- +dss_docker_device: /dev/xvdb diff --git a/roles/docker_storage_setup/tasks/main.yml b/roles/docker_storage_setup/tasks/main.yml new file mode 100755 index 000000000..8af9bbe1e --- /dev/null +++ b/roles/docker_storage_setup/tasks/main.yml @@ -0,0 +1,95 @@ +--- +- name: Ensure docker is installed + action: "{{ ansible_pkg_mgr }} name={{ item }} state=present" + with_items: + - docker + +# Docker doesn't seem to start cleanly the first time run +# when loopback (not directlvm) is configured. Putting in an +# ignore errors, and then sleeping till it can come up cleanly +- name: Try to start docker. This might fail (loopback startup issue) + service: + name: docker + state: started + ignore_errors: yes + +- name: Pause for 1 minute + pause: + seconds: 30 + +- name: Ensure docker is started + service: + name: docker + state: started + +- name: Determine if loopback + shell: docker info | grep 'Data file:.*loop' + register: loop_device_check + ignore_errors: yes + +- debug: + var: loop_device_check + +- name: fail if we don't detect loopback + fail: + msg: loopback not detected! Please investigate manually. + when: loop_device_check.rc == 1 + +- name: "check to see if {{ dss_docker_device }} exists" + command: "test -e {{ dss_docker_device }}" + register: docker_dev_check + ignore_errors: yes + +- debug: var=docker_dev_check + +- name: "fail if {{ dss_docker_device }} doesn't exist" + fail: + msg: "{{ dss_docker_device }} doesn't exist. Please investigate" + when: docker_dev_check.rc != 0 + +- name: stop docker + service: + name: docker + state: stopped + +- name: delete /var/lib/docker + command: rm -rf /var/lib/docker + +- name: remove /var/lib/docker + command: rm -rf /var/lib/docker + +- name: copy the docker-storage-setup config file + copy: + content: > + DEVS={{ dss_docker_device }}\n + VG=docker_vg + dest: /etc/sysconfig/docker-storage-setup + owner: root + group: root + mode: 0664 + +- name: docker storage setup + command: docker-storage-setup + register: docker_storage_setup_output + +- debug: + msg: "{{ docker_storage_setup_output }}" + +- name: extend the vg + command: lvextend -l 90%VG /dev/docker_vg/docker-pool + register: lvextend_output + +- debug: + msg: "{{ lvextend_output }}" + +- name: start docker + service: + name: docker + state: restarted + +- name: docker info + command: docker info + register: dockerinfo + +- debug: + msg: "{{ dockerinfo }}" 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/lib_zabbix/tasks/create_template.yml b/roles/lib_zabbix/tasks/create_template.yml index 61344357a..783249c3a 100644 --- a/roles/lib_zabbix/tasks/create_template.yml +++ b/roles/lib_zabbix/tasks/create_template.yml @@ -61,6 +61,20 @@ with_items: template.ztriggers when: template.ztriggers is defined +- name: Create Actions + zbx_action: + zbx_server: "{{ server }}" + zbx_user: "{{ user }}" + zbx_password: "{{ password }}" + state: "{{ item.state | default('present', True) }}" + name: "{{ item.name }}" + status: "{{ item.status | default('enabled', True) }}" + escalation_time: "{{ item.escalation_time }}" + conditions_filter: "{{ item.conditions_filter }}" + operations: "{{ item.operations }}" + with_items: template.zactions + when: template.zactions is defined + - name: Create Discoveryrules zbx_discoveryrule: zbx_server: "{{ server }}" diff --git a/roles/openshift_examples/files/examples/latest b/roles/openshift_examples/files/examples/latest new file mode 120000 index 000000000..634650e09 --- /dev/null +++ b/roles/openshift_examples/files/examples/latest @@ -0,0 +1 @@ +v1.1
\ No newline at end of file diff --git a/roles/openshift_manage_node/tasks/main.yml b/roles/openshift_manage_node/tasks/main.yml index 06f12053a..cee1f1738 100644 --- a/roles/openshift_manage_node/tasks/main.yml +++ b/roles/openshift_manage_node/tasks/main.yml @@ -3,7 +3,7 @@ {{ openshift.common.client_binary }} get node {{ item | lower }} register: omd_get_node until: omd_get_node.rc == 0 - retries: 20 + retries: 50 delay: 5 changed_when: false with_items: openshift_nodes 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/openshift_master_certificates/tasks/main.yml b/roles/openshift_master_certificates/tasks/main.yml index 72869a592..9017b7d2b 100644 --- a/roles/openshift_master_certificates/tasks/main.yml +++ b/roles/openshift_master_certificates/tasks/main.yml @@ -27,3 +27,12 @@ --overwrite=false when: item.master_certs_missing | bool with_items: masters_needing_certs + +- file: + src: "{{ openshift_master_config_dir }}/{{ item.1 }}" + dest: "{{ openshift_generated_configs_dir }}/{{ item.0.master_cert_subdir }}/{{ item.1 }}" + state: hard + force: true + with_nested: + - masters_needing_certs + - "{{ hostvars[inventory_hostname] | certificates_to_synchronize }}" 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 diff --git a/roles/os_zabbix/vars/template_openshift_node.yml b/roles/os_zabbix/vars/template_openshift_node.yml index c36c593df..66bd3a147 100644 --- a/roles/os_zabbix/vars/template_openshift_node.yml +++ b/roles/os_zabbix/vars/template_openshift_node.yml @@ -59,7 +59,7 @@ g_template_openshift_node: url: 'https://github.com/openshift/ops-sop/blob/node/V3/Alerts/openshift_node.asciidoc' priority: high - - name: '[HEAL] OVS may not be running on {HOST.NAME}' + - name: '[Heal] OVS may not be running on {HOST.NAME}' expression: '{Template Openshift Node:openshift.node.ovs.pids.count.last(#1)}<>4 and {Template Openshift Node:openshift.node.ovs.pids.count.last(#2)}<>4' url: 'https://github.com/openshift/ops-sop/blob/node/V3/Alerts/openshift_node.asciidoc' priority: high @@ -68,5 +68,3 @@ g_template_openshift_node: expression: '{Template Openshift Node:openshift.node.ovs.ports.count.last()}=0' url: 'https://github.com/openshift/ops-sop/blob/node/V3/Alerts/openshift_node.asciidoc' priority: high - - diff --git a/roles/os_zabbix/vars/template_ops_tools.yml b/roles/os_zabbix/vars/template_ops_tools.yml index d1b8a2514..a0a5a4d03 100644 --- a/roles/os_zabbix/vars/template_ops_tools.yml +++ b/roles/os_zabbix/vars/template_ops_tools.yml @@ -21,3 +21,34 @@ g_template_ops_tools: expression: '{Template Operations Tools:disc.ops.runner.command.exitcode[{#OSO_COMMAND}].last()}<>0' url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/check_ops_runner_command.asciidoc' priority: average + + zactions: + - name: 'Remote command for [Heal] triggers' + status: enabled + escalation_time: 60 + conditions_filter: + calculation_type: "and/or" + conditions: + - conditiontype: maintenance status + operator: not in + - conditiontype: trigger name + operator: like + value: "[Heal]" + - conditiontype: trigger value + operator: "=" + value: PROBLEM + operations: + - esc_step_from: 1 + esc_step_to: 1 + esc_period: 0 + operationtype: remote command + opcommand: + command: 'ssh -i /etc/openshift_tools/scriptrunner_id_rsa {{ ozb_scriptrunner_user }}@{{ ozb_scriptrunner_bastion_host }} remote-healer --host \"{HOST.NAME}\" --trigger \"{TRIGGER.NAME}\" --trigger-val \"{TRIGGER.VALUE}\"' + execute_on: "zabbix server" + type: 'custom script' + target_hosts: + - target_type: 'zabbix server' + opconditions: + - conditiontype: 'event acknowledged' + operator: '=' + value: 'not acknowledged' |