From f60131cc098048397aac97ffeb5e6f896de21dfa Mon Sep 17 00:00:00 2001 From: Mohammed Naser Date: Fri, 16 Aug 2019 16:10:40 -0400 Subject: [PATCH] initial commit Change-Id: Ib7a1691adf76d8f90996fcfe9cb9e2371bc138c4 --- .gitignore | 6 ++ Vagrantfile | 32 +++++++++ ansible/site.yaml | 139 ++++++++++++++++++++++++++++++++++++++++ hack/cluster-up.sh | 20 ++++++ kue/__init__.py | 0 kue/cmd/__init__.py | 0 kue/cmd/cli.py | 38 +++++++++++ kue/common/__init__.py | 0 kue/common/config.py | 39 +++++++++++ kue/drivers/__init__.py | 0 kue/drivers/ansible.py | 34 ++++++++++ playbooks/pre.yaml | 29 +++++++++ playbooks/run.yaml | 34 ++++++++++ requirements.txt | 2 + setup.cfg | 12 ++++ setup.py | 19 ++++++ tox.ini | 17 +++++ zuul.d/jobs.yaml | 30 +++++++++ zuul.d/nodesets.yaml | 47 ++++++++++++++ zuul.d/project.yaml | 24 +++++++ 20 files changed, 522 insertions(+) create mode 100644 .gitignore create mode 100644 Vagrantfile create mode 100644 ansible/site.yaml create mode 100755 hack/cluster-up.sh create mode 100644 kue/__init__.py create mode 100644 kue/cmd/__init__.py create mode 100644 kue/cmd/cli.py create mode 100644 kue/common/__init__.py create mode 100644 kue/common/config.py create mode 100644 kue/drivers/__init__.py create mode 100644 kue/drivers/ansible.py create mode 100644 playbooks/pre.yaml create mode 100644 playbooks/run.yaml create mode 100644 requirements.txt create mode 100644 setup.cfg create mode 100644 setup.py create mode 100644 tox.ini create mode 100644 zuul.d/jobs.yaml create mode 100644 zuul.d/nodesets.yaml create mode 100644 zuul.d/project.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..23d07da --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.eggs +.tox +.vagrant +.vscode +__pycache__ +*.egg-info \ No newline at end of file diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000..f37047e --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,32 @@ +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ENV['VAGRANT_LIBVIRT_QEMU_USE_SESSION'] = 'false' + +Vagrant.configure("2") do |config| + config.vm.box = "generic/ubuntu1804" + config.vm.synced_folder ".", "/vagrant", disabled: true + + config.vm.define "master" do |machine| + machine.vm.hostname = "master" + end + + config.vm.define "minion-1" do |machine| + machine.vm.hostname = "minion-1" + end + + config.vm.define "minion-2" do |machine| + machine.vm.hostname = "minion-2" + end +end \ No newline at end of file diff --git a/ansible/site.yaml b/ansible/site.yaml new file mode 100644 index 0000000..1c7df43 --- /dev/null +++ b/ansible/site.yaml @@ -0,0 +1,139 @@ +--- +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Bootstrap nodes + hosts: all + strategy: free + tasks: + - name: Disable swap + become: true + shell: swapoff -a + + - name: Enable forwarding + become: true + shell: iptables -P FORWARD ACCEPT + + - name: Add repository keys + become: true + apt_key: + url: "{{ item }}" + state: present + loop: + - https://download.docker.com/linux/ubuntu/gpg + - https://packages.cloud.google.com/apt/doc/apt-key.gpg + + - name: Add repository + become: true + apt_repository: + repo: "{{ item }}" + state: present + loop: + - "deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable" + - "deb https://apt.kubernetes.io/ kubernetes-xenial main" + + - name: Install packages + become: true + apt: + name: + - docker-ce=18.06.2~ce~3-0~ubuntu + - kubelet=1.15.2-00 + - kubeadm=1.15.2-00 + - kubectl=1.15.2-00 + + - name: Enable services + become: true + service: + name: "{{ item }}" + state: started + enabled: true + loop: + - docker + - kubelet + +- name: Bootstrap cluster + hosts: masters[0] + gather_facts: false + tasks: + - name: Wait for bootstrap node to go up + wait_for_connection: + timeout: 300 + + - name: Initialize cluster + become: true + shell: | + kubeadm init --pod-network-cidr=10.244.0.0/16 + args: + creates: /etc/kubernetes/manifests/kube-apiserver.yaml + +- name: Join nodes to cluster + hosts: all:!masters[0] + strategy: free + gather_facts: false + tasks: + - name: Wait for nodes to go up + wait_for_connection: + timeout: 300 + + - name: Check if we're already part of the cluster + become: true + register: apiserver_stat + stat: + path: /etc/kubernetes/kubelet.conf + + - name: Generate token for cluster join + become: true + delegate_to: "{{ groups['masters'][0] }}" + register: kubeadm_token_create + shell: | + kubeadm token create --ttl 5m --print-join-command + when: + - not apiserver_stat.stat.exists + + - name: Join cluster + become: true + shell: "{{ kubeadm_token_create.stdout }}" + when: + - not apiserver_stat.stat.exists + +- name: Configure administration access + hosts: masters + gather_facts: false + tasks: + - name: Create configuration folders + file: + path: "/home/{{ ansible_user }}/{{ item }}" + state: directory + loop: + - .kube + - manifests + + - name: Copy configuration file + become: true + copy: + src: /etc/kubernetes/admin.conf + dest: "/home/{{ ansible_user }}/.kube/config" + remote_src: true + owner: "{{ ansible_user }}" + group: "{{ ansible_user }}" + +- name: Install manifests + hosts: masters + gather_facts: false + tasks: + - name: Apply flannel configuration + run_once: true + changed_when: false + shell: | + kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml diff --git a/hack/cluster-up.sh b/hack/cluster-up.sh new file mode 100755 index 0000000..22fe1fc --- /dev/null +++ b/hack/cluster-up.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +set -xe + +# Start up the machines +vagrant up + +# Grab all the IP addresses +MASTER_IP=$(vagrant ssh master -c "hostname -I" 2>/dev/null | xargs echo -n) +MINION_1_IP=$(vagrant ssh minion-1 -c "hostname -I" 2>/dev/null | xargs echo -n) +MINION_2_IP=$(vagrant ssh minion-2 -c "hostname -I" 2>/dev/null | xargs echo -n) + +# Start up an SSH agent +eval `ssh-agent -s` +ssh-add .vagrant/machines/master/libvirt/private_key +ssh-add .vagrant/machines/minion-1/libvirt/private_key +ssh-add .vagrant/machines/minion-2/libvirt/private_key +trap "ssh-agent -k" exit + +tox -evenv -- kue-cli --user vagrant --master ${MASTER_IP} --minion ${MINION_1_IP} --minion ${MINION_2_IP} \ No newline at end of file diff --git a/kue/__init__.py b/kue/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kue/cmd/__init__.py b/kue/cmd/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kue/cmd/cli.py b/kue/cmd/cli.py new file mode 100644 index 0000000..99fddb9 --- /dev/null +++ b/kue/cmd/cli.py @@ -0,0 +1,38 @@ +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import argparse + +from kue.drivers import ansible +from kue.common import config + +parser = argparse.ArgumentParser() + +parser.add_argument('--user', type=str, required=True, + help='ssh username') +parser.add_argument('--master', type=str, required=True, + help='master') +parser.add_argument('--minion', type=str, required=True, action='append', + help='minion') + +def main(): + args = parser.parse_args() + + cluster_config = config.ClusterConfig() + cluster_config.user = args.user + cluster_config.masters = [args.master] + cluster_config.minions = args.minion + + cluster = ansible.Cluster(config=cluster_config) + cluster.deploy() \ No newline at end of file diff --git a/kue/common/__init__.py b/kue/common/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kue/common/config.py b/kue/common/config.py new file mode 100644 index 0000000..376dd1b --- /dev/null +++ b/kue/common/config.py @@ -0,0 +1,39 @@ +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +class ClusterConfig(object): + @property + def inventory(self): + return { + "all": { + "children": { + "masters": {}, + "minions": {}, + }, + "vars": { + "ansible_user": self.user + } + }, + "masters": { + "hosts": { + node: {} for node in self.masters + } + }, + "minions": { + "hosts": { + node: {} for node in self.minions + } + } + } diff --git a/kue/drivers/__init__.py b/kue/drivers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kue/drivers/ansible.py b/kue/drivers/ansible.py new file mode 100644 index 0000000..e52d8aa --- /dev/null +++ b/kue/drivers/ansible.py @@ -0,0 +1,34 @@ +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import shutil +import tempfile + +import ansible_runner + + +class Cluster(object): + def __init__(self, config): + self.config = config + + def deploy(self): + private_data_dir = tempfile.mkdtemp() + + try: + shutil.copytree('ansible', '%s/project' % private_data_dir) + r = ansible_runner.run(private_data_dir=private_data_dir, + inventory=self.config.inventory, + playbook='site.yaml') + finally: + shutil.rmtree(private_data_dir, ignore_errors=True) diff --git a/playbooks/pre.yaml b/playbooks/pre.yaml new file mode 100644 index 0000000..b322f82 --- /dev/null +++ b/playbooks/pre.yaml @@ -0,0 +1,29 @@ +--- +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- hosts: all + tasks: + - name: Flush iptables rules + become: true + iptables: + chain: "{{ item }}" + flush: yes + loop: ['INPUT', 'FORWARD', 'OUTPUT'] + +- hosts: masters + tasks: + - name: Install software + become: true + command: python3 -m pip install {{ zuul.project.src_dir }} \ No newline at end of file diff --git a/playbooks/run.yaml b/playbooks/run.yaml new file mode 100644 index 0000000..3a5f4a2 --- /dev/null +++ b/playbooks/run.yaml @@ -0,0 +1,34 @@ +--- +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- hosts: masters + tasks: + - name: Test kue-cli + shell: >- + kue-cli --user {{ ansible_user }} {% for master in groups['masters'] %}--master {{ hostvars[master]['ansible_host'] }} {% endfor %}{% for minion in groups['minions'] %}--minion {{ hostvars[minion]['ansible_host'] }} {% endfor %} + args: + chdir: "{{ zuul.project.src_dir }}" + +- hosts: masters[0] + tasks: + - name: Wait for all nodes to get ready + shell: kubectl get nodes + register: _kubectl_get_nodes + retries: 30 + delay: 3 + until: '"NotReady" not in _kubectl_get_nodes.stdout' + + - name: Get all nodes + shell: kubectl get nodes \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..a21f626 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +ansible==2.8.4 +ansible-runner==1.3.5 \ No newline at end of file diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..3954b60 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,12 @@ +[metadata] +name = kue + +[files] +packages = + kue +data_files = + ansible = ansible/* + +[entry_points] +console_scripts = + kue-cli = kue.cmd.cli:main diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..11be697 --- /dev/null +++ b/setup.py @@ -0,0 +1,19 @@ +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import setuptools + +setuptools.setup( + setup_requires=['pbr'], + pbr=True) diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..3ab8d7a --- /dev/null +++ b/tox.ini @@ -0,0 +1,17 @@ +[tox] +skipsdist = True + +[testenv] +basepython = python3 +usedevelop = True +passenv = SSH_AUTH_SOCK +deps = + -r{toxinidir}/requirements.txt + +[testenv:linters] +deps = + flake8 +commands = flake8 + +[testenv:venv] +commands = {posargs} \ No newline at end of file diff --git a/zuul.d/jobs.yaml b/zuul.d/jobs.yaml new file mode 100644 index 0000000..879ae78 --- /dev/null +++ b/zuul.d/jobs.yaml @@ -0,0 +1,30 @@ +--- +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- job: + name: kue-integration + nodeset: kue-1-node + pre-run: playbooks/pre.yaml + run: playbooks/run.yaml + +- job: + name: kue-integration-1-node + parent: kue-integration + nodeset: kue-1-node + +- job: + name: kue-integration-2-node + parent: kue-integration + nodeset: kue-2-node \ No newline at end of file diff --git a/zuul.d/nodesets.yaml b/zuul.d/nodesets.yaml new file mode 100644 index 0000000..9215eca --- /dev/null +++ b/zuul.d/nodesets.yaml @@ -0,0 +1,47 @@ +--- +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- nodeset: + name: kue-1-node + nodes: + - name: master + label: ubuntu-bionic + - name: minion-1 + label: ubuntu-bionic + groups: + - name: masters + nodes: + - master + - name: minions + nodes: + - minion-1 + +- nodeset: + name: kue-2-node + nodes: + - name: master + label: ubuntu-bionic + - name: minion-1 + label: ubuntu-bionic + - name: minion-2 + label: ubuntu-bionic + groups: + - name: masters + nodes: + - master + - name: minions + nodes: + - minion-1 + - minion-2 \ No newline at end of file diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml new file mode 100644 index 0000000..e6f7893 --- /dev/null +++ b/zuul.d/project.yaml @@ -0,0 +1,24 @@ +--- +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- project: + check: + jobs: + - kue-integration-1-node + - kue-integration-2-node + gate: + jobs: + - kue-integration-1-node + - kue-integration-2-node \ No newline at end of file