mirror of
https://github.com/weaveworks/scope.git
synced 2026-08-18 03:46:45 +00:00
Squashed 'tools/' changes from a3b18bf..52d695c
52d695c Merge pull request #77 from kinvolk/schu/fix-relative-weave-path 77aed01 Merge pull request #73 from weaveworks/mike/sched/fix-unicode-issue 7c080f4 integration/sanity_check: disable SC1090 d6d360a integration/gce.sh: update gcloud command e8def2c provisioning/setup: fix shellcheck SC2140 cc02224 integration/config: fix weave path 9c0d6a5 Fix config_management/README.md 334708c Merge pull request #75 from kinvolk/alban/external-build-1 da2505d gce.sh: template: print creation date e676854 integration tests: fix user account 8530836 host nameing: add repo name b556c0a gce.sh: fix deletion of gce instances 2ecd1c2 integration: fix GCE --zones/--zone parameter 3e863df sched: Fix unicode encoding issues 51785b5 Use rm -f and set current dir using BASH_SOURCE. f5c6d68 Merge pull request #71 from kinvolk/schu/fix-linter-warnings 0269628 Document requirement for `lint_sh` 9a3f09e Fix linter warnings efcf9d2 Merge pull request #53 from weaveworks/2647-testing-mvp d31ea57 Weave Kube playbook now works with multiple nodes. 27868dd Add GCP firewall rule for FastDP crypto. edc8bb3 Differentiated name of dev and test playbooks, to avoid confusion. efa3df7 Moved utility Ansible Yaml to library directory. fcd2769 Add shorthands to run Ansible playbooks against Terraform-provisioned virtual machines. f7946fb Add shorthands to SSH into Terraform-provisioned virtual machines. aad5c6f Mention Terraform and Ansible in README.md. dddabf0 Add Terraform output required for templates' creation. dcc7d02 Add Ansible configuration playbooks for development environments. f86481c Add Ansible configuration playbooks for Docker, K8S and Weave-Net. efedd25 Git-ignore Ansible retry files. 765c4ca Add helper functions to setup Terraform programmatically. 801dd1d Add Terraform cloud provisioning scripts. b8017e1 Install hclfmt on CircleCI. 4815e19 Git-ignore Terraform state files. 0aaebc7 Add script to generate cartesian product of dependencies of cross-version testing. 007d90a Add script to list OS images from GCP, AWS and DO. ca65cc0 Add script to list relevant versions of Go, Docker and Kubernetes. aa66f44 Scripts now source dependencies using absolute path (previously breaking make depending on current directory). 7865e86 Add -p option to parallelise lint. 36c1835 Merge pull request #69 from weaveworks/mflag 9857568 Use mflag and mflagext package from weaveworks/common. 9799112 Quote bash variable. 10a36b3 Merge pull request #67 from weaveworks/shfmt-ignore a59884f Add support for .lintignore. 03cc598 Don't lint generated protobuf code. 2b55c2d Merge pull request #66 from weaveworks/reduce-test-timeout d4e163c Make timeout a flag 49a8609 Reduce test timeout 8fa15cb Merge pull request #63 from weaveworks/test-defaults b783528 Tweak test script so it can be run on a mca git-subtree-dir: tools git-subtree-split: 52d695cc629c524ff17eb06e2de12d78701919c9
This commit is contained in:
@@ -4,3 +4,6 @@ socks/image.tar
|
||||
runner/runner
|
||||
*.pyc
|
||||
*~
|
||||
terraform.tfstate
|
||||
terraform.tfstate.backup
|
||||
*.retry
|
||||
|
||||
@@ -2,12 +2,14 @@
|
||||
|
||||
Included in this repo are tools shared by weave.git and scope.git. They include
|
||||
|
||||
- ```provisioning```: a set of Terraform scripts to provision virtual machines in GCP, AWS or Digital Ocean.
|
||||
- ```config_management```: a set of Ansible playbooks to configure virtual machines for development, testing, etc.
|
||||
- ```cover```: a tool which merges overlapping coverage reports generated by go
|
||||
test
|
||||
- ```files-with-type```: a tool to search directories for files of a given
|
||||
MIME type
|
||||
- ```lint```: a script to lint Go project; runs various tools like golint, go
|
||||
vet, errcheck etc
|
||||
- ```lint```: a script to lint go, sh and hcl files; runs various tools like
|
||||
golint, go vet, errcheck, shellcheck etc
|
||||
- ```rebuild-image```: a script to rebuild docker images when their input files
|
||||
change; useful when you using docker images to build your software, but you
|
||||
don't want to build the image every time.
|
||||
@@ -24,6 +26,11 @@ Included in this repo are tools shared by weave.git and scope.git. They include
|
||||
- ```scheduler```: an appengine application that can be used to distribute
|
||||
tests across different shards in CircleCI.
|
||||
|
||||
## Requirements
|
||||
|
||||
- ```lint``` requires shfmt to lint sh files; get shfmt with
|
||||
```go get -u gopkg.in/mvdan/sh.v1/cmd/shfmt```
|
||||
|
||||
## Using build-tools.git
|
||||
|
||||
To allow you to tie your code to a specific version of build-tools.git, such
|
||||
|
||||
@@ -19,6 +19,7 @@ dependencies:
|
||||
github.com/fzipp/gocyclo \
|
||||
github.com/golang/lint/golint \
|
||||
github.com/kisielk/errcheck \
|
||||
github.com/fatih/hclfmt \
|
||||
gopkg.in/mvdan/sh.v1/cmd/shfmt
|
||||
|
||||
test:
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
# Weaveworks configuration management
|
||||
|
||||
## Introduction
|
||||
|
||||
This project allows you to configure a machine with:
|
||||
|
||||
* Docker and Weave Net for development: `setup_weave-net_dev.yml`
|
||||
* Docker and Weave Net for testing: `setup_weave-net_test.yml`
|
||||
* Docker, Kubernetes and Weave Kube (CNI plugin): `setup_weave-kube.yml`
|
||||
|
||||
You can then use these environments for development, testing and debugging.
|
||||
|
||||
## Set up
|
||||
|
||||
You will need [Python](https://www.python.org/downloads/) and [Ansible 2.+](http://docs.ansible.com/ansible/intro_installation.html) installed on your machine and added to your `PATH` in order to be able to configure environments automatically.
|
||||
|
||||
* On any platform, if you have Python installed: `pip install ansible`
|
||||
* On macOS: `brew install ansible`
|
||||
* On Linux (via Aptitude): `sudo apt install ansible`
|
||||
* On Linux (via YUM): `sudo yum install ansible`
|
||||
* For other platforms or more details, see [here](http://docs.ansible.com/ansible/intro_installation.html)
|
||||
|
||||
Frequent errors during installation are:
|
||||
|
||||
* `fatal error: Python.h: No such file or directory`: install `python-dev`
|
||||
* `fatal error: ffi.h: No such file or directory`: install `libffi-dev`
|
||||
* `fatal error: openssl/opensslv.h: No such file or directory`: install `libssl-dev`
|
||||
|
||||
Full steps for a blank Ubuntu/Debian Linux machine:
|
||||
|
||||
sudo apt-get install -qq -y python-pip python-dev libffi-dev libssl-dev
|
||||
sudo pip install -U cffi
|
||||
sudo pip install ansible
|
||||
|
||||
## Tags
|
||||
|
||||
These can be used to selectively run (`--tags "tag1,tag2"`) or skip (`--skip-tags "tag1,tag2"`) tasks.
|
||||
|
||||
* `output`: print potentially useful output from hosts (e.g. output of `kubectl get pods --all-namespaces`)
|
||||
|
||||
## Usage
|
||||
|
||||
### Local machine
|
||||
|
||||
```
|
||||
ansible-playbook -u <username> -i "localhost", -c local setup_weave-kube.yml
|
||||
```
|
||||
|
||||
### Vagrant
|
||||
|
||||
Provision your local VM using Vagrant:
|
||||
|
||||
```
|
||||
cd $(mktemp -d -t XXX)
|
||||
vagrant init ubuntu/xenial64 # or, e.g. centos/7
|
||||
vagrant up
|
||||
```
|
||||
|
||||
then set the following environment variables by extracting the output of `vagrant ssh-config`:
|
||||
|
||||
```
|
||||
eval $(vagrant ssh-config | sed \
|
||||
-ne 's/\ *HostName /vagrant_ssh_host=/p' \
|
||||
-ne 's/\ *User /vagrant_ssh_user=/p' \
|
||||
-ne 's/\ *Port /vagrant_ssh_port=/p' \
|
||||
-ne 's/\ *IdentityFile /vagrant_ssh_id_file=/p')
|
||||
```
|
||||
|
||||
and finally run:
|
||||
|
||||
```
|
||||
ansible-playbook --private-key=$vagrant_ssh_id_file -u $vagrant_ssh_user \
|
||||
--ssh-extra-args="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \
|
||||
-i "$vagrant_ssh_host:$vagrant_ssh_port," setup_weave-kube.yml
|
||||
```
|
||||
|
||||
or, for specific versions of Kubernetes and Docker:
|
||||
|
||||
```
|
||||
ansible-playbook --private-key=$vagrant_ssh_id_file -u $vagrant_ssh_user \
|
||||
--ssh-extra-args="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \
|
||||
-i "$vagrant_ssh_host:$vagrant_ssh_port," setup_weave-kube.yml \
|
||||
--extra-vars "docker_version=1.12.3 kubernetes_version=1.4.4"
|
||||
```
|
||||
|
||||
NOTE: Kubernetes APT repo includes only the latest version, so currently
|
||||
retrieving an older version will fail.
|
||||
|
||||
### Terraform
|
||||
|
||||
Provision your machine using the Terraform scripts from `../provisioning`, then run:
|
||||
|
||||
```
|
||||
terraform output ansible_inventory > /tmp/ansible_inventory
|
||||
```
|
||||
|
||||
and
|
||||
|
||||
```
|
||||
ansible-playbook \
|
||||
--private-key="$(terraform output private_key_path)" \
|
||||
-u "$(terraform output username)" \
|
||||
-i /tmp/ansible_inventory \
|
||||
--ssh-extra-args="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \
|
||||
../../config_management/setup_weave-kube.yml
|
||||
|
||||
```
|
||||
|
||||
To specify versions of Kubernetes and Docker see Vagrant examples above.
|
||||
|
||||
N.B.: `--ssh-extra-args` is used to provide:
|
||||
|
||||
* `StrictHostKeyChecking=no`: as VMs come and go, the same IP can be used by a different machine, so checking the host's SSH key may fail. Note that this introduces a risk of a man-in-the-middle attack.
|
||||
* `UserKnownHostsFile=/dev/null`: if you previously connected a VM with the same IP but a different public key, and added it to `~/.ssh/known_hosts`, SSH may still fail to connect, hence we use `/dev/null` instead of `~/.ssh/known_hosts`.
|
||||
|
||||
## Resources
|
||||
|
||||
* [https://www.vagrantup.com/docs/provisioning/ansible.html](https://www.vagrantup.com/docs/provisioning/ansible.html)
|
||||
* [http://docs.ansible.com/ansible/guide_vagrant.html](http://docs.ansible.com/ansible/guide_vagrant.html)
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
go_version: 1.7.4
|
||||
terraform_version: 0.8.5
|
||||
docker_version: 1.11.2
|
||||
kubernetes_version: 1.5.2
|
||||
kubernetes_cni_version: 0.3.0.1
|
||||
kubernetes_token: 123456.0123456789123456
|
||||
etcd_container_version: 2.2.5
|
||||
kube_discovery_container_version: 1.0
|
||||
pause_container_version: 3.0
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
################################################################################
|
||||
# Install Ansible's dependencies: python and lsb_release, required respectively
|
||||
# to run Ansible modules and gather Ansible facts.
|
||||
#
|
||||
# See also:
|
||||
# - http://docs.ansible.com/ansible/intro_installation.html#managed-node-requirements
|
||||
# - http://docs.ansible.com/ansible/setup_module.html
|
||||
################################################################################
|
||||
|
||||
- name: check if python is installed (as required by ansible modules)
|
||||
raw: test -e /usr/bin/python
|
||||
register: is_python_installed
|
||||
failed_when: is_python_installed.rc not in [0, 1]
|
||||
changed_when: false # never mutates state.
|
||||
|
||||
- name: install python if missing (as required by ansible modules)
|
||||
when: is_python_installed|failed # skip otherwise
|
||||
raw: (test -e /usr/bin/apt-get && apt-get update && apt-get install -y python-minimal) || (test -e /usr/bin/yum && yum update && yum install -y python)
|
||||
changed_when: is_python_installed.rc == 1
|
||||
|
||||
- name: check if lsb_release is installed (as required for ansible facts)
|
||||
raw: test -e /usr/bin/lsb_release
|
||||
register: is_lsb_release_installed
|
||||
failed_when: is_lsb_release_installed.rc not in [0, 1]
|
||||
changed_when: false # never mutates state.
|
||||
|
||||
- name: install lsb_release if missing (as required for ansible facts)
|
||||
when: is_lsb_release_installed|failed # skip otherwise
|
||||
raw: (test -e /usr/bin/apt-get && apt-get install -y lsb_release) || (test -e /usr/bin/yum && yum install -y redhat-lsb-core)
|
||||
changed_when: is_lsb_release_installed.rc == 1
|
||||
|
||||
- setup: # gather 'facts', i.e. compensates for 'gather_facts: false' in calling playbook.
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
# Set up Development Environment.
|
||||
|
||||
- name: install development tools
|
||||
package:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
with_items:
|
||||
# weave net dependencies
|
||||
- make
|
||||
- vagrant
|
||||
# ansible dependencies
|
||||
- python-pip
|
||||
- python-dev
|
||||
- libffi-dev
|
||||
- libssl-dev
|
||||
# terraform dependencies
|
||||
- unzip
|
||||
# other potentially useful tools:
|
||||
- aufs-tools
|
||||
- ethtool
|
||||
- iputils-arping
|
||||
- libpcap-dev
|
||||
- git
|
||||
- mercurial
|
||||
- bc
|
||||
- jq
|
||||
|
||||
- name: install ansible
|
||||
pip:
|
||||
name: ansible
|
||||
state: present
|
||||
|
||||
- name: install terraform
|
||||
unarchive:
|
||||
src: 'https://releases.hashicorp.com/terraform/{{ terraform_version }}/terraform_{{ terraform_version }}_linux_{{ {"x86_64": "amd64", "i386": "386"}[ansible_architecture] }}.zip'
|
||||
remote_src: yes
|
||||
dest: /usr/bin
|
||||
mode: 0555
|
||||
creates: /usr/bin/terraform
|
||||
@@ -0,0 +1,3 @@
|
||||
[Service]
|
||||
ExecStart=
|
||||
ExecStart=/usr/bin/docker daemon -H fd:// -H unix:///var/run/alt-docker.sock -H tcp://0.0.0.0:2375 -s overlay
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
# Configure Docker
|
||||
# See also: https://docs.docker.com/engine/installation/linux/ubuntulinux/#install
|
||||
|
||||
- name: ensure docker group is present (or create it)
|
||||
group:
|
||||
name: docker
|
||||
state: present
|
||||
|
||||
- name: add user to docker group (avoids sudo-ing)
|
||||
user:
|
||||
name: "{{ ansible_user }}"
|
||||
group: docker
|
||||
state: present
|
||||
|
||||
- name: ensure docker's systemd directory exists
|
||||
file:
|
||||
path: /etc/systemd/system/docker.service.d
|
||||
state: directory
|
||||
recurse: yes
|
||||
|
||||
- name: enable docker remote api over tcp
|
||||
copy:
|
||||
src: "{{ role_path }}/files/docker_over_tcp.conf"
|
||||
dest: /etc/systemd/system/docker.service.d/docker_over_tcp.conf
|
||||
register: docker_over_tcp
|
||||
|
||||
- name: restart docker service
|
||||
systemd:
|
||||
name: docker
|
||||
state: restarted
|
||||
daemon_reload: yes # ensure docker_over_tcp.conf is picked up.
|
||||
enabled: yes
|
||||
when: docker_over_tcp.changed
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
# Debian / Ubuntu specific:
|
||||
|
||||
- name: install dependencies for docker repository
|
||||
package:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
with_items:
|
||||
- apt-transport-https
|
||||
- ca-certificates
|
||||
|
||||
- name: add apt key for the docker repository
|
||||
apt_key:
|
||||
keyserver: hkp://ha.pool.sks-keyservers.net:80
|
||||
id: 58118E89F3A912897C070ADBF76221572C52609D
|
||||
state: present
|
||||
register: apt_key_docker_repo
|
||||
|
||||
- name: add docker's apt repository ({{ ansible_distribution | lower }}-{{ ansible_distribution_release }})
|
||||
apt_repository:
|
||||
repo: deb https://apt.dockerproject.org/repo {{ ansible_distribution | lower }}-{{ ansible_distribution_release }} main
|
||||
state: present
|
||||
register: apt_docker_repo
|
||||
|
||||
- name: update apt's cache
|
||||
apt:
|
||||
update_cache: yes
|
||||
when: apt_key_docker_repo.changed or apt_docker_repo.changed
|
||||
|
||||
- name: install docker-engine
|
||||
package:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
with_items:
|
||||
- docker-engine={{ docker_version }}*
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
# Set up Docker
|
||||
# See also: https://docs.docker.com/engine/installation/linux/ubuntulinux/#install
|
||||
|
||||
- include_role:
|
||||
name: docker-prerequisites
|
||||
|
||||
# Distribution-specific tasks:
|
||||
- include: debian.yml
|
||||
when: ansible_os_family == "Debian"
|
||||
|
||||
- include: redhat.yml
|
||||
when: ansible_os_family == "RedHat"
|
||||
|
||||
- include_role:
|
||||
name: docker-configuration
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
# RedHat / CentOS specific:
|
||||
|
||||
- name: add docker' yum repository (centos/{{ ansible_lsb.major_release }})
|
||||
yum_repository:
|
||||
name: docker
|
||||
description: Docker YUM repo
|
||||
file: external_repos
|
||||
baseurl: https://yum.dockerproject.org/repo/main/centos/{{ ansible_lsb.major_release }}
|
||||
enabled: yes
|
||||
gpgkey: https://yum.dockerproject.org/gpg
|
||||
gpgcheck: yes
|
||||
state: present
|
||||
|
||||
- name: update yum's cache
|
||||
yum:
|
||||
name: "*"
|
||||
update_cache: yes
|
||||
|
||||
- name: install docker-engine
|
||||
package:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
with_items:
|
||||
- docker-engine-{{ docker_version }}
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
# Set up Docker
|
||||
# See also: legacy gce.sh script
|
||||
|
||||
- include_role:
|
||||
name: docker-prerequisites
|
||||
|
||||
- name: add apt key for the docker repository
|
||||
shell: curl -sSL https://get.docker.com/gpg | sudo apt-key add -
|
||||
|
||||
- name: install docker
|
||||
shell: 'curl -sSL https://get.docker.com/ | sed -e s/docker-engine/docker-engine={{ docker_version }}*/ | sh'
|
||||
|
||||
- include_role:
|
||||
name: docker-configuration
|
||||
@@ -0,0 +1,61 @@
|
||||
---
|
||||
# Set up Docker
|
||||
# See also:
|
||||
# - https://docs.docker.com/engine/installation/linux/ubuntulinux/#install
|
||||
# - https://github.com/docker/docker/releases
|
||||
|
||||
- include_role:
|
||||
name: docker-prerequisites
|
||||
|
||||
- name: install daemon
|
||||
package:
|
||||
name: daemon
|
||||
state: present
|
||||
|
||||
- name: 'create directory {{ docker_dir }}/{{ docker_version }}'
|
||||
file:
|
||||
path: '{{ docker_dir }}/{{ docker_version }}'
|
||||
state: directory
|
||||
mode: 0755
|
||||
|
||||
- name: download and extract docker
|
||||
unarchive:
|
||||
src: 'https://get.docker.com/builds/Linux/x86_64/docker-{{ docker_version }}.tgz'
|
||||
remote_src: yes
|
||||
dest: '{{ docker_dir }}/{{ docker_version }}'
|
||||
extra_opts: '--strip-components=1'
|
||||
mode: 0555
|
||||
creates: '{{ docker_dir }}/{{ docker_version }}/docker'
|
||||
|
||||
- name: create symlink to current version
|
||||
file:
|
||||
src: '{{ docker_dir }}/{{ docker_version }}'
|
||||
dest: '{{ docker_dir }}/current'
|
||||
state: link
|
||||
mode: 0555
|
||||
|
||||
- name: list all files to symlink
|
||||
find:
|
||||
paths: '{{ docker_dir }}/current'
|
||||
file_type: file
|
||||
register: binaries
|
||||
changed_when: false
|
||||
|
||||
- name: create symlinks to all binaries
|
||||
file:
|
||||
src: '{{ item }}'
|
||||
dest: /usr/bin/{{ item | basename }}
|
||||
state: link
|
||||
with_items: "{{ binaries.files | map(attribute='path') | list }}"
|
||||
|
||||
- name: killall docker
|
||||
command: killall docker
|
||||
register: killall
|
||||
failed_when: false
|
||||
changed_when: killall.rc == 0
|
||||
|
||||
- name: start dockerd
|
||||
command: daemon -- /usr/bin/dockerd
|
||||
|
||||
- include_role:
|
||||
name: docker-configuration
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
docker_dir: '/opt/docker'
|
||||
docker_url: '{{ "rc" in {{ docker_version }} | ternary( >
|
||||
"https://test.docker.com/builds/Linux/x86_64/docker-{{ docker_version }}.tgz", >
|
||||
"https://get.docker.com/builds/Linux/x86_64/docker-{{ docker_version }}.tgz") }}'
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
# Install Docker's dependencies
|
||||
# See also: https://docs.docker.com/engine/installation/linux/ubuntulinux/#install
|
||||
|
||||
- name: install linux-image-extra-*/virtual
|
||||
package:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
with_items:
|
||||
- linux-image-extra-{{ ansible_kernel }}
|
||||
- linux-image-extra-virtual
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
|
||||
# Distribution-specific tasks:
|
||||
- include: debian.yml
|
||||
when: ansible_os_family == "Debian"
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
# Set up Go.
|
||||
|
||||
- name: install go
|
||||
unarchive:
|
||||
src: 'https://storage.googleapis.com/golang/go{{ go_version }}.linux-{{ {"x86_64": "amd64", "i386": "386"}[ansible_architecture] }}.tar.gz'
|
||||
remote_src: yes
|
||||
dest: /usr/local
|
||||
mode: 0777
|
||||
creates: /usr/local/go/bin/go
|
||||
|
||||
- name: set go env. vars. and add go to path
|
||||
blockinfile:
|
||||
dest: '$HOME/.bashrc'
|
||||
block: |
|
||||
export PATH=$PATH:/usr/local/go/bin
|
||||
export GOPATH=$HOME
|
||||
state: present
|
||||
create: yes
|
||||
mode: 0644
|
||||
become: '{{ item }}'
|
||||
with_items:
|
||||
- true # Run as root
|
||||
- false # Run as SSH user
|
||||
|
||||
- name: source ~/.bashrc from ~/.bash_profile
|
||||
lineinfile:
|
||||
dest: '$HOME/.bash_profile'
|
||||
line: '[ -r $HOME/.bashrc ] && source $HOME/.bashrc'
|
||||
state: present
|
||||
create: yes
|
||||
mode: 0644
|
||||
become: '{{ item }}'
|
||||
with_items:
|
||||
- true # Run as root
|
||||
- false # Run as SSH user
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
|
||||
- name: check if kubelet service exists
|
||||
stat:
|
||||
path: /etc/init.d/kubelet
|
||||
register: kubelet
|
||||
|
||||
# avoids having weave-net and weave-kube conflict in some test cases (e.g. 130_expose_test.sh)
|
||||
- name: stop kubelet service
|
||||
systemd:
|
||||
name: kubelet
|
||||
state: stopped
|
||||
enabled: no
|
||||
when: kubelet.stat.exists
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
# Debian / Ubuntu specific:
|
||||
|
||||
- name: add apt key for the kubernetes repository
|
||||
apt_key:
|
||||
url: https://packages.cloud.google.com/apt/doc/apt-key.gpg
|
||||
state: present
|
||||
register: apt_key_k8s_repo
|
||||
|
||||
- name: add kubernetes' apt repository (kubernetes-{{ ansible_distribution_release }})
|
||||
apt_repository:
|
||||
repo: deb http://apt.kubernetes.io/ kubernetes-{{ ansible_distribution_release }} main
|
||||
state: present
|
||||
register: apt_k8s_repo
|
||||
|
||||
- name: update apt's cache
|
||||
apt:
|
||||
update_cache: yes
|
||||
when: apt_key_k8s_repo.changed or apt_k8s_repo.changed
|
||||
|
||||
- name: install kubelet and kubectl
|
||||
package:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
with_items:
|
||||
- kubelet={{ kubernetes_version }}*
|
||||
- kubectl={{ kubernetes_version }}*
|
||||
- kubernetes-cni={{ kubernetes_cni_version }}*
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
# Install Kubernetes
|
||||
|
||||
# Distribution-specific tasks:
|
||||
- include: debian.yml
|
||||
when: ansible_os_family == "Debian"
|
||||
|
||||
- include: redhat.yml
|
||||
when: ansible_os_family == "RedHat"
|
||||
|
||||
- name: install ebtables and kubeadm
|
||||
package:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
with_items:
|
||||
- ebtables
|
||||
- kubeadm
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
# RedHat / CentOS specific:
|
||||
|
||||
- name: add kubernetes' yum repository (kubernetes-el{{ ansible_lsb.major_release }}-x86-64)
|
||||
yum_repository:
|
||||
name: kubernetes
|
||||
description: Kubernetes YUM repo
|
||||
file: external_repos
|
||||
baseurl: https://packages.cloud.google.com/yum/repos/kubernetes-el{{ ansible_lsb.major_release }}-x86_64
|
||||
enabled: yes
|
||||
gpgkey: https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
|
||||
gpgcheck: yes
|
||||
state: present
|
||||
register: yum_k8s_repo
|
||||
|
||||
- name: update yum's cache
|
||||
yum:
|
||||
name: "*"
|
||||
update_cache: yes
|
||||
when: yum_k8s_repo.changed
|
||||
|
||||
- name: install kubelet and kubectl
|
||||
package:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
with_items:
|
||||
- kubelet-{{ kubernetes_version }}
|
||||
- kubectl-{{ kubernetes_version }}
|
||||
- kubernetes-cni-{{ kubernetes_cni_version }}*
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
# Start Kubernetes
|
||||
|
||||
- name: kubeadm reset
|
||||
command: kubeadm reset
|
||||
|
||||
- name: restart kubelet service
|
||||
systemd:
|
||||
name: kubelet
|
||||
state: restarted
|
||||
enabled: yes
|
||||
|
||||
- name: kubeadm init on the master
|
||||
command: 'kubeadm init --token={{ kubernetes_token }}'
|
||||
when: ' {{ play_hosts[0] == inventory_hostname }}'
|
||||
|
||||
- name: allow pods to be run on the master (if only node)
|
||||
command: kubectl taint nodes --all dedicated-
|
||||
when: '{{ play_hosts | length }} == 1'
|
||||
|
||||
- name: kubeadm join on workers
|
||||
command: "kubeadm join --token={{ kubernetes_token }} {{ hostvars[play_hosts[0]].private_ip }}"
|
||||
when: ' {{ play_hosts[0] != inventory_hostname }}'
|
||||
|
||||
- name: list kubernetes' pods
|
||||
command: kubectl get pods --all-namespaces
|
||||
when: ' {{ play_hosts[0] == inventory_hostname }}'
|
||||
changed_when: false
|
||||
register: kubectl_get_pods
|
||||
tags:
|
||||
- output
|
||||
|
||||
- name: print outpout of `kubectl get pods --all-namespaces`
|
||||
debug: msg="{{ kubectl_get_pods.stdout_lines }}"
|
||||
when: ' {{ play_hosts[0] == inventory_hostname }}'
|
||||
tags:
|
||||
- output
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
# Set machine up to be able to run ansible playbooks.
|
||||
|
||||
- name: check if python is installed (as required by ansible modules)
|
||||
raw: test -e /usr/bin/python
|
||||
register: is_python_installed
|
||||
failed_when: is_python_installed.rc not in [0, 1]
|
||||
changed_when: false # never mutates state.
|
||||
|
||||
- name: install python if missing (as required by ansible modules)
|
||||
when: is_python_installed|failed # skip otherwise
|
||||
raw: (test -e /usr/bin/apt-get && apt-get install -y python-minimal) || (test -e /usr/bin/yum && yum install -y python)
|
||||
changed_when: is_python_installed.rc == 1
|
||||
|
||||
- name: check if lsb_release is installed (as required for ansible facts)
|
||||
raw: test -e /usr/bin/lsb_release
|
||||
register: is_lsb_release_installed
|
||||
failed_when: is_lsb_release_installed.rc not in [0, 1]
|
||||
changed_when: false # never mutates state.
|
||||
|
||||
- name: install lsb_release if missing (as required for ansible facts)
|
||||
when: is_lsb_release_installed|failed # skip otherwise
|
||||
raw: (test -e /usr/bin/apt-get && apt-get install -y lsb_release) || (test -e /usr/bin/yum && yum install -y lsb_release)
|
||||
changed_when: is_lsb_release_installed.rc == 1
|
||||
|
||||
- setup: # gather 'facts', i.e. compensates for the above 'gather_facts: false'.
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
# Set up sock-shop on top of Kubernetes.
|
||||
# Dependencies on other roles:
|
||||
# - kubernetes
|
||||
|
||||
- name: create sock-shop namespace in k8s
|
||||
command: kubectl create namespace sock-shop
|
||||
|
||||
- name: create sock-shop in k8s
|
||||
command: kubectl apply -n sock-shop -f "https://github.com/microservices-demo/microservices-demo/blob/master/deploy/kubernetes/complete-demo.yaml?raw=true"
|
||||
|
||||
- name: describe front-end service
|
||||
command: kubectl describe svc front-end -n sock-shop
|
||||
changed_when: false
|
||||
register: kubectl_describe_svc_frontend
|
||||
tags:
|
||||
- output
|
||||
|
||||
- name: print outpout of `kubectl describe svc front-end -n sock-shop`
|
||||
debug: msg="{{ kubectl_describe_svc_frontend.stdout_lines }}"
|
||||
tags:
|
||||
- output
|
||||
|
||||
- name: list sock-shop k8s' pods
|
||||
command: kubectl get pods -n sock-shop
|
||||
changed_when: false
|
||||
register: kubectl_get_pods
|
||||
tags:
|
||||
- output
|
||||
|
||||
- name: print outpout of `kubectl get pods -n sock-shop`
|
||||
debug: msg="{{ kubectl_get_pods.stdout_lines }}"
|
||||
tags:
|
||||
- output
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
# Set up Weave Kube on top of Kubernetes.
|
||||
|
||||
- name: configure weave net's cni plugin
|
||||
command: kubectl apply -f https://git.io/weave-kube
|
||||
when: ' {{ play_hosts[0] == inventory_hostname }}'
|
||||
|
||||
- name: list kubernetes' pods
|
||||
command: kubectl get pods --all-namespaces
|
||||
when: ' {{ play_hosts[0] == inventory_hostname }}'
|
||||
changed_when: false
|
||||
register: kubectl_get_pods
|
||||
tags:
|
||||
- output
|
||||
|
||||
- name: print outpout of `kubectl get pods --all-namespaces`
|
||||
debug: msg="{{ kubectl_get_pods.stdout_lines }}"
|
||||
when: ' {{ play_hosts[0] == inventory_hostname }}'
|
||||
tags:
|
||||
- output
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
# Set up Development Environment for Weave Net.
|
||||
|
||||
- name: check if weave net has been checked out
|
||||
become: false # Run as SSH-user
|
||||
stat:
|
||||
path: $HOME/src/github.com/weaveworks/weave
|
||||
register: weave
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
|
||||
- name: git clone weave net
|
||||
become: false # Run as SSH-user
|
||||
git:
|
||||
repo: https://github.com/weaveworks/weave.git
|
||||
dest: $HOME/src/github.com/weaveworks/weave
|
||||
when: not weave.stat.exists
|
||||
|
||||
- name: create a convenience symlink to $HOME/src/github.com/weaveworks/weave
|
||||
become: false # Run as SSH-user
|
||||
file:
|
||||
src: $HOME/src/github.com/weaveworks/weave
|
||||
dest: $HOME/weave
|
||||
state: link
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
|
||||
- name: install jq
|
||||
package:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
with_items:
|
||||
- jq
|
||||
|
||||
- name: install ethtool (used by the weave script)
|
||||
package:
|
||||
name: "{{ item }}"
|
||||
install_recommends: no
|
||||
state: present
|
||||
with_items:
|
||||
- ethtool
|
||||
|
||||
- name: install nsenter (used by the weave script)
|
||||
command: docker run --rm -v /usr/local/bin:/target jpetazzo/nsenter
|
||||
|
||||
- name: install pip (for docker-py)
|
||||
package:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
with_items:
|
||||
- python-pip
|
||||
|
||||
- name: install docker-py (for docker_image)
|
||||
pip:
|
||||
name: docker-py
|
||||
state: present
|
||||
|
||||
- name: docker pull images used by tests
|
||||
docker_image:
|
||||
name: '{{ item }}'
|
||||
state: present
|
||||
with_items:
|
||||
- alpine
|
||||
- aanand/docker-dnsutils
|
||||
- weaveworks/hello-world
|
||||
|
||||
- name: docker pull images used by k8s tests
|
||||
docker_image:
|
||||
name: '{{ item }}'
|
||||
state: present
|
||||
with_items:
|
||||
- gcr.io/google_containers/etcd-amd64:{{ etcd_container_version }}
|
||||
- gcr.io/google_containers/kube-apiserver-amd64:v{{ kubernetes_version }}
|
||||
- gcr.io/google_containers/kube-controller-manager-amd64:v{{ kubernetes_version }}
|
||||
- gcr.io/google_containers/kube-proxy-amd64:v{{ kubernetes_version }}
|
||||
- gcr.io/google_containers/kube-scheduler-amd64:v{{ kubernetes_version }}
|
||||
- gcr.io/google_containers/kube-discovery-amd64:{{ kube_discovery_container_version }}
|
||||
- gcr.io/google_containers/pause-amd64:{{ pause_container_version }}
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
# Set up Weave Net.
|
||||
|
||||
- name: install weave net
|
||||
get_url:
|
||||
url: https://git.io/weave
|
||||
dest: /usr/local/bin/weave
|
||||
mode: 0555
|
||||
|
||||
- name: stop weave net
|
||||
command: weave stop
|
||||
|
||||
- name: start weave net
|
||||
command: weave launch
|
||||
|
||||
- name: get weave net's status
|
||||
command: weave status
|
||||
changed_when: false
|
||||
register: weave_status
|
||||
tags:
|
||||
- output
|
||||
|
||||
- name: print outpout of `weave status`
|
||||
debug: msg="{{ weave_status.stdout_lines }}"
|
||||
tags:
|
||||
- output
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
################################################################################
|
||||
# Install Docker and Kubernetes, and configure Kubernetes to
|
||||
# use Weave Net's CNI plugin (a.k.a. Weave Kube).
|
||||
#
|
||||
# See also:
|
||||
# - http://kubernetes.io/docs/getting-started-guides/kubeadm/
|
||||
# - https://github.com/weaveworks/weave-kube
|
||||
################################################################################
|
||||
|
||||
- name: install docker, kubernetes and weave-kube
|
||||
hosts: all
|
||||
gather_facts: false # required in case Python is not available on the host
|
||||
become: true
|
||||
become_user: root
|
||||
|
||||
pre_tasks:
|
||||
- include: library/setup_ansible_dependencies.yml
|
||||
|
||||
roles:
|
||||
- docker-from-get.docker.com
|
||||
- kubernetes-install
|
||||
- weave-net-utilities
|
||||
- kubelet-stop
|
||||
- kubernetes-start
|
||||
- weave-kube
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
################################################################################
|
||||
# Install Docker from Docker's official repository and Weave Net.
|
||||
################################################################################
|
||||
|
||||
- name: install docker and weave net for development
|
||||
hosts: all
|
||||
gather_facts: false # required in case Python is not available on the host
|
||||
become: true
|
||||
become_user: root
|
||||
|
||||
pre_tasks:
|
||||
- include: library/setup_ansible_dependencies.yml
|
||||
|
||||
roles:
|
||||
- dev-tools
|
||||
- golang-from-tarball
|
||||
- docker-from-get.docker.com
|
||||
# Do not run this role when building with Vagrant, as sources have been already checked out:
|
||||
- { role: weave-net-sources, when: "ansible_user != 'vagrant'" }
|
||||
@@ -0,0 +1,19 @@
|
||||
---
|
||||
################################################################################
|
||||
# Install Docker from Docker's official repository and Weave Net.
|
||||
################################################################################
|
||||
|
||||
- name: install docker and weave net for testing
|
||||
hosts: all
|
||||
gather_facts: false # required in case Python is not available on the host
|
||||
become: true
|
||||
become_user: root
|
||||
|
||||
pre_tasks:
|
||||
- include: library/setup_ansible_dependencies.yml
|
||||
|
||||
roles:
|
||||
- docker-from-get.docker.com
|
||||
- kubernetes-install
|
||||
- weave-net-utilities
|
||||
- kubelet-stop
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# Generate the cross product of latest versions of Weave Net's dependencies:
|
||||
# - Go
|
||||
# - Docker
|
||||
# - Kubernetes
|
||||
#
|
||||
# Dependencies:
|
||||
# - python
|
||||
# - git
|
||||
# - list_versions.py
|
||||
#
|
||||
# Testing:
|
||||
# $ python -m doctest -v cross_versions.py
|
||||
|
||||
from os import linesep
|
||||
from sys import argv, exit, stdout, stderr
|
||||
from getopt import getopt, GetoptError
|
||||
from list_versions import DEPS, get_versions_from, filter_versions
|
||||
from itertools import product
|
||||
|
||||
# See also: /usr/include/sysexits.h
|
||||
_ERROR_RUNTIME=1
|
||||
_ERROR_ILLEGAL_ARGS=64
|
||||
|
||||
def _usage(error_message=None):
|
||||
if error_message:
|
||||
stderr.write('ERROR: ' + error_message + linesep)
|
||||
stdout.write(linesep.join([
|
||||
'Usage:',
|
||||
' cross_versions.py [OPTION]...',
|
||||
'Examples:',
|
||||
' cross_versions.py',
|
||||
' cross_versions.py -r',
|
||||
' cross_versions.py --rc',
|
||||
' cross_versions.py -l',
|
||||
' cross_versions.py --latest',
|
||||
'Options:',
|
||||
'-l/--latest Include only the latest version of each major and minor versions sub-tree.',
|
||||
'-r/--rc Include release candidate versions.',
|
||||
'-h/--help Prints this!',
|
||||
''
|
||||
]))
|
||||
|
||||
def _validate_input(argv):
|
||||
try:
|
||||
config = {
|
||||
'rc': False,
|
||||
'latest': False
|
||||
}
|
||||
opts, args = getopt(argv, 'hlr', ['help', 'latest', 'rc'])
|
||||
for opt, value in opts:
|
||||
if opt in ('-h', '--help'):
|
||||
_usage()
|
||||
exit()
|
||||
if opt in ('-l', '--latest'):
|
||||
config['latest'] = True
|
||||
if opt in ('-r', '--rc'):
|
||||
config['rc'] = True
|
||||
if len(args) != 0:
|
||||
raise ValueError('Unsupported argument(s): %s.' % args)
|
||||
return config
|
||||
except GetoptError as e:
|
||||
_usage(str(e))
|
||||
exit(_ERROR_ILLEGAL_ARGS)
|
||||
except ValueError as e:
|
||||
_usage(str(e))
|
||||
exit(_ERROR_ILLEGAL_ARGS)
|
||||
|
||||
def _versions(dependency, config):
|
||||
return map(str,
|
||||
filter_versions(
|
||||
get_versions_from(DEPS[dependency]['url'], DEPS[dependency]['re']),
|
||||
DEPS[dependency]['min'],
|
||||
**config
|
||||
)
|
||||
)
|
||||
|
||||
def cross_versions(config):
|
||||
docker_versions = _versions('docker', config)
|
||||
k8s_versions = _versions('kubernetes', config)
|
||||
return product(docker_versions, k8s_versions)
|
||||
|
||||
def main(argv):
|
||||
try:
|
||||
config = _validate_input(argv)
|
||||
print(linesep.join('\t'.join(triple) for triple in cross_versions(config)))
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
exit(_ERROR_RUNTIME)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(argv[1:])
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
#!/bin/bash
|
||||
|
||||
function usage() {
|
||||
cat <<EOF
|
||||
Description:
|
||||
Script to list OS images, sorted and in a Terraform-friendly format.
|
||||
Dependencies:
|
||||
- gcloud, Google Cloud Platform's CLI
|
||||
- aws,
|
||||
Usage:
|
||||
$ ./$(basename "$0") PROVIDER OS
|
||||
PROVIDER={gcp}
|
||||
OS={ubuntu|debian|centos}
|
||||
Example:
|
||||
$ ./$(basename "$0") gcp ubuntu
|
||||
ubuntu-os-cloud/ubuntu-1204-lts
|
||||
ubuntu-os-cloud/ubuntu-1404-lts
|
||||
ubuntu-os-cloud/ubuntu-1604-lts
|
||||
ubuntu-os-cloud/ubuntu-1610
|
||||
EOF
|
||||
}
|
||||
|
||||
function find_aws_owner_id() {
|
||||
local os_owner_ids=(
|
||||
"ubuntu:099720109477"
|
||||
"debian:379101102735"
|
||||
"centos:679593333241"
|
||||
)
|
||||
for os_owner_id in "${os_owner_ids[@]}"; do
|
||||
os=${os_owner_id%%:*}
|
||||
owner_id=${os_owner_id#*:}
|
||||
if [ "$os" == "$1" ]; then
|
||||
echo "$owner_id"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
echo >&2 "No AWS owner ID for $1."
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo >&2 "No specified provider."
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$2" ]; then
|
||||
if [ "$1" == "help" ]; then
|
||||
usage
|
||||
exit 0
|
||||
else
|
||||
echo >&2 "No specified operating system."
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
'gcp')
|
||||
gcloud compute images list --standard-images --regexp=".*?$2.*" \
|
||||
--format="csv[no-heading][separator=/](selfLink.map().scope(projects).segment(0),family)" \
|
||||
| sort -d
|
||||
;;
|
||||
'aws')
|
||||
aws --region "${3:-us-east-1}" ec2 describe-images \
|
||||
--owners "$(find_aws_owner_id "$2")" \
|
||||
--filters "Name=name,Values=$2*" \
|
||||
--query 'Images[*].{name:Name,id:ImageId}'
|
||||
# Other examples:
|
||||
# - CentOS: aws --region us-east-1 ec2 describe-images --owners aws-marketplace --filters Name=product-code,Values=aw0evgkw8e5c1q413zgy5pjce
|
||||
# - Debian: aws --region us-east-1 ec2 describe-images --owners 379101102735 --filters "Name=architecture,Values=x86_64" "Name=name,Values=debian-jessie-*" "Name=root-device-type,Values=ebs" "Name=virtualization-type,Values=hvm"
|
||||
;;
|
||||
'do')
|
||||
curl -s -X GET \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
|
||||
"https://api.digitalocean.com/v2/images?page=1&per_page=999999" \
|
||||
| jq --raw-output ".images | .[] | .slug" | grep "$2" | sort -d
|
||||
;;
|
||||
*)
|
||||
echo >&2 "Unknown provider [$1]."
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
+266
@@ -0,0 +1,266 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# List all available versions of Weave Net's dependencies:
|
||||
# - Go
|
||||
# - Docker
|
||||
# - Kubernetes
|
||||
#
|
||||
# Depending on the parameters passed, it can gather the equivalent of the below bash one-liners:
|
||||
# git ls-remote --tags https://github.com/golang/go | grep -oP '(?<=refs/tags/go)[\.\d]+$' | sort --version-sort
|
||||
# git ls-remote --tags https://github.com/golang/go | grep -oP '(?<=refs/tags/go)[\.\d]+rc\d+$' | sort --version-sort | tail -n 1
|
||||
# git ls-remote --tags https://github.com/docker/docker | grep -oP '(?<=refs/tags/v)\d+\.\d+\.\d+$' | sort --version-sort
|
||||
# git ls-remote --tags https://github.com/docker/docker | grep -oP '(?<=refs/tags/v)\d+\.\d+\.\d+\-rc\d*$' | sort --version-sort | tail -n 1
|
||||
# git ls-remote --tags https://github.com/kubernetes/kubernetes | grep -oP '(?<=refs/tags/v)\d+\.\d+\.\d+$' | sort --version-sort
|
||||
# git ls-remote --tags https://github.com/kubernetes/kubernetes | grep -oP '(?<=refs/tags/v)\d+\.\d+\.\d+\-beta\.\d+$' | sort --version-sort | tail -n 1
|
||||
#
|
||||
# Dependencies:
|
||||
# - python
|
||||
# - git
|
||||
#
|
||||
# Testing:
|
||||
# $ python -m doctest -v list_versions.py
|
||||
|
||||
from os import linesep, path
|
||||
from sys import argv, exit, stdout, stderr
|
||||
from getopt import getopt, GetoptError
|
||||
from subprocess import Popen, PIPE, STDOUT
|
||||
from pkg_resources import parse_version
|
||||
from itertools import groupby
|
||||
from six.moves import filter
|
||||
import shlex
|
||||
import re
|
||||
|
||||
# See also: /usr/include/sysexits.h
|
||||
_ERROR_RUNTIME=1
|
||||
_ERROR_ILLEGAL_ARGS=64
|
||||
|
||||
_TAG_REGEX='^[0-9a-f]{40}\s+refs/tags/%s$'
|
||||
_VERSION='version'
|
||||
DEPS={
|
||||
'go': {
|
||||
'url': 'https://github.com/golang/go',
|
||||
're': 'go(?P<%s>[\d\.]+(?:rc\d)*)' % _VERSION,
|
||||
'min': None
|
||||
},
|
||||
'docker': {
|
||||
'url': 'https://github.com/docker/docker',
|
||||
're': 'v(?P<%s>\d+\.\d+\.\d+(?:\-rc\d)*)' % _VERSION,
|
||||
# Weave Net only works with Docker from 1.6.0 onwards, so we ignore all previous versions:
|
||||
'min': '1.6.0'
|
||||
},
|
||||
'kubernetes': {
|
||||
'url': 'https://github.com/kubernetes/kubernetes',
|
||||
're': 'v(?P<%s>\d+\.\d+\.\d+(?:\-beta\.\d)*)' % _VERSION,
|
||||
# Weave Kube requires Kubernetes 1.4.2+, so we ignore all previous versions:
|
||||
'min': '1.4.2'
|
||||
}
|
||||
}
|
||||
|
||||
class Version(object):
|
||||
''' Helper class to parse and manipulate (sort, filter, group) software versions. '''
|
||||
def __init__(self, version):
|
||||
self.version = version
|
||||
self.digits = [int(x) if x else 0 for x in re.match('(\d*)\.?(\d*)\.?(\d*).*?', version).groups()]
|
||||
self.major, self.minor, self.patch = self.digits
|
||||
self.__parsed = parse_version(version)
|
||||
self.is_rc = self.__parsed.is_prerelease
|
||||
def __lt__ (self, other):
|
||||
return self.__parsed.__lt__(other.__parsed)
|
||||
def __gt__ (self, other):
|
||||
return self.__parsed.__gt__(other.__parsed)
|
||||
def __le__ (self, other):
|
||||
return self.__parsed.__le__(other.__parsed)
|
||||
def __ge__ (self, other):
|
||||
return self.__parsed.__ge__(other.__parsed)
|
||||
def __eq__ (self, other):
|
||||
return self.__parsed.__eq__(other.__parsed)
|
||||
def __ne__ (self, other):
|
||||
return self.__parsed.__ne__(other.__parsed)
|
||||
def __str__(self):
|
||||
return self.version
|
||||
def __repr__(self):
|
||||
return self.version
|
||||
|
||||
def _read_go_version_from_dockerfile():
|
||||
# Read Go version from weave/build/Dockerfile
|
||||
dockerfile_path = path.join(path.dirname(path.dirname(path.dirname(path.realpath(__file__)))), 'build', 'Dockerfile')
|
||||
with open(dockerfile_path, 'r') as f:
|
||||
for line in f:
|
||||
m = re.match('^FROM golang:(\S*)$', line)
|
||||
if m:
|
||||
return m.group(1)
|
||||
raise RuntimeError("Failed to read Go version from weave/build/Dockerfile. You may be running this script from somewhere else than weave/tools.")
|
||||
|
||||
def _try_set_min_go_version():
|
||||
''' Set the current version of Go used to build Weave Net's containers as the minimum version. '''
|
||||
try:
|
||||
DEPS['go']['min'] = _read_go_version_from_dockerfile()
|
||||
except IOError as e:
|
||||
stderr.write('WARNING: No minimum Go version set. Root cause: %s%s' % (e, linesep))
|
||||
|
||||
def _sanitize(out):
|
||||
return out.decode('ascii').strip().split(linesep)
|
||||
|
||||
def _parse_tag(tag, version_pattern, debug=False):
|
||||
''' Parse Git tag output's line using the provided `version_pattern`, e.g.:
|
||||
>>> _parse_tag('915b77eb4efd68916427caf8c7f0b53218c5ea4a refs/tags/v1.4.6', 'v(?P<version>\d+\.\d+\.\d+(?:\-beta\.\d)*)')
|
||||
'1.4.6'
|
||||
'''
|
||||
pattern = _TAG_REGEX % version_pattern
|
||||
m = re.match(pattern, tag)
|
||||
if m:
|
||||
return m.group(_VERSION)
|
||||
elif debug:
|
||||
stderr.write('ERROR: Failed to parse version out of tag [%s] using [%s].%s' % (tag, pattern, linesep))
|
||||
|
||||
def get_versions_from(git_repo_url, version_pattern):
|
||||
''' Get release and release candidates' versions from the provided Git repository. '''
|
||||
git = Popen(shlex.split('git ls-remote --tags %s' % git_repo_url), stdout=PIPE)
|
||||
out, err = git.communicate()
|
||||
status_code = git.returncode
|
||||
if status_code != 0:
|
||||
raise RuntimeError('Failed to retrieve git tags from %s. Status code: %s. Output: %s. Error: %s' % (git_repo_url, status_code, out, err))
|
||||
return list(filter(None, (_parse_tag(line, version_pattern) for line in _sanitize(out))))
|
||||
|
||||
def _tree(versions, level=0):
|
||||
''' Group versions by major, minor and patch version digits. '''
|
||||
if not versions or level >= len(versions[0].digits):
|
||||
return # Empty versions or no more digits to group by.
|
||||
versions_tree = []
|
||||
for _, versions_group in groupby(versions, lambda v: v.digits[level]):
|
||||
subtree = _tree(list(versions_group), level+1)
|
||||
if subtree:
|
||||
versions_tree.append(subtree)
|
||||
# Return the current subtree if non-empty, or the list of "leaf" versions:
|
||||
return versions_tree if versions_tree else versions
|
||||
|
||||
def _is_iterable(obj):
|
||||
'''
|
||||
Check if the provided object is an iterable collection, i.e. not a string, e.g. a list, a generator:
|
||||
>>> _is_iterable('string')
|
||||
False
|
||||
>>> _is_iterable([1, 2, 3])
|
||||
True
|
||||
>>> _is_iterable((x for x in [1, 2, 3]))
|
||||
True
|
||||
'''
|
||||
return hasattr(obj, '__iter__') and not isinstance(obj, str)
|
||||
|
||||
def _leaf_versions(tree, rc):
|
||||
'''
|
||||
Recursively traverse the versions tree in a depth-first fashion,
|
||||
and collect the last node of each branch, i.e. leaf versions.
|
||||
'''
|
||||
versions = []
|
||||
if _is_iterable(tree):
|
||||
for subtree in tree:
|
||||
versions.extend(_leaf_versions(subtree, rc))
|
||||
if not versions:
|
||||
if rc:
|
||||
last_rc = next(filter(lambda v: v.is_rc, reversed(tree)), None)
|
||||
last_prod = next(filter(lambda v: not v.is_rc, reversed(tree)), None)
|
||||
if last_rc and last_prod and (last_prod < last_rc):
|
||||
versions.extend([last_prod, last_rc])
|
||||
elif not last_prod:
|
||||
versions.append(last_rc)
|
||||
else:
|
||||
# Either there is no RC, or we ignore the RC as older than the latest production version:
|
||||
versions.append(last_prod)
|
||||
else:
|
||||
versions.append(tree[-1])
|
||||
return versions
|
||||
|
||||
def filter_versions(versions, min_version=None, rc=False, latest=False):
|
||||
''' Filter provided versions
|
||||
|
||||
>>> filter_versions(['1.0.0-beta.1', '1.0.0', '1.0.1', '1.1.1', '1.1.2-rc1', '2.0.0'], min_version=None, latest=False, rc=False)
|
||||
[1.0.0, 1.0.1, 1.1.1, 2.0.0]
|
||||
|
||||
>>> filter_versions(['1.0.0-beta.1', '1.0.0', '1.0.1', '1.1.1', '1.1.2-rc1', '2.0.0'], min_version=None, latest=True, rc=False)
|
||||
[1.0.1, 1.1.1, 2.0.0]
|
||||
|
||||
>>> filter_versions(['1.0.0-beta.1', '1.0.0', '1.0.1', '1.1.1', '1.1.2-rc1', '2.0.0'], min_version=None, latest=False, rc=True)
|
||||
[1.0.0-beta.1, 1.0.0, 1.0.1, 1.1.1, 1.1.2-rc1, 2.0.0]
|
||||
|
||||
>>> filter_versions(['1.0.0-beta.1', '1.0.0', '1.0.1', '1.1.1', '1.1.2-rc1', '2.0.0'], min_version='1.1.0', latest=False, rc=True)
|
||||
[1.1.1, 1.1.2-rc1, 2.0.0]
|
||||
|
||||
>>> filter_versions(['1.0.0-beta.1', '1.0.0', '1.0.1', '1.1.1', '1.1.2-rc1', '2.0.0'], min_version=None, latest=True, rc=True)
|
||||
[1.0.1, 1.1.1, 1.1.2-rc1, 2.0.0]
|
||||
|
||||
>>> filter_versions(['1.0.0-beta.1', '1.0.0', '1.0.1', '1.1.1', '1.1.2-rc1', '2.0.0'], min_version='1.1.0', latest=True, rc=True)
|
||||
[1.1.1, 1.1.2-rc1, 2.0.0]
|
||||
'''
|
||||
versions = sorted([Version(v) for v in versions])
|
||||
if min_version:
|
||||
min_version = Version(min_version)
|
||||
versions = [v for v in versions if v >= min_version]
|
||||
if not rc:
|
||||
versions = [v for v in versions if not v.is_rc]
|
||||
if latest:
|
||||
versions_tree = _tree(versions)
|
||||
return _leaf_versions(versions_tree, rc)
|
||||
else:
|
||||
return versions
|
||||
|
||||
def _usage(error_message=None):
|
||||
if error_message:
|
||||
stderr.write('ERROR: ' + error_message + linesep)
|
||||
stdout.write(linesep.join([
|
||||
'Usage:',
|
||||
' list_versions.py [OPTION]... [DEPENDENCY]',
|
||||
'Examples:',
|
||||
' list_versions.py go',
|
||||
' list_versions.py -r docker',
|
||||
' list_versions.py --rc docker',
|
||||
' list_versions.py -l kubernetes',
|
||||
' list_versions.py --latest kubernetes',
|
||||
'Options:',
|
||||
'-l/--latest Include only the latest version of each major and minor versions sub-tree.',
|
||||
'-r/--rc Include release candidate versions.',
|
||||
'-h/--help Prints this!',
|
||||
''
|
||||
]))
|
||||
|
||||
def _validate_input(argv):
|
||||
try:
|
||||
config = {
|
||||
'rc': False,
|
||||
'latest': False
|
||||
}
|
||||
opts, args = getopt(argv, 'hlr', ['help', 'latest', 'rc'])
|
||||
for opt, value in opts:
|
||||
if opt in ('-h', '--help'):
|
||||
_usage()
|
||||
exit()
|
||||
if opt in ('-l', '--latest'):
|
||||
config['latest'] = True
|
||||
if opt in ('-r', '--rc'):
|
||||
config['rc'] = True
|
||||
if len(args) != 1:
|
||||
raise ValueError('Please provide a dependency to get versions of. Expected 1 argument but got %s: %s.' % (len(args), args))
|
||||
dependency=args[0].lower()
|
||||
if dependency not in DEPS.keys():
|
||||
raise ValueError('Please provide a valid dependency. Supported one dependency among {%s} but got: %s.' % (', '.join(DEPS.keys()), dependency))
|
||||
return dependency, config
|
||||
except GetoptError as e:
|
||||
_usage(str(e))
|
||||
exit(_ERROR_ILLEGAL_ARGS)
|
||||
except ValueError as e:
|
||||
_usage(str(e))
|
||||
exit(_ERROR_ILLEGAL_ARGS)
|
||||
|
||||
def main(argv):
|
||||
try:
|
||||
dependency, config = _validate_input(argv)
|
||||
if dependency == 'go':
|
||||
_try_set_min_go_version()
|
||||
versions = get_versions_from(DEPS[dependency]['url'], DEPS[dependency]['re'])
|
||||
versions = filter_versions(versions, DEPS[dependency]['min'], **config)
|
||||
print(linesep.join(map(str, versions)))
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
exit(_ERROR_RUNTIME)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(argv[1:])
|
||||
@@ -130,4 +130,4 @@ end_suite() {
|
||||
whitely assert_end
|
||||
}
|
||||
|
||||
WEAVE=$DIR/../weave
|
||||
WEAVE=$DIR/../../integration/weave
|
||||
|
||||
+18
-6
@@ -9,7 +9,9 @@ set -e
|
||||
|
||||
: "${KEY_FILE:=/tmp/gce_private_key.json}"
|
||||
: "${SSH_KEY_FILE:=$HOME/.ssh/gce_ssh_key}"
|
||||
: "${IMAGE:=ubuntu-14-04}"
|
||||
: "${IMAGE_FAMILY:=ubuntu-1404-lts}"
|
||||
: "${IMAGE_PROJECT:=ubuntu-os-cloud}"
|
||||
: "${USER_ACCOUNT:=ubuntu}"
|
||||
: "${ZONE:=us-central1-a}"
|
||||
: "${PROJECT:=}"
|
||||
: "${TEMPLATE_NAME:=}"
|
||||
@@ -22,7 +24,9 @@ fi
|
||||
|
||||
SUFFIX=""
|
||||
if [ -n "$CIRCLECI" ]; then
|
||||
SUFFIX="-${CIRCLE_BUILD_NUM}-$CIRCLE_NODE_INDEX"
|
||||
SUFFIX="-${CIRCLE_PROJECT_USERNAME}-${CIRCLE_PROJECT_REPONAME}-${CIRCLE_BUILD_NUM}-$CIRCLE_NODE_INDEX"
|
||||
else
|
||||
SUFFIX="-${USER}"
|
||||
fi
|
||||
|
||||
# Setup authentication
|
||||
@@ -41,7 +45,8 @@ function vm_names() {
|
||||
function destroy() {
|
||||
local names
|
||||
names="$(vm_names)"
|
||||
if [ "$(gcloud compute instances list --zone "$ZONE" -q "$names" | wc -l)" -le 1 ]; then
|
||||
# shellcheck disable=SC2086
|
||||
if [ "$(gcloud compute instances list --zones "$ZONE" -q $names | wc -l)" -le 1 ]; then
|
||||
return 0
|
||||
fi
|
||||
for i in {0..10}; do
|
||||
@@ -82,12 +87,16 @@ function try_connect() {
|
||||
|
||||
function install_docker_on() {
|
||||
name=$1
|
||||
echo "Installing Docker on $name for user ${USER_ACCOUNT}"
|
||||
# shellcheck disable=SC2087
|
||||
ssh -t "$name" sudo bash -x -s <<EOF
|
||||
set -x
|
||||
set -e
|
||||
curl -sSL https://get.docker.com/gpg | sudo apt-key add -
|
||||
curl -sSL https://get.docker.com/ | sh
|
||||
apt-get update -qq;
|
||||
apt-get install -q -y --force-yes --no-install-recommends ethtool;
|
||||
usermod -a -G docker vagrant;
|
||||
usermod -a -G docker "${USER_ACCOUNT}";
|
||||
echo 'DOCKER_OPTS="-H unix:///var/run/docker.sock -H unix:///var/run/alt-docker.sock -H tcp://0.0.0.0:2375 -s overlay"' >> /etc/default/docker;
|
||||
service docker restart
|
||||
EOF
|
||||
@@ -136,7 +145,7 @@ function setup() {
|
||||
}
|
||||
|
||||
function make_template() {
|
||||
gcloud compute instances create "$TEMPLATE_NAME" --image "$IMAGE" --zone "$ZONE"
|
||||
gcloud compute instances create "$TEMPLATE_NAME" --image-family "$IMAGE_FAMILY" --image-project "$IMAGE_PROJECT" --zone "$ZONE"
|
||||
gcloud compute config-ssh --ssh-key-file "$SSH_KEY_FILE"
|
||||
name="$TEMPLATE_NAME.$ZONE.$PROJECT"
|
||||
try_connect "$name"
|
||||
@@ -155,7 +164,7 @@ function hosts() {
|
||||
hosts=($hostname "${hosts[@]}")
|
||||
args=("--add-host=$hostname:$(internal_ip "$json" "$name")" "${args[@]}")
|
||||
done
|
||||
echo export SSH=\"ssh -l vagrant\"
|
||||
echo export SSH=\"ssh -l "${USER_ACCOUNT}"\"
|
||||
echo "export HOSTS=\"${hosts[*]}\""
|
||||
echo "export ADD_HOST_ARGS=\"${args[*]}\""
|
||||
rm "$json"
|
||||
@@ -178,6 +187,9 @@ case "$1" in
|
||||
# see if template exists
|
||||
if ! gcloud compute images list | grep "$PROJECT" | grep "$TEMPLATE_NAME"; then
|
||||
make_template
|
||||
else
|
||||
echo "Reusing existing template:"
|
||||
gcloud compute images describe "$TEMPLATE_NAME" | grep "^creationTimestamp"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /bin/bash
|
||||
# shellcheck disable=SC1091
|
||||
. ./config.sh
|
||||
# shellcheck disable=SC1090,SC1091
|
||||
. "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/config.sh"
|
||||
|
||||
set -e
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
# For shell files, it runs shfmt. If you don't have that installed, you can get
|
||||
# it with:
|
||||
# go get -u github.com/mvdan/sh/cmd/shfmt
|
||||
# go get -u gopkg.in/mvdan/sh.v1/cmd/shfmt
|
||||
#
|
||||
# With no arguments, it lints the current files staged
|
||||
# for git commit. Or you can pass it explicit filenames
|
||||
@@ -17,8 +17,11 @@
|
||||
|
||||
set -e
|
||||
|
||||
LINT_IGNORE_FILE=${LINT_IGNORE_FILE:-".lintignore"}
|
||||
|
||||
IGNORE_LINT_COMMENT=
|
||||
IGNORE_SPELLINGS=
|
||||
PARALLEL=
|
||||
while true; do
|
||||
case "$1" in
|
||||
-nocomment)
|
||||
@@ -33,6 +36,10 @@ while true; do
|
||||
IGNORE_SPELLINGS="$2,$IGNORE_SPELLINGS"
|
||||
shift 2
|
||||
;;
|
||||
-p)
|
||||
PARALLEL=1
|
||||
shift 1
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
@@ -142,10 +149,11 @@ lint() {
|
||||
return
|
||||
fi
|
||||
|
||||
# Don't lint static.go
|
||||
# Don't lint specific files
|
||||
case "$(basename "${filename}")" in
|
||||
static.go) return ;;
|
||||
coverage.html) return ;;
|
||||
*.pb.go) return ;;
|
||||
esac
|
||||
|
||||
if [[ "$(file --mime-type "${filename}" | awk '{print $2}')" == "text/x-shellscript" ]]; then
|
||||
@@ -171,12 +179,46 @@ lint_files() {
|
||||
exit $lint_result
|
||||
}
|
||||
|
||||
list_files() {
|
||||
if [ $# -gt 0 ]; then
|
||||
git ls-files --exclude-standard | grep -vE '(^|/)vendor/'
|
||||
matches_any() {
|
||||
local filename="$1"
|
||||
local patterns="$2"
|
||||
while read -r pattern; do
|
||||
# shellcheck disable=SC2053
|
||||
# Use the [[ operator without quotes on $pattern
|
||||
# in order to "glob" the provided filename:
|
||||
[[ "$filename" == $pattern ]] && return 0
|
||||
done <<<"$patterns"
|
||||
return 1
|
||||
}
|
||||
|
||||
filter_out() {
|
||||
local patterns_file="$1"
|
||||
if [ -n "$patterns_file" ] && [ -r "$patterns_file" ]; then
|
||||
local patterns
|
||||
patterns=$(sed '/^#.*$/d ; /^\s*$/d' "$patterns_file") # Remove blank lines and comments before we start iterating.
|
||||
[ -n "$DEBUG" ] && echo >&2 "> Filters:" && echo >&2 "$patterns"
|
||||
local filtered_out=()
|
||||
while read -r filename; do
|
||||
matches_any "$filename" "$patterns" && filtered_out+=("$filename") || echo "$filename"
|
||||
done
|
||||
[ -n "$DEBUG" ] && echo >&2 "> Files filtered out (i.e. NOT linted):" && printf >&2 '%s\n' "${filtered_out[@]}"
|
||||
else
|
||||
git diff --cached --name-only
|
||||
cat # No patterns provided: simply propagate stdin to stdout.
|
||||
fi
|
||||
}
|
||||
|
||||
list_files "$@" | lint_files
|
||||
list_files() {
|
||||
if [ $# -gt 0 ]; then
|
||||
find "$@" | grep -vE '(^|/)vendor/'
|
||||
else
|
||||
git ls-files --exclude-standard | grep -vE '(^|/)vendor/'
|
||||
fi
|
||||
}
|
||||
|
||||
if [ $# = 1 ] && [ -f "$1" ]; then
|
||||
lint "$1"
|
||||
elif [ -n "$PARALLEL" ]; then
|
||||
list_files "$@" | filter_out "$LINT_IGNORE_FILE" | xargs -n1 -P16 "$0"
|
||||
else
|
||||
list_files "$@" | filter_out "$LINT_IGNORE_FILE" | lint_files
|
||||
fi
|
||||
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
# Weaveworks provisioning
|
||||
|
||||
## Introduction
|
||||
|
||||
This project allows you to get hold of some machine either locally or on one of the below cloud providers:
|
||||
|
||||
* Amazon Web Services
|
||||
* Digital Ocean
|
||||
* Google Cloud Platform
|
||||
|
||||
You can then use these machines as is or run various Ansible playbooks from `../config_management` to set up Weave Net, Kubernetes, etc.
|
||||
|
||||
## Set up
|
||||
|
||||
* You will need [Vagrant](https://www.vagrantup.com) installed on your machine and added to your `PATH` in order to be able to provision local (virtual) machines automatically.
|
||||
|
||||
* On macOS: `brew install vagrant`
|
||||
* On Linux (via Aptitude): `sudo apt install vagrant`
|
||||
* If you need a specific version:
|
||||
|
||||
curl -fsS https://releases.hashicorp.com/terraform/x.y.z/terraform_x.y.z_linux_amd64.zip | gunzip > terraform && chmod +x terraform && sudo mv terraform /usr/bin
|
||||
|
||||
* For other platforms or more details, see [here](https://www.vagrantup.com/docs/installation/)
|
||||
|
||||
* You will need [Terraform](https://www.terraform.io) installed on your machine and added to your `PATH` in order to be able to provision cloud-hosted machines automatically.
|
||||
|
||||
* On macOS: `brew install terraform`
|
||||
* On Linux (via Aptitude): `sudo apt install terraform`
|
||||
* For other platforms or more details, see [here](https://www.terraform.io/intro/getting-started/install.html)
|
||||
|
||||
* Depending on the cloud provider, you may have to create an account, manually onboard, create and register SSH keys, etc.
|
||||
Please refer to the `README.md` in each sub-folder for more details.
|
||||
|
||||
## Usage in scripts
|
||||
|
||||
Source `setup.sh`, set the `SECRET_KEY` environment variable, and depending on the cloud provider you want to use, call either:
|
||||
|
||||
* `gcp_on` / `gcp_off`
|
||||
* `do_on` / `do_off`
|
||||
* `aws_on` / `aws_off`
|
||||
|
||||
## Usage in shell
|
||||
|
||||
Source `setup.sh`, set the `SECRET_KEY` environment variable, and depending on the cloud provider you want to use, call either:
|
||||
|
||||
* `gcp_on` / `gcp_off`
|
||||
* `do_on` / `do_off`
|
||||
* `aws_on` / `aws_off`
|
||||
|
||||
Indeed, the functions defined in `setup.sh` are also exported as aliases, so you can call them from your shell directly.
|
||||
|
||||
Other aliases are also defined, in order to make your life easier:
|
||||
|
||||
* `tf_ssh`: to ease SSH-ing into the virtual machines, reading the username and IP address to use from Terraform, as well as setting default SSH options.
|
||||
* `tf_ansi`: to ease applying an Ansible playbook to a set of virtual machines, dynamically creating the inventory, as well as setting default SSH options.
|
||||
@@ -0,0 +1,90 @@
|
||||
# Amazon Web Services
|
||||
|
||||
## Introduction
|
||||
|
||||
This project allows you to get hold of some machine on Amazon Web Services.
|
||||
You can then use these machines as is or run various Ansible playbooks from `../config_management` to set up Weave Net, Kubernetes, etc.
|
||||
|
||||
## Setup
|
||||
|
||||
* Log in [weaveworks.signin.aws.amazon.com/console](https://weaveworks.signin.aws.amazon.com/console/) with your account.
|
||||
|
||||
* Go to `Services` > `IAM` > `Users` > Click on your username > `Security credentials` > `Create access key`.
|
||||
Your access key and secret key will appear on the screen. Set these as environment variables:
|
||||
|
||||
```
|
||||
export AWS_ACCESS_KEY_ID=<your access key>
|
||||
export AWS_SECRET_ACCESS_KEY=<your secret key>
|
||||
```
|
||||
|
||||
* Go to `Services` > `EC2` > Select the availability zone you want to use (see top right corner, e.g. `us-east-1`) > `Import Key Pair`.
|
||||
Enter your SSH public key and the name for it, and click `Import`.
|
||||
Set the path to your private key as an environment variable:
|
||||
|
||||
```
|
||||
export TF_VAR_aws_public_key_name=<your Amazon Web Services SSH key name>
|
||||
export TF_VAR_aws_private_key_path="$HOME/.ssh/id_rsa"
|
||||
```
|
||||
|
||||
* Set your current IP address as an environment variable:
|
||||
|
||||
```
|
||||
export TF_VAR_client_ip=$(curl -s -X GET http://checkip.amazonaws.com/)
|
||||
```
|
||||
|
||||
or pass it as a Terraform variable:
|
||||
|
||||
```
|
||||
$ terraform <command> -var 'client_ip=$(curl -s -X GET http://checkip.amazonaws.com/)'
|
||||
```
|
||||
|
||||
### Bash aliases
|
||||
|
||||
You can set the above variables temporarily in your current shell, permanently in your `~/.bashrc` file, or define aliases to activate/deactivate them at will with one single command by adding the below to your `~/.bashrc` file:
|
||||
|
||||
```
|
||||
function _aws_on() {
|
||||
export AWS_ACCESS_KEY_ID="<your_access_key_id>" # Replace with appropriate value.
|
||||
export AWS_SECRET_ACCESS_KEY="<your_secret_access_key>" # Replace with appropriate value.
|
||||
export TF_VAR_aws_public_key_name="<your_ssh_key_name>" # Replace with appropriate value.
|
||||
export TF_VAR_aws_private_key_path="$HOME/.ssh/id_rsa" # Replace with appropriate value.
|
||||
}
|
||||
alias _aws_on='_aws_on'
|
||||
function _aws_off() {
|
||||
unset AWS_ACCESS_KEY_ID
|
||||
unset AWS_SECRET_ACCESS_KEY
|
||||
unset TF_VAR_aws_public_key_name
|
||||
unset TF_VAR_aws_private_key_path
|
||||
}
|
||||
alias _aws_off='_aws_off'
|
||||
```
|
||||
|
||||
N.B.:
|
||||
|
||||
* sourcing `../setup.sh` defines aliases called `aws_on` and `aws_off`, similarly to the above (however, notice no `_` in front of the name, as opposed to the ones above);
|
||||
* `../setup.sh`'s `aws_on` alias needs the `SECRET_KEY` environment variable to be set in order to decrypt sensitive information.
|
||||
|
||||
## Usage
|
||||
|
||||
* Create the machine: `terraform apply`
|
||||
* Show the machine's status: `terraform show`
|
||||
* Stop and destroy the machine: `terraform destroy`
|
||||
* SSH into the newly-created machine:
|
||||
|
||||
```
|
||||
$ ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no `terraform output username`@`terraform output public_ips`
|
||||
# N.B.: the default username will differ depending on the AMI/OS you installed, e.g. ubuntu for Ubuntu, ec2-user for Red Hat, etc.
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
source ../setup.sh
|
||||
tf_ssh 1 # Or the nth machine, if multiple VMs are provisioned.
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
* [https://www.terraform.io/docs/providers/aws/](https://www.terraform.io/docs/providers/aws/)
|
||||
* [https://www.terraform.io/docs/providers/aws/r/instance.html](https://www.terraform.io/docs/providers/aws/r/instance.html)
|
||||
* [Terraform variables](https://www.terraform.io/intro/getting-started/variables.html)
|
||||
Executable
+137
@@ -0,0 +1,137 @@
|
||||
# Specify the provider and access details
|
||||
provider "aws" {
|
||||
# Access key, secret key and region are sourced from environment variables or input arguments -- see README.md
|
||||
region = "${var.aws_dc}"
|
||||
}
|
||||
|
||||
resource "aws_security_group" "allow_ssh" {
|
||||
name = "${var.name}_allow_ssh"
|
||||
description = "AWS security group to allow SSH-ing onto AWS EC2 instances (created using Terraform)."
|
||||
|
||||
# Open TCP port for SSH:
|
||||
ingress {
|
||||
from_port = 22
|
||||
to_port = 22
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["${var.client_ip}/32"]
|
||||
}
|
||||
|
||||
tags {
|
||||
Name = "${var.name}_allow_ssh"
|
||||
App = "${var.app}"
|
||||
CreatedBy = "terraform"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_security_group" "allow_docker" {
|
||||
name = "${var.name}_allow_docker"
|
||||
description = "AWS security group to allow communication with Docker on AWS EC2 instances (created using Terraform)."
|
||||
|
||||
# Open TCP port for Docker:
|
||||
ingress {
|
||||
from_port = 2375
|
||||
to_port = 2375
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["${var.client_ip}/32"]
|
||||
}
|
||||
|
||||
tags {
|
||||
Name = "${var.name}_allow_docker"
|
||||
App = "${var.app}"
|
||||
CreatedBy = "terraform"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_security_group" "allow_weave" {
|
||||
name = "${var.name}_allow_weave"
|
||||
description = "AWS security group to allow communication with Weave on AWS EC2 instances (created using Terraform)."
|
||||
|
||||
# Open TCP port for Weave:
|
||||
ingress {
|
||||
from_port = 12375
|
||||
to_port = 12375
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["${var.client_ip}/32"]
|
||||
}
|
||||
|
||||
tags {
|
||||
Name = "${var.name}_allow_weave"
|
||||
App = "${var.app}"
|
||||
CreatedBy = "terraform"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_security_group" "allow_private_ingress" {
|
||||
name = "${var.name}_allow_private_ingress"
|
||||
description = "AWS security group to allow all private ingress traffic on AWS EC2 instances (created using Terraform)."
|
||||
|
||||
# Full inbound local network access on both TCP and UDP
|
||||
ingress {
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
cidr_blocks = ["${var.aws_vpc_cidr_block}"]
|
||||
}
|
||||
|
||||
tags {
|
||||
Name = "${var.name}_allow_private_ingress"
|
||||
App = "${var.app}"
|
||||
CreatedBy = "terraform"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_security_group" "allow_all_egress" {
|
||||
name = "${var.name}_allow_all_egress"
|
||||
description = "AWS security group to allow all egress traffic on AWS EC2 instances (created using Terraform)."
|
||||
|
||||
# Full outbound internet access on both TCP and UDP
|
||||
egress {
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
tags {
|
||||
Name = "${var.name}_allow_all_egress"
|
||||
App = "${var.app}"
|
||||
CreatedBy = "terraform"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_instance" "tf_test_vm" {
|
||||
instance_type = "${var.aws_size}"
|
||||
count = "${var.num_hosts}"
|
||||
|
||||
# Lookup the correct AMI based on the region we specified
|
||||
ami = "${lookup(var.aws_amis, var.aws_dc)}"
|
||||
|
||||
key_name = "${var.aws_public_key_name}"
|
||||
|
||||
security_groups = [
|
||||
"${aws_security_group.allow_ssh.name}",
|
||||
"${aws_security_group.allow_docker.name}",
|
||||
"${aws_security_group.allow_weave.name}",
|
||||
"${aws_security_group.allow_private_ingress.name}",
|
||||
"${aws_security_group.allow_all_egress.name}",
|
||||
]
|
||||
|
||||
# Wait for machine to be SSH-able:
|
||||
provisioner "remote-exec" {
|
||||
inline = ["exit"]
|
||||
|
||||
connection {
|
||||
type = "ssh"
|
||||
|
||||
# Lookup the correct username based on the AMI we specified
|
||||
user = "${lookup(var.aws_usernames, "${lookup(var.aws_amis, var.aws_dc)}")}"
|
||||
private_key = "${file("${var.aws_private_key_path}")}"
|
||||
}
|
||||
}
|
||||
|
||||
tags {
|
||||
Name = "${var.name}-${count.index}"
|
||||
App = "${var.app}"
|
||||
CreatedBy = "terraform"
|
||||
}
|
||||
}
|
||||
Executable
+54
@@ -0,0 +1,54 @@
|
||||
output "username" {
|
||||
value = "${lookup(var.aws_usernames, "${lookup(var.aws_amis, var.aws_dc)}")}"
|
||||
}
|
||||
|
||||
output "public_ips" {
|
||||
value = ["${aws_instance.tf_test_vm.*.public_ip}"]
|
||||
}
|
||||
|
||||
output "hostnames" {
|
||||
value = "${join("\n",
|
||||
"${formatlist("%v.%v.%v",
|
||||
aws_instance.tf_test_vm.*.tags.Name,
|
||||
aws_instance.tf_test_vm.*.availability_zone,
|
||||
var.app
|
||||
)}"
|
||||
)}"
|
||||
}
|
||||
|
||||
# /etc/hosts file for the Droplets:
|
||||
output "private_etc_hosts" {
|
||||
value = "${join("\n",
|
||||
"${formatlist("%v %v.%v.%v",
|
||||
aws_instance.tf_test_vm.*.private_ip,
|
||||
aws_instance.tf_test_vm.*.tags.Name,
|
||||
aws_instance.tf_test_vm.*.availability_zone,
|
||||
var.app
|
||||
)}"
|
||||
)}"
|
||||
}
|
||||
|
||||
# /etc/hosts file for the client:
|
||||
output "public_etc_hosts" {
|
||||
value = "${join("\n",
|
||||
"${formatlist("%v %v.%v.%v",
|
||||
aws_instance.tf_test_vm.*.public_ip,
|
||||
aws_instance.tf_test_vm.*.tags.Name,
|
||||
aws_instance.tf_test_vm.*.availability_zone,
|
||||
var.app
|
||||
)}"
|
||||
)}"
|
||||
}
|
||||
|
||||
output "ansible_inventory" {
|
||||
value = "${format("[all]\n%s", join("\n",
|
||||
"${formatlist("%v private_ip=%v",
|
||||
aws_instance.tf_test_vm.*.public_ip,
|
||||
aws_instance.tf_test_vm.*.private_ip,
|
||||
)}"
|
||||
))}"
|
||||
}
|
||||
|
||||
output "private_key_path" {
|
||||
value = "${var.aws_private_key_path}"
|
||||
}
|
||||
Executable
+63
@@ -0,0 +1,63 @@
|
||||
variable "client_ip" {
|
||||
description = "IP address of the client machine"
|
||||
}
|
||||
|
||||
variable "app" {
|
||||
description = "Name of the application using the created EC2 instance(s)."
|
||||
default = "default"
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
description = "Name of the EC2 instance(s)."
|
||||
default = "test"
|
||||
}
|
||||
|
||||
variable "num_hosts" {
|
||||
description = "Number of EC2 instance(s)."
|
||||
default = 1
|
||||
}
|
||||
|
||||
variable "aws_vpc_cidr_block" {
|
||||
description = "AWS VPC CIDR block to use to attribute private IP addresses."
|
||||
default = "172.31.0.0/16"
|
||||
}
|
||||
|
||||
variable "aws_public_key_name" {
|
||||
description = "Name of the SSH keypair to use in AWS."
|
||||
}
|
||||
|
||||
variable "aws_private_key_path" {
|
||||
description = "Path to file containing private key"
|
||||
default = "~/.ssh/id_rsa"
|
||||
}
|
||||
|
||||
variable "aws_dc" {
|
||||
description = "The AWS region to create things in."
|
||||
default = "us-east-1"
|
||||
}
|
||||
|
||||
variable "aws_amis" {
|
||||
default = {
|
||||
# Ubuntu Server 16.04 LTS (HVM), SSD Volume Type:
|
||||
"us-east-1" = "ami-40d28157"
|
||||
"eu-west-2" = "ami-23d0da47"
|
||||
|
||||
# Red Hat Enterprise Linux 7.3 (HVM), SSD Volume Type:
|
||||
|
||||
#"us-east-1" = "ami-b63769a1"
|
||||
}
|
||||
}
|
||||
|
||||
variable "aws_usernames" {
|
||||
description = "User to SSH as into the AWS instance."
|
||||
|
||||
default = {
|
||||
"ami-40d28157" = "ubuntu" # Ubuntu Server 16.04 LTS (HVM)
|
||||
"ami-b63769a1" = "ec2-user" # Red Hat Enterprise Linux 7.3 (HVM)
|
||||
}
|
||||
}
|
||||
|
||||
variable "aws_size" {
|
||||
description = "AWS' selected machine size"
|
||||
default = "t2.medium" # Instance with 2 cores & 4 GB memory
|
||||
}
|
||||
Executable
+98
@@ -0,0 +1,98 @@
|
||||
# Digital Ocean
|
||||
|
||||
## Introduction
|
||||
|
||||
This project allows you to get hold of some machine on Digital Ocean.
|
||||
You can then use these machines as is or run various Ansible playbooks from `../config_management` to set up Weave Net, Kubernetes, etc.
|
||||
|
||||
## Setup
|
||||
|
||||
* Log in [cloud.digitalocean.com](https://cloud.digitalocean.com) with your account.
|
||||
|
||||
* Go to `Settings` > `Security` > `SSH keys` > `Add SSH Key`.
|
||||
Enter your SSH public key and the name for it, and click `Add SSH Key`.
|
||||
Set the path to your private key as an environment variable:
|
||||
|
||||
```
|
||||
export DIGITALOCEAN_SSH_KEY_NAME=<your Digital Ocean SSH key name>
|
||||
export TF_VAR_do_private_key_path="$HOME/.ssh/id_rsa"
|
||||
```
|
||||
|
||||
* Go to `API` > `Tokens` > `Personal access tokens` > `Generate New Token`
|
||||
Enter your token name and click `Generate Token` to get your 64-characters-long API token.
|
||||
Set these as environment variables:
|
||||
|
||||
```
|
||||
export DIGITALOCEAN_TOKEN_NAME="<your Digital Ocean API token name>"
|
||||
export DIGITALOCEAN_TOKEN=<your Digital Ocean API token>
|
||||
```
|
||||
|
||||
* Run the following command to get the Digital Ocean ID for your SSH public key (e.g. `1234567`) and set it as an environment variable:
|
||||
|
||||
```
|
||||
$ export TF_VAR_do_public_key_id=$(curl -s -X GET -H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/account/keys" \
|
||||
| jq -c --arg key_name "$DIGITALOCEAN_SSH_KEY_NAME" '.ssh_keys | .[] | select(.name==$key_name) | .id')
|
||||
```
|
||||
|
||||
or pass it as a Terraform variable:
|
||||
|
||||
```
|
||||
$ terraform <command> \
|
||||
-var 'do_private_key_path=<path to your SSH private key>' \
|
||||
-var 'do_public_key_id=<ID of your SSH public key>'
|
||||
```
|
||||
|
||||
### Bash aliases
|
||||
|
||||
You can set the above variables temporarily in your current shell, permanently in your `~/.bashrc` file, or define aliases to activate/deactivate them at will with one single command by adding the below to your `~/.bashrc` file:
|
||||
|
||||
```
|
||||
function _do_on() {
|
||||
export DIGITALOCEAN_TOKEN_NAME="<your_token_name>" # Replace with appropriate value.
|
||||
export DIGITALOCEAN_TOKEN=<your_token> # Replace with appropriate value.
|
||||
export DIGITALOCEAN_SSH_KEY_NAME="<your_ssh_key_name>" # Replace with appropriate value.
|
||||
export TF_VAR_do_private_key_path="$HOME/.ssh/id_rsa" # Replace with appropriate value.
|
||||
export TF_VAR_do_public_key_path="$HOME/.ssh/id_rsa.pub" # Replace with appropriate value.
|
||||
export TF_VAR_do_public_key_id=<your_ssh_key_id> # Replace with appropriate value.
|
||||
}
|
||||
alias _do_on='_do_on'
|
||||
function _do_off() {
|
||||
unset DIGITALOCEAN_TOKEN_NAME
|
||||
unset DIGITALOCEAN_TOKEN
|
||||
unset DIGITALOCEAN_SSH_KEY_NAME
|
||||
unset TF_VAR_do_private_key_path
|
||||
unset TF_VAR_do_public_key_path
|
||||
unset TF_VAR_do_public_key_id
|
||||
}
|
||||
alias _do_off='_do_off'
|
||||
```
|
||||
|
||||
N.B.:
|
||||
|
||||
* sourcing `../setup.sh` defines aliases called `do_on` and `do_off`, similarly to the above (however, notice no `_` in front of the name, as opposed to the ones above);
|
||||
* `../setup.sh`'s `do_on` alias needs the `SECRET_KEY` environment variable to be set in order to decrypt sensitive information.
|
||||
|
||||
## Usage
|
||||
|
||||
* Create the machine: `terraform apply`
|
||||
* Show the machine's status: `terraform show`
|
||||
* Stop and destroy the machine: `terraform destroy`
|
||||
* SSH into the newly-created machine:
|
||||
|
||||
```
|
||||
$ ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no `terraform output username`@`terraform output public_ips`
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
source ../setup.sh
|
||||
tf_ssh 1 # Or the nth machine, if multiple VMs are provisioned.
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
* [https://www.terraform.io/docs/providers/do/](https://www.terraform.io/docs/providers/do/)
|
||||
* [https://www.terraform.io/docs/providers/do/r/droplet.html](https://www.terraform.io/docs/providers/do/r/droplet.html)
|
||||
* [Terraform variables](https://www.terraform.io/intro/getting-started/variables.html)
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
provider "digitalocean" {
|
||||
# See README.md for setup instructions.
|
||||
}
|
||||
|
||||
# Tags to label and organize droplets:
|
||||
resource "digitalocean_tag" "name" {
|
||||
name = "${var.name}"
|
||||
}
|
||||
|
||||
resource "digitalocean_tag" "app" {
|
||||
name = "${var.app}"
|
||||
}
|
||||
|
||||
resource "digitalocean_tag" "terraform" {
|
||||
name = "terraform"
|
||||
}
|
||||
|
||||
resource "digitalocean_droplet" "tf_test_vm" {
|
||||
ssh_keys = ["${var.do_public_key_id}"]
|
||||
image = "${var.do_os}"
|
||||
region = "${var.do_dc}"
|
||||
size = "${var.do_size}"
|
||||
name = "${var.name}-${count.index}"
|
||||
count = "${var.num_hosts}"
|
||||
|
||||
tags = [
|
||||
"${var.app}",
|
||||
"${var.name}",
|
||||
"terraform",
|
||||
]
|
||||
|
||||
# Wait for machine to be SSH-able:
|
||||
provisioner "remote-exec" {
|
||||
inline = ["exit"]
|
||||
|
||||
connection {
|
||||
type = "ssh"
|
||||
user = "${var.do_username}"
|
||||
private_key = "${file("${var.do_private_key_path}")}"
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+57
@@ -0,0 +1,57 @@
|
||||
output "username" {
|
||||
value = "${var.do_username}"
|
||||
}
|
||||
|
||||
output "public_ips" {
|
||||
value = ["${digitalocean_droplet.tf_test_vm.*.ipv4_address}"]
|
||||
}
|
||||
|
||||
output "hostnames" {
|
||||
value = "${join("\n",
|
||||
"${formatlist("%v.%v.%v",
|
||||
digitalocean_droplet.tf_test_vm.*.name,
|
||||
digitalocean_droplet.tf_test_vm.*.region,
|
||||
var.app
|
||||
)}"
|
||||
)}"
|
||||
}
|
||||
|
||||
# /etc/hosts file for the Droplets:
|
||||
# N.B.: by default Digital Ocean droplets only have public IPs, but in order to
|
||||
# be consistent with other providers' recipes, we provide an output to generate
|
||||
# an /etc/hosts file on the Droplets, even though it is using public IPs only.
|
||||
output "private_etc_hosts" {
|
||||
value = "${join("\n",
|
||||
"${formatlist("%v %v.%v.%v",
|
||||
digitalocean_droplet.tf_test_vm.*.ipv4_address,
|
||||
digitalocean_droplet.tf_test_vm.*.name,
|
||||
digitalocean_droplet.tf_test_vm.*.region,
|
||||
var.app
|
||||
)}"
|
||||
)}"
|
||||
}
|
||||
|
||||
# /etc/hosts file for the client:
|
||||
output "public_etc_hosts" {
|
||||
value = "${join("\n",
|
||||
"${formatlist("%v %v.%v.%v",
|
||||
digitalocean_droplet.tf_test_vm.*.ipv4_address,
|
||||
digitalocean_droplet.tf_test_vm.*.name,
|
||||
digitalocean_droplet.tf_test_vm.*.region,
|
||||
var.app
|
||||
)}"
|
||||
)}"
|
||||
}
|
||||
|
||||
output "ansible_inventory" {
|
||||
value = "${format("[all]\n%s", join("\n",
|
||||
"${formatlist("%v private_ip=%v",
|
||||
digitalocean_droplet.tf_test_vm.*.ipv4_address,
|
||||
digitalocean_droplet.tf_test_vm.*.ipv4_address
|
||||
)}"
|
||||
))}"
|
||||
}
|
||||
|
||||
output "private_key_path" {
|
||||
value = "${var.do_private_key_path}"
|
||||
}
|
||||
Executable
+185
@@ -0,0 +1,185 @@
|
||||
variable "client_ip" {
|
||||
description = "IP address of the client machine"
|
||||
}
|
||||
|
||||
variable "app" {
|
||||
description = "Name of the application using the created droplet(s)."
|
||||
default = "default"
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
description = "Name of the droplet(s)."
|
||||
default = "test"
|
||||
}
|
||||
|
||||
variable "num_hosts" {
|
||||
description = "Number of droplet(s)."
|
||||
default = 1
|
||||
}
|
||||
|
||||
variable "do_private_key_path" {
|
||||
description = "Digital Ocean SSH private key path"
|
||||
default = "~/.ssh/id_rsa"
|
||||
}
|
||||
|
||||
variable "do_public_key_id" {
|
||||
description = "Digital Ocean ID for your SSH public key"
|
||||
|
||||
# You can retrieve it and set it as an environment variable this way:
|
||||
|
||||
# $ export TF_VAR_do_public_key_id=$(curl -s -X GET -H "Content-Type: application/json" -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/account/keys" | jq -c --arg key_name "$DIGITALOCEAN_SSH_KEY_NAME" '.ssh_keys | .[] | select(.name==$key_name) | .id')
|
||||
}
|
||||
|
||||
variable "do_username" {
|
||||
description = "Digital Ocean SSH username"
|
||||
default = "root"
|
||||
}
|
||||
|
||||
variable "do_os" {
|
||||
description = "Digital Ocean OS"
|
||||
default = "ubuntu-16-04-x64"
|
||||
}
|
||||
|
||||
# curl -s -X GET -H "Content-Type: application/json" -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/images?page=1&per_page=999999" | jq ".images | .[] | .slug" | grep -P "ubuntu|coreos|centos" | grep -v alpha | grep -v beta
|
||||
# "ubuntu-16-04-x32"
|
||||
# "ubuntu-16-04-x64"
|
||||
# "ubuntu-16-10-x32"
|
||||
# "ubuntu-16-10-x64"
|
||||
# "ubuntu-14-04-x32"
|
||||
# "ubuntu-14-04-x64"
|
||||
# "ubuntu-12-04-x64"
|
||||
# "ubuntu-12-04-x32"
|
||||
# "coreos-stable"
|
||||
# "centos-6-5-x32"
|
||||
# "centos-6-5-x64"
|
||||
# "centos-7-0-x64"
|
||||
# "centos-7-x64"
|
||||
# "centos-6-x64"
|
||||
# "centos-6-x32"
|
||||
# "centos-5-x64"
|
||||
# "centos-5-x32"
|
||||
|
||||
# Digital Ocean datacenters
|
||||
# See also:
|
||||
# $ curl -s -X GET -H "Content-Type: application/json" -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/regions" | jq -c ".regions | .[] | .slug" | sort -u
|
||||
|
||||
variable "do_dc_ams2" {
|
||||
description = "Digital Ocean Amsterdam Datacenter 2"
|
||||
default = "ams2"
|
||||
}
|
||||
|
||||
variable "do_dc_ams3" {
|
||||
description = "Digital Ocean Amsterdam Datacenter 3"
|
||||
default = "ams3"
|
||||
}
|
||||
|
||||
variable "do_dc_blr1" {
|
||||
description = "Digital Ocean Bangalore Datacenter 1"
|
||||
default = "blr1"
|
||||
}
|
||||
|
||||
variable "do_dc_fra1" {
|
||||
description = "Digital Ocean Frankfurt Datacenter 1"
|
||||
default = "fra1"
|
||||
}
|
||||
|
||||
variable "do_dc_lon1" {
|
||||
description = "Digital Ocean London Datacenter 1"
|
||||
default = "lon1"
|
||||
}
|
||||
|
||||
variable "do_dc_nyc1" {
|
||||
description = "Digital Ocean New York Datacenter 1"
|
||||
default = "nyc1"
|
||||
}
|
||||
|
||||
variable "do_dc_nyc2" {
|
||||
description = "Digital Ocean New York Datacenter 2"
|
||||
default = "nyc2"
|
||||
}
|
||||
|
||||
variable "do_dc_nyc3" {
|
||||
description = "Digital Ocean New York Datacenter 3"
|
||||
default = "nyc3"
|
||||
}
|
||||
|
||||
variable "do_dc_sfo1" {
|
||||
description = "Digital Ocean San Francisco Datacenter 1"
|
||||
default = "sfo1"
|
||||
}
|
||||
|
||||
variable "do_dc_sfo2" {
|
||||
description = "Digital Ocean San Francisco Datacenter 2"
|
||||
default = "sfo2"
|
||||
}
|
||||
|
||||
variable "do_dc_sgp1" {
|
||||
description = "Digital Ocean Singapore Datacenter 1"
|
||||
default = "sgp1"
|
||||
}
|
||||
|
||||
variable "do_dc_tor1" {
|
||||
description = "Digital Ocean Toronto Datacenter 1"
|
||||
default = "tor1"
|
||||
}
|
||||
|
||||
variable "do_dc" {
|
||||
description = "Digital Ocean's selected datacenter"
|
||||
default = "lon1"
|
||||
}
|
||||
|
||||
variable "do_size" {
|
||||
description = "Digital Ocean's selected machine size"
|
||||
default = "4gb"
|
||||
}
|
||||
|
||||
# Digital Ocean sizes
|
||||
|
||||
|
||||
# See also:
|
||||
|
||||
|
||||
# $ curl -s -X GET -H "Content-Type: application/json" -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/sizes" | jq -c ".sizes | .[] | .slug"
|
||||
|
||||
|
||||
# "512mb"
|
||||
|
||||
|
||||
# "1gb"
|
||||
|
||||
|
||||
# "2gb"
|
||||
|
||||
|
||||
# "4gb"
|
||||
|
||||
|
||||
# "8gb"
|
||||
|
||||
|
||||
# "16gb"
|
||||
|
||||
|
||||
# "m-16gb"
|
||||
|
||||
|
||||
# "32gb"
|
||||
|
||||
|
||||
# "m-32gb"
|
||||
|
||||
|
||||
# "48gb"
|
||||
|
||||
|
||||
# "m-64gb"
|
||||
|
||||
|
||||
# "64gb"
|
||||
|
||||
|
||||
# "m-128gb"
|
||||
|
||||
|
||||
# "m-224gb"
|
||||
|
||||
Executable
+126
@@ -0,0 +1,126 @@
|
||||
# Google Cloud Platform
|
||||
|
||||
## Introduction
|
||||
|
||||
This project allows you to get hold of some machine on Google Cloud Platform.
|
||||
You can then use these machines as is or run various Ansible playbooks from `../config_management` to set up Weave Net, Kubernetes, etc.
|
||||
|
||||
## Setup
|
||||
|
||||
* Log in [console.cloud.google.com](https://console.cloud.google.com) with your Google account.
|
||||
|
||||
* Go to `API Manager` > `Credentials` > `Create credentials` > `Service account key`,
|
||||
in `Service account`, select `Compute Engine default service account`,
|
||||
in `Key type`, select `JSON`, and then click `Create`.
|
||||
|
||||
* This will download a JSON file to your machine. Place this file wherever you want and then create the following environment variables:
|
||||
|
||||
```
|
||||
$ export GOOGLE_CREDENTIALS_FILE="path/to/your.json"
|
||||
$ export GOOGLE_CREDENTIALS=$(cat "$GOOGLE_CREDENTIALS_FILE")
|
||||
```
|
||||
|
||||
* Go to `Compute Engine` > `Metadata` > `SSH keys` and add your username and SSH public key;
|
||||
or
|
||||
set it up using `gcloud compute project-info add-metadata --metadata-from-file sshKeys=~/.ssh/id_rsa.pub`.
|
||||
If you used your default SSH key (i.e. `~/.ssh/id_rsa.pub`), then you do not have anything to do.
|
||||
Otherwise, you will have to either define the below environment variable:
|
||||
|
||||
```
|
||||
$ export TF_VAR_gcp_public_key_path=<path to your SSH public key>
|
||||
$ export TF_VAR_gcp_private_key_path=<path to your SSH private key>
|
||||
```
|
||||
|
||||
or to pass these as Terraform variables:
|
||||
|
||||
```
|
||||
$ terraform <command> \
|
||||
-var 'gcp_public_key_path=<path to your SSH public key>' \
|
||||
-var 'gcp_private_key_path=<path to your SSH private key>'
|
||||
```
|
||||
|
||||
* Set the username in your public key as an environment variable.
|
||||
This will be used as the username of the Linux account created on the machine, which you will need to SSH into it later on.
|
||||
|
||||
N.B.:
|
||||
* GCP already has the username set from the SSH public key you uploaded in the previous step.
|
||||
* If your username is an email address, e.g. `name@domain.com`, then GCP uses `name` as the username.
|
||||
|
||||
```
|
||||
export TF_VAR_gcp_username=<your SSH public key username>
|
||||
```
|
||||
|
||||
* Set your current IP address as an environment variable:
|
||||
|
||||
```
|
||||
export TF_VAR_client_ip=$(curl -s -X GET http://checkip.amazonaws.com/)
|
||||
```
|
||||
|
||||
or pass it as a Terraform variable:
|
||||
|
||||
```
|
||||
$ terraform <command> -var 'client_ip=$(curl -s -X GET http://checkip.amazonaws.com/)'
|
||||
```
|
||||
|
||||
* Set your project as an environment variable:
|
||||
|
||||
```
|
||||
export TF_VAR_gcp_project=weave-net-tests
|
||||
```
|
||||
|
||||
or pass it as a Terraform variable:
|
||||
|
||||
```
|
||||
$ terraform <command> -var 'gcp_project=weave-net-tests'
|
||||
```
|
||||
|
||||
### Bash aliases
|
||||
|
||||
You can set the above variables temporarily in your current shell, permanently in your `~/.bashrc` file, or define aliases to activate/deactivate them at will with one single command by adding the below to your `~/.bashrc` file:
|
||||
|
||||
```
|
||||
function _gcp_on() {
|
||||
export GOOGLE_CREDENTIALS_FILE="<path/to/your/json/credentials/file.json"
|
||||
export GOOGLE_CREDENTIALS=$(cat "$GOOGLE_CREDENTIALS_FILE")
|
||||
export TF_VAR_gcp_private_key_path="$HOME/.ssh/id_rsa" # Replace with appropriate value.
|
||||
export TF_VAR_gcp_public_key_path="$HOME/.ssh/id_rsa.pub" # Replace with appropriate value.
|
||||
export TF_VAR_gcp_username=$(cat "$TF_VAR_gcp_public_key_path" | cut -d' ' -f3 | cut -d'@' -f1)
|
||||
}
|
||||
alias _gcp_on='_gcp_on'
|
||||
function _gcp_off() {
|
||||
unset GOOGLE_CREDENTIALS_FILE
|
||||
unset GOOGLE_CREDENTIALS
|
||||
unset TF_VAR_gcp_private_key_path
|
||||
unset TF_VAR_gcp_public_key_path
|
||||
unset TF_VAR_gcp_username
|
||||
}
|
||||
```
|
||||
|
||||
N.B.:
|
||||
|
||||
* sourcing `../setup.sh` defines aliases called `gcp_on` and `gcp_off`, similarly to the above (however, notice no `_` in front of the name, as opposed to the ones above);
|
||||
* `../setup.sh`'s `gcp_on` alias needs the `SECRET_KEY` environment variable to be set in order to decrypt sensitive information.
|
||||
|
||||
## Usage
|
||||
|
||||
* Create the machine: `terraform apply`
|
||||
* Show the machine's status: `terraform show`
|
||||
* Stop and destroy the machine: `terraform destroy`
|
||||
* SSH into the newly-created machine:
|
||||
|
||||
```
|
||||
$ ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no `terraform output username`@`terraform output public_ips`
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
source ../setup.sh
|
||||
tf_ssh 1 # Or the nth machine, if multiple VMs are provisioned.
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
* [https://www.terraform.io/docs/providers/google/](https://www.terraform.io/docs/providers/google/)
|
||||
* [https://www.terraform.io/docs/providers/google/r/compute_instance.html](https://www.terraform.io/docs/providers/google/r/compute_instance.html)
|
||||
* [Terraform variables](https://www.terraform.io/intro/getting-started/variables.html)
|
||||
Executable
+79
@@ -0,0 +1,79 @@
|
||||
provider "google" {
|
||||
# Set the below environment variables:
|
||||
# - GOOGLE_CREDENTIALS
|
||||
# - GOOGLE_PROJECT
|
||||
# - GOOGLE_REGION
|
||||
# or configure directly below.
|
||||
# See also:
|
||||
# - https://www.terraform.io/docs/providers/google/
|
||||
# - https://console.cloud.google.com/apis/credentials/serviceaccountkey?project=<PROJECT ID>&authuser=1
|
||||
region = "${var.gcp_region}"
|
||||
|
||||
project = "${var.gcp_project}"
|
||||
}
|
||||
|
||||
resource "google_compute_instance" "tf_test_vm" {
|
||||
name = "${var.name}-${count.index}"
|
||||
machine_type = "${var.gcp_size}"
|
||||
zone = "${var.gcp_zone}"
|
||||
count = "${var.num_hosts}"
|
||||
|
||||
disk {
|
||||
image = "${var.gcp_image}"
|
||||
}
|
||||
|
||||
tags = [
|
||||
"${var.app}",
|
||||
"${var.name}",
|
||||
"terraform",
|
||||
]
|
||||
|
||||
network_interface {
|
||||
network = "${var.gcp_network}"
|
||||
|
||||
access_config {
|
||||
// Ephemeral IP
|
||||
}
|
||||
}
|
||||
|
||||
metadata {
|
||||
ssh-keys = "${var.gcp_username}:${file("${var.gcp_public_key_path}")}"
|
||||
}
|
||||
|
||||
# Wait for machine to be SSH-able:
|
||||
provisioner "remote-exec" {
|
||||
inline = ["exit"]
|
||||
|
||||
connection {
|
||||
type = "ssh"
|
||||
user = "${var.gcp_username}"
|
||||
private_key = "${file("${var.gcp_private_key_path}")}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_firewall" "fw-allow-docker-and-weave" {
|
||||
name = "${var.name}-allow-docker-and-weave"
|
||||
network = "${var.gcp_network}"
|
||||
target_tags = ["${var.name}"]
|
||||
|
||||
allow {
|
||||
protocol = "tcp"
|
||||
ports = ["2375", "12375"]
|
||||
}
|
||||
|
||||
source_ranges = ["${var.client_ip}"]
|
||||
}
|
||||
|
||||
# Required for FastDP crypto in Weave Net:
|
||||
resource "google_compute_firewall" "fw-allow-esp" {
|
||||
name = "${var.name}-allow-esp"
|
||||
network = "${var.gcp_network}"
|
||||
target_tags = ["${var.name}"]
|
||||
|
||||
allow {
|
||||
protocol = "esp"
|
||||
}
|
||||
|
||||
source_ranges = ["${var.gcp_network_global_cidr}"]
|
||||
}
|
||||
Executable
+66
@@ -0,0 +1,66 @@
|
||||
output "username" {
|
||||
value = "${var.gcp_username}"
|
||||
}
|
||||
|
||||
output "public_ips" {
|
||||
value = ["${google_compute_instance.tf_test_vm.*.network_interface.0.access_config.0.assigned_nat_ip}"]
|
||||
}
|
||||
|
||||
output "hostnames" {
|
||||
value = "${join("\n",
|
||||
"${formatlist("%v.%v.%v",
|
||||
google_compute_instance.tf_test_vm.*.name,
|
||||
google_compute_instance.tf_test_vm.*.zone,
|
||||
var.app
|
||||
)}"
|
||||
)}"
|
||||
}
|
||||
|
||||
# /etc/hosts file for the Compute Engine instances:
|
||||
output "private_etc_hosts" {
|
||||
value = "${join("\n",
|
||||
"${formatlist("%v %v.%v.%v",
|
||||
google_compute_instance.tf_test_vm.*.network_interface.0.address,
|
||||
google_compute_instance.tf_test_vm.*.name,
|
||||
google_compute_instance.tf_test_vm.*.zone,
|
||||
var.app
|
||||
)}"
|
||||
)}"
|
||||
}
|
||||
|
||||
# /etc/hosts file for the client:
|
||||
output "public_etc_hosts" {
|
||||
value = "${join("\n",
|
||||
"${formatlist("%v %v.%v.%v",
|
||||
google_compute_instance.tf_test_vm.*.network_interface.0.access_config.0.assigned_nat_ip,
|
||||
google_compute_instance.tf_test_vm.*.name,
|
||||
google_compute_instance.tf_test_vm.*.zone,
|
||||
var.app
|
||||
)}"
|
||||
)}"
|
||||
}
|
||||
|
||||
output "ansible_inventory" {
|
||||
value = "${format("[all]\n%s", join("\n",
|
||||
"${formatlist("%v private_ip=%v",
|
||||
google_compute_instance.tf_test_vm.*.network_interface.0.access_config.0.assigned_nat_ip,
|
||||
google_compute_instance.tf_test_vm.*.network_interface.0.address
|
||||
)}"
|
||||
))}"
|
||||
}
|
||||
|
||||
output "private_key_path" {
|
||||
value = "${var.gcp_private_key_path}"
|
||||
}
|
||||
|
||||
output "instances_names" {
|
||||
value = ["${google_compute_instance.tf_test_vm.*.name}"]
|
||||
}
|
||||
|
||||
output "image" {
|
||||
value = "${var.gcp_image}"
|
||||
}
|
||||
|
||||
output "zone" {
|
||||
value = "${var.gcp_zone}"
|
||||
}
|
||||
Executable
+71
@@ -0,0 +1,71 @@
|
||||
variable "gcp_username" {
|
||||
description = "Google Cloud Platform SSH username"
|
||||
}
|
||||
|
||||
variable "app" {
|
||||
description = "Name of the application using the created Compute Engine instance(s)."
|
||||
default = "default"
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
description = "Name of the Compute Engine instance(s)."
|
||||
default = "test"
|
||||
}
|
||||
|
||||
variable "num_hosts" {
|
||||
description = "Number of Compute Engine instance(s)."
|
||||
default = 1
|
||||
}
|
||||
|
||||
variable "client_ip" {
|
||||
description = "IP address of the client machine"
|
||||
}
|
||||
|
||||
variable "gcp_public_key_path" {
|
||||
description = "Path to file containing public key"
|
||||
default = "~/.ssh/id_rsa.pub"
|
||||
}
|
||||
|
||||
variable "gcp_private_key_path" {
|
||||
description = "Path to file containing private key"
|
||||
default = "~/.ssh/id_rsa"
|
||||
}
|
||||
|
||||
variable "gcp_project" {
|
||||
description = "Google Cloud Platform project"
|
||||
default = "weave-net-tests"
|
||||
}
|
||||
|
||||
variable "gcp_image" {
|
||||
# See also: https://cloud.google.com/compute/docs/images
|
||||
description = "Google Cloud Platform OS"
|
||||
default = "ubuntu-os-cloud/ubuntu-1604-lts"
|
||||
}
|
||||
|
||||
variable "gcp_size" {
|
||||
# See also:
|
||||
# $ gcloud compute machine-types list
|
||||
description = "Google Cloud Platform's selected machine size"
|
||||
|
||||
default = "n1-standard-1"
|
||||
}
|
||||
|
||||
variable "gcp_region" {
|
||||
description = "Google Cloud Platform's selected region"
|
||||
default = "us-central1"
|
||||
}
|
||||
|
||||
variable "gcp_zone" {
|
||||
description = "Google Cloud Platform's selected zone"
|
||||
default = "us-central1-a"
|
||||
}
|
||||
|
||||
variable "gcp_network" {
|
||||
description = "Google Cloud Platform's selected network"
|
||||
default = "test"
|
||||
}
|
||||
|
||||
variable "gcp_network_global_cidr" {
|
||||
description = "CIDR covering all regions for the selected Google Cloud Platform network"
|
||||
default = "10.128.0.0/9"
|
||||
}
|
||||
Executable
+353
@@ -0,0 +1,353 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Description:
|
||||
# Helper functions to programmatically provision (e.g. for CIT).
|
||||
# Aliases on these functions are also created so that this script can be
|
||||
# sourced in your shell, in your ~/.bashrc file, etc. and directly called.
|
||||
#
|
||||
# Usage:
|
||||
# Source this file and call the relevant functions.
|
||||
#
|
||||
|
||||
function ssh_public_key() {
|
||||
echo -e "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDZBgLQts30PYXEMJnCU21QC+1ZE0Sv/Ry48Au3nYXn1KNoW/7C2qQ3KO2ZnpZRHCstFiU8QIlB9edi0cgcAoDWBkCiFBZEORxMvohWtrRQzf+x59o48lVjA/Fn7G+9hmavhLaDf6Qe7OhH8XUshNtnIQIUvNEWXKE75k32wUbuF8ibhJNpOOYKL4tVXK6IIKg6jR88BwGKPY/NZCl/HbhjnDJY0zCU1pZSprN6o/S953y/XXVozkh1772fCNeu4USfbt0oZOEJ57j6EWwEYIJhoeAEMAoD8ELt/bc/5iex8cuarM4Uib2JHO6WPWbBQ0NlrARIOKLrxkjjfGWarOLWBAgvwQn5zLg1pKb7aI4+jbA+ZSrII5B2HuYE9MDlU8NPL4pHrRfapGLkG/Fe9zNPvScXh+9iSWfD6G5ZoISutjiJO/iVYN0QSuj9QEIj9tl20czFz3Dhnq4sPPl5hoLunyQfajY7C/ipv6ilJyrEc0V6Z9FdPhpEI+HOgJr2vDQTFscQuyfWuzGJDZf6zPdZWo2pBql9E7piARuNAjakylGar/ebkCgfy28XQoDbDT0P0VYp+E8W5EYacx+zc5MuNhRTvbsO12fydT8V61MtA78wM/b0059feph+0zTykEHk670mYVoE3erZX+U1/BVBLSV9QzopO6/Pgx2ryriJfQ== weaveworks-cit"
|
||||
}
|
||||
|
||||
function decrypt() {
|
||||
if [ -z "$1" ]; then
|
||||
echo >&2 "Failed to decode and decrypt $2: no secret key was provided."
|
||||
return 1
|
||||
fi
|
||||
echo "$3" | openssl base64 -d | openssl enc -d -aes256 -pass "pass:$1"
|
||||
}
|
||||
|
||||
function ssh_private_key() {
|
||||
# The private key has been AES256-encrypted and then Base64-encoded using the following command:
|
||||
# $ openssl enc -in /tmp/weaveworks_cit_id_rsa -e -aes256 -pass stdin | openssl base64 > /tmp/weaveworks_cit_id_rsa.aes.b64
|
||||
# The below command does the reverse, i.e. base64-decode and AES-decrypt the file, and prints it to stdout.
|
||||
# N.B.: Ask the password to Marc, or otherwise re-generate the SSH key using:
|
||||
# $ ssh-keygen -t rsa -b 4096 -C "weaveworks-cit"
|
||||
decrypt "$1" "SSH private key" "$(
|
||||
cat <<EOF
|
||||
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
|
||||
EOF
|
||||
)"
|
||||
}
|
||||
|
||||
function set_up_ssh_private_key() {
|
||||
if [ -z "$1" ]; then
|
||||
echo >&2 "Failed to decode and decrypt SSH private key: no secret key was provided."
|
||||
return 1
|
||||
fi
|
||||
local ssh_private_key_path="$HOME/.ssh/weaveworks_cit_id_rsa"
|
||||
[ -e "$ssh_private_key_path" ] && rm -f "$ssh_private_key_path"
|
||||
ssh_private_key "$1" >"$ssh_private_key_path"
|
||||
chmod 400 "$ssh_private_key_path"
|
||||
echo "$ssh_private_key_path"
|
||||
}
|
||||
|
||||
function gcp_credentials() {
|
||||
# The below GCP service account JSON credentials have been AES256-encrypted and then Base64-encoded using the following command:
|
||||
# $ openssl enc -in ~/.ssh/weaveworks-cit.json -e -aes256 -pass stdin | openssl base64 > /tmp/weaveworks-cit.json.aes.b64
|
||||
# The below command does the reverse, i.e. base64-decode and AES-decrypt the file, and prints it to stdout.
|
||||
# N.B.: Ask the password to Marc, or otherwise re-generate the credentials for GCP, as per ../tools/provisioning/gcp/README.md.
|
||||
decrypt "$1" "JSON credentials" "$(
|
||||
cat <<EOF
|
||||
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
|
||||
EOF
|
||||
)"
|
||||
}
|
||||
|
||||
# shellcheck disable=2155
|
||||
function do_on() {
|
||||
# Set up everything required to run tests on Digital Ocean.
|
||||
# Steps from ../tools/provisioning/do/README.md have been followed.
|
||||
# All sensitive files have been encrypted, see respective functions.
|
||||
if [ -z "$SECRET_KEY" ]; then
|
||||
echo >&2 "Failed to configure for Digital Ocean: no value for the SECRET_KEY environment variable."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# SSH public key:
|
||||
export TF_VAR_do_public_key_path="$HOME/.ssh/weaveworks_cit_id_rsa.pub"
|
||||
ssh_public_key >"$TF_VAR_do_public_key_path"
|
||||
export DIGITALOCEAN_SSH_KEY_NAME="weaveworks-cit"
|
||||
export TF_VAR_do_public_key_id=5228799
|
||||
|
||||
# SSH private key:
|
||||
export TF_VAR_do_private_key_path=$(set_up_ssh_private_key "$SECRET_KEY")
|
||||
|
||||
# API token:
|
||||
# The below Digital Ocean token has been AES256-encrypted and then Base64-encoded using the following command:
|
||||
# $ openssl enc -in /tmp/digital_ocean_token.txt -e -aes256 -pass stdin | openssl base64 > /tmp/digital_ocean_token.txt.aes.b64
|
||||
# The below command does the reverse, i.e. base64-decode and AES-decrypt the file, and prints it to stdout.
|
||||
# N.B.: Ask the password to Marc, or otherwise re-generate the token for Digital Ocean, as per ../tools/provisioning/do/README.md.
|
||||
export DIGITALOCEAN_TOKEN=$(decrypt "$SECRET_KEY" "Digital Ocean token" "U2FsdGVkX1/Gq5Rj9dDDraME8xK30JOyJ9dhfQzPBaaePJHqDPIG6of71DdJW0UyFUyRtbRflCPaZ8Um1pDJpU5LoNWQk4uCApC8+xciltT73uQtttLBG8FqgFBvYIHS")
|
||||
export DIGITALOCEAN_TOKEN_NAME="weaveworks-cit"
|
||||
export TF_VAR_client_ip=$(curl -s -X GET http://checkip.amazonaws.com/)
|
||||
}
|
||||
alias do_on='do_on'
|
||||
|
||||
function do_off() {
|
||||
unset TF_VAR_do_public_key_path
|
||||
unset DIGITALOCEAN_SSH_KEY_NAME
|
||||
unset TF_VAR_do_public_key_id
|
||||
unset TF_VAR_do_private_key_path
|
||||
unset DIGITALOCEAN_TOKEN
|
||||
unset DIGITALOCEAN_TOKEN_NAME
|
||||
unset TF_VAR_client_ip
|
||||
}
|
||||
alias do_off='do_off'
|
||||
|
||||
# shellcheck disable=2155
|
||||
function gcp_on() {
|
||||
# Set up everything required to run tests on GCP.
|
||||
# Steps from ../tools/provisioning/gcp/README.md have been followed.
|
||||
# All sensitive files have been encrypted, see respective functions.
|
||||
if [ -z "$SECRET_KEY" ]; then
|
||||
echo >&2 "Failed to configure for Google Cloud Platform: no value for the SECRET_KEY environment variable."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# SSH public key and SSH username:
|
||||
export TF_VAR_gcp_public_key_path="$HOME/.ssh/weaveworks_cit_id_rsa.pub"
|
||||
ssh_public_key >"$TF_VAR_gcp_public_key_path"
|
||||
export TF_VAR_gcp_username=$(cut -d' ' -f3 "$TF_VAR_gcp_public_key_path" | cut -d'@' -f1)
|
||||
|
||||
# SSH private key:
|
||||
export TF_VAR_gcp_private_key_path=$(set_up_ssh_private_key "$SECRET_KEY")
|
||||
|
||||
# JSON credentials:
|
||||
export GOOGLE_CREDENTIALS_FILE="$HOME/.ssh/weaveworks-cit.json"
|
||||
[ -e "$GOOGLE_CREDENTIALS_FILE" ] && rm -f "$GOOGLE_CREDENTIALS_FILE"
|
||||
gcp_credentials "$SECRET_KEY" >"$GOOGLE_CREDENTIALS_FILE"
|
||||
chmod 400 "$GOOGLE_CREDENTIALS_FILE"
|
||||
export GOOGLE_CREDENTIALS=$(cat "$GOOGLE_CREDENTIALS_FILE")
|
||||
|
||||
export TF_VAR_client_ip=$(curl -s -X GET http://checkip.amazonaws.com/)
|
||||
export TF_VAR_gcp_project="${PROJECT:-"weave-net-tests"}"
|
||||
# shellcheck disable=2015
|
||||
[ -z "$PROJECT" ] && echo >&2 "WARNING: no value provided for PROJECT environment variable: defaulted it to $TF_VAR_gcp_project." || true
|
||||
}
|
||||
alias gcp_on='gcp_on'
|
||||
|
||||
function gcp_off() {
|
||||
unset TF_VAR_gcp_public_key_path
|
||||
unset TF_VAR_gcp_username
|
||||
unset TF_VAR_gcp_private_key_path
|
||||
unset GOOGLE_CREDENTIALS_FILE
|
||||
unset GOOGLE_CREDENTIALS
|
||||
unset TF_VAR_client_ip
|
||||
unset TF_VAR_gcp_project
|
||||
}
|
||||
alias gcp_off='gcp_off'
|
||||
|
||||
# shellcheck disable=2155
|
||||
function aws_on() {
|
||||
# Set up everything required to run tests on Amazon Web Services.
|
||||
# Steps from ../tools/provisioning/aws/README.md have been followed.
|
||||
# All sensitive files have been encrypted, see respective functions.
|
||||
if [ -z "$SECRET_KEY" ]; then
|
||||
echo >&2 "Failed to configure for Amazon Web Services: no value for the SECRET_KEY environment variable."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# SSH public key:
|
||||
export TF_VAR_aws_public_key_name="weaveworks_cit_id_rsa"
|
||||
|
||||
# SSH private key:
|
||||
export TF_VAR_aws_private_key_path=$(set_up_ssh_private_key "$SECRET_KEY")
|
||||
|
||||
# The below AWS access key ID and secret access key have been AES256-encrypted and then Base64-encoded using the following commands:
|
||||
# $ openssl enc -in /tmp/aws_access_key_id.txt -e -aes256 -pass stdin | openssl base64 > /tmp/aws_access_key_id.txt.aes.b64
|
||||
# $ openssl enc -in /tmp/aws_secret_access_key.txt -e -aes256 -pass stdin | openssl base64 > /tmp/aws_secret_access_key.txt.aes.b64
|
||||
# The below commands do the reverse, i.e. base64-decode and AES-decrypt the encrypted and encoded strings, and print it to stdout.
|
||||
# N.B.: Ask the password to Marc, or otherwise re-generate the AWS access key ID and secret access key, as per ../tools/provisioning/aws/README.md.
|
||||
export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-$(decrypt "$SECRET_KEY" "AWS access key ID" "U2FsdGVkX1+MLsvG53ZVSmFhjvQtWio0pXQpG5Ua+5JaoizuZKtJZFJxrSSyx0jb")}
|
||||
export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-$(decrypt "$SECRET_KEY" "AWS secret access key" "U2FsdGVkX1+VNjgWv5iGKRqBYP7o8MpOIMnd3BOYPiEho1Mjosx++9CknaZJbeR59vSuz4UdgTS6ezH2dnq2Fw==")}
|
||||
export TF_VAR_client_ip=$(curl -s -X GET http://checkip.amazonaws.com/)
|
||||
}
|
||||
alias aws_on='aws_on'
|
||||
|
||||
function aws_off() {
|
||||
unset TF_VAR_aws_public_key_name
|
||||
unset TF_VAR_aws_private_key_path
|
||||
unset AWS_ACCESS_KEY_ID
|
||||
unset AWS_SECRET_ACCESS_KEY
|
||||
unset TF_VAR_client_ip
|
||||
}
|
||||
alias aws_off='aws_off'
|
||||
|
||||
function tf_ssh_usage() {
|
||||
cat >&2 <<-EOF
|
||||
ERROR: $1
|
||||
|
||||
Usage:
|
||||
$ tf_ssh <host ID (1-based)> [OPTION]...
|
||||
Examples:
|
||||
$ tf_ssh 1
|
||||
$ tf_ssh 1 -o LogLevel VERBOSE
|
||||
Available machines:
|
||||
EOF
|
||||
cat -n >&2 <<<"$(terraform output public_etc_hosts)"
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2155
|
||||
function tf_ssh() {
|
||||
[ -z "$1" ] && tf_ssh_usage "No host ID provided." && return 1
|
||||
local ip="$(sed "$1q;d" <<<"$(terraform output public_etc_hosts)" | cut -d ' ' -f 1)"
|
||||
shift # Drop the first argument, corresponding to the machine ID, to allow passing other arguments to SSH using "$@" -- see below.
|
||||
[ -z "$ip" ] && tf_ssh_usage "Invalid host ID provided." && return 1
|
||||
# shellcheck disable=SC2029
|
||||
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "$@" "$(terraform output username)@$ip"
|
||||
}
|
||||
alias tf_ssh='tf_ssh'
|
||||
|
||||
function tf_ansi_usage() {
|
||||
cat >&2 <<-EOF
|
||||
ERROR: $1
|
||||
|
||||
Usage:
|
||||
$ tf_ansi <playbook or playbook ID (1-based)> [OPTION]...
|
||||
Examples:
|
||||
$ tf_ansi setup_weave-net_dev
|
||||
$ tf_ansi 1
|
||||
$ tf_ansi 1 -vvv
|
||||
Available playbooks:
|
||||
EOF
|
||||
cat -n >&2 <<<"$(for file in "$(dirname "${BASH_SOURCE[0]}")"/../../config_management/*.yml; do basename "$file" | sed 's/.yml//'; done)"
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2155,SC2064
|
||||
function tf_ansi() {
|
||||
[ -z "$1" ] && tf_ansi_usage "No Ansible playbook provided." && return 1
|
||||
local id="$1"
|
||||
shift # Drop the first argument to allow passing other arguments to Ansible using "$@" -- see below.
|
||||
if [[ "$id" =~ ^[0-9]+$ ]]; then
|
||||
local playbooks=(../../config_management/*.yml)
|
||||
local path="${playbooks[(($id-1))]}" # Select the ith entry in the list of playbooks (0-based).
|
||||
else
|
||||
local path="$(dirname "${BASH_SOURCE[0]}")/../../config_management/$id.yml"
|
||||
fi
|
||||
local inventory="$(mktemp /tmp/ansible_inventory_XXX)"
|
||||
trap 'rm -f $inventory' SIGINT SIGTERM RETURN
|
||||
echo -e "$(terraform output ansible_inventory)" >"$inventory"
|
||||
[ ! -r "$path" ] && tf_ansi_usage "Ansible playbook not found: $path" && return 1
|
||||
ansible-playbook "$@" -u "$(terraform output username)" -i "$inventory" --ssh-extra-args="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" "$path"
|
||||
}
|
||||
alias tf_ansi='tf_ansi'
|
||||
+3
-2
@@ -15,7 +15,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/mgutz/ansi"
|
||||
"github.com/weaveworks/docker/pkg/mflag"
|
||||
"github.com/weaveworks/common/mflag"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -148,9 +148,10 @@ func updateScheduler(test string, duration float64) {
|
||||
|
||||
func getSchedule(tests []string) ([]string, error) {
|
||||
var (
|
||||
userName = os.Getenv("CIRCLE_PROJECT_USERNAME")
|
||||
project = os.Getenv("CIRCLE_PROJECT_REPONAME")
|
||||
buildNum = os.Getenv("CIRCLE_BUILD_NUM")
|
||||
testRun = project + "-integration-" + buildNum
|
||||
testRun = userName + "-" + project + "-integration-" + buildNum
|
||||
shardCount = os.Getenv("CIRCLE_NODE_TOTAL")
|
||||
shardID = os.Getenv("CIRCLE_NODE_INDEX")
|
||||
requestBody = &bytes.Buffer{}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
#!/usr/bin/python
|
||||
import sys, string, json, urllib
|
||||
import sys, string, urllib
|
||||
import requests
|
||||
import optparse
|
||||
|
||||
def test_time(target, test_name, runtime):
|
||||
r = requests.post(target + "/record/%s/%f" % (urllib.quote(test_name, safe=""), runtime))
|
||||
print r.text
|
||||
print r.text.encode('utf-8')
|
||||
assert r.status_code == 204
|
||||
|
||||
def test_sched(target, test_run, shard_count, shard_id):
|
||||
tests = json.dumps({'tests': string.split(sys.stdin.read())})
|
||||
r = requests.post(target + "/schedule/%s/%d/%d" % (test_run, shard_count, shard_id), data=tests)
|
||||
tests = {'tests': string.split(sys.stdin.read())}
|
||||
r = requests.post(target + "/schedule/%s/%d/%d" % (test_run, shard_count, shard_id), json=tests)
|
||||
assert r.status_code == 200
|
||||
result = r.json()
|
||||
for test in sorted(result['tests']):
|
||||
print test
|
||||
print test.encode('utf-8')
|
||||
|
||||
def usage():
|
||||
print "%s (--target=...) <cmd> <args..>" % sys.argv[0]
|
||||
|
||||
+2
-2
@@ -9,8 +9,8 @@ import (
|
||||
"text/template"
|
||||
|
||||
socks5 "github.com/armon/go-socks5"
|
||||
"github.com/weaveworks/docker/pkg/mflag"
|
||||
"github.com/weaveworks/weave/common/mflagext"
|
||||
"github.com/weaveworks/common/mflag"
|
||||
"github.com/weaveworks/common/mflagext"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
|
||||
@@ -3,12 +3,14 @@
|
||||
set -e
|
||||
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
GO_TEST_ARGS=(-tags netgo -cpu 4 -timeout 8m)
|
||||
SLOW=
|
||||
NO_GO_GET=
|
||||
NO_GO_GET=true
|
||||
TAGS=
|
||||
PARALLEL=
|
||||
TIMEOUT=1m
|
||||
|
||||
usage() {
|
||||
echo "$0 [-slow] [-in-container foo]"
|
||||
echo "$0 [-slow] [-in-container foo] [-netgo] [-(no-)go-get] [-timeout 1m]"
|
||||
}
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
@@ -21,6 +23,22 @@ while [ $# -gt 0 ]; do
|
||||
NO_GO_GET=true
|
||||
shift 1
|
||||
;;
|
||||
"-go-get")
|
||||
NO_GO_GET=
|
||||
shift 1
|
||||
;;
|
||||
"-netgo")
|
||||
TAGS="-tags netgo"
|
||||
shift 1
|
||||
;;
|
||||
"-p")
|
||||
PARALLEL=true
|
||||
shift 1
|
||||
;;
|
||||
"-timeout")
|
||||
TIMEOUT=$2
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 2
|
||||
@@ -28,6 +46,8 @@ while [ $# -gt 0 ]; do
|
||||
esac
|
||||
done
|
||||
|
||||
GO_TEST_ARGS=($TAGS -cpu 4 -timeout $TIMEOUT)
|
||||
|
||||
if [ -n "$SLOW" ] || [ -n "$CIRCLECI" ]; then
|
||||
SLOW=true
|
||||
fi
|
||||
@@ -60,7 +80,7 @@ fi
|
||||
# If running on circle, use the scheduler to work out what tests to run on what shard
|
||||
if [ -n "$CIRCLECI" ] && [ -z "$NO_SCHEDULER" ] && [ -x "$DIR/sched" ]; then
|
||||
PREFIX=$(go list -e ./ | sed -e 's/\//-/g')
|
||||
TESTDIRS=($(echo "${TESTDIRS[@]}" | "$DIR/sched" sched "$PREFIX-$CIRCLE_BUILD_NUM" "$CIRCLE_NODE_TOTAL" "$CIRCLE_NODE_INDEX"))
|
||||
TESTDIRS=($(echo "${TESTDIRS[@]}" | "$DIR/sched" sched "$PREFIX-$CIRCLE_PROJECT_USERNAME-$CIRCLE_PROJECT_REPONAME-$CIRCLE_BUILD_NUM" "$CIRCLE_NODE_TOTAL" "$CIRCLE_NODE_INDEX"))
|
||||
echo "${TESTDIRS[@]}"
|
||||
fi
|
||||
|
||||
@@ -69,33 +89,49 @@ PACKAGE_BASE=$(go list -e ./)
|
||||
# Speed up the tests by compiling and installing their dependencies first.
|
||||
go test -i "${GO_TEST_ARGS[@]}" "${TESTDIRS[@]}"
|
||||
|
||||
for dir in "${TESTDIRS[@]}"; do
|
||||
run_test() {
|
||||
local dir=$1
|
||||
if [ -z "$NO_GO_GET" ]; then
|
||||
go get -t -tags netgo "$dir"
|
||||
go get -t "$TAGS" "$dir"
|
||||
fi
|
||||
|
||||
GO_TEST_ARGS_RUN=("${GO_TEST_ARGS[@]}")
|
||||
local GO_TEST_ARGS_RUN=("${GO_TEST_ARGS[@]}")
|
||||
if [ -n "$SLOW" ]; then
|
||||
local COVERPKGS
|
||||
COVERPKGS=$( (
|
||||
go list "$dir"
|
||||
go list -f '{{join .Deps "\n"}}' "$dir" | grep -v "vendor" | grep "^$PACKAGE_BASE/"
|
||||
) | paste -s -d, -)
|
||||
local output
|
||||
output=$(mktemp "$coverdir/unit.XXXXXXXXXX")
|
||||
GO_TEST_ARGS_RUN=("${GO_TEST_ARGS[@]}" -coverprofile=$output -coverpkg=$COVERPKGS)
|
||||
local GO_TEST_ARGS_RUN=("${GO_TEST_ARGS[@]}" -coverprofile=$output -coverpkg=$COVERPKGS)
|
||||
fi
|
||||
|
||||
local START
|
||||
START=$(date +%s)
|
||||
if ! go test "${GO_TEST_ARGS_RUN[@]}" "$dir"; then
|
||||
fail=1
|
||||
fi
|
||||
RUNTIME=$(($(date +%s) - START))
|
||||
local RUNTIME=$(($(date +%s) - START))
|
||||
|
||||
# Report test runtime when running on circle, to help scheduler
|
||||
if [ -n "$CIRCLECI" ] && [ -z "$NO_SCHEDULER" ] && [ -x "$DIR/sched" ]; then
|
||||
"$DIR/sched" time "$dir" "$RUNTIME"
|
||||
fi
|
||||
}
|
||||
|
||||
for dir in "${TESTDIRS[@]}"; do
|
||||
if [ -n "$PARALLEL" ]; then
|
||||
run_test "$dir" &
|
||||
else
|
||||
run_test "$dir"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$PARALLEL" ]; then
|
||||
wait
|
||||
fi
|
||||
|
||||
if [ -n "$SLOW" ] && [ -z "$COVERDIR" ]; then
|
||||
go get github.com/weaveworks/tools/cover
|
||||
cover "$coverdir"/* >profile.cov
|
||||
|
||||
Reference in New Issue
Block a user