diff options
37 files changed, 524 insertions, 130 deletions
diff --git a/.tito/packages/openshift-ansible b/.tito/packages/openshift-ansible index e3f5491cd..bc2fab995 100644 --- a/.tito/packages/openshift-ansible +++ b/.tito/packages/openshift-ansible @@ -1 +1 @@ -3.0.37-1 ./ +3.0.38-1 ./ diff --git a/README_GCE.md b/README_GCE.md index ea673b44d..9439b569e 100644 --- a/README_GCE.md +++ b/README_GCE.md @@ -42,12 +42,17 @@ Create a gce.ini file for GCE Mandatory customization variables (check the values according to your tenant): * zone = europe-west1-d * network = default -* gce_machine_type = n1-standard-2 -* gce_machine_master_type = n1-standard-1 -* gce_machine_node_type = n1-standard-2 -* gce_machine_image = preinstalled-slave-50g-v5 -* gce_machine_master_image = preinstalled-slave-50g-v5 -* gce_machine_node_image = preinstalled-slave-50g-v5 + +Optional Variable Overrides: +* gce_ssh_user - ssh user, defaults to the current logged in user +* gce_machine_type = n1-standard-1 - default machine type +* gce_machine_etcd_type = n1-standard-1 - machine type for etcd hosts +* gce_machine_master_type = n1-standard-1 - machine type for master hosts +* gce_machine_node_type = n1-standard-1 - machine type for node hosts +* gce_machine_image = centos-7 - default image +* gce_machine_etcd_image = centos-7 - image for etcd hosts +* gce_machine_master_image = centos-7 - image for master hosts +* gce_machine_node_image = centos-7 - image for node hosts 1. vi ~/.gce/gce.ini @@ -62,9 +67,9 @@ network = default gce_machine_type = n1-standard-2 gce_machine_master_type = n1-standard-1 gce_machine_node_type = n1-standard-2 -gce_machine_image = preinstalled-slave-50g-v5 -gce_machine_master_image = preinstalled-slave-50g-v5 -gce_machine_node_image = preinstalled-slave-50g-v5 +gce_machine_image = centos-7 +gce_machine_master_image = centos-7 +gce_machine_node_image = centos-7 ``` 1. Define the environment variable GCE_INI_PATH so gce.py can pick it up and bin/cluster can also read it @@ -92,10 +97,15 @@ argument will result in all gce instances being listed) Creating a cluster ------------------ -1. To create a cluster with one master and two nodes +1. To create a cluster with one master, one infra node, and two compute nodes ``` bin/cluster create gce <cluster-id> ``` +1. To create a cluster with 3 masters, 3 etcd hosts, 2 infra nodes and 10 +compute nodes +``` + bin/cluster create gce -m 3 -e 3 -i 2 -n 10 <cluster-id> +``` Updating a cluster --------------------- @@ -104,6 +114,16 @@ Updating a cluster bin/cluster update gce <cluster-id> ``` +Add additional nodes +--------------------- +1. To add additional infra nodes +``` + bin/cluster add-nodes gce -i <num nodes> <cluster-id> +``` +1. To add additional compute nodes +``` + bin/cluster add-nodes gce -n <num nodes> <cluster-id> +``` Terminating a cluster --------------------- 1. To terminate the cluster diff --git a/inventory/byo/hosts.aep.example b/inventory/byo/hosts.aep.example index 04cbd004f..253aa464e 100644 --- a/inventory/byo/hosts.aep.example +++ b/inventory/byo/hosts.aep.example @@ -74,7 +74,7 @@ deployment_type=atomic-enterprise #openshift_additional_repos=[{'id': 'aep-devel', 'name': 'aep-devel', 'baseurl': 'http://example.com/puddle/build/AtomicOpenShift/3.1/latest/RH7-RHOSE-3.0/$basearch/os', 'enabled': 1, 'gpgcheck': 0}] # htpasswd auth -openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', 'challenge': 'true', 'kind': 'HTPasswdPasswordIdentityProvider', 'filename': '/etc/origin/htpasswd'}] +openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', 'challenge': 'true', 'kind': 'HTPasswdPasswordIdentityProvider', 'filename': '/etc/origin/master/htpasswd'}] # Allow all auth #openshift_master_identity_providers=[{'name': 'allow_all', 'login': 'true', 'challenge': 'true', 'kind': 'AllowAllPasswordIdentityProvider'}] diff --git a/inventory/byo/hosts.origin.example b/inventory/byo/hosts.origin.example index 78e84740d..6f6a9e9d7 100644 --- a/inventory/byo/hosts.origin.example +++ b/inventory/byo/hosts.origin.example @@ -79,7 +79,7 @@ deployment_type=origin #openshift_additional_repos=[{'id': 'fedora-openshift-origin-copr', 'name': 'OpenShift Origin COPR for Fedora', 'baseurl': 'https://copr-be.cloud.fedoraproject.org/results/maxamillion/fedora-openshift/fedora-$releasever-$basearch/', 'enabled': 1, 'gpgcheck': 1, gpgkey: 'https://copr-be.cloud.fedoraproject.org/results/maxamillion/fedora-openshift/pubkey.gpg'}] # htpasswd auth -openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', 'challenge': 'true', 'kind': 'HTPasswdPasswordIdentityProvider', 'filename': '/etc/origin/htpasswd'}] +openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', 'challenge': 'true', 'kind': 'HTPasswdPasswordIdentityProvider', 'filename': '/etc/origin/master/htpasswd'}] # Allow all auth #openshift_master_identity_providers=[{'name': 'allow_all', 'login': 'true', 'challenge': 'true', 'kind': 'AllowAllPasswordIdentityProvider'}] diff --git a/inventory/byo/hosts.ose.example b/inventory/byo/hosts.ose.example index 5f9c3eeef..6d2059333 100644 --- a/inventory/byo/hosts.ose.example +++ b/inventory/byo/hosts.ose.example @@ -74,7 +74,7 @@ deployment_type=openshift-enterprise #openshift_additional_repos=[{'id': 'ose-devel', 'name': 'ose-devel', 'baseurl': 'http://example.com/puddle/build/AtomicOpenShift/3.1/latest/RH7-RHOSE-3.0/$basearch/os', 'enabled': 1, 'gpgcheck': 0}] # htpasswd auth -openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', 'challenge': 'true', 'kind': 'HTPasswdPasswordIdentityProvider', 'filename': '/etc/origin/htpasswd'}] +openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', 'challenge': 'true', 'kind': 'HTPasswdPasswordIdentityProvider', 'filename': '/etc/origin/master/htpasswd'}] # Allow all auth #openshift_master_identity_providers=[{'name': 'allow_all', 'login': 'true', 'challenge': 'true', 'kind': 'AllowAllPasswordIdentityProvider'}] diff --git a/openshift-ansible.spec b/openshift-ansible.spec index 051a6d966..218c714f5 100644 --- a/openshift-ansible.spec +++ b/openshift-ansible.spec @@ -5,7 +5,7 @@ } Name: openshift-ansible -Version: 3.0.37 +Version: 3.0.38 Release: 1%{?dist} Summary: Openshift and Atomic Enterprise Ansible License: ASL 2.0 @@ -259,6 +259,30 @@ Atomic OpenShift Utilities includes %changelog +* Tue Feb 02 2016 Brenton Leanhardt <bleanhar@redhat.com> 3.0.38-1 +- aoi: Ask for osm_default_subdomain in interactive mode (smunilla@redhat.com) +- add item to hold number of stray OVS rules found/removed (jdiaz@redhat.com) +- changed adhoc playbook to match new host monitoring container + (mwoodson@redhat.com) +- Multi-master fixes for provider playbooks (jdetiber@redhat.com) +- zabbix: added master local api items and triggers (mwoodson@redhat.com) +- Added docs around oo_nodes_with_label (jdetiber@redhat.com) +- fix for terminate (jdetiber@redhat.com) +- Fix node tags for aws provider (jdetiber@redhat.com) +- use yaml for loading lable info instead of json (jdetiber@redhat.com) +- infra_node fixes (jdetiber@redhat.com) +- removing extraneous comments (rharriso@redhat.com) +- Remove commented lines and fix pylint check (rharriso@redhat.com) +- Cleaning up the dyn ansible module for merging (rharriso@redhat.com) +- Fix missing bool filter (sdodson@redhat.com) +- Sync platest imagestreams (sdodson@redhat.com) +- Fixing last pylint error (rharriso@redhat.com) +- Fix hostname for aws cloud provider (jdetiber@redhat.com) +- Fixing pylint errors (rharriso@redhat.com) +- Give openvswitch container some time to start (jprovazn@redhat.com) +- s3_registry no filter named 'lookup' (florian.lambert@enovance.com) +- WIP adding the lib_dyn role for the dyn_record module (rharriso@redhat.com) + * Fri Jan 29 2016 Kenny Woodson <kwoodson@redhat.com> 3.0.37-1 - Adding ip address option (kwoodson@redhat.com) - Enable cockpit when not is_atomic. (abutcher@redhat.com) diff --git a/playbooks/adhoc/docker_storage_cleanup/docker_storage_cleanup.yml b/playbooks/adhoc/docker_storage_cleanup/docker_storage_cleanup.yml index a19291a9f..b6dde357e 100644 --- a/playbooks/adhoc/docker_storage_cleanup/docker_storage_cleanup.yml +++ b/playbooks/adhoc/docker_storage_cleanup/docker_storage_cleanup.yml @@ -57,7 +57,7 @@ # leaving off the '-t' for docker exec. With it, it doesn't work with ansible and tty support - name: update zabbix docker items - command: docker exec -i oso-rhel7-zagg-client /usr/local/bin/cron-send-docker-metrics.py + command: docker exec -i oso-rhel7-host-monitoring /usr/local/bin/cron-send-docker-metrics.py # Get and show docker info again. - name: Get docker info diff --git a/playbooks/adhoc/s3_registry/s3_registry.yml b/playbooks/adhoc/s3_registry/s3_registry.yml index 0814efae2..38ce92e92 100644 --- a/playbooks/adhoc/s3_registry/s3_registry.yml +++ b/playbooks/adhoc/s3_registry/s3_registry.yml @@ -14,7 +14,7 @@ aws_access_key: "{{ lookup('env', 'S3_ACCESS_KEY_ID') }}" aws_secret_key: "{{ lookup('env', 'S3_SECRET_ACCESS_KEY') }}" aws_bucket_name: "{{ aws_bucket | default(clusterid ~ '-docker') }}" - aws_bucket_region: "{{ aws_region | lookup('env', 'S3_REGION') | default('us-east-1') }}" + aws_bucket_region: "{{ aws_region | default(lookup('env', 'S3_REGION') | default('us-east-1', true)) }}" tasks: diff --git a/playbooks/aws/openshift-cluster/config.yml b/playbooks/aws/openshift-cluster/config.yml index 34dfbaa1e..9f077bfc2 100644 --- a/playbooks/aws/openshift-cluster/config.yml +++ b/playbooks/aws/openshift-cluster/config.yml @@ -9,9 +9,9 @@ openshift_cluster_id: "{{ cluster_id }}" openshift_debug_level: "{{ debug_level }}" openshift_deployment_type: "{{ deployment_type }}" - openshift_hostname: "{{ ec2_private_ip_address }}" openshift_public_hostname: "{{ ec2_ip_address }}" openshift_registry_selector: 'type=infra' openshift_router_selector: 'type=infra' openshift_infra_nodes: "{{ g_infra_hosts }}" openshift_node_labels: '{"region": "{{ ec2_region }}", "type": "{{ hostvars[inventory_hostname]["ec2_tag_sub-host-type"] if inventory_hostname in groups["tag_host-type_node"] else hostvars[inventory_hostname]["ec2_tag_host-type"] }}"}' + openshift_master_cluster_method: 'native' diff --git a/playbooks/aws/openshift-cluster/scaleup.yml b/playbooks/aws/openshift-cluster/scaleup.yml index c2135cd03..7e3a47964 100644 --- a/playbooks/aws/openshift-cluster/scaleup.yml +++ b/playbooks/aws/openshift-cluster/scaleup.yml @@ -29,5 +29,4 @@ openshift_cluster_id: "{{ cluster_id }}" openshift_debug_level: "{{ debug_level }}" openshift_deployment_type: "{{ deployment_type }}" - openshift_hostname: "{{ ec2_private_ip_address }}" openshift_public_hostname: "{{ ec2_ip_address }}" diff --git a/playbooks/byo/openshift-cluster/cluster_hosts.yml b/playbooks/byo/openshift-cluster/cluster_hosts.yml index e093b2580..10872e738 100644 --- a/playbooks/byo/openshift-cluster/cluster_hosts.yml +++ b/playbooks/byo/openshift-cluster/cluster_hosts.yml @@ -7,6 +7,8 @@ g_master_hosts: "{{ groups.masters | default([]) }}" g_node_hosts: "{{ groups.nodes | default([]) }}" +g_new_node_hosts: "{{ groups.new_nodes | default([]) }}" + g_nfs_hosts: "{{ groups.nfs | default([]) }}" g_all_hosts: "{{ g_master_hosts | union(g_node_hosts) | union(g_etcd_hosts) diff --git a/playbooks/common/openshift-cluster/evaluate_groups.yml b/playbooks/common/openshift-cluster/evaluate_groups.yml index db7105ed5..7917bfba5 100644 --- a/playbooks/common/openshift-cluster/evaluate_groups.yml +++ b/playbooks/common/openshift-cluster/evaluate_groups.yml @@ -47,7 +47,7 @@ # Use g_new_node_hosts if it exists otherwise g_node_hosts - set_fact: - g_node_hosts_to_config: "{{ g_new_node_hosts | default(g_node_hosts | default([])) }}" + g_node_hosts_to_config: "{{ g_new_node_hosts | default(g_node_hosts | default([], true), true) }}" - name: Evaluate oo_nodes_to_config add_host: diff --git a/playbooks/common/openshift-etcd/config.yml b/playbooks/common/openshift-etcd/config.yml index d23a54511..93eb157cb 100644 --- a/playbooks/common/openshift-etcd/config.yml +++ b/playbooks/common/openshift-etcd/config.yml @@ -69,8 +69,32 @@ validate_checksum: yes with_items: etcd_needing_server_certs -- name: Configure etcd hosts - hosts: oo_etcd_to_config +# Configure a first etcd host to avoid conflicts in choosing a leader +# if other members come online too quickly. +- name: Configure first etcd host + hosts: oo_first_etcd + vars: + sync_tmpdir: "{{ hostvars.localhost.g_etcd_mktemp.stdout }}" + etcd_url_scheme: https + etcd_peer_url_scheme: https + etcd_peers_group: oo_etcd_to_config + pre_tasks: + - name: Ensure certificate directory exists + file: + path: "{{ etcd_cert_config_dir }}" + state: directory + - name: Unarchive the tarball on the etcd host + unarchive: + src: "{{ sync_tmpdir }}/{{ etcd_cert_subdir }}.tgz" + dest: "{{ etcd_cert_config_dir }}" + when: etcd_server_certs_missing + roles: + - etcd + - role: nickhammond.logrotate + +# Configure the remaining etcd hosts, skipping the first one we dealt with above. +- name: Configure remaining etcd hosts + hosts: oo_etcd_to_config:!oo_first_etcd vars: sync_tmpdir: "{{ hostvars.localhost.g_etcd_mktemp.stdout }}" etcd_url_scheme: https diff --git a/playbooks/common/openshift-node/config.yml b/playbooks/common/openshift-node/config.yml index 81ec9ab6d..e07de0e99 100644 --- a/playbooks/common/openshift-node/config.yml +++ b/playbooks/common/openshift-node/config.yml @@ -80,6 +80,7 @@ when: etcd_client_flannel_certs_missing is defined and etcd_client_flannel_certs_missing roles: - role: etcd_certificates + when: openshift_use_flannel | default(false) | bool post_tasks: - name: Create a tarball of the etcd flannel certs command: > diff --git a/playbooks/gce/openshift-cluster/add_nodes.yml b/playbooks/gce/openshift-cluster/add_nodes.yml new file mode 100644 index 000000000..765e03fdc --- /dev/null +++ b/playbooks/gce/openshift-cluster/add_nodes.yml @@ -0,0 +1,43 @@ +--- +- name: Launch instance(s) + hosts: localhost + connection: local + become: no + gather_facts: no + vars_files: + - vars.yml + vars: + oo_extend_env: True + tasks: + - fail: + msg: Deployment type not supported for gce provider yet + when: deployment_type == 'enterprise' + + - include: ../../common/openshift-cluster/tasks/set_node_launch_facts.yml + vars: + type: "compute" + count: "{{ num_nodes }}" + - include: tasks/launch_instances.yml + vars: + instances: "{{ node_names }}" + cluster: "{{ cluster_id }}" + type: "{{ k8s_type }}" + g_sub_host_type: "{{ sub_host_type }}" + gce_machine_type: "{{ lookup('env', 'gce_machine_node_type') | default(lookup('env', 'gce_machine_type'), true) }}" + gce_machine_image: "{{ lookup('env', 'gce_machine_node_image') | default(lookup('env', 'gce_machine_image'), true) }}" + + - include: ../../common/openshift-cluster/tasks/set_node_launch_facts.yml + vars: + type: "infra" + count: "{{ num_infra }}" + - include: tasks/launch_instances.yml + vars: + instances: "{{ node_names }}" + cluster: "{{ cluster_id }}" + type: "{{ k8s_type }}" + g_sub_host_type: "{{ sub_host_type }}" + gce_machine_type: "{{ lookup('env', 'gce_machine_node_type') | default(lookup('env', 'gce_machine_type'), true) }}" + gce_machine_image: "{{ lookup('env', 'gce_machine_node_image') | default(lookup('env', 'gce_machine_image'), true) }}" + +- include: scaleup.yml +- include: list.yml diff --git a/playbooks/gce/openshift-cluster/config.yml b/playbooks/gce/openshift-cluster/config.yml index 089b1db32..834164bab 100644 --- a/playbooks/gce/openshift-cluster/config.yml +++ b/playbooks/gce/openshift-cluster/config.yml @@ -1,6 +1,4 @@ --- -# TODO: fix firewall related bug with GCE and origin, since GCE is overriding -# /etc/sysconfig/iptables - include: ../../common/openshift-cluster/config.yml vars_files: - ../../gce/openshift-cluster/vars.yml @@ -16,3 +14,4 @@ openshift_registry_selector: 'type=infra' openshift_router_selector: 'type=infra' openshift_infra_nodes: "{{ g_infra_hosts }}" + openshift_master_cluster_method: 'native' diff --git a/playbooks/gce/openshift-cluster/join_node.yml b/playbooks/gce/openshift-cluster/join_node.yml deleted file mode 100644 index 75343dffa..000000000 --- a/playbooks/gce/openshift-cluster/join_node.yml +++ /dev/null @@ -1,51 +0,0 @@ ---- -- name: Populate oo_hosts_to_update group - hosts: localhost - connection: local - become: no - gather_facts: no - vars_files: - - vars.yml - - cluster_hosts.yml - tasks: - - name: Evaluate oo_hosts_to_update - add_host: - name: "{{ node_ip }}" - groups: oo_hosts_to_update - ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" - -- include: ../../common/openshift-cluster/update_repos_and_packages.yml - -- name: Populate oo_masters_to_config host group - hosts: localhost - connection: local - become: no - gather_facts: no - vars_files: - - vars.yml - - cluster_hosts.yml - tasks: - - name: Evaluate oo_nodes_to_config - add_host: - name: "{{ node_ip }}" - ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" - groups: oo_nodes_to_config - - - name: Evaluate oo_first_master - add_host: - name: "{{ master_hosts | first }}" - ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" - groups: oo_first_master - when: master_hosts is defined and master_hosts|length > 0 - -#- include: config.yml -- include: ../../common/openshift-node/config.yml - vars: - openshift_cluster_id: "{{ cluster_id }}" - openshift_debug_level: 4 - openshift_deployment_type: "{{ deployment_type }}" - openshift_hostname: "{{ ansible_default_ipv4.address }}" - openshift_node_labels: "{{ lookup('oo_option', 'openshift_node_labels') }} " diff --git a/playbooks/gce/openshift-cluster/launch.yml b/playbooks/gce/openshift-cluster/launch.yml index 562bf8d29..7532a678b 100644 --- a/playbooks/gce/openshift-cluster/launch.yml +++ b/playbooks/gce/openshift-cluster/launch.yml @@ -10,6 +10,17 @@ - fail: msg="Deployment type not supported for gce provider yet" when: deployment_type == 'enterprise' + - include: ../../common/openshift-cluster/tasks/set_etcd_launch_facts.yml + - include: tasks/launch_instances.yml + vars: + instances: "{{ etcd_names }}" + cluster: "{{ cluster_id }}" + type: "{{ k8s_type }}" + g_sub_host_type: "default" + gce_machine_type: "{{ lookup('env', 'gce_machine_etcd_type') | default(lookup('env', 'gce_machine_type'), true) }}" + gce_machine_image: "{{ lookup('env', 'gce_machine_etcd_image') | default(lookup('env', 'gce_machine_image'), true) }}" + + - include: ../../common/openshift-cluster/tasks/set_master_launch_facts.yml - include: tasks/launch_instances.yml vars: @@ -43,6 +54,8 @@ cluster: "{{ cluster_id }}" type: "{{ k8s_type }}" g_sub_host_type: "{{ sub_host_type }}" + gce_machine_type: "{{ lookup('env', 'gce_machine_node_type') | default(lookup('env', 'gce_machine_type'), true) }}" + gce_machine_image: "{{ lookup('env', 'gce_machine_node_image') | default(lookup('env', 'gce_machine_image'), true) }}" - add_host: name: "{{ master_names.0 }}" @@ -50,17 +63,5 @@ when: master_names is defined and master_names.0 is defined - include: update.yml -# -#- name: Deploy OpenShift Services -# hosts: service_master -# connection: ssh -# gather_facts: yes -# roles: -# - openshift_registry -# - openshift_router -# -#- include: ../../common/openshift-cluster/create_services.yml -# vars: -# g_svc_master: "{{ service_master }}" - include: list.yml diff --git a/playbooks/gce/openshift-cluster/list.yml b/playbooks/gce/openshift-cluster/list.yml index e67685912..f3004ede9 100644 --- a/playbooks/gce/openshift-cluster/list.yml +++ b/playbooks/gce/openshift-cluster/list.yml @@ -14,7 +14,7 @@ - add_host: name: "{{ item }}" groups: oo_list_hosts - ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user | default(ansible_ssh_user, true) }}" + ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" with_items: groups[scratch_group] | default([], true) | difference(['localhost']) | difference(groups.status_terminated | default([], true)) @@ -23,4 +23,4 @@ gather_facts: no tasks: - debug: - msg: "private ip:{{ hostvars[inventory_hostname].gce_private_ip }}" + msg: "public ip: {{ hostvars[inventory_hostname].gce_public_ip }} private ip:{{ hostvars[inventory_hostname].gce_private_ip }}" diff --git a/playbooks/gce/openshift-cluster/service.yml b/playbooks/gce/openshift-cluster/service.yml index 8925de4cb..914f38c1f 100644 --- a/playbooks/gce/openshift-cluster/service.yml +++ b/playbooks/gce/openshift-cluster/service.yml @@ -14,14 +14,14 @@ - add_host: name: "{{ item }}" groups: g_service_nodes - ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user | default(ansible_ssh_user, true) }}" + ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" with_items: "{{ node_hosts | default([]) | difference(['localhost']) | difference(groups.status_terminated) }}" - add_host: name: "{{ item }}" groups: g_service_masters - ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user | default(ansible_ssh_user, true) }}" + ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" with_items: "{{ master_hosts | default([]) | difference(['localhost']) | difference(groups.status_terminated) }}" diff --git a/playbooks/gce/openshift-cluster/tasks/launch_instances.yml b/playbooks/gce/openshift-cluster/tasks/launch_instances.yml index 488b62eb9..8ebf71cd4 100644 --- a/playbooks/gce/openshift-cluster/tasks/launch_instances.yml +++ b/playbooks/gce/openshift-cluster/tasks/launch_instances.yml @@ -1,7 +1,4 @@ --- -# TODO: when we are ready to go to ansible 1.9+ support only, we can update to -# the gce task to use the disk_auto_delete parameter to avoid having to delete -# the disk as a separate step on termination - name: Launch instance(s) gce: instance_names: "{{ instances }}" @@ -41,7 +38,7 @@ add_host: hostname: "{{ item.name }}" ansible_ssh_host: "{{ item.public_ip }}" - ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user | default(ansible_ssh_user, true) }}" + ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" groups: "{{ item.tags | oo_prepend_strings_in_list('tag_') | join(',') }}" gce_public_ip: "{{ item.public_ip }}" diff --git a/playbooks/gce/openshift-cluster/terminate.yml b/playbooks/gce/openshift-cluster/terminate.yml index faa46c0d6..94b4ab14b 100644 --- a/playbooks/gce/openshift-cluster/terminate.yml +++ b/playbooks/gce/openshift-cluster/terminate.yml @@ -10,7 +10,7 @@ - add_host: name: "{{ item }}" groups: oo_hosts_to_terminate - ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user | default(ansible_ssh_user, true) }}" + ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" with_items: (groups['tag_clusterid-' ~ cluster_id] | default([])) | difference(['localhost']) diff --git a/playbooks/gce/openshift-cluster/update.yml b/playbooks/gce/openshift-cluster/update.yml index dadceae58..2dc540978 100644 --- a/playbooks/gce/openshift-cluster/update.yml +++ b/playbooks/gce/openshift-cluster/update.yml @@ -12,7 +12,7 @@ add_host: name: "{{ item }}" groups: oo_hosts_to_update - ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user | default(ansible_ssh_user, true) }}" + ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" with_items: "{{ g_all_hosts | default([]) }}" diff --git a/playbooks/gce/openshift-cluster/vars.yml b/playbooks/gce/openshift-cluster/vars.yml index f004a9e6b..1ae73fd68 100644 --- a/playbooks/gce/openshift-cluster/vars.yml +++ b/playbooks/gce/openshift-cluster/vars.yml @@ -4,14 +4,14 @@ debug_level: 2 deployment_rhel7_ent_base: image: rhel-7 machine_type: n1-standard-1 - ssh_user: + ssh_user: "{{ lookup('env', 'gce_ssh_user') | default(ansible_ssh_user, true) }}" sudo: yes deployment_vars: origin: - image: preinstalled-slave-50g-v5 + image: centos-7 machine_type: n1-standard-1 - ssh_user: root + ssh_user: "{{ lookup('env', 'gce_ssh_user') | default(ansible_ssh_user, true) }}" sudo: yes online: image: libra-rhel7 diff --git a/playbooks/gce/openshift-cluster/wip.yml b/playbooks/gce/openshift-cluster/wip.yml deleted file mode 100644 index 0e3757546..000000000 --- a/playbooks/gce/openshift-cluster/wip.yml +++ /dev/null @@ -1,27 +0,0 @@ ---- -- name: WIP - hosts: localhost - become: no - connection: local - gather_facts: no - vars_files: - - vars.yml - tasks: - - name: Evaluate oo_masters_for_deploy - add_host: - name: "{{ item }}" - groups: oo_masters_for_deploy - ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user | default(ansible_ssh_user, true) }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" - with_items: "{{ g_master_hosts | default([]) }}" - -- name: Deploy OpenShift Services - hosts: oo_masters_for_deploy - connection: ssh - gather_facts: yes - user: root - vars_files: - - vars.yml - roles: - - openshift_registry - - openshift_router diff --git a/playbooks/libvirt/openshift-cluster/config.yml b/playbooks/libvirt/openshift-cluster/config.yml index 61791c86f..6b327f7d0 100644 --- a/playbooks/libvirt/openshift-cluster/config.yml +++ b/playbooks/libvirt/openshift-cluster/config.yml @@ -16,3 +16,4 @@ openshift_registry_selector: 'type=infra' openshift_router_selector: 'type=infra' openshift_infra_nodes: "{{ g_infra_hosts }}" + openshift_master_cluster_method: 'native' diff --git a/playbooks/openstack/openshift-cluster/config.yml b/playbooks/openstack/openshift-cluster/config.yml index cd920d2b9..e09a72ae1 100644 --- a/playbooks/openstack/openshift-cluster/config.yml +++ b/playbooks/openstack/openshift-cluster/config.yml @@ -14,3 +14,4 @@ openshift_registry_selector: 'type=infra' openshift_router_selector: 'type=infra' openshift_infra_nodes: "{{ g_infra_hosts }}" + openshift_master_cluster_method: 'native' diff --git a/roles/etcd_common/tasks/main.yml b/roles/etcd_common/tasks/main.yml index cd108495d..be75fdab2 100644 --- a/roles/etcd_common/tasks/main.yml +++ b/roles/etcd_common/tasks/main.yml @@ -5,9 +5,9 @@ - fail: msg: "Interface {{ item.value.etcd_interface }} not found on host {{ item.key }}" when: "'etcd_interface' in item.value and 'interface' not in item.value" - with_dict: etcd_host_int_map + with_dict: etcd_host_int_map | default({}) - fail: msg: IPv4 address not found for {{ item.value.interface.device }} on host {{ item.key }} when: "'ipv4' not in item.value.interface or 'address' not in item.value.interface.ipv4" - with_dict: etcd_host_int_map + with_dict: etcd_host_int_map | default({}) diff --git a/roles/lib_dyn/README.md b/roles/lib_dyn/README.md new file mode 100644 index 000000000..1eec9f81c --- /dev/null +++ b/roles/lib_dyn/README.md @@ -0,0 +1,27 @@ +lib_dyn +========= + +A role containing the dyn_record module for managing DNS records through Dyn's +API + +Requirements +------------ + +The module requires the `dyn` python module for interacting with the Dyn API. +https://github.com/dyninc/dyn-python + +Example Playbook +---------------- + +To make sure the `dyn_record` module is available for use include the role +before it is used. + + - hosts: servers + roles: + - lib_dyn + +License +------- + +Apache + diff --git a/roles/lib_dyn/library/dyn_record.py b/roles/lib_dyn/library/dyn_record.py new file mode 100644 index 000000000..5e088a674 --- /dev/null +++ b/roles/lib_dyn/library/dyn_record.py @@ -0,0 +1,269 @@ +#!/usr/bin/python +# +# (c) 2015, Russell Harrison <rharriso@redhat.com> +# +# 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. +'''Ansible module to manage records in the Dyn Managed DNS service''' +DOCUMENTATION = ''' +--- +module: dyn_record +version_added: "1.9" +short_description: Manage records in the Dyn Managed DNS service. +description: + - "Manages DNS records via the REST API of the Dyn Managed DNS service. It + - "handles records only; there is no manipulation of zones or account support" + - "yet. See: U(https://help.dyn.com/dns-api-knowledge-base/)" +options: + state: + description: + -"Whether the record should be c(present) or c(absent). Optionally the" + - "state c(list) can be used to return the current value of a record." + required: true + choices: [ 'present', 'absent', 'list' ] + default: present + + customer_name: + description: + - "The Dyn customer name for your account. If not set the value of the" + - "c(DYNECT_CUSTOMER_NAME) environment variable is used." + required: false + default: nil + + user_name: + description: + - "The Dyn user name to log in with. If not set the value of the" + - "c(DYNECT_USER_NAME) environment variable is used." + required: false + default: null + + user_password: + description: + - "The Dyn user's password to log in with. If not set the value of the" + - "c(DYNECT_PASSWORD) environment variable is used." + required: false + default: null + + zone: + description: + - "The DNS zone in which your record is located." + required: true + default: null + + record_fqdn: + description: + - "Fully qualified domain name of the record name to get, create, delete," + - "or update." + required: true + default: null + + record_type: + description: + - "Record type." + required: true + choices: [ 'A', 'AAAA', 'CNAME', 'PTR', 'TXT' ] + default: null + + record_value: + description: + - "Record value. If record_value is not specified; no changes will be" + - "made and the module will fail" + required: false + default: null + + record_ttl: + 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.' + required: false + default: 0 + +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. + +requirements: [ dyn ] +author: "Russell Harrison" +''' + +try: + IMPORT_ERROR = False + from dyn.tm.session import DynectSession + from dyn.tm.zones import Zone + import dyn.tm.errors + import os + +except ImportError as error: + IMPORT_ERROR = str(error) + +# Each of the record types use a different method for the value. +RECORD_PARAMS = { + 'A' : {'value_param': 'address'}, + 'AAAA' : {'value_param': 'address'}, + 'CNAME' : {'value_param': 'cname'}, + 'PTR' : {'value_param': 'ptrdname'}, + 'TXT' : {'value_param': 'txtdata'} +} + +# You'll notice that the value_param doesn't match the key (records_key) +# in the dict returned from Dyn when doing a dyn_node.get_all_records() +# This is a frustrating lookup dict to allow mapping to the RECORD_PARAMS +# dict so we can lookup other values in it efficiently + +def get_record_type(record_key): + '''Get the record type represented by the keys returned from get_any_records.''' + 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.''' + return record_type.lower() + '_records' + +def get_any_records(module, node): + '''Get any records for a given node''' + # Lets get a list of the A records for the node + try: + records = node.get_any_records() + except dyn.tm.errors.DynectGetError as error: + if 'Not in zone' in str(error): + # The node isn't in the zone so we'll return an empty dictionary + return {} + else: + # An unknown error happened so we'll need to return it. + module.fail_json(msg='Unable to get records', + error=str(error)) + + # Return a dictionary of the record objects + return records + +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 + 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]] + return ret_dict + +def main(): + '''Ansible module for managing Dyn DNS records.''' + module = AnsibleModule( + argument_spec=dict( + state=dict(required=True, choices=['present', 'absent', 'list']), + customer_name=dict(default=os.environ.get('DYNECT_CUSTOMER_NAME', None), type='str'), + user_name=dict(default=os.environ.get('DYNECT_USER_NAME', None), type='str', no_log=True), + user_password=dict(default=os.environ.get('DYNECT_PASSWORD', None), type='str', no_log=True), + zone=dict(required=True), + record_fqdn=dict(required=False), + record_type=dict(required=False, choices=[ + 'A', 'AAAA', 'CNAME', 'PTR', 'TXT']), + record_value=dict(required=False), + record_ttl=dict(required=False, default=0, type='int'), + ), + required_together=( + ['record_fqdn', 'record_value', 'record_ttl', 'record_type'] + ) + ) + + if IMPORT_ERROR: + module.fail_json(msg="Unable to import dyn module: https://pypi.python.org/pypi/dyn", + error=IMPORT_ERROR) + + # Start the Dyn session + try: + _ = DynectSession(module.params['customer_name'], + 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)) + + # 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'] + ) + else: + 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'], '') + + # Retrieve the zone object from dyn + dyn_zone = Zone(module.params['zone']) + + # Retrieve the node object from dyn + dyn_node = dyn_zone.get_node(node=dyn_node_name) + + # All states will need a list of the exiting records for the zone. + dyn_node_records = get_any_records(module, dyn_node) + + if module.params['state'] == 'list': + module.exit_json(changed=False, + records=get_record_values( + dyn_node_records, + )) + + if module.params['state'] == 'present': + + # 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']) + + # 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 + module.params['record_value'] in values[value_key]): + + module.exit_json(changed=False) + + + # Working on the assumption that there is only one record per + # node we will first delete the node if there are any records before + # creating the correct record + if dyn_node_records: + 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'] + ) + + # 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) + +# 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 +from ansible.module_utils.basic import * +if __name__ == '__main__': + main() diff --git a/roles/lib_dyn/meta/main.yml b/roles/lib_dyn/meta/main.yml new file mode 100644 index 000000000..5475c6971 --- /dev/null +++ b/roles/lib_dyn/meta/main.yml @@ -0,0 +1,33 @@ +--- +galaxy_info: + author: Russell Harrison + description: A role to provide the dyn_record module + company: Red Hat, Inc. + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + license: Apache + min_ansible_version: 1.9 + platforms: + - name: EL + versions: + - 7 + #- name: Fedora + # versions: + # - 19 + # - 20 + # - 21 + # - 22 + # Below are all categories currently available. Just as with + # the platforms above, uncomment those that apply to your role. + categories: + - networking +dependencies: [] + # List your role dependencies here, one per line. + # Be sure to remove the '[]' above if you add dependencies + # to this list. + # + # No role dependencies at this time. The module contained in this role does + # require the dyn python module. + # https://pypi.python.org/pypi/dyn + diff --git a/roles/lib_dyn/tasks/main.yml b/roles/lib_dyn/tasks/main.yml new file mode 100644 index 000000000..9b3b1b0b9 --- /dev/null +++ b/roles/lib_dyn/tasks/main.yml @@ -0,0 +1,5 @@ +--- +# tasks file for lib_dyn + +- name: Make sure python-dyn is installed + yum: name=python-dyn state=present diff --git a/roles/os_zabbix/vars/template_openshift_node.yml b/roles/os_zabbix/vars/template_openshift_node.yml index ce28b1048..ff65ef158 100644 --- a/roles/os_zabbix/vars/template_openshift_node.yml +++ b/roles/os_zabbix/vars/template_openshift_node.yml @@ -20,6 +20,12 @@ g_template_openshift_node: applications: - Openshift Node + - key: openshift.node.ovs.stray.rules + description: Number of OVS stray rules found/removed + type: int + applications: + - Openshift Node + ztriggers: - name: 'Openshift Node process not running on {HOST.NAME}' expression: '{Template Openshift Node:openshift.node.process.count.max(#3)}<1' diff --git a/utils/src/ooinstall/cli_installer.py b/utils/src/ooinstall/cli_installer.py index 1aacf3a4b..3046d4d58 100644 --- a/utils/src/ooinstall/cli_installer.py +++ b/utils/src/ooinstall/cli_installer.py @@ -45,6 +45,15 @@ passwordless sudo access. click.echo(message) return click.prompt('User for ssh access', default='root') +def get_master_routingconfig_subdomain(): + click.clear() + message = """ +You might want to override the default subdomain uses for exposed routes. If you don't know what +this is, use the default value. +""" + click.echo(message) + return click.prompt('New default subdomain (ENTER for none)', default='') + def list_hosts(hosts): hosts_idx = range(len(hosts)) for idx in hosts_idx: @@ -498,6 +507,10 @@ https://docs.openshift.com/enterprise/latest/admin_guide/install/prerequisites.h oo_cfg.hosts = collect_hosts(oo_cfg) click.clear() + if not oo_cfg.settings.get('master_routingconfig_subdomain', None): + oo_cfg.settings['master_routingconfig_subdomain'] = get_master_routingconfig_subdomain() + click.clear() + return oo_cfg diff --git a/utils/src/ooinstall/openshift_ansible.py b/utils/src/ooinstall/openshift_ansible.py index c0d115fdc..cbb6f33e1 100644 --- a/utils/src/ooinstall/openshift_ansible.py +++ b/utils/src/ooinstall/openshift_ansible.py @@ -114,6 +114,9 @@ def write_inventory_vars(base_inventory, multiple_masters, proxy): base_inventory.write('openshift_master_cluster_method=native\n') base_inventory.write("openshift_master_cluster_hostname={}\n".format(proxy.hostname)) base_inventory.write("openshift_master_cluster_public_hostname={}\n".format(proxy.public_hostname)) + if CFG.settings['master_routingconfig_subdomain']: + base_inventory.write("osm_default_subdomain={}\n".format(CFG.settings['master_routingconfig_subdomain'])) + def write_host(host, inventory, schedulable=None): diff --git a/utils/test/cli_installer_tests.py b/utils/test/cli_installer_tests.py index 72e8521d0..baab5d56f 100644 --- a/utils/test/cli_installer_tests.py +++ b/utils/test/cli_installer_tests.py @@ -102,6 +102,7 @@ hosts: QUICKHA_CONFIG = """ variant: %s ansible_ssh_user: root +master_routingconfig_subdomain: example.com hosts: - connect_to: 10.0.0.1 ip: 10.0.0.1 @@ -228,6 +229,7 @@ hosts: QUICKHA_CONFIG_PRECONFIGURED_LB = """ variant: %s ansible_ssh_user: root +master_routingconfig_subdomain: example.com hosts: - connect_to: 10.0.0.1 ip: 10.0.0.1 diff --git a/utils/test/fixture.py b/utils/test/fixture.py index be759578a..1b1c2e5c2 100644 --- a/utils/test/fixture.py +++ b/utils/test/fixture.py @@ -11,6 +11,7 @@ from click.testing import CliRunner SAMPLE_CONFIG = """ variant: %s ansible_ssh_user: root +master_routingconfig_subdomain: example.com hosts: - connect_to: 10.0.0.1 ip: 10.0.0.1 @@ -196,6 +197,8 @@ def build_input(ssh_user=None, hosts=None, variant_num=None, inputs.append(master_lb[0]) inputs.append('y' if master_lb[1] else 'n') + inputs.append('example.com') + # TODO: support option 2, fresh install if add_nodes: if schedulable_masters_ok: @@ -228,4 +231,3 @@ def build_input(ssh_user=None, hosts=None, variant_num=None, ]) return '\n'.join(inputs) - |