├── src ├── cnos-configuration │ ├── library │ ├── README.md │ ├── configure-networking.yaml │ └── roles │ │ └── configure-networking │ │ ├── tasks │ │ └── main.yaml │ │ └── templates │ │ └── configuration.j2 ├── eos-configuration │ ├── roles │ │ ├── networking_setup │ │ │ ├── defaults │ │ │ │ └── main.yaml │ │ │ ├── templates │ │ │ │ ├── eos_vlan.cfg.j2 │ │ │ │ └── eos_intf.cfg.j2 │ │ │ └── tasks │ │ │ │ └── main.yaml │ │ └── enable_eapi_https │ │ │ └── tasks │ │ │ └── main.yml │ ├── vars │ │ └── all.yaml │ └── configure_eos.yaml ├── prerequisites │ ├── roles │ │ ├── openshift_dns │ │ │ ├── templates │ │ │ │ ├── dnsmasq.conf.j2 │ │ │ │ └── hosts.j2 │ │ │ ├── handlers │ │ │ │ └── main.yml │ │ │ ├── vars │ │ │ │ └── main.yml │ │ │ └── tasks │ │ │ │ └── main.yml │ │ ├── rhel_subscribe │ │ │ ├── defaults │ │ │ │ └── main.yaml │ │ │ └── tasks │ │ │ │ ├── os_definition.yml │ │ │ │ └── main.yml │ │ ├── gluster_subscribe │ │ │ ├── defaults │ │ │ │ └── main.yaml │ │ │ └── tasks │ │ │ │ └── main.yml │ │ ├── rhel_unsubscribe │ │ │ └── tasks │ │ │ │ └── main.yml │ │ ├── openshift_node_preparation │ │ │ ├── handlers │ │ │ │ └── main.yml │ │ │ └── tasks │ │ │ │ ├── os_definition.yml │ │ │ │ └── main.yml │ │ ├── openshift_remote_access_master │ │ │ └── tasks │ │ │ │ └── main.yml │ │ ├── openshift_remote_access_slaves │ │ │ └── tasks │ │ │ │ └── main.yml │ │ └── known_hosts │ │ │ └── tasks │ │ │ └── main.yaml │ └── nodes_setup.yaml ├── ipxe-deployer │ ├── roles │ │ ├── deploy_ipxe │ │ │ ├── vars │ │ │ │ └── main.yml │ │ │ ├── defaults │ │ │ │ └── main.yml │ │ │ ├── templates │ │ │ │ ├── main.ipxe.j2 │ │ │ │ ├── nginx_container.service.j2 │ │ │ │ ├── dnsmasq_container.service.j2 │ │ │ │ ├── dnsmasq_c.conf.j2 │ │ │ │ └── reboot.sh │ │ │ ├── files │ │ │ │ ├── dnsmasq │ │ │ │ │ └── Dockerfile │ │ │ │ └── nginx │ │ │ │ │ └── Dockerfile │ │ │ └── tasks │ │ │ │ └── main.yml │ │ ├── configure_ipxe │ │ │ ├── templates │ │ │ │ ├── ipmi.list.txt.j2 │ │ │ │ ├── serial.ipxe.j2 │ │ │ │ └── atomic.ks.j2 │ │ │ └── tasks │ │ │ │ └── main.yml │ │ └── firewall │ │ │ └── tasks │ │ │ └── main.yml │ └── ipxe.yml ├── keepalived-multimaster │ ├── roles │ │ └── keepalived_haproxy │ │ │ ├── templates │ │ │ ├── healthcheck-keepalived.sh.j2 │ │ │ ├── keepalived.service.j2 │ │ │ └── keepalived.cfg.j2 │ │ │ ├── files │ │ │ └── keepalived │ │ │ │ └── Dockerfile │ │ │ ├── defaults │ │ │ └── main.yaml │ │ │ └── tasks │ │ │ └── main.yaml │ └── keepalived.yaml ├── etcd-scaling │ ├── roles │ │ └── etcd_scale │ │ │ ├── handlers │ │ │ └── main.yml │ │ │ ├── vars │ │ │ └── main.yml │ │ │ ├── templates │ │ │ ├── etcd.docker.service │ │ │ └── etcd.conf.j2 │ │ │ ├── tasks │ │ │ ├── rpm.yml │ │ │ ├── container.yml │ │ │ ├── main.yml │ │ │ └── certificates.yml │ │ │ ├── defaults │ │ │ └── main.yml │ │ │ └── library │ │ │ └── delegated_serial_command.py │ ├── README.md │ └── scale.yml └── drbd │ ├── README.md │ ├── roles │ └── deploy_drbd │ │ ├── templates │ │ └── nfs.res.j2 │ │ ├── defaults │ │ └── main.yml │ │ ├── vars │ │ └── main.yml │ │ └── tasks │ │ └── main.yml │ └── drbd.yml ├── .gitmodules ├── README.md ├── hosts.example └── LICENSE /src/cnos-configuration/library: -------------------------------------------------------------------------------- 1 | ansible-cnos/library/ -------------------------------------------------------------------------------- /src/eos-configuration/roles/networking_setup/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | -------------------------------------------------------------------------------- /src/prerequisites/roles/openshift_dns/templates/dnsmasq.conf.j2: -------------------------------------------------------------------------------- 1 | no-hosts 2 | conf-dir=/etc/dnsmasq.d 3 | -------------------------------------------------------------------------------- /src/ipxe-deployer/roles/deploy_ipxe/vars/main.yml: -------------------------------------------------------------------------------- 1 | #--- 2 | host_public_ip: hostvars['{{ item }}']['ipmi'] 3 | -------------------------------------------------------------------------------- /src/eos-configuration/vars/all.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | eos_connection: 3 | transport: eapi 4 | authorize: yes 5 | use_ssl: True 6 | validate_certs: False 7 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/cnos-configuration/ansible-cnos"] 2 | path = src/cnos-configuration/ansible-cnos 3 | url = https://github.com/lenovo/ansible-cnos.git 4 | -------------------------------------------------------------------------------- /src/ipxe-deployer/roles/configure_ipxe/templates/ipmi.list.txt.j2: -------------------------------------------------------------------------------- 1 | {% for host in groups['nodes'] %} 2 | #{{hostvars[host]['serial']}} 3 | {{hostvars[host]['ipmi']}} 4 | {% endfor %} 5 | -------------------------------------------------------------------------------- /src/keepalived-multimaster/roles/keepalived_haproxy/templates/healthcheck-keepalived.sh.j2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | curl -k -H "Accept:application/json" https://127.0.0.1:8443/healthz/ping 4 | -------------------------------------------------------------------------------- /src/prerequisites/roles/openshift_dns/handlers/main.yml: -------------------------------------------------------------------------------- 1 | # handlers file for dnsmasq 2 | --- 3 | - name: restart dnsmasq 4 | systemd: 5 | name: dnsmasq_container 6 | state: restarted 7 | -------------------------------------------------------------------------------- /src/etcd-scaling/roles/etcd_scale/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: restart etcd 4 | service: name={{ etcd_service }} state=restarted 5 | when: not (etcd_service_status_changed | default(false) | bool) 6 | -------------------------------------------------------------------------------- /src/ipxe-deployer/roles/deploy_ipxe/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | root_password: 'openshift' 3 | nginx_image: 'openshift3/nginx' 4 | nginx_image_tag: '1.0_ra' 5 | dnsmasq_image: 'openshift3/dnsmasq' 6 | dnsmasq_image_tag: '1.0_ra' 7 | -------------------------------------------------------------------------------- /src/eos-configuration/roles/networking_setup/templates/eos_vlan.cfg.j2: -------------------------------------------------------------------------------- 1 | {% if external_vlan is defined %} 2 | vlan {{ external_vlan }} 3 | name ocp_public 4 | {% endif %} 5 | 6 | {% if internal_vlan is defined %} 7 | vlan {{ internal_vlan }} 8 | name ocp_internal 9 | {% endif %} 10 | -------------------------------------------------------------------------------- /src/keepalived-multimaster/roles/keepalived_haproxy/files/keepalived/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM registry.access.redhat.com/rhel7 2 | RUN yum -y update && \ 3 | yum -y install keepalived ipset-libs && \ 4 | yum clean all 5 | CMD ["keepalived", "-n", "-P", "-l", "-f", "/etc/keepalived/keepalived.cfg", "-D"] 6 | -------------------------------------------------------------------------------- /src/ipxe-deployer/roles/configure_ipxe/templates/serial.ipxe.j2: -------------------------------------------------------------------------------- 1 | #!ipxe 2 | 3 | set base http://{{ bastion_ip}}/atomic/media 4 | set pxe images/pxeboot 5 | set ks atomic-{{ item }}.ks 6 | 7 | kernel ${base}/${pxe}/vmlinuz initrd=initrd.img ip=dhcp inst.repo=${base} inst.ks=${base}/${ks} 8 | initrd ${base}/${pxe}/initrd.img 9 | boot 10 | -------------------------------------------------------------------------------- /src/drbd/README.md: -------------------------------------------------------------------------------- 1 | **Ansible playbook for DRBD deployment automation** 2 | ansible-playbook drbd.yaml 3 | 4 | DRBD installs on nodes added to [nfs] section in ansible inventory file 5 | 6 | If Your **VG/private interface** differs from the ones in reference architecture then change proper parameters in: 7 | 8 | _defaults/main.yml_ 9 | 10 | _vars/main.yml_ 11 | -------------------------------------------------------------------------------- /src/ipxe-deployer/roles/deploy_ipxe/templates/main.ipxe.j2: -------------------------------------------------------------------------------- 1 | #!ipxe 2 | set base http://{{ bastion_ip }}/ipxe 3 | 4 | echo Configuring network... 5 | isset ${ip} || dhcp || echo DHCP failed 6 | 7 | set url_serial ${base}/serial/${smbios/serial}.ipxe 8 | 9 | echo Trying ${url_serial}... 10 | chain --autofree ${url_serial} || echo FAILED 11 | 12 | echo Trying local boot 13 | -------------------------------------------------------------------------------- /src/ipxe-deployer/roles/deploy_ipxe/files/dnsmasq/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM registry.access.redhat.com/rhel7 2 | MAINTAINER Lukasz Sztachanski 3 | RUN yum -y update && yum -y install dnsmasq && yum clean all 4 | 5 | VOLUME /tftp 6 | VOLUME /etc/dnsmasq.d 7 | 8 | EXPOSE 53 53/udp 67 67/udp 9 | 10 | ENTRYPOINT ["dnsmasq", "-k", "--conf-file=/etc/dnsmasq.conf", "--no-daemon"] 11 | -------------------------------------------------------------------------------- /src/etcd-scaling/roles/etcd_scale/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | etcd_is_containerized: "{{ containerized }}" 3 | etcd_hostname: "{{ openshift_hostname }}" 4 | etcd_ip: "{{ openshift_ip }}" 5 | etcd_cert_subdir: "etcd-{{ openshift_hostname }}" 6 | etcd_cert_prefix: 7 | etcd_cert_config_dir: /etc/etcd 8 | etcd_peer_url_scheme: https 9 | etcd_url_scheme: https 10 | etcd_ca_host: "{{ groups.etcd.0 }}" 11 | jin_initial_cluster: "{{ scale_initial_cluster.stdout_lines[3] }}" 12 | -------------------------------------------------------------------------------- /src/ipxe-deployer/roles/deploy_ipxe/templates/nginx_container.service.j2: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Docker nginx container 3 | Requires=docker.service 4 | After=docker.service 5 | 6 | [Service] 7 | Restart=always 8 | RestartSec=5s 9 | ExecStartPre=-/usr/bin/docker rm -f nginx 10 | ExecStart=/usr/bin/docker run --name nginx -v "/tftp:/opt/rh/rh-nginx110/root/usr/share/nginx/html:ro,z" -p 80:8080 {{ nginx_image }}:{{ nginx_image_tag }} 11 | ExecStop=/usr/bin/docker rm -f nginx 12 | 13 | [Install] 14 | WantedBy=default.target 15 | -------------------------------------------------------------------------------- /src/cnos-configuration/README.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | 1. requires forked [Lenovo-cnos repo](https://github.com/lenovo/ansible-cnos.git). Included as a submodule. 4 | ```$ git submodule init``` 5 | ```$ git submodule update``` 6 | 2. make sure, that you don't have ssh-agent used in this session, or login will fail. 7 | ```$ unset SSH_AUTH_SOCK``` 8 | 3. Install `python-paramiko` in version *2.1.1* or newer. 9 | 4. Execute with appriopriate python path. 10 | ```$ env PYTHONPATH=`pwd`/ansible-cnos/library/ ansible-playbook configure-networking.yaml``` 11 | -------------------------------------------------------------------------------- /src/drbd/roles/deploy_drbd/templates/nfs.res.j2: -------------------------------------------------------------------------------- 1 | resource nfs { 2 | protocol C; 3 | on {{ primary_hostname }} { 4 | device /dev/drbd0; 5 | disk /dev/mapper/{{ vg_name }}-drbd_registry; 6 | address {{ primary_private_address }}:7788; 7 | meta-disk internal; 8 | } 9 | on {{ secondary_hostname }} { 10 | device /dev/drbd0; 11 | disk /dev/mapper/{{ vg_name }}-drbd_registry; 12 | address {{ secondary_private_address }}:7788; 13 | meta-disk internal; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/ipxe-deployer/roles/deploy_ipxe/templates/dnsmasq_container.service.j2: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Docker dnsmasq container 3 | Requires=docker.service 4 | After=docker.service 5 | 6 | [Service] 7 | Restart=always 8 | RestartSec=5s 9 | ExecStartPre=-/usr/bin/docker rm -f dnsmasq 10 | ExecStart=/usr/bin/docker run --name dnsmasq -v "/etc/dnsmasq.d:/etc/dnsmasq.d:ro" -v "/tftp/ipxe:/tftp:ro,z" -v "/etc/dnsmasq_c.conf:/etc/dnsmasq.conf:ro" --cap-add=NET_ADMIN --net=host {{dnsmasq_image}}:{{ dnsmasq_image_tag }} 11 | ExecStop=/usr/bin/docker rm -f dnsmasq 12 | 13 | [Install] 14 | WantedBy=default.target 15 | -------------------------------------------------------------------------------- /src/etcd-scaling/README.md: -------------------------------------------------------------------------------- 1 | **Roles for etcd scaling and management.** 2 | 3 | **scale.yml** - scale etcd cluster basing on new_etcd hosts in OpenShift inventory file 4 | 5 | 6 | ```[OSEv3:children] 7 | 8 | [...] 9 | 10 | new_etcd 11 | [new_etcd] 12 | 13 | etcd-4 openshift_ip=100.64.80.15 openshift_hostname=etcd-4.openshift.com containerized=True 14 | 15 | etcd-5 openshift_ip=100.64.80.16 openshift_hostname=etcd-5.openshift.com containerized=True 16 | ``` 17 | ``` 18 | $ ansible-playbook scale.yml 19 | ``` 20 | 21 | This script assumes that environment has already a functional etcd cluster with at least 3 members. 22 | 23 | -------------------------------------------------------------------------------- /src/keepalived-multimaster/roles/keepalived_haproxy/templates/keepalived.service.j2: -------------------------------------------------------------------------------- 1 | [Unit] 2 | After=docker.service 3 | Requires=docker.service 4 | PartOf=docker.service 5 | 6 | [Service] 7 | ExecStartPre=-/usr/bin/docker rm -f openshift_keepalived 8 | ExecStart=/usr/bin/docker run --name openshift_keepalived --rm -v /etc/keepalived:/etc/keepalived:z,ro --cap-add=NET_ADMIN --net=host -v /dev/log:/dev/log:z -v /lib/modules:/lib/modules:ro {{ keepalived_image }}:{{ keepalived_image_tag }} 9 | ExecStop=/usr/bin/docker stop openshift_keepalived 10 | LimitNOFILE=100000 11 | LimitCORE=infinity 12 | Restart=always 13 | RestartSec=5s 14 | 15 | [Install] 16 | WantedBy=docker.service 17 | -------------------------------------------------------------------------------- /src/etcd-scaling/roles/etcd_scale/templates/etcd.docker.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=The Etcd Server container 3 | After=docker.service 4 | Requires=docker.service 5 | PartOf=docker.service 6 | 7 | [Service] 8 | EnvironmentFile=/etc/etcd/etcd.conf 9 | ExecStartPre=-/usr/bin/docker rm -f {{ etcd_service }} 10 | ExecStart=/usr/bin/docker run --name {{ etcd_service }} --rm -v /var/lib/etcd:/var/lib/etcd:z -v /etc/etcd:/etc/etcd:z --env-file=/etc/etcd/etcd.conf --net=host --entrypoint=/usr/bin/etcd {{ etcd_image }} 11 | ExecStop=/usr/bin/docker stop {{ etcd_service }} 12 | SyslogIdentifier=etcd_container 13 | Restart=always 14 | RestartSec=5s 15 | 16 | [Install] 17 | WantedBy=docker.service 18 | -------------------------------------------------------------------------------- /src/drbd/roles/deploy_drbd/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | vg_name: vg00 16 | -------------------------------------------------------------------------------- /src/drbd/drbd.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017 Intel Corporation 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | - hosts: nfs 15 | gather_facts: yes 16 | roles: 17 | - deploy_drbd 18 | 19 | -------------------------------------------------------------------------------- /src/prerequisites/roles/rhel_subscribe/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | rhel_subscription_pool: '*OpenShift*' 16 | -------------------------------------------------------------------------------- /src/prerequisites/roles/gluster_subscribe/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | gluster_subscription_pool: '*Gluster Storage*' 16 | -------------------------------------------------------------------------------- /src/etcd-scaling/scale.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017 Intel Corporation 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | - hosts: new_etcd 15 | gather_facts: no 16 | roles: 17 | - etcd_scale 18 | serial: 1 19 | 20 | -------------------------------------------------------------------------------- /src/keepalived-multimaster/keepalived.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | - hosts: lb 16 | gather_facts: no 17 | roles: 18 | - keepalived_haproxy 19 | -------------------------------------------------------------------------------- /src/prerequisites/roles/rhel_unsubscribe/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | - name: Remove RedHat subscriptions 16 | redhat_subscription: 17 | state: absent 18 | -------------------------------------------------------------------------------- /src/prerequisites/roles/openshift_node_preparation/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | - name: Restart network 16 | systemd: 17 | name: NetworkManager 18 | state: restarted 19 | -------------------------------------------------------------------------------- /src/etcd-scaling/roles/etcd_scale/tasks/rpm.yml: -------------------------------------------------------------------------------- 1 | - name: Install etcd 2 | action: "{{ ansible_pkg_mgr }} name=etcd state=present" 3 | when: not etcd_is_containerized | bool 4 | 5 | - name: Validate permissions on the config dir 6 | file: 7 | path: "{{ etcd_conf_dir }}" 8 | state: directory 9 | owner: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}" 10 | group: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}" 11 | mode: 0700 12 | 13 | - include: certificates.yml 14 | 15 | - name: Create etcd config file for new instancie 16 | template: 17 | src: etcd.conf.j2 18 | dest: /etc/etcd/etcd.conf 19 | backup: true 20 | 21 | - name: Restart and enable etcd 22 | service: 23 | name: etcd 24 | state: restarted 25 | enabled: yes 26 | register: start_result 27 | -------------------------------------------------------------------------------- /src/keepalived-multimaster/roles/keepalived_haproxy/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | keepalived_priority_start: 100 16 | keepalived_image: "openshift3/keepalived" 17 | keepalived_image_tag: "1.0_ra" 18 | -------------------------------------------------------------------------------- /src/cnos-configuration/configure-networking.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017 Intel Corporation 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | - name: Proceeding with switch configuration 16 | hosts: switches 17 | gather_facts: no 18 | connection: local 19 | roles: 20 | - configure-networking 21 | -------------------------------------------------------------------------------- /src/ipxe-deployer/roles/deploy_ipxe/files/nginx/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM registry.access.redhat.com/rhel7 2 | MAINTAINER Lukasz Sztachanski 3 | RUN yum repolist > /dev/null && \ 4 | yum install -y yum-utils && \ 5 | yum-config-manager --disable \* &> /dev/null && \ 6 | yum-config-manager --enable rhel-server-rhscl-7-rpms && \ 7 | yum-config-manager --enable rhel-7-server-rpms && \ 8 | yum-config-manager --enable rhel-7-server-optional-rpms && \ 9 | yum -y update && \ 10 | yum -y install rh-nginx110.x86_64 && \ 11 | yum clean all && sed -i s/80\ default/8080\ default/ \ 12 | /etc/opt/rh/rh-nginx110/nginx/nginx.conf 13 | 14 | EXPOSE 8080 15 | USER 999 16 | 17 | VOLUME /opt/rh/rh-nginx110/root/usr/share/nginx/html 18 | 19 | ENTRYPOINT [ "/opt/rh/rh-nginx110/root/usr/sbin/nginx", "-g", "daemon off;" ] 20 | -------------------------------------------------------------------------------- /src/eos-configuration/configure_eos.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | - hosts: arista 16 | connection: local 17 | gather_facts: false 18 | roles: 19 | - enable_eapi_https 20 | - networking_setup 21 | vars_files: 22 | - vars/all.yaml 23 | -------------------------------------------------------------------------------- /src/ipxe-deployer/ipxe.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | - hosts: local 16 | connection: local 17 | roles: 18 | - {role: deploy_ipxe, tags: ['run']} 19 | - {role: configure_ipxe, tags: ['config']} 20 | - {role: firewall, tags: ['firewall']} 21 | -------------------------------------------------------------------------------- /src/prerequisites/roles/openshift_dns/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | cluster_hostname: "{{ openshift_master_cluster_hostname }}" 16 | cluster_ip: "{{ openshift_master_cluster_ip }}" 17 | public_hostname: "{{ openshift_master_cluster_public_hostname }}" 18 | -------------------------------------------------------------------------------- /src/prerequisites/roles/rhel_subscribe/tasks/os_definition.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | - set_fact: 16 | os_version: RHEL 17 | 18 | - name: Define OS variant 19 | command: cat /etc/os-release 20 | register: osrelease 21 | 22 | - set_fact: 23 | os_version: atomic 24 | when: osrelease.stdout.find('tomic') != -1 25 | 26 | -------------------------------------------------------------------------------- /src/prerequisites/roles/openshift_node_preparation/tasks/os_definition.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | - set_fact: 16 | os_version: RHEL 17 | 18 | - name: Define os variant 19 | command: cat /etc/os-release 20 | register: osrelease 21 | 22 | - set_fact: 23 | os_version: atomic 24 | when: osrelease.stdout.find('tomic') != -1 25 | 26 | -------------------------------------------------------------------------------- /src/ipxe-deployer/roles/deploy_ipxe/templates/dnsmasq_c.conf.j2: -------------------------------------------------------------------------------- 1 | #dnsmasq.conf 2 | 3 | # include additional configuration files 4 | conf-dir=/etc/dnsmasq.d 5 | 6 | # Speeds up dhcp, but also dangerous where another dhcp server exists 7 | #dhcp-authoritative 8 | 9 | # Log lots of extra information about DHCP transactions. 10 | log-dhcp 11 | 12 | # For debugging purposes, log each DNS query as it passes through dnsmasq. 13 | #log-queries 14 | 15 | 16 | ### tftp options 17 | enable-tftp 18 | tftp-root=/tftp 19 | 20 | ### dns options 21 | 22 | # do not use local /etc/hosts file 23 | no-hosts 24 | 25 | # do not use local /etc/resolv.conf file 26 | no-resolv 27 | 28 | # do not forward queries without domain name 29 | domain-needed 30 | 31 | # forward all queries to following dns 32 | server=8.8.8.8 33 | 34 | ### dhcp options 35 | 36 | dhcp-match=set:ipxe,175 37 | dhcp-boot=tag:!ipxe,ipxe.efi 38 | dhcp-boot=http://{{ bastion_ip }}/ipxe/main.ipxe 39 | dhcp-range={{ dhcp_first_ip }},{{ dhcp_last_ip }} 40 | 41 | # end of config file 42 | -------------------------------------------------------------------------------- /src/prerequisites/roles/openshift_dns/templates/hosts.j2: -------------------------------------------------------------------------------- 1 | #[master/worker private ip] 2 | {% for host in groups['masters'] %} 3 | address=/{{hostvars[host]['openshift_hostname']}}/{{hostvars[host]['inventory_hostname']}}/{{ hostvars[host]['openshift_ip'] }} 4 | {% endfor %} 5 | {% for host in groups['nodes'] %} 6 | address=/{{hostvars[host]['openshift_hostname']}}/{{hostvars[host]['inventory_hostname']}}/{{ hostvars[host]['openshift_ip'] }} 7 | {% endfor %} 8 | {% for host in groups['etcd'] %} 9 | address=/{{hostvars[host]['openshift_hostname']}}/{{hostvars[host]['inventory_hostname']}}/{{ hostvars[host]['openshift_ip'] }} 10 | {% endfor %} 11 | {% for host in groups['lb'] %} 12 | address=/{{hostvars[host]['openshift_hostname']}}/{{hostvars[host]['inventory_hostname']}}/{{ hostvars[host]['openshift_ip'] }} 13 | {% endfor %} 14 | 15 | # [lb private ip] 16 | host-record={{ openshift_master_cluster_hostname }},{{ openshift_master_cluster_ip }} 17 | # [lb public ip] 18 | address=/{{ openshift_master_cluster_public_hostname }}/{{ openshift_master_cluster_public_ip }} 19 | -------------------------------------------------------------------------------- /src/drbd/roles/deploy_drbd/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | drbd_primary_host: "{{ groups.nfs.0 }}" 16 | drbd_secondary_host: "{{ groups.nfs.1 }}" 17 | primary_private_address: "{{ hostvars[groups.nfs.0]['ansible_bond0']['ipv4']['address'] }}" 18 | secondary_private_address: "{{ hostvars[groups.nfs.1]['ansible_bond0']['ipv4']['address'] }}" 19 | primary_hostname: "{{ hostvars[groups.nfs.0]['ansible_fqdn'] }}" 20 | secondary_hostname: "{{ hostvars[groups.nfs.1]['ansible_fqdn'] }}" 21 | -------------------------------------------------------------------------------- /src/eos-configuration/roles/enable_eapi_https/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | - name: Check if eAPI is enabled 16 | wait_for: 17 | host: "{{ansible_host}}" 18 | port: 443 19 | timeout: 1 20 | state: started 21 | register: eapi_listening 22 | ignore_errors: true 23 | 24 | - name: Enabling EAPI https access 25 | eos_eapi: 26 | http: False 27 | https: True 28 | state: started 29 | provider: 30 | transport: cli 31 | authorize: yes 32 | when: eapi_listening|failed 33 | -------------------------------------------------------------------------------- /src/ipxe-deployer/roles/configure_ipxe/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | - name: Create ipmi.list.txt 16 | template: 17 | src: ipmi.list.txt.j2 18 | dest: /tftp/ipmi.list.txt 19 | 20 | - name: Create Atomic kickstarts 21 | template: 22 | src: atomic.ks.j2 23 | dest: /tftp/atomic/media/atomic-{{ item }}.ks 24 | with_items: "{{ groups.nodes }}" 25 | 26 | - name: Create iPXE configs 27 | template: 28 | src: serial.ipxe.j2 29 | dest: /tftp/ipxe/serial/{{ hostvars[item]['serial'] }}.ipxe 30 | with_items: "{{ groups.nodes }}" 31 | -------------------------------------------------------------------------------- /src/prerequisites/roles/openshift_remote_access_master/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | - user: 16 | name: openshift 17 | shell: /bin/bash 18 | group: root 19 | append: yes 20 | 21 | - name: add ssh key 22 | user: 23 | name: openshift 24 | generate_ssh_key: yes 25 | ssh_key_bits: 2048 26 | ssh_key_file: .ssh/id_rsa 27 | append: yes 28 | 29 | - name: set up sudo without password 30 | lineinfile: 31 | dest: /etc/sudoers 32 | state: present 33 | line: 'openshift ALL=(ALL) NOPASSWD: ALL' 34 | -------------------------------------------------------------------------------- /src/prerequisites/roles/openshift_dns/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | - name: add specific configuration files 16 | template: 17 | src: "hosts.j2" 18 | dest: "/etc/dnsmasq.d/hosts" 19 | owner: root 20 | group: root 21 | mode: 0644 22 | notify: restart dnsmasq 23 | 24 | - name: start and enable service 25 | systemd: 26 | name: dnsmasq_container 27 | state: restarted 28 | 29 | - name: Add local DNS 30 | lineinfile: 31 | dest: /etc/resolv.conf 32 | state: present 33 | line: "nameserver 127.0.0.1" 34 | 35 | - name: Wait for dnsmasq to restart 36 | pause: 37 | seconds: 5 38 | -------------------------------------------------------------------------------- /src/etcd-scaling/roles/etcd_scale/tasks/container.yml: -------------------------------------------------------------------------------- 1 | - name: Pull etcd container 2 | command: docker pull {{ etcd_image }} 3 | register: pull_result 4 | changed_when: "'Downloaded newer image' in pull_result.stdout" 5 | 6 | - name: Install etcd container service file 7 | template: 8 | dest: "/etc/systemd/system/etcd_container.service" 9 | src: etcd.docker.service 10 | register: install_etcd_result 11 | 12 | - name: Reload systemd 13 | command: systemctl daemon-reload 14 | 15 | - name: Ensure etcd datadir exists 16 | file: 17 | path: "{{ etcd_data_dir }}" 18 | state: directory 19 | mode: 0700 20 | 21 | - name: Generate certificates 22 | include: certificates.yml 23 | 24 | - name: Create etcd config file for new instancie 25 | template: 26 | src: etcd.conf.j2 27 | dest: /etc/etcd/etcd.conf 28 | backup: true 29 | 30 | - name: Remove all quotations 31 | replace: 32 | dest: /etc/etcd/etcd.conf 33 | regexp: '"' 34 | replace: '' 35 | 36 | #- name: Restart etcd 37 | # service: 38 | # name: etcd_container 39 | # state: started 40 | 41 | - name: Restart and enable etcd 42 | service: 43 | name: etcd_container 44 | state: restarted 45 | enabled: yes 46 | register: start_result 47 | -------------------------------------------------------------------------------- /src/eos-configuration/roles/networking_setup/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | - name: Configuring top level settings 16 | eos_config: 17 | lines: 18 | - hostname {{ inventory_hostname }} 19 | provider: "{{ eos_connection }}" 20 | 21 | - name: Applying vlans configuration 22 | eos_config: 23 | src: templates/eos_vlan.cfg.j2 24 | provider: "{{ eos_connection }}" 25 | 26 | - name: Applying interfaces configuration 27 | eos_config: 28 | src: templates/eos_intf.cfg.j2 29 | provider: "{{ eos_connection }}" 30 | 31 | - name: Saving the configuration 32 | eos_command: 33 | commands: 34 | - write 35 | provider: "{{ eos_connection }}" 36 | -------------------------------------------------------------------------------- /src/prerequisites/nodes_setup.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | - hosts: local 16 | connection: local 17 | roles: 18 | - rhel_unsubscribe 19 | - rhel_subscribe 20 | - openshift_remote_access_master 21 | - openshift_dns 22 | - known_hosts 23 | post_tasks: 24 | - name: Install openshift-ansible 25 | yum: name={{ item }} state=latest 26 | with_items: 27 | - openshift-ansible 28 | - atomic-openshift-utils 29 | 30 | - hosts: nodes 31 | vars: 32 | ansible_ssh_user: root 33 | roles: 34 | - openshift_remote_access_slaves 35 | - rhel_unsubscribe 36 | - rhel_subscribe 37 | - openshift_node_preparation 38 | 39 | - hosts: glusterfs, glusterfs_registry 40 | vars: 41 | ansible_ssh_user: root 42 | roles: 43 | - gluster_subscribe 44 | -------------------------------------------------------------------------------- /src/etcd-scaling/roles/etcd_scale/templates/etcd.conf.j2: -------------------------------------------------------------------------------- 1 | {% macro initial_cluster() -%} 2 | {% for host in etcd_peers | default([]) -%} 3 | {% if loop.last -%} 4 | {{ hostvars[host].etcd_hostname }}={{ etcd_peer_url_scheme }}://{{ hostvars[host].etcd_ip }}:{{ etcd_peer_port }} 5 | {%- else -%} 6 | {{ hostvars[host].etcd_hostname }}={{ etcd_peer_url_scheme }}://{{ hostvars[host].etcd_ip }}:{{ etcd_peer_port }}, 7 | {%- endif -%} 8 | {% endfor -%} 9 | {% endmacro -%} 10 | 11 | ETCD_NAME={{ etcd_hostname }} 12 | ETCD_LISTEN_PEER_URLS={{ etcd_listen_peer_urls }} 13 | ETCD_DATA_DIR={{ etcd_data_dir }} 14 | ETCD_HEARTBEAT_INTERVAL=500 15 | ETCD_ELECTION_TIMEOUT=2500 16 | ETCD_LISTEN_CLIENT_URLS={{ etcd_listen_client_urls }} 17 | #ETCD_MAX_SNAPSHOTS=5 18 | #ETCD_MAX_WALS=5 19 | #ETCD_CORS= 20 | 21 | #[cluster] 22 | ETCD_INITIAL_ADVERTISE_PEER_URLS={{ etcd_initial_advertise_peer_urls }} 23 | {{ jin_initial_cluster }} 24 | ETCD_INITIAL_CLUSTER_STATE=existing 25 | ETCD_ADVERTISE_CLIENT_URLS={{ etcd_advertise_client_urls }} 26 | 27 | #[proxy] 28 | #ETCD_PROXY=off 29 | 30 | #[security] 31 | {% if etcd_url_scheme == 'https' -%} 32 | ETCD_CA_FILE={{ etcd_ca_file }} 33 | ETCD_CERT_FILE={{ etcd_cert_file }} 34 | ETCD_KEY_FILE={{ etcd_key_file }} 35 | {% endif -%} 36 | {% if etcd_peer_url_scheme == 'https' -%} 37 | ETCD_PEER_CA_FILE={{ etcd_peer_ca_file }} 38 | ETCD_PEER_CERT_FILE={{ etcd_peer_cert_file }} 39 | ETCD_PEER_KEY_FILE={{ etcd_peer_key_file }} 40 | {% endif -%} 41 | -------------------------------------------------------------------------------- /src/prerequisites/roles/openshift_remote_access_slaves/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | - name: add group 16 | group: 17 | name: openshift 18 | state: present 19 | - user: 20 | name: openshift 21 | shell: /bin/bash 22 | group: openshift 23 | groups: adm 24 | append: yes 25 | 26 | - name: set up sudo without password 27 | lineinfile: 28 | dest: /etc/sudoers 29 | state: present 30 | line: 'openshift ALL=(ALL) NOPASSWD: ALL' 31 | - name: ensure the directory exist 32 | file: 33 | path: /home/openshift/.ssh/ 34 | recurse: yes 35 | owner: openshift 36 | group: openshift 37 | state: directory 38 | 39 | - name: copy ssh keys 40 | copy: 41 | src: /home/openshift/.ssh/id_rsa.pub 42 | dest: /home/openshift/.ssh/authorized_keys 43 | owner: openshift 44 | group: openshift 45 | mode: 0600 46 | -------------------------------------------------------------------------------- /src/prerequisites/roles/known_hosts/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | - name: Make sure the known_hosts file and path exist 16 | file: 17 | path: "{{ ansible_env.HOME }}/.ssh" 18 | state: directory 19 | mode: 0700 20 | 21 | - name: Generate known_hosts content 22 | shell: ssh-keyscan -H -T 10 {{ item }} >> "{{ ansible_env.HOME }}/.ssh/known_hosts" 23 | with_items: 24 | - "{{ groups['masters'] }}" 25 | - "{{ groups['nodes'] }}" 26 | - "{{ groups['etcd'] }}" 27 | - "{{ groups['lb'] }}" 28 | - "{{ groups['glusterfs'] }}" 29 | - "{{ groups['glusterfs_registry'] }}" 30 | 31 | - name: Create {{ ansible_ssh_user }} SSH dir 32 | file: 33 | path: "/home/{{ ansible_ssh_user }}/.ssh" 34 | state: directory 35 | mode: 0700 36 | owner: "{{ ansible_ssh_user }}" 37 | 38 | - name: Copy known_hosts file to openshift's home directory 39 | copy: 40 | dest: "/home/{{ ansible_ssh_user }}/.ssh/" 41 | owner: "{{ ansible_ssh_user }}" 42 | mode: 0600 43 | src: "{{ ansible_env.HOME }}/.ssh/known_hosts" 44 | -------------------------------------------------------------------------------- /src/cnos-configuration/roles/configure-networking/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | - name: Make sure, that python-paramiko is installed in latest version 16 | yum: 17 | name: python-paramiko 18 | state: latest 19 | 20 | - name: create a local temp directory 21 | command: mktemp -d "{{ lookup('env', 'TMPDIR') | default('/tmp/') }}/cnos_template.XXXX" 22 | register: tmpdir 23 | 24 | - name: Generating configuration template 25 | template: src=configuration.j2 dest={{ tmpdir }}/configuration_{{ inventory_hostname }}_commands.txt 26 | with_items: "{{ cnos_template_data }}" 27 | 28 | - name: Applying configuration template 29 | cnos_template: 30 | host={{ inventory_hostname }} 31 | username={{ hostvars[inventory_hostname]['username']}} 32 | deviceType={{ hostvars[inventory_hostname]['deviceType'] }} 33 | password={{ hostvars[inventory_hostname]['password']}} 34 | commandfile={{ tmpdir }}/configuration_{{ inventory_hostname }}_commands.txt 35 | outputfile={{ tmpdir }}/cnos_template_{{ inventory_hostname }}_output.txt 36 | with_items: "{{ cnos_template_data }}" 37 | -------------------------------------------------------------------------------- /src/prerequisites/roles/openshift_node_preparation/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | - include: os_definition.yml 16 | - name: install packagges 17 | yum: 18 | name: "{{ item }}" 19 | state: latest 20 | with_items: 21 | - wget 22 | - git 23 | - net-tools 24 | - bind-utils 25 | - iptables-services 26 | - bridge-utils 27 | - bash-completion 28 | when: os_version != 'atomic' 29 | - name: yum update 30 | yum: 31 | name: '*' 32 | state: latest 33 | when: os_version != 'atomic' 34 | - name: atomic-openshift-utils 35 | yum: 36 | name: "{{ item }}" 37 | state: latest 38 | with_items: 39 | - atomic-openshift-utils 40 | - atomic-openshift-excluder 41 | - atomic-openshift-docker-excluder 42 | - docker 43 | when: os_version != 'atomic' 44 | - name: Workaround for docker 1.12 45 | lineinfile: 46 | dest: /etc/yum.conf 47 | state: present 48 | line: 'exclude=docker*1.12*' 49 | - name: Enable insecure registry 50 | lineinfile: 51 | dest: /etc/sysconfig/docker 52 | state: present 53 | line: "OPTIONS=' --selinux-enabled --insecure-registry {{ openshift_master_portal_net }}'" 54 | -------------------------------------------------------------------------------- /src/keepalived-multimaster/roles/keepalived_haproxy/templates/keepalived.cfg.j2: -------------------------------------------------------------------------------- 1 | global_defs { 2 | router_id LVS_DEVEL 3 | } 4 | 5 | vrrp_script haproxy_check { 6 | script "/etc/keepalived/healthcheck-keepalived.sh" 7 | interval 2 8 | } 9 | 10 | vrrp_instance OCP_EXT { 11 | interface {{ internal_interface }}{% if internal_vlan is defined %}.{{ internal_vlan }}{% endif %} 12 | 13 | virtual_router_id 51 14 | 15 | priority 100 16 | 17 | state BACKUP 18 | 19 | 20 | virtual_ipaddress { 21 | {{ openshift_master_cluster_public_ip }} dev {{ external_interface }}{% if external_vlan is defined %}.{{ external_vlan }}{% endif %} 22 | 23 | } 24 | 25 | track_script { 26 | haproxy_check 27 | } 28 | 29 | authentication { 30 | auth_type PASS 31 | auth_pass {{ keepalived_external_pass.stdout }} 32 | } 33 | 34 | unicast_src_ip {{ openshift_ip }} 35 | 36 | unicast_peer { {% for host in groups['lb'] %} 37 | "{{ hostvars[host].openshift_ip }}" 38 | {% endfor %} 39 | } 40 | 41 | } 42 | 43 | vrrp_instance OCP_INT { 44 | interface {{ internal_interface }}{% if internal_vlan is defined %}.{{ internal_vlan }}{% endif %} 45 | 46 | virtual_router_id 91 47 | 48 | priority 100 49 | 50 | state BACKUP 51 | 52 | virtual_ipaddress { 53 | {{ openshift_master_cluster_ip }} dev {{ internal_interface }}{% if internal_vlan is defined %}.{{ internal_vlan }}{% endif %} 54 | 55 | } 56 | 57 | track_script { 58 | haproxy_check 59 | } 60 | 61 | authentication { 62 | auth_type PASS 63 | auth_pass {{ keepalived_internal_pass.stdout }} 64 | } 65 | 66 | unicast_src_ip {{ openshift_ip }} 67 | 68 | unicast_peer { {% for host in groups['lb'] %} 69 | "{{ hostvars[host].openshift_ip }}" 70 | {% endfor %} 71 | } 72 | } 73 | 74 | -------------------------------------------------------------------------------- /src/prerequisites/roles/gluster_subscribe/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | - name: RedHat subscriptions 16 | redhat_subscription: 17 | username: "{{ rhel_subscription_user }}" 18 | password: "{{ rhel_subscription_pass }}" 19 | force_register: no 20 | 21 | - name: Retrieve the GlusterFS Pool ID 22 | command: subscription-manager list --available --matches="{{ gluster_subscription_pool }}" --pool-only 23 | register: glusterfs_pool_id 24 | changed_when: False 25 | 26 | - name: Determine if GlusterFS Pool Already Attached 27 | command: subscription-manager list --consumed --matches="{{ gluster_subscription_pool }}" --pool-only 28 | register: glusterfs_pool_attached 29 | changed_when: False 30 | when: glusterfs_pool_id.stdout == '' 31 | 32 | - fail: 33 | msg: "Unable to find pool matching {{ gluster_subscription_pool }} in available or consumed pools" 34 | when: glusterfs_pool_id.stdout == '' and glusterfs_pool_attached is defined and glusterfs_pool_attached.stdout == '' 35 | 36 | - name: Attach to GlusterFS Pool 37 | command: subscription-manager subscribe --pool {{ glusterfs_pool_id.stdout_lines[0] }} 38 | when: glusterfs_pool_id.stdout != '' 39 | 40 | - name: enable the repositories 41 | command: subscription-manager repos --enable={{ item }} 42 | with_items: 43 | - rh-gluster-3-for-rhel-7-server-rpms 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DISCONTINUATION OF PROJECT 2 | 3 | This project will no longer be maintained by Intel. 4 | 5 | Intel has ceased development and contributions including, but not limited to, maintenance, bug fixes, new releases, or updates, to this project. 6 | 7 | Intel no longer accepts patches to this project. 8 | 9 | If you have an ongoing need to use this project, are interested in independently developing it, or would like to maintain patches for the open source software community, please create your own fork of this project. 10 | 11 | # Deploying Red Hat OpenShift® Container Platform 3.6 with Container-Native Storage 12 | 13 | ## Instructions 14 | Please, refer to [Reference Architecture document](https://builders.intel.com/docs/cloudbuilders/deploying-red-hat-openshift-container-platform-3-6-with-container-native-storage.pdf) 15 | for actual instructions. 16 | 17 | ### Clone the repository 18 | `git clone git@github.com:intel/openshift-container-architecture.git` 19 | 20 | ### Creating inventory 21 | Inventory file has to be filled manually. 22 | Refer to *hosts.example* for possible variables. 23 | 24 | `cp hosts.example /etc/ansible/hosts; 25 | vim /etc/ansible/hosts` 26 | 27 | ### Switch Configuration (optional) 28 | Update inventory group *[arista]* and run: 29 | 30 | `ansible-playbook src/eos-configuration/configure_eos.yaml` 31 | 32 | ### Provisioning system setup 33 | 34 | `ansible-playbook ipxe-deployer/ipxe.yml` 35 | 36 | `env IPMI_PASSWORD=password /tftp/reboot.sh -b pxe -r -f /tftp/ipmi.list.txt` 37 | 38 | ### Preparing the nodes for OpenShift Container Platform 39 | 40 | `ansible-playbook src/prerequisites/nodes_setup.yaml -k` 41 | 42 | ### Setting up multimaster HA 43 | switch user to *openshift*: 44 | 45 | `su - openshift` 46 | 47 | run: 48 | 49 | `ansible-playbook src/keepalived-multimaster/keepalived.yaml` 50 | 51 | ### Deploying OpenShift cluster 52 | As user *openshift* run: 53 | 54 | `ansible-playbook /usr/share/ansible/openshift-ansible/playbooks/byo/config.yml` 55 | -------------------------------------------------------------------------------- /src/etcd-scaling/roles/etcd_scale/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ansible_pkg_mgr: yum 3 | etcd_service: "{{ 'etcd' if not etcd_is_containerized | bool else 'etcd_container' }}" 4 | etcd_client_port: 2379 5 | etcd_peer_port: 2380 6 | etcd_url_scheme: https 7 | etcd_peer_url_scheme: https 8 | 9 | etcd_initial_cluster_state: new 10 | etcd_initial_cluster_token: etcd-cluster-1 11 | 12 | etcd_initial_advertise_peer_urls: "{{ etcd_peer_url_scheme }}://{{ etcd_ip }}:{{ etcd_peer_port }}" 13 | etcd_listen_peer_urls: "{{ etcd_peer_url_scheme }}://{{ etcd_ip }}:{{ etcd_peer_port }}" 14 | etcd_advertise_client_urls: "{{ etcd_url_scheme }}://{{ etcd_ip }}:{{ etcd_client_port }}" 15 | etcd_listen_client_urls: "{{ etcd_url_scheme }}://{{ etcd_ip }}:{{ etcd_client_port }}" 16 | 17 | etcd_data_dir: /var/lib/etcd/ 18 | 19 | # etcd server vars 20 | etcd_conf_dir: /etc/etcd 21 | etcd_ca_file: "{{ etcd_conf_dir }}/ca.crt" 22 | etcd_cert_file: "{{ etcd_conf_dir }}/server.crt" 23 | etcd_key_file: "{{ etcd_conf_dir }}/server.key" 24 | etcd_peer_ca_file: "{{ etcd_conf_dir }}/ca.crt" 25 | etcd_peer_cert_file: "{{ etcd_conf_dir }}/peer.crt" 26 | etcd_peer_key_file: "{{ etcd_conf_dir }}/peer.key" 27 | 28 | # etcd ca vars 29 | etcd_ca_dir: "{{ etcd_conf_dir}}/ca" 30 | etcd_generated_certs_dir: "{{ etcd_conf_dir }}/generated_certs" 31 | etcd_ca_cert: "{{ etcd_ca_dir }}/ca.crt" 32 | etcd_ca_key: "{{ etcd_ca_dir }}/ca.key" 33 | etcd_openssl_conf: "{{ etcd_ca_dir }}/openssl.cnf" 34 | etcd_ca_name: etcd_ca 35 | etcd_req_ext: etcd_v3_req 36 | etcd_ca_exts_peer: etcd_v3_ca_peer 37 | etcd_ca_exts_server: etcd_v3_ca_server 38 | etcd_ca_exts_self: etcd_v3_ca_self 39 | etcd_ca_exts_client: etcd_v3_ca_client 40 | etcd_ca_crl_dir: "{{ etcd_ca_dir }}/crl" 41 | etcd_ca_new_certs_dir: "{{ etcd_ca_dir }}/certs" 42 | etcd_ca_db: "{{ etcd_ca_dir }}/index.txt" 43 | etcd_ca_serial: "{{ etcd_ca_dir }}/serial" 44 | etcd_ca_crl_number: "{{ etcd_ca_dir }}/crlnumber" 45 | etcd_ca_default_days: 1825 46 | 47 | etcd_image: "registry.access.redhat.com/rhel7/etcd" 48 | -------------------------------------------------------------------------------- /src/etcd-scaling/roles/etcd_scale/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017 Intel Corporation 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | - name: debug 15 | debug: 16 | msg: "ETCD is containerized" 17 | when: etcd_is_containerized | bool 18 | 19 | - name: debug 20 | debug: 21 | msg: "ETCD is NOT containerized" 22 | when: not etcd_is_containerized | bool 23 | 24 | - name: Add etcd hosts to cluster 25 | command: > 26 | etcdctl -C https://{{ etcd_ca_host }}:2379 27 | --ca-file=/etc/etcd/ca.crt --cert-file=/etc/etcd/peer.crt 28 | --key-file=/etc/etcd/peer.key member add {{ etcd_hostname }} https://{{ etcd_ip }}:2380 29 | delegate_to: "{{ etcd_ca_host }}" 30 | register: scale_initial_cluster 31 | 32 | - name: Add firewall rule for port 2379 33 | lineinfile: 34 | path: /etc/sysconfig/iptables 35 | line: "-A OS_FIREWALL_ALLOW -p tcp -m state --state NEW -m tcp --dport 2379 -j ACCEPT" 36 | insertbefore: 'COMMIT' 37 | 38 | - name: Add firewall rule for port 2380 39 | lineinfile: 40 | path: /etc/sysconfig/iptables 41 | line: "-A OS_FIREWALL_ALLOW -p tcp -m state --state NEW -m tcp --dport 2380 -j ACCEPT" 42 | insertbefore: 'COMMIT' 43 | 44 | - name: Restart firewall 45 | service: 46 | name: iptables 47 | state: restarted 48 | 49 | - include: container.yml 50 | when: etcd_is_containerized | bool 51 | 52 | - include: rpm.yml 53 | when: not etcd_is_containerized | bool 54 | 55 | - pause: 56 | seconds: 5 57 | -------------------------------------------------------------------------------- /src/keepalived-multimaster/roles/keepalived_haproxy/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | - name: Create a local temp directory for docker build 16 | file: 17 | path: /tmp/keepalived_build/ 18 | state: directory 19 | 20 | - name: Copy Dockerfile 21 | copy: 22 | src: keepalived/Dockerfile 23 | dest: /tmp/keepalived_build/Dockerfile 24 | 25 | - name: Build keepalived image 26 | docker_image: > 27 | name={{ keepalived_image }} 28 | tag={{ keepalived_image_tag }} 29 | path=/tmp/keepalived_build 30 | state=present 31 | 32 | - name: Remove build directory 33 | file: 34 | path: /tmp/keepalived_build 35 | state: absent 36 | 37 | - name: Generate random internal password 38 | shell: uuidgen 39 | run_once: true 40 | register: keepalived_internal_pass 41 | 42 | - name: Generate random external password 43 | shell: uuidgen 44 | run_once: true 45 | register: keepalived_external_pass 46 | 47 | - name: Creates directory 48 | file: 49 | path: /etc/keepalived 50 | state: directory 51 | 52 | - name: Configure keepalived 53 | template: 54 | src: keepalived.cfg.j2 55 | dest: /etc/keepalived/keepalived.cfg 56 | 57 | - name: Generate systemd keepalived file 58 | template: 59 | src: keepalived.service.j2 60 | dest: /etc/systemd/system/keepalived.service 61 | 62 | - name: Generate healthcheck script 63 | template: 64 | src: healthcheck-keepalived.sh.j2 65 | dest: /etc/keepalived/healthcheck-keepalived.sh 66 | mode: "o+rx" 67 | 68 | - name: Start keepalived 69 | systemd: 70 | name: keepalived 71 | state: restarted 72 | enabled: yes 73 | daemon_reload: yes 74 | -------------------------------------------------------------------------------- /src/prerequisites/roles/rhel_subscribe/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | - include: os_definition.yml 16 | 17 | - name: RedHat subscriptions 18 | redhat_subscription: 19 | username: "{{ rhel_subscription_user }}" 20 | password: "{{ rhel_subscription_pass }}" 21 | force_register: no 22 | 23 | - name: Retrieve the OpenShift Pool ID 24 | command: subscription-manager list --available --matches="{{ rhel_subscription_pool }}" --pool-only 25 | register: openshift_pool_id 26 | changed_when: False 27 | 28 | - name: Determine if OpenShift Pool Already Attached 29 | command: subscription-manager list --consumed --matches="{{ rhel_subscription_pool }}" --pool-only 30 | register: openshift_pool_attached 31 | changed_when: False 32 | when: openshift_pool_id.stdout == '' 33 | 34 | - fail: 35 | msg: "Unable to find pool matching {{ rhel_subscription_pool }} in available or consumed pools" 36 | when: openshift_pool_id.stdout == '' and openshift_pool_attached is defined and openshift_pool_attached.stdout == '' 37 | 38 | - name: Attach to OpenShift Pool 39 | command: subscription-manager subscribe --pool {{ openshift_pool_id.stdout_lines[0] }} 40 | when: openshift_pool_id.stdout != '' 41 | 42 | - name: Clean all repositories 43 | command: subscription-manager repos --disable=* 44 | 45 | - name: Clean all repositories 46 | file: path=/etc/yum.repos.d state=absent 47 | 48 | - file: path=/etc/yum.repos.d state=directory 49 | 50 | - name: enable the repositories 51 | command: subscription-manager repos --enable={{ item }} 52 | with_items: 53 | - rhel-7-server-rpms 54 | - rhel-7-server-extras-rpms 55 | - rhel-7-server-ose-3.6-rpms 56 | - rhel-7-fast-datapath-rpms 57 | when: os_version != 'atomic' 58 | -------------------------------------------------------------------------------- /src/ipxe-deployer/roles/deploy_ipxe/templates/reboot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | ipmitool="/usr/bin/ipmitool" 16 | 17 | if [ -z $IPMI_PASSWORD ]; then 18 | echo $0: IPMI_PASSWORD environment has to be set 19 | exit 1 20 | elif [ $# -le 1 ]; then 21 | echo $0 -b disk -r -f FILENAME 22 | echo "$0: Parameters";echo 23 | echo "-b (disk|pxe) - boot from (order)" 24 | echo "-r - reboot" 25 | echo "-f - file containg ips and/or hostnames" 26 | echo "Example: $0 -b pxe -r -f server.list.txt" 27 | echo; echo "IPMI password is extracted from IPMI_PASSWORD environment" 28 | exit 1 29 | elif [ ! -f $ipmitool ]; then 30 | echo "$0: install ipmitool package" 31 | exit 1 32 | fi 33 | 34 | OPTIND=1 35 | boot_first="null" 36 | file="" 37 | reboot=0 38 | # getops 39 | while getopts "b:f:r" arg; do 40 | case "$arg" in 41 | b) 42 | boot_first=$OPTARG 43 | ;; 44 | f) 45 | file=$OPTARG 46 | ;; 47 | r) 48 | reboot=1 49 | ;; 50 | \?) 51 | exit 1 52 | ;; 53 | esac 54 | done 55 | shift $((OPTIND-1)) 56 | 57 | if [ ! -f $file ]; then 58 | echo "$0: provide file with the list of IPMI endpoints" 59 | exit 1 60 | elif [ `wc -l $file|awk '{print $1}'` -gt 0 ]; then 61 | echo "boot first: $boot_first" 62 | echo "file: $file" 63 | echo "reboot: $reboot" 64 | 65 | for server in `grep -v ^\# $file`; do 66 | if [ $boot_first = "disk" -o $boot_first = "pxe" ]; then 67 | echo "$0: changing primary boot device for $server" 68 | $ipmitool -I lanplus -H $server -U root -E chassis bootdev $boot_first 69 | fi 70 | if [ $reboot -eq 1 ]; then 71 | echo "$0: rebooting $server" 72 | $ipmitool -I lanplus -H $server -U root -E power cycle 73 | fi 74 | done 75 | else 76 | echo "$0: unexpected script execution; empty or non-existing file." 77 | exit 1 78 | fi 79 | -------------------------------------------------------------------------------- /src/ipxe-deployer/roles/firewall/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | - name: Check if firewalld is running 17 | command: systemctl status firewalld 18 | ignore_errors: yes 19 | changed_when: false 20 | register: firewalld_status 21 | failed_when: false 22 | 23 | - name: Report status of firewalld 24 | fail: 25 | msg: "Firewalld is stopped or disabled. Please enable firewalld if you want to use NAT features on bastion node" 26 | when: firewalld_status | failed 27 | 28 | - name: Enable tftp traffic 29 | firewalld: 30 | service: tftp 31 | permanent: true 32 | state: enabled 33 | zone: public 34 | 35 | - name: Enable dhcp traffic 36 | firewalld: 37 | service: dhcp 38 | permanent: true 39 | state: enabled 40 | zone: public 41 | 42 | - name: Enable dns traffic 43 | firewalld: 44 | service: dns 45 | permanent: true 46 | state: enabled 47 | zone: public 48 | 49 | - name: Enable http traffic 50 | firewalld: 51 | service: http 52 | permanent: true 53 | state: enabled 54 | zone: public 55 | 56 | - name: Add docker0 interface to public zone 57 | firewalld: 58 | zone: public 59 | interface: docker0 60 | permanent: true 61 | state: enabled 62 | 63 | - name: Add NAT rule 64 | command: firewall-cmd --direct --add-rule ipv4 nat POSTROUTING 0 -o {{ external_interface }}{% if external_vlan is defined %}.{{ external_vlan }}{% endif %} -j MASQUERADE 65 | 66 | - name: Add forwarding rule public -> private 67 | command: firewall-cmd --direct --add-rule ipv4 filter FORWARD 0 -i {{ internal_interface }}{% if internal_vlan is defined %}.{{ internal_vlan }}{% endif %} -o {{ external_interface }}{% if external_vlan is defined %}.{{ external_vlan }}{% endif %} -j ACCEPT 68 | 69 | - name: Add forwarding rule private -> public 70 | command: firewall-cmd --direct --add-rule ipv4 filter FORWARD 0 -i {{ external_interface }}{% if external_vlan is defined %}.{{ external_vlan }}{% endif %} -o {{ internal_interface }}{% if internal_vlan is defined %}.{{ internal_vlan }}{% endif %} -m state --state RELATED,ESTABLISHED -j ACCEPT 71 | 72 | - name: Add masquerade 73 | command: firewall-cmd --zone=public --add-masquerade --permanent 74 | 75 | - name: Reload firewalld 76 | command: firewall-cmd --reload 77 | -------------------------------------------------------------------------------- /src/drbd/roles/deploy_drbd/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017 Intel Corporation 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | - name: add EPEL repository 16 | command: rpm -ivh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm 17 | ignore_errors: True 18 | 19 | - rpm_key: 20 | state: present 21 | key: https://www.elrepo.org/RPM-GPG-KEY-elrepo.org 22 | 23 | - name: Install DRBD utils 24 | yum: 25 | name: "{{ item }}" 26 | state: present 27 | with_items: 28 | - drbd84-utils 29 | - kmod-drbd84 30 | 31 | - name: Create drbd config file 32 | template: 33 | src: nfs.res.j2 34 | dest: /etc/drbd.d/nfs.res 35 | 36 | - name: Create drbd device on both nodes 37 | shell: yes yes | drbdadm create-md nfs 38 | 39 | - name: Turn up the drbd device 40 | shell: yes yes | drbdadm up nfs 41 | 42 | - name: Set a primary drbd device 43 | command: drbdadm primary nfs --force 44 | when: ansible_host == "{{ drbd_primary_host }}" 45 | 46 | - name: Set a secondary drbd device 47 | command: drbdadm secondary nfs 48 | when: ansible_host == "{{ drbd_secondary_host }}" 49 | 50 | - name: Start and enable drbd service 51 | service: 52 | name: drbd 53 | state: started 54 | enabled: yes 55 | 56 | - name: Format drbd device 57 | filesystem: 58 | fstype: xfs 59 | dev: /dev/drbd0 60 | when: ansible_host == "{{ drbd_primary_host }}" 61 | 62 | - name: Create exports directory 63 | file: path=/exports state=directory 64 | 65 | - name: Mount drbd device on primary node 66 | command: mount /dev/drbd0 /exports 67 | when: ansible_host == "{{ drbd_primary_host }}" 68 | 69 | - name: Add rc.local drbd mount on primary node 70 | lineinfile: 71 | dest: /etc/rc.local 72 | line: "sleep 10s; drbdadm primary nfs --force; mount /dev/drbd0 /exports" 73 | when: ansible_host == "{{ drbd_primary_host }}" 74 | 75 | - name: Make rc.local file executable 76 | file: 77 | path: /etc/rc.d/rc.local 78 | mode: "u+x" 79 | when: ansible_host == "{{ drbd_primary_host }}" 80 | 81 | - name: Add iptables rule for drbd connections on primary node 82 | iptables: 83 | chain: INPUT 84 | jump: ACCEPT 85 | source: "{{ secondary_private_address }}" 86 | when: ansible_host == "{{ drbd_primary_host }}" 87 | 88 | - name: Add iptables rule for drbd connections on secondary node 89 | iptables: 90 | chain: INPUT 91 | jump: ACCEPT 92 | source: "{{ primary_private_address }}" 93 | when: ansible_host == "{{ drbd_secondary_host }}" 94 | -------------------------------------------------------------------------------- /src/ipxe-deployer/roles/deploy_ipxe/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) 2017 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | - name: install required packages 17 | yum: 18 | name: "{{ item }}" 19 | state: present 20 | with_items: 21 | - "docker-python" 22 | - "ipxe-bootimgs" 23 | 24 | - name: Ensure docker is started 25 | systemd: 26 | name: docker 27 | enabled: yes 28 | state: started 29 | 30 | - name: build nginx image 31 | docker_image: > 32 | name={{nginx_image}} 33 | tag={{ nginx_image_tag }} 34 | path={{playbook_dir}}/roles/deploy_ipxe/files/nginx/ 35 | state=present 36 | 37 | - name: build dnsmasq image 38 | docker_image: > 39 | name={{ dnsmasq_image }} 40 | tag={{ dnsmasq_image_tag }} 41 | path={{playbook_dir}}/roles/deploy_ipxe/files/dnsmasq/ 42 | state=present 43 | 44 | - name: Create dnsmasq config file 45 | template: 46 | src: dnsmasq_c.conf.j2 47 | dest: /etc/dnsmasq_c.conf 48 | 49 | - name: Create dnsmasq systemd unit 50 | template: 51 | src: dnsmasq_container.service.j2 52 | dest: /etc/systemd/system/dnsmasq_container.service 53 | 54 | - name: Create nginx systemd unit 55 | template: 56 | src: nginx_container.service.j2 57 | dest: /etc/systemd/system/nginx_container.service 58 | 59 | - name: Create directory structure 60 | file: 61 | path: "{{ item }}" 62 | state: directory 63 | mode: 0755 64 | with_items: 65 | - "/etc/dnsmasq.d" 66 | - "/tftp" 67 | - "/tftp/ipxe/serial" 68 | - "/tftp/atomic/media" 69 | 70 | - name: Copy undionly iPXE image 71 | copy: 72 | src: /usr/share/ipxe/ipxe.efi 73 | dest: /tftp/ipxe/ipxe.efi 74 | mode: 0644 75 | 76 | - name: Create reboot script 77 | template: 78 | src: reboot.sh 79 | dest: /tftp/reboot.sh 80 | 81 | - name: Make reboot.sh executable 82 | file: dest=/tftp/reboot.sh mode=a+x 83 | 84 | - name: Create ipxe main config systemd unit 85 | template: 86 | src: main.ipxe.j2 87 | dest: /tftp/ipxe/main.ipxe 88 | 89 | - name: Set Selinux labels 90 | command: chcon -Rt svirt_sandbox_file_t /tftp 91 | 92 | - name: Start and enable nginx_container service 93 | systemd: 94 | name: nginx_container.service 95 | state: started 96 | enabled: True 97 | daemon_reload: yes 98 | 99 | - name: Start dnsmasq_container service 100 | systemd: 101 | name: dnsmasq_container.service 102 | state: started 103 | enabled: True 104 | daemon_reload: yes 105 | -------------------------------------------------------------------------------- /src/ipxe-deployer/roles/configure_ipxe/templates/atomic.ks.j2: -------------------------------------------------------------------------------- 1 | lang en_US.UTF-8 2 | keyboard us 3 | timezone Etc/UTC --isUtc 4 | url --url="http://{{ bastion_ip }}/atomic/media/" 5 | rootpw --iscrypted {{ root_password|password_hash('sha512') }} 6 | auth --enableshadow --passalgo=sha512 7 | ostreesetup --nogpg --osname=rhel-atomic-host --remote=rhel-atomic-host --url=file:///install/ostree --ref=rhel-atomic-host/7/x86_64/standard 8 | services --disabled cloud-init,cloud-config,cloud-final,cloud-init-local 9 | network --bootproto=static --device=eno1 --onboot=off 10 | network --bootproto=static --device=eno2 --onboot=off 11 | clearpart --all --initlabel 12 | zerombr 13 | part /boot --fstype ext4 --size=500 14 | part /boot/efi --fstype vfat --size=200 15 | part pv.01 --size=100000 --grow --ondisk=sda 16 | volgroup vg00 pv.01 17 | logvol swap --vgname=vg00 --name=swapvol --fstype=swap --size=4000 18 | logvol / --vgname=vg00 --fstype=xfs --size=80000 --name=lv_root 19 | reboot 20 | %post --erroronfail 21 | fn=/etc/ostree/remotes.d/rhel-atomic-host.conf; if test -f ${fn} && grep -q -e '^url=file:///install/ostree' ${fn}$; then rm ${fn}; fi 22 | %end 23 | %post --erroronfail 24 | 25 | cat << EOF > /etc/sysconfig/network-scripts/ifcfg-bond0 26 | DEVICE=bond0 27 | ONBOOT=yes 28 | {% if hostvars[item]['openshift_public_ip'] is defined and external_vlan is not defined %} 29 | IPADDR={{ hostvars[item]['openshift_public_ip'] }} 30 | NETMASK={{ external_netmask }} 31 | GATEWAY={{ external_gateway }} 32 | {% elif hostvars[item]['openshift_public_ip'] is defined and external_vlan is defined %} 33 | IPADDR={{ hostvars[item]['openshift_ip'] }} 34 | NETMASK={{ internal_netmask }} 35 | DNS1={{ local_dns }} 36 | {% elif internal_vlan is not defined %} 37 | IPADDR={{ hostvars[item]['openshift_ip'] }} 38 | NETMASK={{ internal_netmask }} 39 | GATEWAY={{ internal_gateway }} 40 | DNS1={{ local_dns }} 41 | {% endif %} 42 | BOOTPROTO=none 43 | USERCTL=no 44 | BONDING_OPTS="mode=1 miimon=100 xmit_hash_policy=0 use_carrier=1" 45 | EOF 46 | 47 | {% if internal_vlan is defined %} 48 | cat << EOF > /etc/sysconfig/network-scripts/ifcfg-bond0.{{ internal_vlan }} 49 | DEVICE=bond0.{{ internal_vlan }} 50 | IPADDR={{ hostvars[item]['openshift_ip'] }} 51 | NETMASK={{ internal_netmask }} 52 | {% if hostvars[item]['openshift_public_ip'] is undefined %} 53 | GATEWAY={{ internal_gateway }} 54 | {% endif %} 55 | DNS1={{ local_dns }} 56 | ONBOOT=yes 57 | VLAN=yes 58 | BOOTPROTO=none 59 | USERCTL=no 60 | EOF 61 | {% endif %} 62 | 63 | {% if external_vlan is defined and hostvars[item]['openshift_public_ip'] is defined %} 64 | cat << EOF > /etc/sysconfig/network-scripts/ifcfg-bond0.{{ external_vlan }} 65 | DEVICE=bond0.{{ external_vlan }} 66 | IPADDR={{ hostvars[item]['openshift_public_ip'] }} 67 | NETMASK={{ external_netmask }} 68 | GATEWAY={{ external_gateway }} 69 | DNS1={{ local_dns }} 70 | ONBOOT=yes 71 | VLAN=yes 72 | BOOTPROTO=none 73 | USERCTL=no 74 | EOF 75 | {% endif %} 76 | 77 | cat << EOF > /etc/sysconfig/network-scripts/ifcfg-enp24s0f0 78 | DEVICE=enp24s0f0 79 | ONBOOT=yes 80 | MASTER=bond0 81 | SLAVE=yes 82 | EOF 83 | 84 | cat << EOF > /etc/sysconfig/network-scripts/ifcfg-enp24s0f1 85 | DEVICE=enp24s0f1 86 | ONBOOT=yes 87 | MASTER=bond0 88 | SLAVE=yes 89 | EOF 90 | 91 | cat << EOF > /etc/hostname 92 | {{ hostvars[item]['openshift_hostname'] }} 93 | EOF 94 | 95 | rm -f /etc/ostree/remotes.d/*.conf 96 | echo 'unconfigured-state=This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.' >> $(ostree admin --print-current-dir).origin 97 | %end 98 | -------------------------------------------------------------------------------- /src/eos-configuration/roles/networking_setup/templates/eos_intf.cfg.j2: -------------------------------------------------------------------------------- 1 | interface Ethernet1/1 2 | description Server 1 3 | speed forced 25gfull 4 | switchport trunk native vlan {{ internal_vlan }} 5 | switchport trunk allowed vlan {{ external_vlan }},{{ internal_vlan }} 6 | switchport mode trunk 7 | spanning-tree portfast 8 | ! 9 | interface Ethernet1/2 10 | description Server 2 11 | speed forced 25gfull 12 | switchport trunk native vlan {{ internal_vlan }} 13 | switchport trunk allowed vlan {{ external_vlan }},{{ internal_vlan }} 14 | switchport mode trunk 15 | spanning-tree portfast 16 | ! 17 | interface Ethernet1/3 18 | description Server 3 19 | speed forced 25gfull 20 | switchport trunk native vlan {{ internal_vlan }} 21 | switchport trunk allowed vlan {{ external_vlan }},{{ internal_vlan }} 22 | switchport mode trunk 23 | spanning-tree portfast 24 | ! 25 | interface Ethernet1/4 26 | description Server 4 27 | speed forced 25gfull 28 | switchport trunk native vlan {{ internal_vlan }} 29 | switchport trunk allowed vlan {{ external_vlan }},{{ internal_vlan }} 30 | switchport mode trunk 31 | spanning-tree portfast 32 | ! 33 | interface Ethernet2/1 34 | description Server 5 35 | speed forced 25gfull 36 | switchport trunk native vlan {{ internal_vlan }} 37 | switchport trunk allowed vlan {{ external_vlan }},{{ internal_vlan }} 38 | switchport mode trunk 39 | spanning-tree portfast 40 | ! 41 | interface Ethernet2/2 42 | description Server 6 43 | speed forced 25gfull 44 | switchport trunk native vlan {{ internal_vlan }} 45 | switchport trunk allowed vlan {{ external_vlan }},{{ internal_vlan }} 46 | switchport mode trunk 47 | spanning-tree portfast 48 | ! 49 | interface Ethernet2/3 50 | description Server 7 51 | speed forced 25gfull 52 | switchport trunk native vlan {{ internal_vlan }} 53 | switchport trunk allowed vlan {{ external_vlan }},{{ internal_vlan }} 54 | switchport mode trunk 55 | spanning-tree portfast 56 | ! 57 | interface Ethernet2/4 58 | description Server 8 59 | speed forced 25gfull 60 | switchport trunk native vlan {{ internal_vlan }} 61 | switchport trunk allowed vlan {{ external_vlan }},{{ internal_vlan }} 62 | switchport mode trunk 63 | spanning-tree portfast 64 | ! 65 | interface Ethernet3/1 66 | description Server 9 67 | speed forced 25gfull 68 | switchport trunk native vlan {{ internal_vlan }} 69 | switchport trunk allowed vlan {{ external_vlan }},{{ internal_vlan }} 70 | switchport mode trunk 71 | spanning-tree portfast 72 | ! 73 | interface Ethernet3/2 74 | description Server 10 75 | speed forced 25gfull 76 | switchport trunk native vlan {{ internal_vlan }} 77 | switchport trunk allowed vlan {{ external_vlan }},{{ internal_vlan }} 78 | switchport mode trunk 79 | spanning-tree portfast 80 | ! 81 | interface Ethernet3/3 82 | description Server 11 83 | speed forced 25gfull 84 | switchport trunk native vlan {{ internal_vlan }} 85 | switchport trunk allowed vlan {{ external_vlan }},{{ internal_vlan }} 86 | switchport mode trunk 87 | spanning-tree portfast 88 | ! 89 | interface Ethernet3/4 90 | description Server 12 91 | speed forced 25gfull 92 | switchport trunk native vlan {{ internal_vlan }} 93 | switchport trunk allowed vlan {{ external_vlan }},{{ internal_vlan }} 94 | switchport mode trunk 95 | spanning-tree portfast 96 | ! 97 | interface Ethernet4/1 98 | description Server 13 99 | speed forced 25gfull 100 | switchport trunk native vlan {{ internal_vlan }} 101 | switchport trunk allowed vlan {{ external_vlan }},{{ internal_vlan }} 102 | switchport mode trunk 103 | spanning-tree portfast 104 | ! 105 | interface Ethernet4/2 106 | description Server 14 107 | speed forced 25gfull 108 | switchport trunk native vlan {{ internal_vlan }} 109 | switchport trunk allowed vlan {{ external_vlan }},{{ internal_vlan }} 110 | switchport mode trunk 111 | spanning-tree portfast 112 | ! 113 | interface Ethernet4/3 114 | description Server 15 115 | speed forced 25gfull 116 | switchport trunk native vlan {{ internal_vlan }} 117 | switchport trunk allowed vlan {{ external_vlan }},{{ internal_vlan }} 118 | switchport mode trunk 119 | spanning-tree portfast 120 | ! 121 | -------------------------------------------------------------------------------- /src/cnos-configuration/roles/configure-networking/templates/configuration.j2: -------------------------------------------------------------------------------- 1 | ! 2 | vlag enable 3 | ! 4 | vlan 1 5 | ! 6 | vlan 1001 7 | name "VLAN-1001-Cluster-Native" 8 | ! 9 | vlan 2001 10 | name "VLAN-2001-ISL-VLAG" 11 | ! 12 | interface Ethernet1/1/1 13 | bridge-port mode trunk 14 | bridge-port trunk native vlan 1001 15 | bridge-port trunk allowed vlan 1,1001 16 | aggregation-group 11 mode active 17 | spanning-tree port type edge 18 | ! 19 | interface Ethernet1/1/2 20 | bridge-port mode trunk 21 | bridge-port trunk native vlan 1001 22 | bridge-port trunk allowed vlan 1,1001 23 | aggregation-group 12 mode active 24 | spanning-tree port type edge 25 | ! 26 | interface Ethernet1/1/3 27 | bridge-port mode trunk 28 | bridge-port trunk native vlan 1001 29 | bridge-port trunk allowed vlan 1,1001 30 | aggregation-group 13 mode active 31 | spanning-tree port type edge 32 | ! 33 | interface Ethernet1/1/4 34 | bridge-port mode trunk 35 | bridge-port trunk native vlan 1001 36 | bridge-port trunk allowed vlan 1,1001 37 | aggregation-group 14 mode active 38 | spanning-tree port type edge 39 | ! 40 | interface Ethernet1/2/1 41 | bridge-port mode trunk 42 | bridge-port trunk native vlan 1001 43 | bridge-port trunk allowed vlan 1,1001 44 | aggregation-group 21 mode active 45 | spanning-tree port type edge 46 | ! 47 | interface Ethernet1/2/2 48 | bridge-port mode trunk 49 | bridge-port trunk native vlan 1001 50 | bridge-port trunk allowed vlan 1,1001 51 | aggregation-group 22 mode active 52 | spanning-tree port type edge 53 | ! 54 | interface Ethernet1/2/3 55 | bridge-port mode trunk 56 | bridge-port trunk native vlan 1001 57 | bridge-port trunk allowed vlan 1,1001 58 | aggregation-group 23 mode active 59 | spanning-tree port type edge 60 | ! 61 | interface Ethernet1/2/4 62 | bridge-port mode trunk 63 | bridge-port trunk native vlan 1001 64 | bridge-port trunk allowed vlan 1,1001 65 | aggregation-group 24 mode active 66 | spanning-tree port type edge 67 | ! 68 | interface Ethernet1/3/1 69 | bridge-port mode trunk 70 | bridge-port trunk native vlan 1001 71 | bridge-port trunk allowed vlan 1,1001 72 | aggregation-group 31 mode active 73 | spanning-tree port type edge 74 | ! 75 | interface Ethernet1/3/2 76 | bridge-port mode trunk 77 | bridge-port trunk native vlan 1001 78 | bridge-port trunk allowed vlan 1,1001 79 | aggregation-group 32 mode active 80 | spanning-tree port type edge 81 | ! 82 | interface Ethernet1/3/3 83 | bridge-port mode trunk 84 | bridge-port trunk native vlan 1001 85 | bridge-port trunk allowed vlan 1,1001 86 | aggregation-group 33 mode active 87 | spanning-tree port type edge 88 | ! 89 | interface Ethernet1/3/4 90 | bridge-port mode trunk 91 | bridge-port trunk native vlan 1001 92 | bridge-port trunk allowed vlan 1,1001 93 | aggregation-group 34 mode active 94 | spanning-tree port type edge 95 | ! 96 | interface Ethernet1/31 97 | bridge-port mode trunk 98 | bridge-port trunk native vlan 2001 99 | bridge-port trunk allowed vlan 1,1001,2001 100 | aggregation-group 1 mode active 101 | lacp port-priority 10 102 | ! 103 | interface Ethernet1/32 104 | bridge-port mode trunk 105 | bridge-port trunk native vlan 2001 106 | bridge-port trunk allowed vlan 1,1001,2001 107 | aggregation-group 1 mode active 108 | lacp port-priority 10 109 | ! 110 | interface loopback0 111 | no bridge-port 112 | ! 113 | interface Vlan1 114 | no bridge-port 115 | ! 116 | interface port-aggregation1 117 | lacp suspend-individual 118 | bridge-port mode trunk 119 | bridge-port trunk native vlan 2001 120 | bridge-port trunk allowed vlan 1,1001,2001 121 | ! 122 | interface port-aggregation11 123 | bridge-port mode trunk 124 | bridge-port trunk native vlan 1001 125 | bridge-port trunk allowed vlan 1,1001 126 | ! 127 | interface port-aggregation12 128 | bridge-port mode trunk 129 | bridge-port trunk native vlan 1001 130 | bridge-port trunk allowed vlan 1,1001 131 | ! 132 | interface port-aggregation13 133 | bridge-port mode trunk 134 | bridge-port trunk native vlan 1001 135 | bridge-port trunk allowed vlan 1,1001 136 | ! 137 | interface port-aggregation14 138 | bridge-port mode trunk 139 | bridge-port trunk native vlan 1001 140 | bridge-port trunk allowed vlan 1,1001 141 | ! 142 | interface port-aggregation21 143 | bridge-port mode trunk 144 | bridge-port trunk native vlan 1001 145 | bridge-port trunk allowed vlan 1,1001 146 | ! 147 | interface port-aggregation22 148 | bridge-port mode trunk 149 | bridge-port trunk native vlan 1001 150 | bridge-port trunk allowed vlan 1,1001 151 | ! 152 | interface port-aggregation23 153 | bridge-port mode trunk 154 | bridge-port trunk native vlan 1001 155 | bridge-port trunk allowed vlan 1,1001 156 | ! 157 | interface port-aggregation24 158 | bridge-port mode trunk 159 | bridge-port trunk native vlan 1001 160 | bridge-port trunk allowed vlan 1,1001 161 | ! 162 | interface port-aggregation31 163 | bridge-port mode trunk 164 | bridge-port trunk native vlan 1001 165 | bridge-port trunk allowed vlan 1,1001 166 | ! 167 | interface port-aggregation32 168 | bridge-port mode trunk 169 | bridge-port trunk native vlan 1001 170 | bridge-port trunk allowed vlan 1,1001 171 | ! 172 | interface port-aggregation33 173 | bridge-port mode trunk 174 | bridge-port trunk native vlan 1001 175 | bridge-port trunk allowed vlan 1,1001 176 | ! 177 | interface port-aggregation34 178 | bridge-port mode trunk 179 | bridge-port trunk native vlan 1001 180 | bridge-port trunk allowed vlan 1,1001 181 | ! 182 | line con 0 183 | line vty 0 39 184 | ! 185 | ! 186 | ! 187 | end 188 | 189 | -------------------------------------------------------------------------------- /src/etcd-scaling/roles/etcd_scale/tasks/certificates.yml: -------------------------------------------------------------------------------- 1 | #---------Certificates 2 | - name: Check status of etcd certificates 3 | stat: 4 | path: "{{ etcd_cert_config_dir }}/{{ item }}" 5 | with_items: 6 | - "{{ etcd_cert_prefix }}server.crt" 7 | - "{{ etcd_cert_prefix }}peer.crt" 8 | - "{{ etcd_cert_prefix }}ca.crt" 9 | register: g_etcd_server_cert_stat_result 10 | 11 | 12 | - name: Ensure generated_certs directory present 13 | file: 14 | path: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}" 15 | state: directory 16 | mode: 0700 17 | delegate_to: "{{ etcd_ca_host }}" 18 | 19 | - name: Create the server csr 20 | command: > 21 | openssl req -new -keyout {{ etcd_cert_prefix }}server.key 22 | -config {{ etcd_openssl_conf }} 23 | -out {{ etcd_cert_prefix }}server.csr 24 | -reqexts {{ etcd_req_ext }} -batch -nodes 25 | -subj /CN={{ etcd_hostname }} 26 | args: 27 | chdir: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}" 28 | creates: "{{ etcd_generated_certs_dir ~ '/' ~ etcd_cert_subdir ~ '/' 29 | ~ etcd_cert_prefix ~ 'server.csr' }}" 30 | environment: 31 | SAN: "IP:{{ etcd_ip }}" 32 | delegate_to: "{{ etcd_ca_host }}" 33 | 34 | - name: Sign and create the server crt 35 | delegated_serial_command: 36 | command: > 37 | openssl ca -name {{ etcd_ca_name }} -config {{ etcd_openssl_conf }} 38 | -out {{ etcd_cert_prefix }}server.crt 39 | -in {{ etcd_cert_prefix }}server.csr 40 | -extensions {{ etcd_ca_exts_server }} -batch 41 | chdir: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}" 42 | creates: "{{ etcd_generated_certs_dir ~ '/' ~ etcd_cert_subdir ~ '/' 43 | ~ etcd_cert_prefix ~ 'server.crt' }}" 44 | environment: 45 | SAN: "IP:{{ etcd_ip }}" 46 | delegate_to: "{{ etcd_ca_host }}" 47 | 48 | 49 | - name: Create the peer csr 50 | command: > 51 | openssl req -new -keyout {{ etcd_cert_prefix }}peer.key 52 | -config {{ etcd_openssl_conf }} 53 | -out {{ etcd_cert_prefix }}peer.csr 54 | -reqexts {{ etcd_req_ext }} -batch -nodes 55 | -subj /CN={{ etcd_hostname }} 56 | args: 57 | chdir: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}" 58 | creates: "{{ etcd_generated_certs_dir ~ '/' ~ etcd_cert_subdir ~ '/' 59 | ~ etcd_cert_prefix ~ 'peer.csr' }}" 60 | environment: 61 | SAN: "IP:{{ etcd_ip }}" 62 | delegate_to: "{{ etcd_ca_host }}" 63 | 64 | 65 | # Certificates must be signed serially in order to avoid competing 66 | # for the serial file. 67 | - name: Sign and create the peer crt 68 | delegated_serial_command: 69 | command: > 70 | openssl ca -name {{ etcd_ca_name }} -config {{ etcd_openssl_conf }} 71 | -out {{ etcd_cert_prefix }}peer.crt 72 | -in {{ etcd_cert_prefix }}peer.csr 73 | -extensions {{ etcd_ca_exts_peer }} -batch 74 | chdir: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}" 75 | creates: "{{ etcd_generated_certs_dir ~ '/' ~ etcd_cert_subdir ~ '/' 76 | ~ etcd_cert_prefix ~ 'peer.crt' }}" 77 | environment: 78 | SAN: "IP:{{ etcd_ip }}" 79 | delegate_to: "{{ etcd_ca_host }}" 80 | 81 | - file: 82 | src: "{{ etcd_ca_cert }}" 83 | dest: "{{ etcd_generated_certs_dir}}/{{ etcd_cert_subdir }}/{{ etcd_cert_prefix }}ca.crt" 84 | state: hard 85 | delegate_to: "{{ etcd_ca_host }}" 86 | 87 | - name: Create local temp directory for syncing certs 88 | local_action: command mktemp -d /tmp/etcd_certificates-XXXXXXX 89 | become_user: openshift 90 | register: g_etcd_server_mktemp 91 | changed_when: False 92 | delegate_to: localhost 93 | 94 | - name: Create a tarball of the etcd certs 95 | command: > 96 | tar -czvf {{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}.tgz 97 | -C {{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }} . 98 | args: 99 | creates: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}.tgz" 100 | # Disables the following warning: 101 | # Consider using unarchive module rather than running tar 102 | warn: no 103 | delegate_to: "{{ etcd_ca_host }}" 104 | 105 | - name: Retrieve etcd cert tarball 106 | fetch: 107 | src: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}.tgz" 108 | dest: "{{ g_etcd_server_mktemp.stdout }}/" 109 | flat: yes 110 | fail_on_missing: yes 111 | validate_checksum: yes 112 | delegate_to: "{{ etcd_ca_host }}" 113 | 114 | - name: Ensure certificate directory exists 115 | file: 116 | path: "{{ etcd_cert_config_dir }}" 117 | state: directory 118 | 119 | - name: Unarchive cert tarball 120 | unarchive: 121 | src: "{{ g_etcd_server_mktemp.stdout }}/{{ etcd_cert_subdir }}.tgz" 122 | dest: "{{ etcd_cert_config_dir }}" 123 | 124 | - name: Delete temporary directory 125 | file: name={{ g_etcd_server_mktemp.stdout }} state=absent 126 | become_user: openshift 127 | changed_when: False 128 | delegate_to: localhost 129 | 130 | - name: Validate permissions on certificate files 131 | file: 132 | path: "{{ item }}" 133 | mode: 0600 134 | owner: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}" 135 | group: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}" 136 | when: etcd_url_scheme == 'https' 137 | with_items: 138 | - "{{ etcd_ca_file }}" 139 | - "{{ etcd_cert_file }}" 140 | - "{{ etcd_key_file }}" 141 | 142 | - name: Validate permissions on peer certificate files 143 | file: 144 | path: "{{ item }}" 145 | mode: 0600 146 | owner: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}" 147 | group: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}" 148 | when: etcd_peer_url_scheme == 'https' 149 | with_items: 150 | - "{{ etcd_peer_ca_file }}" 151 | - "{{ etcd_peer_cert_file }}" 152 | - "{{ etcd_peer_key_file }}" 153 | 154 | - name: Validate permissions on the config dir 155 | file: 156 | path: "{{ etcd_conf_dir }}" 157 | state: directory 158 | owner: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}" 159 | group: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}" 160 | mode: 0700 161 | -------------------------------------------------------------------------------- /hosts.example: -------------------------------------------------------------------------------- 1 | [OSEv3:children] 2 | masters 3 | nodes 4 | etcd 5 | lb 6 | local 7 | glusterfs 8 | glusterfs_registry 9 | 10 | [OSEv3:vars] 11 | ansible_ssh_user=openshift 12 | ansible_become=true 13 | openshift_master_cluster_method=native 14 | openshift_master_cluster_hostname=ocp.example.local 15 | openshift_master_cluster_public_hostname=ocp.example.com 16 | openshift_master_default_subdomain=apps.ocp.example.com 17 | openshift_master_cluster_ip=172.30.4.30 18 | openshift_master_cluster_public_ip=100.65.0.30 19 | openshift_master_portal_net=10.0.0.0/16 20 | deployment_type=openshift-enterprise 21 | openshift_release=v3.6 22 | os_sdn_network_plugin_name='redhat/openshift-ovs-multitenant' 23 | openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', 'challenge': 'true', 'kind': 'HTPasswdPasswordIdentityProvider', 'filename': '/etc/origin/master/users.htpasswd'}] 24 | openshift_master_htpasswd_users={'admin': '$apr1$vC6GcVUP$AHZDU5BAFF6dDMfk.IFzG1'} 25 | rhel_subscription_user=user@example.com 26 | rhel_subscription_pass=portal_password 27 | openshift_hosted_registry_storage_kind=glusterfs 28 | openshift_hosted_registry_storage_volume_size=200Gi 29 | openshift_storage_glusterfs_registry_storageclass=True 30 | local_dns=172.30.4.10 31 | external_interface=bond0 32 | external_vlan= 2017 33 | external_netmask=255.255.240.0 34 | external_gateway=100.65.0.1 35 | internal_interface=bond0 36 | internal_netmask=255.255.255.0 37 | bastion_ip=172.30.4.10 38 | internal_gateway={{ bastion_ip }} 39 | dhcp_first_ip=172.30.4.100 40 | dhcp_last_ip=172.30.4.150 41 | root_password=NODE_ROOT_PASSWORD 42 | 43 | [local] 44 | 127.0.0.1 45 | 46 | [masters] 47 | master1.ocp.example.local containerized=True openshift_schedulable=False openshift_ip=172.30.4.11 openshift_hostname=master1.ocp.example.local 48 | master2.ocp.example.local containerized=True openshift_schedulable=False openshift_ip=172.30.4.12 openshift_hostname=master2.ocp.example.local 49 | master3.ocp.example.local containerized=True openshift_schedulable=False openshift_ip=172.30.4.13 openshift_hostname=master3.ocp.example.local 50 | 51 | [nodes] 52 | master1.ocp.example.local openshift_schedulable=False openshift_ip=172.30.4.11 openshift_hostname=master1.ocp.example.local ipmi=192.168.25.12 serial=BQF973900001 53 | master2.ocp.example.local openshift_schedulable=False openshift_ip=172.30.4.12 openshift_hostname=master2.ocp.example.local ipmi=192.168.25.13 serial=BQF973900002 54 | master3.ocp.example.local openshift_schedulable=False openshift_ip=172.30.4.13 openshift_hostname=master3.ocp.example.local ipmi=192.168.25.14 serial=BQF973900003 55 | infra1.ocp.example.local openshift_node_labels="{'region': 'infra'}" openshift_schedulable=True containerized=True openshift_public_ip=100.65.0.14 openshift_ip=172.30.4.14 openshift_hostname=infra1.ocp.example.local ipmi=192.168.25.15 serial=BQF973900006 56 | infra2.ocp.example.local openshift_node_labels="{'region': 'infra'}" openshift_schedulable=True containerized=True openshift_public_ip=100.65.0.15 openshift_ip=172.30.4.15 openshift_hostname=infra2.ocp.example.local ipmi=192.168.25.16 serial=BQF973900004 57 | app1.ocp.example.local containerized=True openshift_schedulable=True openshift_ip=172.30.4.16 openshift_hostname=app1.ocp.example.local ipmi=192.168.25.17 serial=BQF973900007 58 | app2.ocp.example.local containerized=True openshift_schedulable=True openshift_ip=172.30.4.17 openshift_hostname=app2.ocp.example.local ipmi=192.168.25.18 serial=BQF973900009 59 | app3.ocp.example.local containerized=True openshift_schedulable=True openshift_ip=172.30.4.18 openshift_hostname=app3.ocp.example.local ipmi=192.168.25.19 serial=BQF973900008 60 | app4.ocp.example.local containerized=True openshift_schedulable=True openshift_ip=172.30.4.19 openshift_hostname=app4.ocp.example.local ipmi=192.168.25.20 serial=BQF973900011 61 | app5.ocp.example.local containerized=True openshift_schedulable=True openshift_ip=172.30.4.20 openshift_hostname=app5.ocp.example.local ipmi=192.168.25.21 serial=BQF973900010 62 | app6.ocp.example.local containerized=True openshift_schedulable=True openshift_ip=172.30.4.21 openshift_hostname=app6.ocp.example.local ipmi=192.168.25.22 serial=BQF973900012 63 | gluster1.ocp.example.local containerized=True openshift_schedulable=True openshift_ip=172.30.4.22 openshift_hostname=gluster1.ocp.example.local ipmi=192.168.25.23 serial=BQF974100202 64 | gluster2.ocp.example.local containerized=True openshift_schedulable=True openshift_ip=172.30.4.23 openshift_hostname=gluster2.ocp.example.local ipmi=192.168.25.24 serial=BQF974100201 65 | gluster3.ocp.example.local containerized=True openshift_schedulable=True openshift_ip=172.30.4.24 openshift_hostname=gluster3.ocp.example.local ipmi=192.168.25.25 serial=BQF974100203 66 | 67 | [etcd] 68 | etcd1.ocp.example.local containerized=True openshift_ip=172.30.4.11 openshift_hostname=etcd1.ocp.example.local 69 | etcd2.ocp.example.local containerized=True openshift_ip=172.30.4.12 openshift_hostname=etcd2.ocp.example.local 70 | etcd3.ocp.example.local containerized=True openshift_ip=172.30.4.13 openshift_hostname=etcd3.ocp.example.local 71 | 72 | [lb] 73 | lb1.ocp.example.local openshift_hostname=lb1.ocp.example.local openshift_ip=172.30.4.14 openshift_public_ip=100.65.0.14 74 | lb2.ocp.example.local openshift_hostname=lb2.ocp.example.local openshift_ip=172.30.4.15 openshift_public_ip=100.65.0.15 75 | 76 | [glusterfs] 77 | app1.ocp.example.local glusterfs_ip=172.30.4.16 glusterfs_devices="[ '/dev/nvme0n1' ]" 78 | app2.ocp.example.local glusterfs_ip=172.30.4.17 glusterfs_devices="[ '/dev/nvme0n1' ]" 79 | app3.ocp.example.local glusterfs_ip=172.30.4.18 glusterfs_devices="[ '/dev/nvme0n1' ]" 80 | app4.ocp.example.local glusterfs_ip=172.30.4.19 glusterfs_devices="[ '/dev/nvme0n1' ]" 81 | app5.ocp.example.local glusterfs_ip=172.30.4.20 glusterfs_devices="[ '/dev/nvme0n1' ]" 82 | app6.ocp.example.local glusterfs_ip=172.30.4.21 glusterfs_devices="[ '/dev/nvme0n1' ]" 83 | 84 | [glusterfs_registry] 85 | gluster1.ocp.example.local glusterfs_ip=172.30.4.22 glusterfs_devices="[ '/dev/sdb', '/dev/sdc', '/dev/sdd', '/dev/sde', '/dev/sdf', '/dev/sdg', '/dev/sdh', '/dev/sdi', '/dev/sdj', '/dev/sdk', '/dev/sdl', '/dev/sdm', '/dev/sdn', '/dev/sdo', '/dev/sdp', '/dev/sdq', '/dev/sdr', '/dev/sds', '/dev/sdt', '/dev/sdu' ]" 86 | gluster2.ocp.example.local glusterfs_ip=172.30.4.23 glusterfs_devices="[ '/dev/sdb', '/dev/sdc', '/dev/sdd', '/dev/sde', '/dev/sdf', '/dev/sdg', '/dev/sdh', '/dev/sdi', '/dev/sdj', '/dev/sdk', '/dev/sdl', '/dev/sdm', '/dev/sdn', '/dev/sdo', '/dev/sdp', '/dev/sdq', '/dev/sdr', '/dev/sds', '/dev/sdt', '/dev/sdu' ]" 87 | gluster3.ocp.example.local glusterfs_ip=172.30.4.24 glusterfs_devices="[ '/dev/sdb', '/dev/sdc', '/dev/sdd', '/dev/sde', '/dev/sdf', '/dev/sdg', '/dev/sdh', '/dev/sdi', '/dev/sdj', '/dev/sdk', '/dev/sdl', '/dev/sdm', '/dev/sdn', '/dev/sdo', '/dev/sdp', '/dev/sdq', '/dev/sdr', '/dev/sds', '/dev/sdt', '/dev/sdu' ]" 88 | 89 | [arista] 90 | arista-1 ansible_host=192.168.25.2 ansible_user=admin ansible_password=SWITCH_ADMIN_PASSWORD 91 | arista-2 ansible_host=192.168.25.3 ansible_user=admin ansible_password=SWITCH_ADMIN_PASSWORD 92 | -------------------------------------------------------------------------------- /src/etcd-scaling/roles/etcd_scale/library/delegated_serial_command.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | # (c) 2012, Michael DeHaan , and others 5 | # (c) 2016, Andrew Butcher 6 | # 7 | # This module is derrived from the Ansible command module. 8 | # 9 | # Ansible is free software: you can redistribute it and/or modify 10 | # it under the terms of the GNU General Public License as published by 11 | # the Free Software Foundation, either version 3 of the License, or 12 | # (at your option) any later version. 13 | # 14 | # Ansible is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | # GNU General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU General Public License 20 | # along with Ansible. If not, see . 21 | 22 | 23 | # pylint: disable=unused-wildcard-import,wildcard-import,unused-import,redefined-builtin 24 | 25 | ''' delegated_serial_command ''' 26 | 27 | import copy 28 | import sys 29 | import datetime 30 | import glob 31 | import traceback 32 | import re 33 | import shlex 34 | import os 35 | import fcntl 36 | import time 37 | 38 | DOCUMENTATION = ''' 39 | --- 40 | module: delegated_serial_command 41 | short_description: Executes a command on a remote node 42 | version_added: historical 43 | description: 44 | - The M(command) module takes the command name followed by a list 45 | of space-delimited arguments. 46 | - The given command will be executed on all selected nodes. It 47 | will not be processed through the shell, so variables like 48 | C($HOME) and operations like C("<"), C(">"), C("|"), and C("&") 49 | will not work (use the M(shell) module if you need these 50 | features). 51 | - Creates and maintains a lockfile such that this module will 52 | wait for other invocations to proceed. 53 | options: 54 | command: 55 | description: 56 | - the command to run 57 | required: true 58 | default: null 59 | creates: 60 | description: 61 | - a filename or (since 2.0) glob pattern, when it already 62 | exists, this step will B(not) be run. 63 | required: no 64 | default: null 65 | removes: 66 | description: 67 | - a filename or (since 2.0) glob pattern, when it does not 68 | exist, this step will B(not) be run. 69 | version_added: "0.8" 70 | required: no 71 | default: null 72 | chdir: 73 | description: 74 | - cd into this directory before running the command 75 | version_added: "0.6" 76 | required: false 77 | default: null 78 | executable: 79 | description: 80 | - change the shell used to execute the command. Should be an 81 | absolute path to the executable. 82 | required: false 83 | default: null 84 | version_added: "0.9" 85 | warn: 86 | version_added: "1.8" 87 | default: yes 88 | description: 89 | - if command warnings are on in ansible.cfg, do not warn about 90 | this particular line if set to no/false. 91 | required: false 92 | lockfile: 93 | default: yes 94 | description: 95 | - the lockfile that will be created 96 | timeout: 97 | default: yes 98 | description: 99 | - time in milliseconds to wait to obtain the lock 100 | notes: 101 | - If you want to run a command through the shell (say you are using C(<), 102 | C(>), C(|), etc), you actually want the M(shell) module instead. The 103 | M(command) module is much more secure as it's not affected by the user's 104 | environment. 105 | - " C(creates), C(removes), and C(chdir) can be specified after 106 | the command. For instance, if you only want to run a command if 107 | a certain file does not exist, use this." 108 | author: 109 | - Ansible Core Team 110 | - Michael DeHaan 111 | - Andrew Butcher 112 | ''' 113 | 114 | EXAMPLES = ''' 115 | # Example from Ansible Playbooks. 116 | - delegated_serial_command: 117 | command: /sbin/shutdown -t now 118 | 119 | # Run the command if the specified file does not exist. 120 | - delegated_serial_command: 121 | command: /usr/bin/make_database.sh arg1 arg2 122 | creates: /path/to/database 123 | ''' 124 | 125 | # Dict of options and their defaults 126 | OPTIONS = {'chdir': None, 127 | 'creates': None, 128 | 'command': None, 129 | 'executable': None, 130 | 'NO_LOG': None, 131 | 'removes': None, 132 | 'warn': True, 133 | 'lockfile': None, 134 | 'timeout': None} 135 | 136 | def check_command(commandline): 137 | ''' Check provided command ''' 138 | arguments = {'chown': 'owner', 'chmod': 'mode', 'chgrp': 'group', 139 | 'ln': 'state=link', 'mkdir': 'state=directory', 140 | 'rmdir': 'state=absent', 'rm': 'state=absent', 'touch': 'state=touch'} 141 | commands = {'git': 'git', 'hg': 'hg', 'curl': 'get_url or uri', 'wget': 'get_url or uri', 142 | 'svn': 'subversion', 'service': 'service', 143 | 'mount': 'mount', 'rpm': 'yum, dnf or zypper', 'yum': 'yum', 'apt-get': 'apt', 144 | 'tar': 'unarchive', 'unzip': 'unarchive', 'sed': 'template or lineinfile', 145 | 'rsync': 'synchronize', 'dnf': 'dnf', 'zypper': 'zypper'} 146 | become = ['sudo', 'su', 'pbrun', 'pfexec', 'runas'] 147 | warnings = list() 148 | command = os.path.basename(commandline.split()[0]) 149 | # pylint: disable=line-too-long 150 | if command in arguments: 151 | warnings.append("Consider using file module with {0} rather than running {1}".format(arguments[command], command)) 152 | if command in commands: 153 | warnings.append("Consider using {0} module rather than running {1}".format(commands[command], command)) 154 | if command in become: 155 | warnings.append( 156 | "Consider using 'become', 'become_method', and 'become_user' rather than running {0}".format(command,)) 157 | return warnings 158 | 159 | 160 | # pylint: disable=too-many-statements,too-many-branches,too-many-locals 161 | def main(): 162 | ''' Main module function ''' 163 | module = AnsibleModule( 164 | argument_spec=dict( 165 | _uses_shell=dict(type='bool', default=False), 166 | command=dict(required=True), 167 | chdir=dict(), 168 | executable=dict(), 169 | creates=dict(), 170 | removes=dict(), 171 | warn=dict(type='bool', default=True), 172 | lockfile=dict(default='/tmp/delegated_serial_command.lock'), 173 | timeout=dict(type='int', default=30) 174 | ) 175 | ) 176 | 177 | shell = module.params['_uses_shell'] 178 | chdir = module.params['chdir'] 179 | executable = module.params['executable'] 180 | command = module.params['command'] 181 | creates = module.params['creates'] 182 | removes = module.params['removes'] 183 | warn = module.params['warn'] 184 | lockfile = module.params['lockfile'] 185 | timeout = module.params['timeout'] 186 | 187 | if command.strip() == '': 188 | module.fail_json(rc=256, msg="no command given") 189 | 190 | iterated = 0 191 | lockfd = open(lockfile, 'w+') 192 | while iterated < timeout: 193 | try: 194 | fcntl.flock(lockfd, fcntl.LOCK_EX | fcntl.LOCK_NB) 195 | break 196 | # pylint: disable=invalid-name 197 | except IOError as e: 198 | if e.errno != errno.EAGAIN: 199 | module.fail_json(msg="I/O Error {0}: {1}".format(e.errno, e.strerror)) 200 | else: 201 | iterated += 1 202 | time.sleep(0.1) 203 | 204 | if chdir: 205 | chdir = os.path.abspath(os.path.expanduser(chdir)) 206 | os.chdir(chdir) 207 | 208 | if creates: 209 | # do not run the command if the line contains creates=filename 210 | # and the filename already exists. This allows idempotence 211 | # of command executions. 212 | path = os.path.expanduser(creates) 213 | if glob.glob(path): 214 | module.exit_json( 215 | cmd=command, 216 | stdout="skipped, since %s exists" % path, 217 | changed=False, 218 | stderr=False, 219 | rc=0 220 | ) 221 | 222 | if removes: 223 | # do not run the command if the line contains removes=filename 224 | # and the filename does not exist. This allows idempotence 225 | # of command executions. 226 | path = os.path.expanduser(removes) 227 | if not glob.glob(path): 228 | module.exit_json( 229 | cmd=command, 230 | stdout="skipped, since %s does not exist" % path, 231 | changed=False, 232 | stderr=False, 233 | rc=0 234 | ) 235 | 236 | warnings = list() 237 | if warn: 238 | warnings = check_command(command) 239 | 240 | if not shell: 241 | command = shlex.split(command) 242 | startd = datetime.datetime.now() 243 | 244 | # pylint: disable=invalid-name 245 | rc, out, err = module.run_command(command, executable=executable, use_unsafe_shell=shell) 246 | 247 | fcntl.flock(lockfd, fcntl.LOCK_UN) 248 | lockfd.close() 249 | 250 | endd = datetime.datetime.now() 251 | delta = endd - startd 252 | 253 | if out is None: 254 | out = '' 255 | if err is None: 256 | err = '' 257 | 258 | module.exit_json( 259 | cmd=command, 260 | stdout=out.rstrip("\r\n"), 261 | stderr=err.rstrip("\r\n"), 262 | rc=rc, 263 | start=str(startd), 264 | end=str(endd), 265 | delta=str(delta), 266 | changed=True, 267 | warnings=warnings, 268 | iterated=iterated 269 | ) 270 | 271 | # import module snippets 272 | from ansible.module_utils.basic import * 273 | 274 | main() 275 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | Copyright (c) 2017 Intel Corporation 180 | 181 | Licensed under the Apache License, Version 2.0 (the "License"); 182 | you may not use this file except in compliance with the License. 183 | You may obtain a copy of the License at 184 | 185 | http://www.apache.org/licenses/LICENSE-2.0 186 | 187 | Unless required by applicable law or agreed to in writing, software 188 | distributed under the License is distributed on an "AS IS" BASIS, 189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 190 | See the License for the specific language governing permissions and 191 | limitations under the License. 192 | 193 | --------------------------------------------------------------------------------