├── .gitignore ├── README.md ├── chapter3 ├── Vagrantfile ├── labs │ ├── cmd_vs_entrypoint │ │ └── Dockerfile │ ├── docker-centos-vim │ │ └── Dockerfile │ ├── docker-python │ │ └── Dockerfile │ ├── flask-hello-world │ │ ├── Dockerfile │ │ └── app.py │ ├── hello-world │ │ ├── Dockerfile │ │ ├── hello │ │ └── hello.c │ └── ubuntu-stress │ │ └── Dockerfile └── setup.sh ├── chapter4 ├── Vagrantfile ├── labs │ ├── flask-redis │ │ ├── Dockerfile │ │ ├── app.py │ │ └── multi-host-network.md │ └── labs │ │ ├── docker-nginx │ │ ├── Dockerfile │ │ └── index.html │ │ ├── flask-hello-world │ │ ├── Dockerfile │ │ ├── manage.py │ │ └── test │ │ └── flask-skeleton │ │ ├── .coveragerc │ │ ├── .gitignore │ │ ├── .gitlab-ci.yml │ │ ├── .gitlab │ │ ├── issue_templates │ │ │ ├── Bug.md │ │ │ └── Feature.md │ │ └── merge_request_templates │ │ │ └── default.md │ │ ├── CONTRIBUTING.md │ │ ├── Dockerfile │ │ ├── LICENSE │ │ ├── README.md │ │ ├── doc │ │ ├── Makefile │ │ ├── make.bat │ │ └── source │ │ │ ├── _static │ │ │ └── .placeholder │ │ │ ├── _templates │ │ │ └── .placeholder │ │ │ ├── conf.py │ │ │ └── index.rst │ │ ├── manage.py │ │ ├── migrations │ │ ├── README │ │ ├── alembic.ini │ │ ├── env.py │ │ └── script.py.mako │ │ ├── requirements.txt │ │ ├── scripts │ │ ├── deploy.sh │ │ └── dev.sh │ │ ├── skeleton │ │ ├── __init__.py │ │ ├── client │ │ │ ├── static │ │ │ │ ├── main.css │ │ │ │ └── main.js │ │ │ └── templates │ │ │ │ ├── _base.html │ │ │ │ ├── errors │ │ │ │ ├── 401.html │ │ │ │ ├── 403.html │ │ │ │ ├── 404.html │ │ │ │ └── 500.html │ │ │ │ ├── footer.html │ │ │ │ ├── header.html │ │ │ │ ├── main │ │ │ │ ├── about.html │ │ │ │ └── home.html │ │ │ │ └── user │ │ │ │ ├── login.html │ │ │ │ ├── members.html │ │ │ │ └── register.html │ │ └── server │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ ├── main │ │ │ ├── __init__.py │ │ │ └── views.py │ │ │ ├── models.py │ │ │ └── user │ │ │ ├── __init__.py │ │ │ ├── forms.py │ │ │ └── views.py │ │ ├── test-requirements.txt │ │ ├── tests │ │ ├── __init__.py │ │ ├── base.py │ │ ├── test_config.py │ │ ├── test_main.py │ │ └── test_user.py │ │ └── tox.ini ├── multi-host-network.md └── setup.sh ├── chapter5 ├── Vagrantfile ├── labs │ ├── docker-nginx │ │ ├── Dockerfile │ │ └── index.html │ ├── flask-hello-world │ │ ├── Dockerfile │ │ ├── manage.py │ │ └── test │ └── flask-skeleton │ │ ├── .coveragerc │ │ ├── .gitignore │ │ ├── .gitlab-ci.yml │ │ ├── .gitlab │ │ ├── issue_templates │ │ │ ├── Bug.md │ │ │ └── Feature.md │ │ └── merge_request_templates │ │ │ └── default.md │ │ ├── CONTRIBUTING.md │ │ ├── Dockerfile │ │ ├── LICENSE │ │ ├── README.md │ │ ├── doc │ │ ├── Makefile │ │ ├── make.bat │ │ └── source │ │ │ ├── _static │ │ │ └── .placeholder │ │ │ ├── _templates │ │ │ └── .placeholder │ │ │ ├── conf.py │ │ │ └── index.rst │ │ ├── manage.py │ │ ├── migrations │ │ ├── README │ │ ├── alembic.ini │ │ ├── env.py │ │ └── script.py.mako │ │ ├── requirements.txt │ │ ├── scripts │ │ ├── deploy.sh │ │ └── dev.sh │ │ ├── skeleton │ │ ├── __init__.py │ │ ├── client │ │ │ ├── static │ │ │ │ ├── main.css │ │ │ │ └── main.js │ │ │ └── templates │ │ │ │ ├── _base.html │ │ │ │ ├── errors │ │ │ │ ├── 401.html │ │ │ │ ├── 403.html │ │ │ │ ├── 404.html │ │ │ │ └── 500.html │ │ │ │ ├── footer.html │ │ │ │ ├── header.html │ │ │ │ ├── main │ │ │ │ ├── about.html │ │ │ │ └── home.html │ │ │ │ └── user │ │ │ │ ├── login.html │ │ │ │ ├── members.html │ │ │ │ └── register.html │ │ └── server │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ ├── main │ │ │ ├── __init__.py │ │ │ └── views.py │ │ │ ├── models.py │ │ │ └── user │ │ │ ├── __init__.py │ │ │ ├── forms.py │ │ │ └── views.py │ │ ├── test-requirements.txt │ │ ├── tests │ │ ├── __init__.py │ │ ├── base.py │ │ ├── test_config.py │ │ ├── test_main.py │ │ └── test_user.py │ │ └── tox.ini └── setup.sh ├── chapter6 ├── Vagrantfile ├── labs │ ├── example-voting-app │ │ ├── README.md │ │ ├── architecture.png │ │ ├── docker-compose.yml │ │ ├── result-app │ │ │ ├── Dockerfile │ │ │ ├── package.json │ │ │ ├── server.js │ │ │ └── views │ │ │ │ ├── angular.min.js │ │ │ │ ├── app.js │ │ │ │ ├── faker.js │ │ │ │ ├── index.html │ │ │ │ ├── socket.io.js │ │ │ │ └── stylesheets │ │ │ │ └── style.css │ │ ├── voting-app │ │ │ ├── Dockerfile │ │ │ ├── app.py │ │ │ ├── requirements.txt │ │ │ ├── static │ │ │ │ ├── faker.js │ │ │ │ ├── font-awesome │ │ │ │ │ ├── css │ │ │ │ │ │ ├── font-awesome.css │ │ │ │ │ │ └── font-awesome.min.css │ │ │ │ │ └── fonts │ │ │ │ │ │ ├── FontAwesome.otf │ │ │ │ │ │ ├── fontawesome-webfont.eot │ │ │ │ │ │ ├── fontawesome-webfont.svg │ │ │ │ │ │ ├── fontawesome-webfont.ttf │ │ │ │ │ │ ├── fontawesome-webfont.woff │ │ │ │ │ │ └── fontawesome-webfont.woff2 │ │ │ │ ├── jquery.cookie.min.js │ │ │ │ ├── jquery.min.js │ │ │ │ └── stylesheets │ │ │ │ │ └── style.css │ │ │ ├── templates │ │ │ │ └── index.html │ │ │ └── utils │ │ │ │ ├── __init__.py │ │ │ │ └── __init__.pyc │ │ └── worker │ │ │ ├── Dockerfile │ │ │ ├── pom.xml │ │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── worker │ │ │ └── Worker.java │ ├── flask-redis │ │ ├── Dockerfile │ │ ├── app.py │ │ └── docker-compose.yml │ ├── lb-scale │ │ ├── Dockerfile │ │ ├── app.py │ │ └── docker-compose.yml │ └── wordpress │ │ └── docker-compose.yml └── setup.sh ├── chapter7 ├── README.md ├── Vagrantfile ├── labs │ ├── example-vote-app │ │ └── docker-compose.yml │ ├── secret-example │ │ ├── docker-compose.yml │ │ └── password │ └── wordpress │ │ └── docker-compose.yml └── setup.sh ├── chapter8 ├── Vagrantfile └── labs │ └── flask-skeleton │ ├── .coveragerc │ ├── .gitignore │ ├── .gitlab-ci.yml │ ├── CONTRIBUTING.md │ ├── Dockerfile │ ├── LICENSE │ ├── README.md │ ├── doc │ ├── Makefile │ ├── make.bat │ └── source │ │ ├── _static │ │ └── .placeholder │ │ ├── _templates │ │ └── .placeholder │ │ ├── conf.py │ │ └── index.rst │ ├── manage.py │ ├── migrations │ ├── README │ ├── alembic.ini │ ├── env.py │ └── script.py.mako │ ├── requirements.txt │ ├── scripts │ ├── deploy.sh │ └── dev.sh │ ├── skeleton │ ├── __init__.py │ ├── client │ │ ├── static │ │ │ ├── main.css │ │ │ └── main.js │ │ └── templates │ │ │ ├── _base.html │ │ │ ├── errors │ │ │ ├── 401.html │ │ │ ├── 403.html │ │ │ ├── 404.html │ │ │ └── 500.html │ │ │ ├── footer.html │ │ │ ├── header.html │ │ │ ├── main │ │ │ ├── about.html │ │ │ └── home.html │ │ │ └── user │ │ │ ├── login.html │ │ │ ├── members.html │ │ │ └── register.html │ └── server │ │ ├── __init__.py │ │ ├── config.py │ │ ├── main │ │ ├── __init__.py │ │ └── views.py │ │ ├── models.py │ │ └── user │ │ ├── __init__.py │ │ ├── forms.py │ │ └── views.py │ ├── test-requirements.txt │ ├── tests │ ├── __init__.py │ ├── base.py │ ├── test_config.py │ ├── test_main.py │ └── test_user.py │ └── tox.ini ├── chapter9 ├── gif │ └── k8s-dashboard.png ├── labs │ ├── deployment │ │ └── deployment_nginx.yml │ ├── pod-basic │ │ ├── README.md │ │ ├── pod_busybox.yml │ │ └── pod_nginx.yml │ ├── replicas-set │ │ ├── rc_nginx.yml │ │ └── rs_nginx.yml │ └── services │ │ ├── pod_busybox.yml │ │ ├── pod_nginx.yml │ │ └── service_nginx.yml └── tectonic-sandbox-1.7.5-tectonic.1 │ ├── README.md │ ├── Vagrantfile │ └── provisioning │ ├── config-controller-1.img │ ├── config-controller-1.vmdk │ ├── config-worker-1.img │ ├── config-worker-1.vmdk │ ├── controller.clc │ ├── controller.ign │ ├── controller.ign.merged │ ├── etc │ ├── kubernetes │ │ └── kubeconfig │ └── ssl │ │ └── etcd │ │ ├── ca.crt │ │ ├── peer.crt │ │ ├── peer.pem │ │ ├── server.crt │ │ └── server.key │ ├── tectonic-startup.sh │ ├── tectonic │ ├── auth │ │ └── kubeconfig │ ├── bootkube.sh │ ├── bootstrap-manifests │ │ ├── bootstrap-apiserver.yaml │ │ ├── bootstrap-controller-manager.yaml │ │ └── bootstrap-scheduler.yaml │ ├── manifests │ │ ├── kube-apiserver-secret.yaml │ │ ├── kube-apiserver.yaml │ │ ├── kube-cloud-config.yaml │ │ ├── kube-controller-manager-disruption.yaml │ │ ├── kube-controller-manager-secret.yaml │ │ ├── kube-controller-manager.yaml │ │ ├── kube-dns.yaml │ │ ├── kube-flannel.yaml │ │ ├── kube-proxy.yaml │ │ ├── kube-scheduler-disruption.yaml │ │ ├── kube-scheduler.yaml │ │ ├── kube-system-rbac-role-binding.yaml │ │ └── pod-checkpointer.yaml │ ├── tectonic-rkt.sh │ ├── tectonic.sh │ ├── tectonic │ │ ├── config.yaml │ │ ├── console │ │ │ ├── deployment.yaml │ │ │ └── service.yaml │ │ ├── etcd │ │ │ └── etcd-operator.yaml │ │ ├── heapster │ │ │ ├── deployment.yaml │ │ │ └── service.yaml │ │ ├── identity │ │ │ ├── configmap.yaml │ │ │ ├── deployment.yaml │ │ │ └── services.yaml │ │ ├── ingress │ │ │ ├── default-backend │ │ │ │ ├── configmap.yaml │ │ │ │ ├── deployment.yaml │ │ │ │ └── service.yaml │ │ │ ├── hostport │ │ │ │ ├── daemonset.yaml │ │ │ │ └── service.yaml │ │ │ ├── ingress.yaml │ │ │ └── nodeport │ │ │ │ ├── deployment.yaml │ │ │ │ └── service.yaml │ │ ├── namespace.yaml │ │ ├── rbac │ │ │ ├── binding-admin.yaml │ │ │ ├── binding-discovery.yaml │ │ │ ├── role-admin.yaml │ │ │ └── role-user.yaml │ │ ├── secrets │ │ │ ├── ca-cert.yaml │ │ │ ├── identity-grpc-client.yaml │ │ │ ├── identity-grpc-server.yaml │ │ │ ├── ingress-tls.yaml │ │ │ ├── license.json │ │ │ └── pull.json │ │ ├── stats-emitter.yaml │ │ └── updater │ │ │ ├── app-version-kind.yaml │ │ │ ├── app_versions │ │ │ ├── app-version-kubernetes.yaml │ │ │ ├── app-version-tectonic-cluo.yaml │ │ │ ├── app-version-tectonic-cluster.yaml │ │ │ ├── app-version-tectonic-etcd.yaml │ │ │ └── app-version-tectonic-monitoring.yaml │ │ │ ├── cluster-config.yaml │ │ │ ├── migration-status-kind.yaml │ │ │ ├── node-agent.yaml │ │ │ ├── operators │ │ │ ├── kube-version-operator.yaml │ │ │ ├── tectonic-channel-operator.yaml │ │ │ ├── tectonic-cluo-operator.yaml │ │ │ ├── tectonic-etcd-operator.yaml │ │ │ └── tectonic-prometheus-operator.yaml │ │ │ ├── tectonic-channel-operator-config.yaml │ │ │ ├── tectonic-channel-operator-kind.yaml │ │ │ └── tectonic-monitoring-config.yaml │ └── tls │ │ ├── apiserver.crt │ │ ├── apiserver.key │ │ ├── ca.crt │ │ ├── ca.key │ │ ├── etcd-client-ca.crt │ │ ├── etcd-client.crt │ │ ├── etcd-client.key │ │ ├── etcd │ │ ├── peer.crt │ │ ├── peer.key │ │ ├── server.crt │ │ └── server.key │ │ ├── kubelet.crt │ │ ├── kubelet.key │ │ ├── service-account.key │ │ └── service-account.pub │ ├── templates │ ├── ca-cert.tmpl │ ├── config.tmpl │ ├── configmap.tmpl │ ├── identity-grpc-client.tmpl │ ├── identity-grpc-server.tmpl │ ├── ingress-tls.tmpl │ ├── kube-apiserver-secret.tmpl │ ├── kube-controller-manager-secret.tmpl │ ├── kubeconfig.tmpl │ └── tectonic-monitoring-auth-secret.tmpl │ ├── worker.clc │ ├── worker.ign │ └── worker.ign.merged ├── 实验环境常见问题汇总.md ├── 慕课网手记-Kubernetes之年.md └── 慕课网手记-Minikube的安装.md /.gitignore: -------------------------------------------------------------------------------- 1 | .vagrant -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker DevOps课程源码 2 | 3 | 本代码仓库会不定期进行更新。请大家关注。 4 | 5 | ## 关于翻墙 6 | 7 | 本课程里部分link可能需要翻墙,大家如果自己没有VPN的话,可以尝试蓝灯 8 | 9 | https://github.com/getlantern/forum 10 | 11 | ## 本课程的一些常用链接汇总 12 | 13 | Vagrant下载 https://www.vagrantup.com/downloads.html 14 | 15 | Virtualbox 5.1下载 https://www.virtualbox.org/wiki/Download_Old_Builds_5_1 16 | 17 | Docker国内源安装 https://get.daocloud.io/#install-docker 18 | 19 | Docker官方网站 https://www.docker.com/ 20 | 21 | Docker官方文档中心 https://docs.docker.com/ 22 | 23 | DockerHub https://hub.docker.com/ 24 | 25 | -------------------------------------------------------------------------------- /chapter3/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | Vagrant.require_version ">= 1.6.0" 5 | 6 | boxes = [ 7 | { 8 | :name => "docker-host", 9 | :eth1 => "192.168.205.10", 10 | :mem => "1024", 11 | :cpu => "1" 12 | } 13 | ] 14 | 15 | Vagrant.configure(2) do |config| 16 | 17 | config.vm.box = "centos/7" 18 | boxes.each do |opts| 19 | config.vm.define opts[:name] do |config| 20 | config.vm.hostname = opts[:name] 21 | config.vm.provider "vmware_fusion" do |v| 22 | v.vmx["memsize"] = opts[:mem] 23 | v.vmx["numvcpus"] = opts[:cpu] 24 | end 25 | config.vm.provider "virtualbox" do |v| 26 | v.customize ["modifyvm", :id, "--memory", opts[:mem]] 27 | v.customize ["modifyvm", :id, "--cpus", opts[:cpu]] 28 | end 29 | config.vm.network :private_network, ip: opts[:eth1] 30 | end 31 | end 32 | config.vm.synced_folder "./labs", "/home/vagrant/labs" 33 | config.vm.provision "shell", privileged: true, path: "./setup.sh" 34 | end 35 | -------------------------------------------------------------------------------- /chapter3/labs/cmd_vs_entrypoint/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos 2 | ENV name Docker 3 | CMD echo "hello $name" 4 | -------------------------------------------------------------------------------- /chapter3/labs/docker-centos-vim/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos 2 | RUN yum install -y vim 3 | -------------------------------------------------------------------------------- /chapter3/labs/docker-python/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu 2 | RUN apt-get update && apt-get install -y python 3 | 4 | -------------------------------------------------------------------------------- /chapter3/labs/flask-hello-world/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:2.7 2 | LABEL maintainer="Peng Xiao" 3 | RUN pip install flask 4 | COPY app.py /app/ 5 | WORKDIR /app 6 | EXPOSE 5000 7 | CMD ["python", "app.py"] 8 | -------------------------------------------------------------------------------- /chapter3/labs/flask-hello-world/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | app = Flask(__name__) 3 | @app.route('/') 4 | def hello(): 5 | return "hello docker" 6 | if __name__ == '__main__': 7 | app.run(host="0.0.0.0", port=5000) 8 | -------------------------------------------------------------------------------- /chapter3/labs/hello-world/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM scratch 2 | ADD hello / 3 | CMD ["/hello"] 4 | -------------------------------------------------------------------------------- /chapter3/labs/hello-world/hello: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter3/labs/hello-world/hello -------------------------------------------------------------------------------- /chapter3/labs/hello-world/hello.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | printf("hello docker\n"); 6 | } 7 | -------------------------------------------------------------------------------- /chapter3/labs/ubuntu-stress/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu 2 | RUN apt-get update && apt-get install -y stress 3 | ENTRYPOINT ["/usr/bin/stress"] 4 | CMD [] 5 | -------------------------------------------------------------------------------- /chapter3/setup.sh: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | 3 | # install some tools 4 | sudo yum install -y git vim gcc glibc-static telnet bridge-utils net-tools 5 | 6 | # install docker 7 | curl -fsSL get.docker.com -o get-docker.sh 8 | sh get-docker.sh 9 | 10 | # start docker service 11 | sudo systemctl start docker 12 | 13 | rm -rf get-docker.sh 14 | -------------------------------------------------------------------------------- /chapter4/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | Vagrant.require_version ">= 1.6.0" 5 | 6 | boxes = [ 7 | { 8 | :name => "docker-node1", 9 | :eth1 => "192.168.205.10", 10 | :mem => "1024", 11 | :cpu => "1" 12 | }, 13 | { 14 | :name => "docker-node2", 15 | :eth1 => "192.168.205.11", 16 | :mem => "1024", 17 | :cpu => "1" 18 | } 19 | ] 20 | 21 | Vagrant.configure(2) do |config| 22 | 23 | config.vm.box = "centos/7" 24 | 25 | boxes.each do |opts| 26 | config.vm.define opts[:name] do |config| 27 | config.vm.hostname = opts[:name] 28 | config.vm.provider "vmware_fusion" do |v| 29 | v.vmx["memsize"] = opts[:mem] 30 | v.vmx["numvcpus"] = opts[:cpu] 31 | end 32 | 33 | config.vm.provider "virtualbox" do |v| 34 | v.customize ["modifyvm", :id, "--memory", opts[:mem]] 35 | v.customize ["modifyvm", :id, "--cpus", opts[:cpu]] 36 | end 37 | 38 | config.vm.network :private_network, ip: opts[:eth1] 39 | end 40 | end 41 | 42 | config.vm.synced_folder "./labs", "/home/vagrant/labs" 43 | config.vm.provision "shell", privileged: true, path: "./setup.sh" 44 | 45 | end 46 | -------------------------------------------------------------------------------- /chapter4/labs/flask-redis/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:2.7 2 | LABEL maintaner="Peng Xiao xiaoquwl@gmail.com" 3 | COPY . /app 4 | WORKDIR /app 5 | RUN pip install flask redis 6 | EXPOSE 5000 7 | CMD [ "python", "app.py" ] -------------------------------------------------------------------------------- /chapter4/labs/flask-redis/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | from redis import Redis 3 | import os 4 | import socket 5 | 6 | app = Flask(__name__) 7 | redis = Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379) 8 | 9 | 10 | @app.route('/') 11 | def hello(): 12 | redis.incr('hits') 13 | return 'Hello Container World! I have been seen %s times and my hostname is %s.\n' % (redis.get('hits'),socket.gethostname()) 14 | 15 | 16 | if __name__ == "__main__": 17 | app.run(host="0.0.0.0", port=5000, debug=True) 18 | -------------------------------------------------------------------------------- /chapter4/labs/labs/docker-nginx/Dockerfile: -------------------------------------------------------------------------------- 1 | # this same shows how we can extend/change an existing official image from Docker Hub 2 | 3 | FROM nginx:latest 4 | # highly recommend you always pin versions for anything beyond dev/learn 5 | 6 | WORKDIR /usr/share/nginx/html 7 | # change working directory to root of nginx webhost 8 | # using WORKDIR is prefered to using 'RUN cd /some/path' 9 | 10 | COPY index.html index.html 11 | 12 | # I don't have to specify EXPOSE or CMD because they're in my FROM 13 | -------------------------------------------------------------------------------- /chapter4/labs/labs/docker-nginx/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | hello 7 | 8 | 9 | 10 | 11 |

Hello Docker!

12 | 13 | 14 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-hello-world/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:2.7-alpine 2 | LABEL maintainer="Peng Xiao" 3 | RUN pip install flask Flask-Script 4 | COPY . /app/ 5 | WORKDIR /app 6 | EXPOSE 5000 7 | ENTRYPOINT [ "python", "manage.py" ] 8 | CMD [] -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-hello-world/manage.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | app = Flask(__name__) 3 | @app.route('/') 4 | def hello(): 5 | return "hello dockeddr" 6 | 7 | from flask_script import Manager 8 | 9 | manager = Manager(app) 10 | 11 | if __name__ == '__main__': 12 | manager.run() 13 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-hello-world/test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter4/labs/labs/flask-hello-world/test -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | source = skeleton 3 | omit = 4 | skeleton/tests/* 5 | */__init__.py 6 | 7 | [report] 8 | exclude_lines = 9 | def __repr__ 10 | def __str__ 11 | def parse_args 12 | pragma: no cover 13 | raise NotImplementedError 14 | if __name__ == .__main__.: 15 | 16 | ignore_errors = True 17 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask stuff: 57 | instance/ 58 | .webassets-cache 59 | 60 | # Scrapy stuff: 61 | .scrapy 62 | 63 | # Sphinx documentation 64 | docs/_build/ 65 | 66 | # PyBuilder 67 | target/ 68 | 69 | # IPython Notebook 70 | .ipynb_checkpoints 71 | 72 | # pyenv 73 | .python-version 74 | 75 | # celery beat schedule file 76 | celerybeat-schedule 77 | 78 | # dotenv 79 | .env 80 | 81 | # virtualenv 82 | venv/ 83 | ENV/ 84 | 85 | # Spyder project settings 86 | .spyderproject 87 | 88 | # Rope project settings 89 | .ropeproject 90 | 91 | *.sqlite 92 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | variables: 2 | GIT_SSL_NO_VERIFY: "1" 3 | 4 | stages: 5 | - test 6 | - build 7 | - deploy 8 | 9 | pep8: 10 | stage: test 11 | image: python:2.7 12 | script: 13 | - pip install tox 14 | - tox -e pep8 15 | tags: 16 | - python27 17 | 18 | unittest-py27: 19 | stage: test 20 | image: python:2.7 21 | script: 22 | - pip install tox 23 | - tox -e py27 24 | tags: 25 | - python27 26 | 27 | unittest-py34: 28 | stage: test 29 | image: python:3.4 30 | script: 31 | - pip install tox 32 | - tox -e py34 33 | tags: 34 | - python34 35 | 36 | sphnix: 37 | stage: test 38 | image: python:2.7 39 | script: 40 | - pip install tox 41 | - tox -e docs 42 | tags: 43 | - python27 44 | 45 | build: 46 | stage: build 47 | tags: 48 | - shell 49 | script: 50 | - docker build -t skeleton . 51 | only: 52 | - master 53 | 54 | deploy: 55 | stage: deploy 56 | tags: 57 | - shell 58 | script: 59 | - scripts/deploy.sh 60 | - export 61 | only: 62 | - master 63 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/.gitlab/issue_templates/Bug.md: -------------------------------------------------------------------------------- 1 | ### Summary 2 | 3 | (Summarize the bug encountered concisely) 4 | 5 | ### Steps to reproduce 6 | 7 | (How one can reproduce the issue - this is very important) 8 | 9 | ### Expected behavior 10 | 11 | (What you should see instead) 12 | 13 | ### Actual behaviour 14 | 15 | (What actually happens) 16 | 17 | ### Relevant logs and/or screenshots 18 | 19 | (Paste any relevant logs - please use code blocks (```) to format console output, 20 | logs, and code as it's very hard to read otherwise.) 21 | 22 | 23 | ### Possible fixes 24 | 25 | (If you can, link to the line of code that might be responsible for the problem) 26 | 27 | 28 | /label ~"Bug" 29 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/.gitlab/issue_templates/Feature.md: -------------------------------------------------------------------------------- 1 | ### Feature Description 2 | 3 | 4 | ### Implementation 5 | 6 | 7 | /label ~"Feature" 8 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/.gitlab/merge_request_templates/default.md: -------------------------------------------------------------------------------- 1 | **1. Explain what do you want to merge** 2 | 3 | - 4 | - 5 | 6 | **2. Does this MR meet the acceptance criteria?** 7 | 8 | - [ ] I have read [Contribution guidelines](https://as-gitlab.cisco.com/demo/skeleton/blob/master/CONTRIBUTING.md) 9 | - [ ] I have run the command `tox` locally and get successful results. 10 | - [ ] Branch has no merge conflicts with master (if you do - rebase it please) 11 | 12 | **3. What are the relevant issue numbers?** 13 | 14 | 15 | Thanks for your MR, you're awesome! :+1: 16 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Hacking Guide 2 | 3 | ## Code style 4 | 5 | Step 1: Read http://www.python.org/dev/peps/pep-0008/ 6 | 7 | Step 2: Read http://www.python.org/dev/peps/pep-0008/ again 8 | 9 | Step 3: Read on 10 | 11 | ## Running Tests 12 | 13 | Run tox 14 | 15 | ``` 16 | $ cd skeleton 17 | $ tox 18 | ``` 19 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:2.7 2 | LABEL maintainer="Peng Xiao" 3 | 4 | COPY . /skeleton 5 | WORKDIR /skeleton 6 | RUN pip install -r requirements.txt 7 | EXPOSE 5000 8 | ENTRYPOINT ["scripts/dev.sh"] 9 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2016 Michael Herman 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/README.md: -------------------------------------------------------------------------------- 1 | [![build status](https://gitlab-demo.com/Demo/flask-skeleton/badges/master/build.svg)](https://gitlab-demo.com/Demo/flask-skeleton/commits/master) 2 | [![coverage report](https://gitlab-demo.com/Demo/flask-skeleton/badges/master/coverage.svg)](https://gitlab-demo.com/Demo/flask-skeleton/commits/master) 3 | 4 | 5 | # Flask Skeleton 6 | 7 | Flask starter project... 8 | 9 | ## Quick Start 10 | 11 | ### Basics 12 | 13 | 1. Activate a virtualenv 14 | 1. Install the requirements 15 | 16 | ### Set Environment Variables 17 | 18 | Update *skeleton/server/config.py*, and then run: 19 | 20 | ```sh 21 | $ export APP_SETTINGS="skeleton.server.config.DevelopmentConfig" 22 | ``` 23 | 24 | or 25 | 26 | ```sh 27 | $ export APP_SETTINGS="skeleton.server.config.ProductionConfig" 28 | ``` 29 | 30 | ### Create DB 31 | 32 | ```sh 33 | $ python manage.py create_db 34 | $ python manage.py db init 35 | $ python manage.py db migrate 36 | $ python manage.py create_admin 37 | $ python manage.py create_data 38 | ``` 39 | 40 | ### Run the Application 41 | 42 | ```sh 43 | $ python manage.py runserver 44 | ``` 45 | 46 | So access the application at the address [http://localhost:5000/](http://localhost:5000/) 47 | 48 | > Want to specify a different port? 49 | 50 | > ```sh 51 | > $ python manage.py runserver -h 0.0.0.0 -p 8080 52 | > ``` 53 | 54 | ### Testing1 55 | 56 | ``` 57 | $ tox 58 | ``` 59 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/doc/source/_static/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter4/labs/labs/flask-skeleton/doc/source/_static/.placeholder -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/doc/source/_templates/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter4/labs/labs/flask-skeleton/doc/source/_templates/.placeholder -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/doc/source/index.rst: -------------------------------------------------------------------------------- 1 | .. yacore documentation master file, created by 2 | sphinx-quickstart on Mon Aug 1 21:41:36 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to yacore's documentation! 7 | ================================== 8 | 9 | This is a test line 10 | test again 11 | test 12 | Contents: 13 | 14 | .. toctree:: 15 | :maxdepth: 2 16 | 17 | 18 | 19 | Indices and tables 20 | ================== 21 | 22 | * :ref:`genindex` 23 | * :ref:`modindex` 24 | * :ref:`search` 25 | 26 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/manage.py: -------------------------------------------------------------------------------- 1 | # manage.py 2 | 3 | import unittest 4 | 5 | from flask_script import Manager 6 | from flask_migrate import Migrate, MigrateCommand 7 | 8 | from skeleton.server import app, db 9 | from skeleton.server.models import User 10 | 11 | 12 | migrate = Migrate(app, db) 13 | manager = Manager(app) 14 | 15 | # migrations 16 | manager.add_command('db', MigrateCommand) 17 | 18 | 19 | @manager.command 20 | def test(): 21 | """Runs the unit tests without coverage.""" 22 | tests = unittest.TestLoader().discover('tests', pattern='test*.py') 23 | result = unittest.TextTestRunner(verbosity=2).run(tests) 24 | if result.wasSuccessful(): 25 | return 0 26 | else: 27 | return 1 28 | 29 | 30 | @manager.command 31 | def create_db(): 32 | """Creates the db tables.""" 33 | db.create_all() 34 | 35 | 36 | @manager.command 37 | def drop_db(): 38 | """Drops the db tables.""" 39 | db.drop_all() 40 | 41 | 42 | @manager.command 43 | def create_admin(): 44 | """Creates the admin user.""" 45 | db.session.add(User(email='admin@cisco.com', password='admin', admin=True)) 46 | db.session.commit() 47 | 48 | 49 | @manager.command 50 | def create_data(): 51 | """Creates sample data.""" 52 | pass 53 | 54 | 55 | if __name__ == '__main__': 56 | manager.run() 57 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/migrations/README: -------------------------------------------------------------------------------- 1 | Generic single-database configuration. -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/migrations/alembic.ini: -------------------------------------------------------------------------------- 1 | # A generic, single database configuration. 2 | 3 | [alembic] 4 | # template used to generate migration files 5 | # file_template = %%(rev)s_%%(slug)s 6 | 7 | # set to 'true' to run the environment during 8 | # the 'revision' command, regardless of autogenerate 9 | # revision_environment = false 10 | 11 | 12 | # Logging configuration 13 | [loggers] 14 | keys = root,sqlalchemy,alembic 15 | 16 | [handlers] 17 | keys = console 18 | 19 | [formatters] 20 | keys = generic 21 | 22 | [logger_root] 23 | level = WARN 24 | handlers = console 25 | qualname = 26 | 27 | [logger_sqlalchemy] 28 | level = WARN 29 | handlers = 30 | qualname = sqlalchemy.engine 31 | 32 | [logger_alembic] 33 | level = INFO 34 | handlers = 35 | qualname = alembic 36 | 37 | [handler_console] 38 | class = StreamHandler 39 | args = (sys.stderr,) 40 | level = NOTSET 41 | formatter = generic 42 | 43 | [formatter_generic] 44 | format = %(levelname)-5.5s [%(name)s] %(message)s 45 | datefmt = %H:%M:%S 46 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = ${repr(up_revision)} 11 | down_revision = ${repr(down_revision)} 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | ${imports if imports else ""} 16 | 17 | def upgrade(): 18 | ${upgrades if upgrades else "pass"} 19 | 20 | 21 | def downgrade(): 22 | ${downgrades if downgrades else "pass"} 23 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/requirements.txt: -------------------------------------------------------------------------------- 1 | alembic==0.8.6 2 | bcrypt==3.1.0 3 | blinker==1.4 4 | cffi==1.7.0 5 | click==6.6 6 | dominate==2.2.1 7 | Flask==0.10.1 8 | Flask-Bcrypt==0.7.1 9 | Flask-Bootstrap==3.3.6.0 10 | Flask-DebugToolbar==0.10.0 11 | Flask-Login==0.3.2 12 | Flask-Migrate==1.8.1 13 | Flask-Script==2.0.5 14 | Flask-SQLAlchemy==2.1 15 | Flask-WTF==0.12 16 | itsdangerous==0.24 17 | Jinja2==2.8 18 | Mako==1.0.4 19 | MarkupSafe==0.23 20 | pycparser==2.14 21 | python-editor==1.0.1 22 | six==1.10.0 23 | SQLAlchemy==1.0.14 24 | visitor==0.1.3 25 | Werkzeug==0.11.10 26 | WTForms==2.1 27 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/scripts/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | docker ps -a | grep penxiao_skeleton | awk '{print$1}' | xargs docker stop 4 | docker ps -a | grep penxiao_skeleton | awk '{print$1}' | xargs docker rm 5 | docker run -d -p 80:5000 --name penxiao_skeleton skeleton 6 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/scripts/dev.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | export APP_SETTINGS="skeleton.server.config.ProductionConfig" 4 | python manage.py create_db 5 | python manage.py create_admin 6 | python manage.py create_data 7 | python manage.py runserver -h 0.0.0.0 8 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/skeleton/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter4/labs/labs/flask-skeleton/skeleton/__init__.py -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/skeleton/client/static/main.css: -------------------------------------------------------------------------------- 1 | /* custom css */ 2 | 3 | .site-content { 4 | padding-top: 75px; 5 | } -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/skeleton/client/static/main.js: -------------------------------------------------------------------------------- 1 | // custom javascript 2 | 3 | $( document ).ready(function() { 4 | console.log('Sanity Check!'); 5 | }); -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/skeleton/client/templates/errors/401.html: -------------------------------------------------------------------------------- 1 | {% extends "_base.html" %} 2 | 3 | {% block page_title %}- Unauthorized{% endblock %} 4 | 5 | {% block content %} 6 |
7 |
8 |

401

9 |

You are not authorized to view this page. Please log in.

10 |
11 |
12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/skeleton/client/templates/errors/403.html: -------------------------------------------------------------------------------- 1 | {% extends "_base.html" %} 2 | 3 | {% block page_title %}- Unauthorized{% endblock %} 4 | 5 | {% block content %} 6 |
7 |
8 |

401

9 |

You are not authorized to view this page. Please log in.

10 |
11 |
12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/skeleton/client/templates/errors/404.html: -------------------------------------------------------------------------------- 1 | {% extends "_base.html" %} 2 | 3 | {% block page_title %}- Page Not Found{% endblock %} 4 | 5 | {% block content %} 6 |
7 |
8 |

404

9 |

Sorry. The requested page doesn't exist. Go home.

10 |
11 |
12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/skeleton/client/templates/errors/500.html: -------------------------------------------------------------------------------- 1 | {% extends "_base.html" %} 2 | 3 | {% block page_title %}- Server Error{% endblock %} 4 | 5 | {% block content %} 6 |
7 |
8 |

500

9 |

Sorry. Something went terribly wrong. Go home.

10 |
11 |
12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/skeleton/client/templates/footer.html: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/skeleton/client/templates/header.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/skeleton/client/templates/main/about.html: -------------------------------------------------------------------------------- 1 | {% extends "_base.html" %} 2 | 3 | {% block content %} 4 | 5 |
6 |
7 |

About

8 |
9 |
10 | 11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/skeleton/client/templates/main/home.html: -------------------------------------------------------------------------------- 1 | {% extends "_base.html" %} 2 | 3 | {% block content %} 4 | 5 |
6 |
7 |

Welcome!

8 |
9 |
10 | 11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/skeleton/client/templates/user/login.html: -------------------------------------------------------------------------------- 1 | {% extends '_base.html' %} 2 | {% import "bootstrap/wtf.html" as wtf %} 3 | 4 | {% block content %} 5 | 6 |
7 |

Please login

8 |
9 | 10 |
11 | 12 | 13 |
14 | 15 | {{ form.csrf_token }} 16 | {{ form.hidden_tag() }} 17 | {{ wtf.form_errors(form, hiddens="only") }} 18 | 19 | 20 |
21 | 22 | {{ wtf.form_field(form.email) }} 23 | {{ wtf.form_field(form.password) }} 24 | 25 | 26 |

27 |

Need to Register?

28 |
29 | 30 |
31 | 32 | 33 | {% endblock content %} 34 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/skeleton/client/templates/user/members.html: -------------------------------------------------------------------------------- 1 | {% extends "_base.html" %} 2 | {% block content %} 3 |

Welcome, {{ current_user.email }}!

4 |

This is the members-only page :)

5 | {% endblock %} 6 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/skeleton/client/templates/user/register.html: -------------------------------------------------------------------------------- 1 | {% extends '_base.html' %} 2 | {% import "bootstrap/wtf.html" as wtf %} 3 | 4 | {% block content %} 5 | 6 |
7 |

Please Register

8 |
9 | 10 |
11 | 12 | 13 |
14 | 15 | {{ form.csrf_token }} 16 | {{ form.hidden_tag() }} 17 | {{ wtf.form_errors(form, hiddens="only") }} 18 | 19 | 20 |
21 | 22 | {{ wtf.form_field(form.email) }} 23 | {{ wtf.form_field(form.password) }} 24 | {{ wtf.form_field(form.confirm) }} 25 | 26 | 27 |

28 |

Already have an account? Sign in.

29 | 30 |
31 | 32 |
33 | 34 | 35 | {% endblock content %} 36 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/skeleton/server/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | 4 | import os 5 | 6 | from flask import Flask, render_template 7 | from flask_login import LoginManager 8 | from flask_bcrypt import Bcrypt 9 | from flask_debugtoolbar import DebugToolbarExtension 10 | from flask_bootstrap import Bootstrap 11 | from flask_sqlalchemy import SQLAlchemy 12 | 13 | 14 | app = Flask( 15 | __name__, 16 | template_folder='../client/templates', 17 | static_folder='../client/static' 18 | ) 19 | 20 | app_settings = os.getenv('APP_SETTINGS', 'skeleton.server.config.DevelopmentConfig') 21 | app.config.from_object(app_settings) 22 | 23 | login_manager = LoginManager() 24 | login_manager.init_app(app) 25 | bcrypt = Bcrypt(app) 26 | toolbar = DebugToolbarExtension(app) 27 | bootstrap = Bootstrap(app) 28 | db = SQLAlchemy(app) 29 | 30 | from skeleton.server.user.views import user_blueprint 31 | from skeleton.server.main.views import main_blueprint 32 | app.register_blueprint(user_blueprint) 33 | app.register_blueprint(main_blueprint) 34 | 35 | from skeleton.server.models import User 36 | 37 | login_manager.login_view = "user.login" 38 | login_manager.login_message_category = 'danger' 39 | 40 | 41 | @login_manager.user_loader 42 | def load_user(user_id): 43 | return User.query.filter(User.id == int(user_id)).first() 44 | 45 | 46 | @app.errorhandler(401) 47 | def forbidden_page_401(error): 48 | return render_template("errors/401.html"), 401 49 | 50 | 51 | @app.errorhandler(403) 52 | def forbidden_page_403(error): 53 | return render_template("errors/403.html"), 403 54 | 55 | 56 | @app.errorhandler(404) 57 | def page_not_found(error): 58 | return render_template("errors/404.html"), 404 59 | 60 | 61 | @app.errorhandler(500) 62 | def server_error_page(error): 63 | return render_template("errors/500.html"), 500 64 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/skeleton/server/config.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | 4 | import os 5 | basedir = os.path.abspath(os.path.dirname(__file__)) 6 | 7 | 8 | class BaseConfig(object): 9 | """Base configuration.""" 10 | SECRET_KEY = 'my_precious' 11 | DEBUG = False 12 | BCRYPT_LOG_ROUNDS = 13 13 | WTF_CSRF_ENABLED = True 14 | DEBUG_TB_ENABLED = False 15 | DEBUG_TB_INTERCEPT_REDIRECTS = False 16 | SQLALCHEMY_TRACK_MODIFICATIONS = False 17 | SQLALCHEMY_DATABASE_URI = os.environ.get( 18 | 'DATABASE_URL', 'sqlite:///' + os.path.join(basedir, 'db.sqlite')) 19 | 20 | 21 | class DevelopmentConfig(BaseConfig): 22 | """Development configuration.""" 23 | DEBUG = True 24 | BCRYPT_LOG_ROUNDS = 4 25 | WTF_CSRF_ENABLED = False 26 | DEBUG_TB_ENABLED = True 27 | 28 | 29 | class TestingConfig(BaseConfig): 30 | """Testing configuration.""" 31 | DEBUG = True 32 | TESTING = True 33 | BCRYPT_LOG_ROUNDS = 4 34 | WTF_CSRF_ENABLED = False 35 | DEBUG_TB_ENABLED = False 36 | PRESERVE_CONTEXT_ON_EXCEPTION = False 37 | 38 | 39 | class ProductionConfig(BaseConfig): 40 | """Production configuration.""" 41 | SECRET_KEY = 'my_precious' 42 | DEBUG = False 43 | DEBUG_TB_ENABLED = False 44 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/skeleton/server/main/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter4/labs/labs/flask-skeleton/skeleton/server/main/__init__.py -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/skeleton/server/main/views.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | 4 | from flask import render_template, Blueprint 5 | 6 | main_blueprint = Blueprint('main', __name__,) 7 | 8 | 9 | @main_blueprint.route('/') 10 | def home(): 11 | return render_template('main/home.html') 12 | 13 | 14 | @main_blueprint.route("/about/") 15 | def about(): 16 | return render_template("main/about.html") 17 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/skeleton/server/models.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | 4 | import datetime 5 | 6 | from skeleton.server import app, db, bcrypt 7 | 8 | 9 | class User(db.Model): 10 | 11 | __tablename__ = "users" 12 | 13 | id = db.Column(db.Integer, primary_key=True, autoincrement=True) 14 | email = db.Column(db.String(255), unique=True, nullable=False) 15 | password = db.Column(db.String(255), nullable=False) 16 | registered_on = db.Column(db.DateTime, nullable=False) 17 | admin = db.Column(db.Boolean, nullable=False, default=False) 18 | 19 | def __init__(self, email, password, admin=False): 20 | self.email = email 21 | self.password = bcrypt.generate_password_hash( 22 | password, app.config.get('BCRYPT_LOG_ROUNDS') 23 | ) 24 | self.registered_on = datetime.datetime.now() 25 | self.admin = admin 26 | 27 | def is_authenticated(self): 28 | return True 29 | 30 | def is_active(self): 31 | return True 32 | 33 | def is_anonymous(self): 34 | return False 35 | 36 | def get_id(self): 37 | return self.id 38 | 39 | def __repr__(self): 40 | return ''.format(self.email) 41 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/skeleton/server/user/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter4/labs/labs/flask-skeleton/skeleton/server/user/__init__.py -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/skeleton/server/user/forms.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | 4 | from flask_wtf import Form 5 | from wtforms import StringField, PasswordField 6 | from wtforms.validators import DataRequired, Email, Length, EqualTo 7 | 8 | 9 | class LoginForm(Form): 10 | email = StringField('Email Address', [DataRequired(), Email()]) 11 | password = PasswordField('Password', [DataRequired()]) 12 | 13 | 14 | class RegisterForm(Form): 15 | email = StringField( 16 | 'Email Address', 17 | validators=[DataRequired(), Email(message=None), Length(min=6, max=40)]) 18 | password = PasswordField( 19 | 'Password', 20 | validators=[DataRequired(), Length(min=6, max=25)] 21 | ) 22 | confirm = PasswordField( 23 | 'Confirm password', 24 | validators=[ 25 | DataRequired(), 26 | EqualTo('password', message='Passwords must match.') 27 | ] 28 | ) 29 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/test-requirements.txt: -------------------------------------------------------------------------------- 1 | flake8==2.4.0 2 | Flask-Testing==0.4.2 3 | discover 4 | nose 5 | coverage==4.0.3 6 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter4/labs/labs/flask-skeleton/tests/__init__.py -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/tests/base.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | 4 | from flask_testing import TestCase 5 | 6 | from skeleton.server import app, db 7 | from skeleton.server.models import User 8 | 9 | 10 | class BaseTestCase(TestCase): 11 | 12 | def create_app(self): 13 | app.config.from_object('skeleton.server.config.TestingConfig') 14 | return app 15 | 16 | def setUp(self): 17 | db.create_all() 18 | user = User(email="ad@min.com", password="admin_user") 19 | db.session.add(user) 20 | db.session.commit() 21 | 22 | def tearDown(self): 23 | db.session.remove() 24 | db.drop_all() 25 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/tests/test_main.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | 4 | import unittest 5 | 6 | from base import BaseTestCase 7 | 8 | 9 | class TestMainBlueprint(BaseTestCase): 10 | 11 | def test_index(self): 12 | # Ensure Flask is setup. 13 | response = self.client.get('/', follow_redirects=True) 14 | self.assertEqual(response.status_code, 200) 15 | self.assertIn(b'Welcome!', response.data) 16 | self.assertIn(b'Register/Login', response.data) 17 | 18 | def test_footer(self): 19 | response = self.client.get('/', follow_redirects=True) 20 | self.assertEqual(response.status_code, 200) 21 | self.assertIn(b'GitLab Demo', response.data) 22 | 23 | def test_about(self): 24 | # Ensure about route behaves correctly. 25 | response = self.client.get('/about', follow_redirects=True) 26 | self.assertEqual(response.status_code, 200) 27 | self.assertIn(b'About', response.data) 28 | 29 | def test_404(self): 30 | # Ensure 404 error is handled. 31 | response = self.client.get('/404') 32 | self.assert404(response) 33 | self.assertTemplateUsed('errors/404.html') 34 | 35 | 36 | if __name__ == '__main__': 37 | unittest.main() 38 | -------------------------------------------------------------------------------- /chapter4/labs/labs/flask-skeleton/tox.ini: -------------------------------------------------------------------------------- 1 | # Tox (http://tox.testrun.org/) is a tool for running tests 2 | # in multiple virtualenvs. This configuration file will run the 3 | # test suite on all supported python versions. To use it, "pip install tox" 4 | # and then run "tox" from this directory. 5 | 6 | [tox] 7 | # List the environment that will be run by default 8 | minversion = 1.6 9 | envlist = py27, py34, pep8, docs 10 | skipsdist = True 11 | 12 | [testenv] 13 | setenv = VIRTUAL_ENV={envdir} 14 | LANG=en_US.UTF-8 15 | LANGUAGE=en_US:en 16 | LC_ALL=C 17 | 18 | [testenv:py27] 19 | deps = -r{toxinidir}/test-requirements.txt 20 | -r{toxinidir}/requirements.txt 21 | 22 | 23 | commands = 24 | coverage run manage.py test 25 | coverage report -m 26 | 27 | [testenv:py34] 28 | deps = -r{toxinidir}/test-requirements.txt 29 | -r{toxinidir}/requirements.txt 30 | 31 | commands = 32 | coverage run manage.py test 33 | coverage report -m 34 | 35 | [testenv:pep8] 36 | sitepackages = False 37 | deps = -r{toxinidir}/test-requirements.txt 38 | commands = 39 | flake8 {posargs} 40 | 41 | [flake8] 42 | # E712 is ignored on purpose, since it is normal to use 'column == true' 43 | # in sqlalchemy. 44 | # H803 skipped on purpose per list discussion. 45 | # E125 is deliberately excluded. See https://github.com/jcrocholl/pep8/issues/126 46 | # The rest of the ignores are TODOs 47 | # New from hacking 0.9: E129, E131, E265, E713, H407, H405, H904 48 | # Stricter in hacking 0.9: F402 49 | # E251 Skipped due to https://github.com/jcrocholl/pep8/issues/301 50 | 51 | max-line-length=120 52 | exclude = .venv,.git,.tox,dist,doc,*lib/python*,*egg,build,tools 53 | 54 | [testenv:docs] 55 | deps= 56 | sphinx 57 | sphinx_rtd_theme 58 | commands = sphinx-build -W -b html doc/source doc/build 59 | -------------------------------------------------------------------------------- /chapter4/setup.sh: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | 3 | # install some tools 4 | sudo yum install -y git vim gcc glibc-static telnet bridge-utils 5 | 6 | # install docker 7 | curl -fsSL get.docker.com -o get-docker.sh 8 | sh get-docker.sh 9 | 10 | # start docker service 11 | sudo groupadd docker 12 | sudo usermod -aG docker vagrant 13 | sudo systemctl start docker 14 | 15 | rm -rf get-docker.sh 16 | -------------------------------------------------------------------------------- /chapter5/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | Vagrant.require_version ">= 1.6.0" 5 | 6 | boxes = [ 7 | { 8 | :name => "docker-host", 9 | :eth1 => "192.168.205.10", 10 | :mem => "1024", 11 | :cpu => "1" 12 | } 13 | ] 14 | 15 | Vagrant.configure(2) do |config| 16 | 17 | config.vm.box = "centos/7" 18 | boxes.each do |opts| 19 | config.vm.define opts[:name] do |config| 20 | config.vm.hostname = opts[:name] 21 | config.vm.provider "vmware_fusion" do |v| 22 | v.vmx["memsize"] = opts[:mem] 23 | v.vmx["numvcpus"] = opts[:cpu] 24 | end 25 | config.vm.provider "virtualbox" do |v| 26 | v.customize ["modifyvm", :id, "--memory", opts[:mem]] 27 | v.customize ["modifyvm", :id, "--cpus", opts[:cpu]] 28 | end 29 | config.vm.network :private_network, ip: opts[:eth1] 30 | end 31 | end 32 | config.vm.synced_folder "./labs", "/home/vagrant/labs" 33 | config.vm.provision "shell", privileged: true, path: "./setup.sh" 34 | end 35 | -------------------------------------------------------------------------------- /chapter5/labs/docker-nginx/Dockerfile: -------------------------------------------------------------------------------- 1 | # this same shows how we can extend/change an existing official image from Docker Hub 2 | 3 | FROM nginx:latest 4 | # highly recommend you always pin versions for anything beyond dev/learn 5 | 6 | WORKDIR /usr/share/nginx/html 7 | # change working directory to root of nginx webhost 8 | # using WORKDIR is prefered to using 'RUN cd /some/path' 9 | 10 | COPY index.html index.html 11 | 12 | # I don't have to specify EXPOSE or CMD because they're in my FROM 13 | -------------------------------------------------------------------------------- /chapter5/labs/docker-nginx/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | hello 7 | 8 | 9 | 10 | 11 |

Hello Docker!

12 | 13 | 14 | -------------------------------------------------------------------------------- /chapter5/labs/flask-hello-world/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:2.7-alpine 2 | LABEL maintainer="Peng Xiao" 3 | RUN pip install flask Flask-Script 4 | COPY . /app/ 5 | WORKDIR /app 6 | EXPOSE 5000 7 | ENTRYPOINT [ "python", "manage.py" ] 8 | CMD [] -------------------------------------------------------------------------------- /chapter5/labs/flask-hello-world/manage.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | app = Flask(__name__) 3 | @app.route('/') 4 | def hello(): 5 | return "hello dockeddr" 6 | 7 | from flask_script import Manager 8 | 9 | manager = Manager(app) 10 | 11 | if __name__ == '__main__': 12 | manager.run() 13 | -------------------------------------------------------------------------------- /chapter5/labs/flask-hello-world/test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter5/labs/flask-hello-world/test -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | source = skeleton 3 | omit = 4 | skeleton/tests/* 5 | */__init__.py 6 | 7 | [report] 8 | exclude_lines = 9 | def __repr__ 10 | def __str__ 11 | def parse_args 12 | pragma: no cover 13 | raise NotImplementedError 14 | if __name__ == .__main__.: 15 | 16 | ignore_errors = True 17 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask stuff: 57 | instance/ 58 | .webassets-cache 59 | 60 | # Scrapy stuff: 61 | .scrapy 62 | 63 | # Sphinx documentation 64 | docs/_build/ 65 | 66 | # PyBuilder 67 | target/ 68 | 69 | # IPython Notebook 70 | .ipynb_checkpoints 71 | 72 | # pyenv 73 | .python-version 74 | 75 | # celery beat schedule file 76 | celerybeat-schedule 77 | 78 | # dotenv 79 | .env 80 | 81 | # virtualenv 82 | venv/ 83 | ENV/ 84 | 85 | # Spyder project settings 86 | .spyderproject 87 | 88 | # Rope project settings 89 | .ropeproject 90 | 91 | *.sqlite 92 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | variables: 2 | GIT_SSL_NO_VERIFY: "1" 3 | 4 | stages: 5 | - test 6 | - build 7 | - deploy 8 | 9 | pep8: 10 | stage: test 11 | image: python:2.7 12 | script: 13 | - pip install tox 14 | - tox -e pep8 15 | tags: 16 | - python27 17 | 18 | unittest-py27: 19 | stage: test 20 | image: python:2.7 21 | script: 22 | - pip install tox 23 | - tox -e py27 24 | tags: 25 | - python27 26 | 27 | unittest-py34: 28 | stage: test 29 | image: python:3.4 30 | script: 31 | - pip install tox 32 | - tox -e py34 33 | tags: 34 | - python34 35 | 36 | sphnix: 37 | stage: test 38 | image: python:2.7 39 | script: 40 | - pip install tox 41 | - tox -e docs 42 | tags: 43 | - python27 44 | 45 | build: 46 | stage: build 47 | tags: 48 | - shell 49 | script: 50 | - docker build -t skeleton . 51 | only: 52 | - master 53 | 54 | deploy: 55 | stage: deploy 56 | tags: 57 | - shell 58 | script: 59 | - scripts/deploy.sh 60 | - export 61 | only: 62 | - master 63 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/.gitlab/issue_templates/Bug.md: -------------------------------------------------------------------------------- 1 | ### Summary 2 | 3 | (Summarize the bug encountered concisely) 4 | 5 | ### Steps to reproduce 6 | 7 | (How one can reproduce the issue - this is very important) 8 | 9 | ### Expected behavior 10 | 11 | (What you should see instead) 12 | 13 | ### Actual behaviour 14 | 15 | (What actually happens) 16 | 17 | ### Relevant logs and/or screenshots 18 | 19 | (Paste any relevant logs - please use code blocks (```) to format console output, 20 | logs, and code as it's very hard to read otherwise.) 21 | 22 | 23 | ### Possible fixes 24 | 25 | (If you can, link to the line of code that might be responsible for the problem) 26 | 27 | 28 | /label ~"Bug" 29 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/.gitlab/issue_templates/Feature.md: -------------------------------------------------------------------------------- 1 | ### Feature Description 2 | 3 | 4 | ### Implementation 5 | 6 | 7 | /label ~"Feature" 8 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/.gitlab/merge_request_templates/default.md: -------------------------------------------------------------------------------- 1 | **1. Explain what do you want to merge** 2 | 3 | - 4 | - 5 | 6 | **2. Does this MR meet the acceptance criteria?** 7 | 8 | - [ ] I have read [Contribution guidelines](https://as-gitlab.cisco.com/demo/skeleton/blob/master/CONTRIBUTING.md) 9 | - [ ] I have run the command `tox` locally and get successful results. 10 | - [ ] Branch has no merge conflicts with master (if you do - rebase it please) 11 | 12 | **3. What are the relevant issue numbers?** 13 | 14 | 15 | Thanks for your MR, you're awesome! :+1: 16 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Hacking Guide 2 | 3 | ## Code style 4 | 5 | Step 1: Read http://www.python.org/dev/peps/pep-0008/ 6 | 7 | Step 2: Read http://www.python.org/dev/peps/pep-0008/ again 8 | 9 | Step 3: Read on 10 | 11 | ## Running Tests 12 | 13 | Run tox 14 | 15 | ``` 16 | $ cd skeleton 17 | $ tox 18 | ``` 19 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:2.7 2 | LABEL maintainer="Peng Xiao" 3 | 4 | COPY . /skeleton 5 | WORKDIR /skeleton 6 | RUN pip install -r requirements.txt 7 | EXPOSE 5000 8 | ENTRYPOINT ["scripts/dev.sh"] 9 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2016 Michael Herman 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/README.md: -------------------------------------------------------------------------------- 1 | [![build status](https://gitlab-demo.com/Demo/flask-skeleton/badges/master/build.svg)](https://gitlab-demo.com/Demo/flask-skeleton/commits/master) 2 | [![coverage report](https://gitlab-demo.com/Demo/flask-skeleton/badges/master/coverage.svg)](https://gitlab-demo.com/Demo/flask-skeleton/commits/master) 3 | 4 | 5 | # Flask Skeleton 6 | 7 | Flask starter project... 8 | 9 | ## Quick Start 10 | 11 | ### Basics 12 | 13 | 1. Activate a virtualenv 14 | 1. Install the requirements 15 | 16 | ### Set Environment Variables 17 | 18 | Update *skeleton/server/config.py*, and then run: 19 | 20 | ```sh 21 | $ export APP_SETTINGS="skeleton.server.config.DevelopmentConfig" 22 | ``` 23 | 24 | or 25 | 26 | ```sh 27 | $ export APP_SETTINGS="skeleton.server.config.ProductionConfig" 28 | ``` 29 | 30 | ### Create DB 31 | 32 | ```sh 33 | $ python manage.py create_db 34 | $ python manage.py db init 35 | $ python manage.py db migrate 36 | $ python manage.py create_admin 37 | $ python manage.py create_data 38 | ``` 39 | 40 | ### Run the Application 41 | 42 | ```sh 43 | $ python manage.py runserver 44 | ``` 45 | 46 | So access the application at the address [http://localhost:5000/](http://localhost:5000/) 47 | 48 | > Want to specify a different port? 49 | 50 | > ```sh 51 | > $ python manage.py runserver -h 0.0.0.0 -p 8080 52 | > ``` 53 | 54 | ### Testing1 55 | 56 | ``` 57 | $ tox 58 | ``` 59 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/doc/source/_static/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter5/labs/flask-skeleton/doc/source/_static/.placeholder -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/doc/source/_templates/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter5/labs/flask-skeleton/doc/source/_templates/.placeholder -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/doc/source/index.rst: -------------------------------------------------------------------------------- 1 | .. yacore documentation master file, created by 2 | sphinx-quickstart on Mon Aug 1 21:41:36 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to yacore's documentation! 7 | ================================== 8 | 9 | This is a test line 10 | test again 11 | test 12 | Contents: 13 | 14 | .. toctree:: 15 | :maxdepth: 2 16 | 17 | 18 | 19 | Indices and tables 20 | ================== 21 | 22 | * :ref:`genindex` 23 | * :ref:`modindex` 24 | * :ref:`search` 25 | 26 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/manage.py: -------------------------------------------------------------------------------- 1 | # manage.py 2 | 3 | import unittest 4 | 5 | from flask_script import Manager 6 | from flask_migrate import Migrate, MigrateCommand 7 | 8 | from skeleton.server import app, db 9 | from skeleton.server.models import User 10 | 11 | 12 | migrate = Migrate(app, db) 13 | manager = Manager(app) 14 | 15 | # migrations 16 | manager.add_command('db', MigrateCommand) 17 | 18 | 19 | @manager.command 20 | def test(): 21 | """Runs the unit tests without coverage.""" 22 | tests = unittest.TestLoader().discover('tests', pattern='test*.py') 23 | result = unittest.TextTestRunner(verbosity=2).run(tests) 24 | if result.wasSuccessful(): 25 | return 0 26 | else: 27 | return 1 28 | 29 | 30 | @manager.command 31 | def create_db(): 32 | """Creates the db tables.""" 33 | db.create_all() 34 | 35 | 36 | @manager.command 37 | def drop_db(): 38 | """Drops the db tables.""" 39 | db.drop_all() 40 | 41 | 42 | @manager.command 43 | def create_admin(): 44 | """Creates the admin user.""" 45 | db.session.add(User(email='admin@cisco.com', password='admin', admin=True)) 46 | db.session.commit() 47 | 48 | 49 | @manager.command 50 | def create_data(): 51 | """Creates sample data.""" 52 | pass 53 | 54 | 55 | if __name__ == '__main__': 56 | manager.run() 57 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/migrations/README: -------------------------------------------------------------------------------- 1 | Generic single-database configuration. -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/migrations/alembic.ini: -------------------------------------------------------------------------------- 1 | # A generic, single database configuration. 2 | 3 | [alembic] 4 | # template used to generate migration files 5 | # file_template = %%(rev)s_%%(slug)s 6 | 7 | # set to 'true' to run the environment during 8 | # the 'revision' command, regardless of autogenerate 9 | # revision_environment = false 10 | 11 | 12 | # Logging configuration 13 | [loggers] 14 | keys = root,sqlalchemy,alembic 15 | 16 | [handlers] 17 | keys = console 18 | 19 | [formatters] 20 | keys = generic 21 | 22 | [logger_root] 23 | level = WARN 24 | handlers = console 25 | qualname = 26 | 27 | [logger_sqlalchemy] 28 | level = WARN 29 | handlers = 30 | qualname = sqlalchemy.engine 31 | 32 | [logger_alembic] 33 | level = INFO 34 | handlers = 35 | qualname = alembic 36 | 37 | [handler_console] 38 | class = StreamHandler 39 | args = (sys.stderr,) 40 | level = NOTSET 41 | formatter = generic 42 | 43 | [formatter_generic] 44 | format = %(levelname)-5.5s [%(name)s] %(message)s 45 | datefmt = %H:%M:%S 46 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = ${repr(up_revision)} 11 | down_revision = ${repr(down_revision)} 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | ${imports if imports else ""} 16 | 17 | def upgrade(): 18 | ${upgrades if upgrades else "pass"} 19 | 20 | 21 | def downgrade(): 22 | ${downgrades if downgrades else "pass"} 23 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/requirements.txt: -------------------------------------------------------------------------------- 1 | alembic==0.8.6 2 | bcrypt==3.1.0 3 | blinker==1.4 4 | cffi==1.7.0 5 | click==6.6 6 | dominate==2.2.1 7 | Flask==0.10.1 8 | Flask-Bcrypt==0.7.1 9 | Flask-Bootstrap==3.3.6.0 10 | Flask-DebugToolbar==0.10.0 11 | Flask-Login==0.3.2 12 | Flask-Migrate==1.8.1 13 | Flask-Script==2.0.5 14 | Flask-SQLAlchemy==2.1 15 | Flask-WTF==0.12 16 | itsdangerous==0.24 17 | Jinja2==2.8 18 | Mako==1.0.4 19 | MarkupSafe==0.23 20 | pycparser==2.14 21 | python-editor==1.0.1 22 | six==1.10.0 23 | SQLAlchemy==1.0.14 24 | visitor==0.1.3 25 | Werkzeug==0.11.10 26 | WTForms==2.1 27 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/scripts/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | docker ps -a | grep penxiao_skeleton | awk '{print$1}' | xargs docker stop 4 | docker ps -a | grep penxiao_skeleton | awk '{print$1}' | xargs docker rm 5 | docker run -d -p 80:5000 --name penxiao_skeleton skeleton 6 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/scripts/dev.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | export APP_SETTINGS="skeleton.server.config.ProductionConfig" 4 | python manage.py create_db 5 | python manage.py create_admin 6 | python manage.py create_data 7 | python manage.py runserver -h 0.0.0.0 8 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/skeleton/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter5/labs/flask-skeleton/skeleton/__init__.py -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/skeleton/client/static/main.css: -------------------------------------------------------------------------------- 1 | /* custom css */ 2 | 3 | .site-content { 4 | padding-top: 75px; 5 | } -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/skeleton/client/static/main.js: -------------------------------------------------------------------------------- 1 | // custom javascript 2 | 3 | $( document ).ready(function() { 4 | console.log('Sanity Check!'); 5 | }); -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/skeleton/client/templates/errors/401.html: -------------------------------------------------------------------------------- 1 | {% extends "_base.html" %} 2 | 3 | {% block page_title %}- Unauthorized{% endblock %} 4 | 5 | {% block content %} 6 |
7 |
8 |

401

9 |

You are not authorized to view this page. Please log in.

10 |
11 |
12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/skeleton/client/templates/errors/403.html: -------------------------------------------------------------------------------- 1 | {% extends "_base.html" %} 2 | 3 | {% block page_title %}- Unauthorized{% endblock %} 4 | 5 | {% block content %} 6 |
7 |
8 |

401

9 |

You are not authorized to view this page. Please log in.

10 |
11 |
12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/skeleton/client/templates/errors/404.html: -------------------------------------------------------------------------------- 1 | {% extends "_base.html" %} 2 | 3 | {% block page_title %}- Page Not Found{% endblock %} 4 | 5 | {% block content %} 6 |
7 |
8 |

404

9 |

Sorry. The requested page doesn't exist. Go home.

10 |
11 |
12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/skeleton/client/templates/errors/500.html: -------------------------------------------------------------------------------- 1 | {% extends "_base.html" %} 2 | 3 | {% block page_title %}- Server Error{% endblock %} 4 | 5 | {% block content %} 6 |
7 |
8 |

500

9 |

Sorry. Something went terribly wrong. Go home.

10 |
11 |
12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/skeleton/client/templates/footer.html: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/skeleton/client/templates/header.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/skeleton/client/templates/main/about.html: -------------------------------------------------------------------------------- 1 | {% extends "_base.html" %} 2 | 3 | {% block content %} 4 | 5 |
6 |
7 |

About

8 |
9 |
10 | 11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/skeleton/client/templates/main/home.html: -------------------------------------------------------------------------------- 1 | {% extends "_base.html" %} 2 | 3 | {% block content %} 4 | 5 |
6 |
7 |

Welcome!

8 |
9 |
10 | 11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/skeleton/client/templates/user/login.html: -------------------------------------------------------------------------------- 1 | {% extends '_base.html' %} 2 | {% import "bootstrap/wtf.html" as wtf %} 3 | 4 | {% block content %} 5 | 6 |
7 |

Please login

8 |
9 | 10 |
11 | 12 | 13 |
14 | 15 | {{ form.csrf_token }} 16 | {{ form.hidden_tag() }} 17 | {{ wtf.form_errors(form, hiddens="only") }} 18 | 19 | 20 |
21 | 22 | {{ wtf.form_field(form.email) }} 23 | {{ wtf.form_field(form.password) }} 24 | 25 | 26 |

27 |

Need to Register?

28 |
29 | 30 |
31 | 32 | 33 | {% endblock content %} 34 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/skeleton/client/templates/user/members.html: -------------------------------------------------------------------------------- 1 | {% extends "_base.html" %} 2 | {% block content %} 3 |

Welcome, {{ current_user.email }}!

4 |

This is the members-only page :)

5 | {% endblock %} 6 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/skeleton/client/templates/user/register.html: -------------------------------------------------------------------------------- 1 | {% extends '_base.html' %} 2 | {% import "bootstrap/wtf.html" as wtf %} 3 | 4 | {% block content %} 5 | 6 |
7 |

Please Register

8 |
9 | 10 |
11 | 12 | 13 |
14 | 15 | {{ form.csrf_token }} 16 | {{ form.hidden_tag() }} 17 | {{ wtf.form_errors(form, hiddens="only") }} 18 | 19 | 20 |
21 | 22 | {{ wtf.form_field(form.email) }} 23 | {{ wtf.form_field(form.password) }} 24 | {{ wtf.form_field(form.confirm) }} 25 | 26 | 27 |

28 |

Already have an account? Sign in.

29 | 30 |
31 | 32 |
33 | 34 | 35 | {% endblock content %} 36 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/skeleton/server/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | 4 | import os 5 | 6 | from flask import Flask, render_template 7 | from flask_login import LoginManager 8 | from flask_bcrypt import Bcrypt 9 | from flask_debugtoolbar import DebugToolbarExtension 10 | from flask_bootstrap import Bootstrap 11 | from flask_sqlalchemy import SQLAlchemy 12 | 13 | 14 | app = Flask( 15 | __name__, 16 | template_folder='../client/templates', 17 | static_folder='../client/static' 18 | ) 19 | 20 | app_settings = os.getenv('APP_SETTINGS', 'skeleton.server.config.DevelopmentConfig') 21 | app.config.from_object(app_settings) 22 | 23 | login_manager = LoginManager() 24 | login_manager.init_app(app) 25 | bcrypt = Bcrypt(app) 26 | toolbar = DebugToolbarExtension(app) 27 | bootstrap = Bootstrap(app) 28 | db = SQLAlchemy(app) 29 | 30 | from skeleton.server.user.views import user_blueprint 31 | from skeleton.server.main.views import main_blueprint 32 | app.register_blueprint(user_blueprint) 33 | app.register_blueprint(main_blueprint) 34 | 35 | from skeleton.server.models import User 36 | 37 | login_manager.login_view = "user.login" 38 | login_manager.login_message_category = 'danger' 39 | 40 | 41 | @login_manager.user_loader 42 | def load_user(user_id): 43 | return User.query.filter(User.id == int(user_id)).first() 44 | 45 | 46 | @app.errorhandler(401) 47 | def forbidden_page_401(error): 48 | return render_template("errors/401.html"), 401 49 | 50 | 51 | @app.errorhandler(403) 52 | def forbidden_page_403(error): 53 | return render_template("errors/403.html"), 403 54 | 55 | 56 | @app.errorhandler(404) 57 | def page_not_found(error): 58 | return render_template("errors/404.html"), 404 59 | 60 | 61 | @app.errorhandler(500) 62 | def server_error_page(error): 63 | return render_template("errors/500.html"), 500 64 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/skeleton/server/config.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | 4 | import os 5 | basedir = os.path.abspath(os.path.dirname(__file__)) 6 | 7 | 8 | class BaseConfig(object): 9 | """Base configuration.""" 10 | SECRET_KEY = 'my_precious' 11 | DEBUG = False 12 | BCRYPT_LOG_ROUNDS = 13 13 | WTF_CSRF_ENABLED = True 14 | DEBUG_TB_ENABLED = False 15 | DEBUG_TB_INTERCEPT_REDIRECTS = False 16 | SQLALCHEMY_TRACK_MODIFICATIONS = False 17 | SQLALCHEMY_DATABASE_URI = os.environ.get( 18 | 'DATABASE_URL', 'sqlite:///' + os.path.join(basedir, 'db.sqlite')) 19 | 20 | 21 | class DevelopmentConfig(BaseConfig): 22 | """Development configuration.""" 23 | DEBUG = True 24 | BCRYPT_LOG_ROUNDS = 4 25 | WTF_CSRF_ENABLED = False 26 | DEBUG_TB_ENABLED = True 27 | 28 | 29 | class TestingConfig(BaseConfig): 30 | """Testing configuration.""" 31 | DEBUG = True 32 | TESTING = True 33 | BCRYPT_LOG_ROUNDS = 4 34 | WTF_CSRF_ENABLED = False 35 | DEBUG_TB_ENABLED = False 36 | PRESERVE_CONTEXT_ON_EXCEPTION = False 37 | 38 | 39 | class ProductionConfig(BaseConfig): 40 | """Production configuration.""" 41 | SECRET_KEY = 'my_precious' 42 | DEBUG = False 43 | DEBUG_TB_ENABLED = False 44 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/skeleton/server/main/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter5/labs/flask-skeleton/skeleton/server/main/__init__.py -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/skeleton/server/main/views.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | 4 | from flask import render_template, Blueprint 5 | 6 | main_blueprint = Blueprint('main', __name__,) 7 | 8 | 9 | @main_blueprint.route('/') 10 | def home(): 11 | return render_template('main/home.html') 12 | 13 | 14 | @main_blueprint.route("/about/") 15 | def about(): 16 | return render_template("main/about.html") 17 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/skeleton/server/models.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | 4 | import datetime 5 | 6 | from skeleton.server import app, db, bcrypt 7 | 8 | 9 | class User(db.Model): 10 | 11 | __tablename__ = "users" 12 | 13 | id = db.Column(db.Integer, primary_key=True, autoincrement=True) 14 | email = db.Column(db.String(255), unique=True, nullable=False) 15 | password = db.Column(db.String(255), nullable=False) 16 | registered_on = db.Column(db.DateTime, nullable=False) 17 | admin = db.Column(db.Boolean, nullable=False, default=False) 18 | 19 | def __init__(self, email, password, admin=False): 20 | self.email = email 21 | self.password = bcrypt.generate_password_hash( 22 | password, app.config.get('BCRYPT_LOG_ROUNDS') 23 | ) 24 | self.registered_on = datetime.datetime.now() 25 | self.admin = admin 26 | 27 | def is_authenticated(self): 28 | return True 29 | 30 | def is_active(self): 31 | return True 32 | 33 | def is_anonymous(self): 34 | return False 35 | 36 | def get_id(self): 37 | return self.id 38 | 39 | def __repr__(self): 40 | return ''.format(self.email) 41 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/skeleton/server/user/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter5/labs/flask-skeleton/skeleton/server/user/__init__.py -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/skeleton/server/user/forms.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | 4 | from flask_wtf import Form 5 | from wtforms import StringField, PasswordField 6 | from wtforms.validators import DataRequired, Email, Length, EqualTo 7 | 8 | 9 | class LoginForm(Form): 10 | email = StringField('Email Address', [DataRequired(), Email()]) 11 | password = PasswordField('Password', [DataRequired()]) 12 | 13 | 14 | class RegisterForm(Form): 15 | email = StringField( 16 | 'Email Address', 17 | validators=[DataRequired(), Email(message=None), Length(min=6, max=40)]) 18 | password = PasswordField( 19 | 'Password', 20 | validators=[DataRequired(), Length(min=6, max=25)] 21 | ) 22 | confirm = PasswordField( 23 | 'Confirm password', 24 | validators=[ 25 | DataRequired(), 26 | EqualTo('password', message='Passwords must match.') 27 | ] 28 | ) 29 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/test-requirements.txt: -------------------------------------------------------------------------------- 1 | flake8==2.4.0 2 | Flask-Testing==0.4.2 3 | discover 4 | nose 5 | coverage==4.0.3 6 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter5/labs/flask-skeleton/tests/__init__.py -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/tests/base.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | 4 | from flask_testing import TestCase 5 | 6 | from skeleton.server import app, db 7 | from skeleton.server.models import User 8 | 9 | 10 | class BaseTestCase(TestCase): 11 | 12 | def create_app(self): 13 | app.config.from_object('skeleton.server.config.TestingConfig') 14 | return app 15 | 16 | def setUp(self): 17 | db.create_all() 18 | user = User(email="ad@min.com", password="admin_user") 19 | db.session.add(user) 20 | db.session.commit() 21 | 22 | def tearDown(self): 23 | db.session.remove() 24 | db.drop_all() 25 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/tests/test_main.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | 4 | import unittest 5 | 6 | from base import BaseTestCase 7 | 8 | 9 | class TestMainBlueprint(BaseTestCase): 10 | 11 | def test_index(self): 12 | # Ensure Flask is setup. 13 | response = self.client.get('/', follow_redirects=True) 14 | self.assertEqual(response.status_code, 200) 15 | self.assertIn(b'Welcome!', response.data) 16 | self.assertIn(b'Register/Login', response.data) 17 | 18 | def test_footer(self): 19 | response = self.client.get('/', follow_redirects=True) 20 | self.assertEqual(response.status_code, 200) 21 | self.assertIn(b'GitLab Demo', response.data) 22 | 23 | def test_about(self): 24 | # Ensure about route behaves correctly. 25 | response = self.client.get('/about', follow_redirects=True) 26 | self.assertEqual(response.status_code, 200) 27 | self.assertIn(b'About', response.data) 28 | 29 | def test_404(self): 30 | # Ensure 404 error is handled. 31 | response = self.client.get('/404') 32 | self.assert404(response) 33 | self.assertTemplateUsed('errors/404.html') 34 | 35 | 36 | if __name__ == '__main__': 37 | unittest.main() 38 | -------------------------------------------------------------------------------- /chapter5/labs/flask-skeleton/tox.ini: -------------------------------------------------------------------------------- 1 | # Tox (http://tox.testrun.org/) is a tool for running tests 2 | # in multiple virtualenvs. This configuration file will run the 3 | # test suite on all supported python versions. To use it, "pip install tox" 4 | # and then run "tox" from this directory. 5 | 6 | [tox] 7 | # List the environment that will be run by default 8 | minversion = 1.6 9 | envlist = py27, py34, pep8, docs 10 | skipsdist = True 11 | 12 | [testenv] 13 | setenv = VIRTUAL_ENV={envdir} 14 | LANG=en_US.UTF-8 15 | LANGUAGE=en_US:en 16 | LC_ALL=C 17 | 18 | [testenv:py27] 19 | deps = -r{toxinidir}/test-requirements.txt 20 | -r{toxinidir}/requirements.txt 21 | 22 | 23 | commands = 24 | coverage run manage.py test 25 | coverage report -m 26 | 27 | [testenv:py34] 28 | deps = -r{toxinidir}/test-requirements.txt 29 | -r{toxinidir}/requirements.txt 30 | 31 | commands = 32 | coverage run manage.py test 33 | coverage report -m 34 | 35 | [testenv:pep8] 36 | sitepackages = False 37 | deps = -r{toxinidir}/test-requirements.txt 38 | commands = 39 | flake8 {posargs} 40 | 41 | [flake8] 42 | # E712 is ignored on purpose, since it is normal to use 'column == true' 43 | # in sqlalchemy. 44 | # H803 skipped on purpose per list discussion. 45 | # E125 is deliberately excluded. See https://github.com/jcrocholl/pep8/issues/126 46 | # The rest of the ignores are TODOs 47 | # New from hacking 0.9: E129, E131, E265, E713, H407, H405, H904 48 | # Stricter in hacking 0.9: F402 49 | # E251 Skipped due to https://github.com/jcrocholl/pep8/issues/301 50 | 51 | max-line-length=120 52 | exclude = .venv,.git,.tox,dist,doc,*lib/python*,*egg,build,tools 53 | 54 | [testenv:docs] 55 | deps= 56 | sphinx 57 | sphinx_rtd_theme 58 | commands = sphinx-build -W -b html doc/source doc/build 59 | -------------------------------------------------------------------------------- /chapter5/setup.sh: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | 3 | # install some tools 4 | sudo yum install -y git vim gcc glibc-static telnet 5 | 6 | # install docker 7 | curl -fsSL get.docker.com -o get-docker.sh 8 | sh get-docker.sh 9 | 10 | # start docker service 11 | sudo groupadd docker 12 | sudo gpasswd -a vagrant docker 13 | sudo systemctl start docker 14 | 15 | rm -rf get-docker.sh -------------------------------------------------------------------------------- /chapter6/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | Vagrant.require_version ">= 1.6.0" 5 | 6 | boxes = [ 7 | { 8 | :name => "docker-host", 9 | :eth1 => "192.168.205.10", 10 | :mem => "1024", 11 | :cpu => "1" 12 | } 13 | ] 14 | 15 | Vagrant.configure(2) do |config| 16 | 17 | config.vm.box = "centos/7" 18 | boxes.each do |opts| 19 | config.vm.define opts[:name] do |config| 20 | config.vm.hostname = opts[:name] 21 | config.vm.provider "vmware_fusion" do |v| 22 | v.vmx["memsize"] = opts[:mem] 23 | v.vmx["numvcpus"] = opts[:cpu] 24 | end 25 | config.vm.provider "virtualbox" do |v| 26 | v.customize ["modifyvm", :id, "--memory", opts[:mem]] 27 | v.customize ["modifyvm", :id, "--cpus", opts[:cpu]] 28 | end 29 | config.vm.network :private_network, ip: opts[:eth1] 30 | end 31 | end 32 | config.vm.synced_folder "./labs", "/home/vagrant/labs" 33 | config.vm.provision "shell", privileged: true, path: "./setup.sh" 34 | end 35 | -------------------------------------------------------------------------------- /chapter6/labs/example-voting-app/README.md: -------------------------------------------------------------------------------- 1 | Example Voting App 2 | ================== 3 | 4 | This is an example Docker app with multiple services. It is run with Docker Compose and uses Docker Networking to connect containers together. You will need Docker Compose 1.6 or later. 5 | 6 | More info at https://blog.docker.com/2015/11/docker-toolbox-compose/ 7 | 8 | Architecture 9 | ----- 10 | 11 | * A Python webapp which lets you vote between two options 12 | * A Redis queue which collects new votes 13 | * A Java worker which consumes votes and stores them in… 14 | * A Postgres database backed by a Docker volume 15 | * A Node.js webapp which shows the results of the voting in real time 16 | 17 | ![pic](architecture.png) 18 | 19 | Running 20 | ------- 21 | 22 | Run in this directory: 23 | 24 | $ docker-compose up 25 | 26 | The app will be running on port 5000 on your Docker host, and the results will be on port 5001. 27 | 28 | Docker Hub images 29 | ----------------- 30 | 31 | Docker Hub images for services in this app are built automatically from master: 32 | 33 | - [docker/example-voting-app-voting-app](https://hub.docker.com/r/docker/example-voting-app-voting-app/) 34 | - [docker/example-voting-app-result-app](https://hub.docker.com/r/docker/example-voting-app-result-app/) 35 | - [docker/example-voting-app-worker](https://hub.docker.com/r/docker/example-voting-app-worker/) 36 | -------------------------------------------------------------------------------- /chapter6/labs/example-voting-app/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter6/labs/example-voting-app/architecture.png -------------------------------------------------------------------------------- /chapter6/labs/example-voting-app/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | voting-app: 5 | build: ./voting-app/. 6 | volumes: 7 | - ./voting-app:/app 8 | ports: 9 | - "5000:80" 10 | links: 11 | - redis 12 | networks: 13 | - front-tier 14 | - back-tier 15 | 16 | result-app: 17 | build: ./result-app/. 18 | volumes: 19 | - ./result-app:/app 20 | ports: 21 | - "5001:80" 22 | links: 23 | - db 24 | networks: 25 | - front-tier 26 | - back-tier 27 | 28 | worker: 29 | build: ./worker 30 | links: 31 | - db 32 | - redis 33 | networks: 34 | - back-tier 35 | 36 | redis: 37 | image: redis 38 | ports: ["6379"] 39 | networks: 40 | - back-tier 41 | 42 | db: 43 | image: postgres:9.4 44 | volumes: 45 | - "db-data:/var/lib/postgresql/data" 46 | networks: 47 | - back-tier 48 | 49 | volumes: 50 | db-data: 51 | 52 | networks: 53 | front-tier: 54 | back-tier: 55 | 56 | 57 | -------------------------------------------------------------------------------- /chapter6/labs/example-voting-app/result-app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:0.10 2 | 3 | RUN mkdir /app 4 | WORKDIR /app 5 | 6 | ADD package.json /app/package.json 7 | RUN npm install && npm ls 8 | RUN mv /app/node_modules /node_modules 9 | 10 | ADD . /app 11 | 12 | ENV PORT 80 13 | EXPOSE 80 14 | 15 | CMD ["node", "server.js"] 16 | -------------------------------------------------------------------------------- /chapter6/labs/example-voting-app/result-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "result-app", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "MIT", 11 | "dependencies": { 12 | "body-parser": "^1.14.1", 13 | "cookie-parser": "^1.4.0", 14 | "express": "^4.13.3", 15 | "method-override": "^2.3.5", 16 | "async": "^1.5.0", 17 | "pg": "^4.4.3", 18 | "socket.io": "^1.3.7" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /chapter6/labs/example-voting-app/result-app/views/app.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('catsvsdogs', []); 2 | var socket = io.connect({transports:['polling']}); 3 | 4 | var bg1 = document.getElementById('background-stats-1'); 5 | var bg2 = document.getElementById('background-stats-2'); 6 | 7 | app.controller('statsCtrl', function($scope){ 8 | var animateStats = function(a,b){ 9 | if(a+b>0){ 10 | var percentA = a/(a+b)*100; 11 | var percentB = 100-percentA; 12 | bg1.style.width= percentA+"%"; 13 | bg2.style.width = percentB+"%"; 14 | } 15 | }; 16 | 17 | $scope.aPercent = 50; 18 | $scope.bPercent = 50; 19 | 20 | var updateScores = function(){ 21 | socket.on('scores', function (json) { 22 | data = JSON.parse(json); 23 | var a = parseInt(data.a || 0); 24 | var b = parseInt(data.b || 0); 25 | 26 | animateStats(a, b); 27 | 28 | $scope.$apply(function() { 29 | if(a + b > 0){ 30 | $scope.aPercent = a/(a+b) * 100; 31 | $scope.bPercent = b/(a+b) * 100; 32 | $scope.total = a + b 33 | } 34 | }); 35 | }); 36 | }; 37 | 38 | var init = function(){ 39 | document.body.style.opacity=1; 40 | updateScores(); 41 | }; 42 | socket.on('message',function(data){ 43 | init(); 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /chapter6/labs/example-voting-app/voting-app/Dockerfile: -------------------------------------------------------------------------------- 1 | # Using official python runtime base image 2 | FROM python:2.7 3 | 4 | # Set the application directory 5 | WORKDIR /app 6 | 7 | # Install our requirements.txt 8 | ADD requirements.txt /app/requirements.txt 9 | RUN pip install -r requirements.txt 10 | 11 | # Copy our code from the current folder to /app inside the container 12 | ADD . /app 13 | 14 | # Make port 5000 available for links and/or publish 15 | EXPOSE 80 16 | 17 | # Define our command to be run when launching the container 18 | CMD ["python", "app.py"] 19 | -------------------------------------------------------------------------------- /chapter6/labs/example-voting-app/voting-app/app.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # import sys 3 | # reload(sys) 4 | # sys.setdefaultencoding("utf-8") 5 | 6 | from flask import Flask 7 | from flask import render_template 8 | from flask import request 9 | from flask import make_response 10 | from utils import connect_to_redis 11 | import os 12 | import socket 13 | import random 14 | import json 15 | 16 | option_a = os.getenv('OPTION_A', u"CAT") 17 | option_b = os.getenv('OPTION_B', u"DOG") 18 | hostname = socket.gethostname() 19 | 20 | redis = connect_to_redis("redis") 21 | app = Flask(__name__) 22 | 23 | 24 | @app.route("/", methods=['POST', 'GET']) 25 | def hello(): 26 | voter_id = request.cookies.get('voter_id') 27 | if not voter_id: 28 | voter_id = hex(random.getrandbits(64))[2:-1] 29 | 30 | vote = request.cookies.get('vote', '') 31 | 32 | if request.method == 'POST': 33 | vote = request.form['vote'] 34 | data = json.dumps({'voter_id': voter_id, 'vote': vote}) 35 | redis.rpush('votes', data) 36 | 37 | resp = make_response(render_template( 38 | 'index.html', 39 | option_a=option_a, 40 | option_b=option_b, 41 | hostname=hostname, 42 | vote=vote, 43 | )) 44 | resp.set_cookie('voter_id', voter_id) 45 | resp.set_cookie('vote', vote) 46 | return resp 47 | 48 | 49 | if __name__ == "__main__": 50 | app.run(host='0.0.0.0', port=80, debug=True) 51 | -------------------------------------------------------------------------------- /chapter6/labs/example-voting-app/voting-app/requirements.txt: -------------------------------------------------------------------------------- 1 | Flask 2 | Redis -------------------------------------------------------------------------------- /chapter6/labs/example-voting-app/voting-app/static/font-awesome/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter6/labs/example-voting-app/voting-app/static/font-awesome/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /chapter6/labs/example-voting-app/voting-app/static/font-awesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter6/labs/example-voting-app/voting-app/static/font-awesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /chapter6/labs/example-voting-app/voting-app/static/font-awesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter6/labs/example-voting-app/voting-app/static/font-awesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /chapter6/labs/example-voting-app/voting-app/static/font-awesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter6/labs/example-voting-app/voting-app/static/font-awesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /chapter6/labs/example-voting-app/voting-app/static/font-awesome/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter6/labs/example-voting-app/voting-app/static/font-awesome/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /chapter6/labs/example-voting-app/voting-app/static/jquery.cookie.min.js: -------------------------------------------------------------------------------- 1 | /*! jquery.cookie v1.4.1 | MIT */ 2 | !function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?a(require("jquery")):a(jQuery)}(function(a){function b(a){return h.raw?a:encodeURIComponent(a)}function c(a){return h.raw?a:decodeURIComponent(a)}function d(a){return b(h.json?JSON.stringify(a):String(a))}function e(a){0===a.indexOf('"')&&(a=a.slice(1,-1).replace(/\\"/g,'"').replace(/\\\\/g,"\\"));try{return a=decodeURIComponent(a.replace(g," ")),h.json?JSON.parse(a):a}catch(b){}}function f(b,c){var d=h.raw?b:e(b);return a.isFunction(c)?c(d):d}var g=/\+/g,h=a.cookie=function(e,g,i){if(void 0!==g&&!a.isFunction(g)){if(i=a.extend({},h.defaults,i),"number"==typeof i.expires){var j=i.expires,k=i.expires=new Date;k.setTime(+k+864e5*j)}return document.cookie=[b(e),"=",d(g),i.expires?"; expires="+i.expires.toUTCString():"",i.path?"; path="+i.path:"",i.domain?"; domain="+i.domain:"",i.secure?"; secure":""].join("")}for(var l=e?void 0:{},m=document.cookie?document.cookie.split("; "):[],n=0,o=m.length;o>n;n++){var p=m[n].split("="),q=c(p.shift()),r=p.join("=");if(e&&e===q){l=f(r,g);break}e||void 0===(r=f(r))||(l[q]=r)}return l};h.defaults={},a.removeCookie=function(b,c){return void 0===a.cookie(b)?!1:(a.cookie(b,"",a.extend({},c,{expires:-1})),!a.cookie(b))}}); -------------------------------------------------------------------------------- /chapter6/labs/example-voting-app/voting-app/utils/__init__.py: -------------------------------------------------------------------------------- 1 | import time 2 | from redis import Redis, ConnectionError 3 | 4 | 5 | def connect_to_redis(host): 6 | time.sleep(2) 7 | print "Connecting to redis" 8 | 9 | while True: 10 | try: 11 | redis = Redis(host=host, db=0) 12 | redis.ping() 13 | print "Connected to redis" 14 | return redis 15 | except ConnectionError: 16 | print "Failed to connect to redis - retrying" 17 | time.sleep(1) 18 | -------------------------------------------------------------------------------- /chapter6/labs/example-voting-app/voting-app/utils/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter6/labs/example-voting-app/voting-app/utils/__init__.pyc -------------------------------------------------------------------------------- /chapter6/labs/example-voting-app/worker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM java:7 2 | 3 | RUN apt-get update -qq && apt-get install -y maven && apt-get clean 4 | 5 | WORKDIR /code 6 | 7 | ADD pom.xml /code/pom.xml 8 | RUN ["mvn", "dependency:resolve"] 9 | RUN ["mvn", "verify"] 10 | 11 | # Adding source, compile and package into a fat jar 12 | ADD src /code/src 13 | RUN ["mvn", "package"] 14 | 15 | CMD ["/usr/lib/jvm/java-7-openjdk-amd64/bin/java", "-jar", "target/worker-jar-with-dependencies.jar"] 16 | -------------------------------------------------------------------------------- /chapter6/labs/flask-redis/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:2.7 2 | LABEL maintaner="Peng Xiao xiaoquwl@gmail.com" 3 | COPY . /app 4 | WORKDIR /app 5 | RUN pip install flask redis 6 | EXPOSE 5000 7 | CMD [ "python", "app.py" ] -------------------------------------------------------------------------------- /chapter6/labs/flask-redis/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | from redis import Redis 3 | import os 4 | import socket 5 | 6 | app = Flask(__name__) 7 | redis = Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379) 8 | 9 | 10 | @app.route('/') 11 | def hello(): 12 | redis.incr('hits') 13 | return 'Hello Container World! I have been seen %s times and my hostname is %s.\n' % (redis.get('hits'),socket.gethostname()) 14 | 15 | 16 | if __name__ == "__main__": 17 | app.run(host="0.0.0.0", port=5000, debug=True) 18 | -------------------------------------------------------------------------------- /chapter6/labs/flask-redis/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | 5 | redis: 6 | image: redis 7 | 8 | web: 9 | build: 10 | context: . 11 | dockerfile: Dockerfile 12 | ports: 13 | - 8080:5000 14 | environment: 15 | REDIS_HOST: redis 16 | -------------------------------------------------------------------------------- /chapter6/labs/lb-scale/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:2.7 2 | LABEL maintaner="Peng Xiao xiaoquwl@gmail.com" 3 | COPY . /app 4 | WORKDIR /app 5 | RUN pip install flask redis 6 | EXPOSE 80 7 | CMD [ "python", "app.py" ] -------------------------------------------------------------------------------- /chapter6/labs/lb-scale/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | from redis import Redis 3 | import os 4 | import socket 5 | 6 | app = Flask(__name__) 7 | redis = Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379) 8 | 9 | 10 | @app.route('/') 11 | def hello(): 12 | redis.incr('hits') 13 | return 'Hello Container World! I have been seen %s times and my hostname is %s.\n' % (redis.get('hits'),socket.gethostname()) 14 | 15 | 16 | if __name__ == "__main__": 17 | app.run(host="0.0.0.0", port=80, debug=True) 18 | -------------------------------------------------------------------------------- /chapter6/labs/lb-scale/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | 5 | redis: 6 | image: redis 7 | 8 | web: 9 | build: 10 | context: . 11 | dockerfile: Dockerfile 12 | environment: 13 | REDIS_HOST: redis 14 | 15 | lb: 16 | image: dockercloud/haproxy 17 | links: 18 | - web 19 | ports: 20 | - 8080:80 21 | volumes: 22 | - /var/run/docker.sock:/var/run/docker.sock 23 | -------------------------------------------------------------------------------- /chapter6/labs/wordpress/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | 5 | wordpress: 6 | image: wordpress 7 | ports: 8 | - 8080:80 9 | environment: 10 | WORDPRESS_DB_HOST: mysql 11 | WORDPRESS_DB_PASSWORD: root 12 | networks: 13 | - my-bridge 14 | 15 | mysql: 16 | image: mysql 17 | environment: 18 | MYSQL_ROOT_PASSWORD: root 19 | MYSQL_DATABASE: wordpress 20 | volumes: 21 | - mysql-data:/var/lib/mysql 22 | networks: 23 | - my-bridge 24 | 25 | volumes: 26 | mysql-data: 27 | 28 | networks: 29 | my-bridge: 30 | driver: bridge -------------------------------------------------------------------------------- /chapter6/setup.sh: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | 3 | # install some tools 4 | sudo yum install -y git vim gcc glibc-static telnet 5 | 6 | # install docker 7 | curl -fsSL get.docker.com -o get-docker.sh 8 | sh get-docker.sh 9 | 10 | # start docker service 11 | sudo groupadd docker 12 | sudo gpasswd -a vagrant docker 13 | sudo systemctl start docker 14 | 15 | rm -rf get-docker.sh 16 | -------------------------------------------------------------------------------- /chapter7/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # RAFT 通俗解释 4 | 5 | http://thesecretlivesofdata.com/raft/ -------------------------------------------------------------------------------- /chapter7/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | Vagrant.require_version ">= 1.6.0" 5 | 6 | boxes = [ 7 | { 8 | :name => "swarm-manager", 9 | :eth1 => "192.168.205.10", 10 | :mem => "1024", 11 | :cpu => "1" 12 | }, 13 | { 14 | :name => "swarm-worker1", 15 | :eth1 => "192.168.205.11", 16 | :mem => "1024", 17 | :cpu => "1" 18 | }, 19 | { 20 | :name => "swarm-worker2", 21 | :eth1 => "192.168.205.12", 22 | :mem => "1024", 23 | :cpu => "1" 24 | } 25 | ] 26 | 27 | Vagrant.configure(2) do |config| 28 | 29 | config.vm.box = "centos/7" 30 | 31 | boxes.each do |opts| 32 | config.vm.define opts[:name] do |config| 33 | config.vm.hostname = opts[:name] 34 | config.vm.provider "vmware_fusion" do |v| 35 | v.vmx["memsize"] = opts[:mem] 36 | v.vmx["numvcpus"] = opts[:cpu] 37 | end 38 | 39 | config.vm.provider "virtualbox" do |v| 40 | v.customize ["modifyvm", :id, "--memory", opts[:mem]] 41 | v.customize ["modifyvm", :id, "--cpus", opts[:cpu]] 42 | end 43 | 44 | config.vm.network :private_network, ip: opts[:eth1] 45 | end 46 | end 47 | 48 | config.vm.synced_folder "./labs", "/home/vagrant/labs" 49 | config.vm.provision "shell", privileged: true, path: "./setup.sh" 50 | 51 | end 52 | -------------------------------------------------------------------------------- /chapter7/labs/secret-example/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | 5 | web: 6 | image: wordpress 7 | ports: 8 | - 8080:80 9 | secrets: 10 | - my-pw 11 | environment: 12 | WORDPRESS_DB_HOST: mysql 13 | WORDPRESS_DB_PASSWORD_FILE: /run/secrets/my-pw 14 | networks: 15 | - my-network 16 | depends_on: 17 | - mysql 18 | deploy: 19 | mode: replicated 20 | replicas: 3 21 | restart_policy: 22 | condition: on-failure 23 | delay: 5s 24 | max_attempts: 3 25 | update_config: 26 | parallelism: 1 27 | delay: 10s 28 | 29 | mysql: 30 | image: mysql 31 | secrets: 32 | - my-pw 33 | environment: 34 | MYSQL_ROOT_PASSWORD_FILE: /run/secrets/my-pw 35 | MYSQL_DATABASE: wordpress 36 | volumes: 37 | - mysql-data:/var/lib/mysql 38 | networks: 39 | - my-network 40 | deploy: 41 | mode: global 42 | placement: 43 | constraints: 44 | - node.role == manager 45 | 46 | volumes: 47 | mysql-data: 48 | 49 | networks: 50 | my-network: 51 | driver: overlay 52 | 53 | # secrets: 54 | # my-pw: 55 | # file: ./password -------------------------------------------------------------------------------- /chapter7/labs/secret-example/password: -------------------------------------------------------------------------------- 1 | adminadmin -------------------------------------------------------------------------------- /chapter7/labs/wordpress/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | 5 | web: 6 | image: wordpress 7 | ports: 8 | - 8080:80 9 | environment: 10 | WORDPRESS_DB_HOST: mysql 11 | WORDPRESS_DB_PASSWORD: root 12 | networks: 13 | - my-network 14 | depends_on: 15 | - mysql 16 | deploy: 17 | mode: replicated 18 | replicas: 3 19 | restart_policy: 20 | condition: on-failure 21 | delay: 5s 22 | max_attempts: 3 23 | update_config: 24 | parallelism: 1 25 | delay: 10s 26 | 27 | mysql: 28 | image: mysql 29 | environment: 30 | MYSQL_ROOT_PASSWORD: root 31 | MYSQL_DATABASE: wordpress 32 | volumes: 33 | - mysql-data:/var/lib/mysql 34 | networks: 35 | - my-network 36 | deploy: 37 | mode: global 38 | placement: 39 | constraints: 40 | - node.role == manager 41 | 42 | volumes: 43 | mysql-data: 44 | 45 | networks: 46 | my-network: 47 | driver: overlay -------------------------------------------------------------------------------- /chapter7/setup.sh: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | 3 | # install some tools 4 | sudo yum install -y git vim gcc glibc-static telnet bridge-utils 5 | 6 | # install docker 7 | curl -fsSL get.docker.com -o get-docker.sh 8 | sh get-docker.sh 9 | 10 | # start docker service 11 | sudo groupadd docker 12 | sudo gpasswd -a vagrant docker 13 | sudo systemctl start docker 14 | 15 | rm -rf get-docker.sh 16 | -------------------------------------------------------------------------------- /chapter8/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | Vagrant.require_version ">= 1.6.0" 5 | 6 | boxes = [ 7 | { 8 | :name => "docker-ee-manager", 9 | :eth1 => "192.168.205.50", 10 | :mem => "3072", 11 | :cpu => "1" 12 | }, 13 | { 14 | :name => "docker-ee-worker", 15 | :eth1 => "192.168.205.60", 16 | :mem => "3072", 17 | :cpu => "1" 18 | } 19 | 20 | ] 21 | 22 | Vagrant.configure(2) do |config| 23 | 24 | config.vm.box = "centos/7" 25 | boxes.each do |opts| 26 | config.vm.define opts[:name] do |config| 27 | config.vm.hostname = opts[:name] 28 | config.vm.provider "vmware_fusion" do |v| 29 | v.vmx["memsize"] = opts[:mem] 30 | v.vmx["numvcpus"] = opts[:cpu] 31 | end 32 | config.vm.provider "virtualbox" do |v| 33 | v.customize ["modifyvm", :id, "--memory", opts[:mem]] 34 | v.customize ["modifyvm", :id, "--cpus", opts[:cpu]] 35 | end 36 | config.vm.network :private_network, ip: opts[:eth1] 37 | end 38 | end 39 | config.vm.synced_folder "./labs", "/home/vagrant/labs" 40 | end 41 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | source = skeleton 3 | omit = 4 | skeleton/tests/* 5 | */__init__.py 6 | 7 | [report] 8 | exclude_lines = 9 | def __repr__ 10 | def __str__ 11 | def parse_args 12 | pragma: no cover 13 | raise NotImplementedError 14 | if __name__ == .__main__.: 15 | 16 | ignore_errors = True 17 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask stuff: 57 | instance/ 58 | .webassets-cache 59 | 60 | # Scrapy stuff: 61 | .scrapy 62 | 63 | # Sphinx documentation 64 | docs/_build/ 65 | 66 | # PyBuilder 67 | target/ 68 | 69 | # IPython Notebook 70 | .ipynb_checkpoints 71 | 72 | # pyenv 73 | .python-version 74 | 75 | # celery beat schedule file 76 | celerybeat-schedule 77 | 78 | # dotenv 79 | .env 80 | 81 | # virtualenv 82 | venv/ 83 | ENV/ 84 | 85 | # Spyder project settings 86 | .spyderproject 87 | 88 | # Rope project settings 89 | .ropeproject 90 | 91 | *.sqlite 92 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | variables: 2 | GIT_SSL_NO_VERIFY: "1" 3 | 4 | stages: 5 | - test 6 | - build 7 | - deploy 8 | 9 | pep8: 10 | stage: test 11 | image: python:2.7 12 | script: 13 | - pip install tox 14 | - tox -e pep8 15 | tags: 16 | - python27 17 | 18 | unittest-py27: 19 | stage: test 20 | image: python:2.7 21 | script: 22 | - pip install tox 23 | - tox -e py27 24 | tags: 25 | - python27 26 | 27 | unittest-py34: 28 | stage: test 29 | image: python:3.4 30 | script: 31 | - pip install tox 32 | - tox -e py34 33 | tags: 34 | - python34 35 | 36 | sphnix: 37 | stage: test 38 | image: python:2.7 39 | script: 40 | - pip install tox 41 | - tox -e docs 42 | tags: 43 | - python27 44 | 45 | build: 46 | stage: build 47 | tags: 48 | - shell 49 | script: 50 | - docker build -t skeleton . 51 | only: 52 | - master 53 | 54 | deploy: 55 | stage: deploy 56 | tags: 57 | - shell 58 | script: 59 | - scripts/deploy.sh 60 | - export 61 | only: 62 | - master 63 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Hacking Guide 2 | 3 | ## Code style 4 | 5 | Step 1: Read http://www.python.org/dev/peps/pep-0008/ 6 | 7 | Step 2: Read http://www.python.org/dev/peps/pep-0008/ again 8 | 9 | Step 3: Read on 10 | 11 | ## Running Tests 12 | 13 | Run tox 14 | 15 | ``` 16 | $ cd skeleton 17 | $ tox 18 | ``` 19 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:2.7 2 | 3 | MAINTAINER Peng Xiao 4 | 5 | COPY . /skeleton 6 | WORKDIR /skeleton 7 | RUN pip install -r requirements.txt 8 | EXPOSE 5050 9 | ENTRYPOINT ["scripts/dev.sh"] 10 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2016 Michael Herman 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/README.md: -------------------------------------------------------------------------------- 1 | [![build status](https://gitlab-demo.com/Demo/flask-skeleton/badges/master/build.svg)](https://gitlab-demo.com/Demo/flask-skeleton/commits/master) 2 | [![coverage report](https://gitlab-demo.com/Demo/flask-skeleton/badges/master/coverage.svg)](https://gitlab-demo.com/Demo/flask-skeleton/commits/master) 3 | 4 | 5 | # Flask Skeleton 6 | 7 | Flask starter project... 8 | 9 | ## Quick Start 10 | 11 | ### Basics 12 | 13 | 1. Activate a virtualenv 14 | 1. Install the requirements 15 | 16 | ### Set Environment Variables 17 | 18 | Update *skeleton/server/config.py*, and then run: 19 | 20 | ```sh 21 | $ export APP_SETTINGS="skeleton.server.config.DevelopmentConfig" 22 | ``` 23 | 24 | or 25 | 26 | ```sh 27 | $ export APP_SETTINGS="skeleton.server.config.ProductionConfig" 28 | ``` 29 | 30 | ### Create DB 31 | 32 | ```sh 33 | $ python manage.py create_db 34 | $ python manage.py db init 35 | $ python manage.py db migrate 36 | $ python manage.py create_admin 37 | $ python manage.py create_data 38 | ``` 39 | 40 | ### Run the Application 41 | 42 | ```sh 43 | $ python manage.py runserver 44 | ``` 45 | 46 | So access the application at the address [http://localhost:5000/](http://localhost:5000/) 47 | 48 | > Want to specify a different port? 49 | 50 | > ```sh 51 | > $ python manage.py runserver -h 0.0.0.0 -p 8080 52 | > ``` 53 | 54 | ### Testing1 55 | 56 | ``` 57 | $ tox 58 | ``` 59 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/doc/source/_static/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter8/labs/flask-skeleton/doc/source/_static/.placeholder -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/doc/source/_templates/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter8/labs/flask-skeleton/doc/source/_templates/.placeholder -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/doc/source/index.rst: -------------------------------------------------------------------------------- 1 | .. yacore documentation master file, created by 2 | sphinx-quickstart on Mon Aug 1 21:41:36 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to yacore's documentation! 7 | ================================== 8 | 9 | This is a test line 10 | test again 11 | test 12 | Contents: 13 | 14 | .. toctree:: 15 | :maxdepth: 2 16 | 17 | 18 | 19 | Indices and tables 20 | ================== 21 | 22 | * :ref:`genindex` 23 | * :ref:`modindex` 24 | * :ref:`search` 25 | 26 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/manage.py: -------------------------------------------------------------------------------- 1 | # manage.py 2 | 3 | import unittest 4 | 5 | from flask_script import Manager 6 | from flask_migrate import Migrate, MigrateCommand 7 | 8 | from skeleton.server import app, db 9 | from skeleton.server.models import User 10 | 11 | 12 | migrate = Migrate(app, db) 13 | manager = Manager(app) 14 | 15 | # migrations 16 | manager.add_command('db', MigrateCommand) 17 | 18 | 19 | @manager.command 20 | def test(): 21 | """Runs the unit tests without coverage.""" 22 | tests = unittest.TestLoader().discover('tests', pattern='test*.py') 23 | result = unittest.TextTestRunner(verbosity=2).run(tests) 24 | if result.wasSuccessful(): 25 | return 0 26 | else: 27 | return 1 28 | 29 | 30 | @manager.command 31 | def create_db(): 32 | """Creates the db tables.""" 33 | db.create_all() 34 | 35 | 36 | @manager.command 37 | def drop_db(): 38 | """Drops the db tables.""" 39 | db.drop_all() 40 | 41 | 42 | @manager.command 43 | def create_admin(): 44 | """Creates the admin user.""" 45 | db.session.add(User(email='admin@cisco.com', password='admin', admin=True)) 46 | db.session.commit() 47 | 48 | 49 | @manager.command 50 | def create_data(): 51 | """Creates sample data.""" 52 | pass 53 | 54 | 55 | if __name__ == '__main__': 56 | manager.run() 57 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/migrations/README: -------------------------------------------------------------------------------- 1 | Generic single-database configuration. -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/migrations/alembic.ini: -------------------------------------------------------------------------------- 1 | # A generic, single database configuration. 2 | 3 | [alembic] 4 | # template used to generate migration files 5 | # file_template = %%(rev)s_%%(slug)s 6 | 7 | # set to 'true' to run the environment during 8 | # the 'revision' command, regardless of autogenerate 9 | # revision_environment = false 10 | 11 | 12 | # Logging configuration 13 | [loggers] 14 | keys = root,sqlalchemy,alembic 15 | 16 | [handlers] 17 | keys = console 18 | 19 | [formatters] 20 | keys = generic 21 | 22 | [logger_root] 23 | level = WARN 24 | handlers = console 25 | qualname = 26 | 27 | [logger_sqlalchemy] 28 | level = WARN 29 | handlers = 30 | qualname = sqlalchemy.engine 31 | 32 | [logger_alembic] 33 | level = INFO 34 | handlers = 35 | qualname = alembic 36 | 37 | [handler_console] 38 | class = StreamHandler 39 | args = (sys.stderr,) 40 | level = NOTSET 41 | formatter = generic 42 | 43 | [formatter_generic] 44 | format = %(levelname)-5.5s [%(name)s] %(message)s 45 | datefmt = %H:%M:%S 46 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = ${repr(up_revision)} 11 | down_revision = ${repr(down_revision)} 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | ${imports if imports else ""} 16 | 17 | def upgrade(): 18 | ${upgrades if upgrades else "pass"} 19 | 20 | 21 | def downgrade(): 22 | ${downgrades if downgrades else "pass"} 23 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/requirements.txt: -------------------------------------------------------------------------------- 1 | alembic==0.8.6 2 | bcrypt==3.1.0 3 | blinker==1.4 4 | cffi==1.7.0 5 | click==6.6 6 | dominate==2.2.1 7 | Flask==0.10.1 8 | Flask-Bcrypt==0.7.1 9 | Flask-Bootstrap==3.3.6.0 10 | Flask-DebugToolbar==0.10.0 11 | Flask-Login==0.3.2 12 | Flask-Migrate==1.8.1 13 | Flask-Script==2.0.5 14 | Flask-SQLAlchemy==2.1 15 | Flask-WTF==0.12 16 | itsdangerous==0.24 17 | Jinja2==2.8 18 | Mako==1.0.4 19 | MarkupSafe==0.23 20 | pycparser==2.14 21 | python-editor==1.0.1 22 | six==1.10.0 23 | SQLAlchemy==1.0.14 24 | visitor==0.1.3 25 | Werkzeug==0.11.10 26 | WTForms==2.1 27 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/scripts/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | docker ps -a | grep penxiao_skeleton | awk '{print$1}' | xargs docker stop 4 | docker ps -a | grep penxiao_skeleton | awk '{print$1}' | xargs docker rm 5 | docker run -d -p 80:5000 --name penxiao_skeleton skeleton 6 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/scripts/dev.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | export APP_SETTINGS="skeleton.server.config.ProductionConfig" 4 | python manage.py create_db 5 | python manage.py create_admin 6 | python manage.py create_data 7 | python manage.py runserver -h 0.0.0.0 8 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/skeleton/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter8/labs/flask-skeleton/skeleton/__init__.py -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/skeleton/client/static/main.css: -------------------------------------------------------------------------------- 1 | /* custom css */ 2 | 3 | .site-content { 4 | padding-top: 75px; 5 | } -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/skeleton/client/static/main.js: -------------------------------------------------------------------------------- 1 | // custom javascript 2 | 3 | $( document ).ready(function() { 4 | console.log('Sanity Check!'); 5 | }); -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/skeleton/client/templates/errors/401.html: -------------------------------------------------------------------------------- 1 | {% extends "_base.html" %} 2 | 3 | {% block page_title %}- Unauthorized{% endblock %} 4 | 5 | {% block content %} 6 |
7 |
8 |

401

9 |

You are not authorized to view this page. Please log in.

10 |
11 |
12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/skeleton/client/templates/errors/403.html: -------------------------------------------------------------------------------- 1 | {% extends "_base.html" %} 2 | 3 | {% block page_title %}- Unauthorized{% endblock %} 4 | 5 | {% block content %} 6 |
7 |
8 |

401

9 |

You are not authorized to view this page. Please log in.

10 |
11 |
12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/skeleton/client/templates/errors/404.html: -------------------------------------------------------------------------------- 1 | {% extends "_base.html" %} 2 | 3 | {% block page_title %}- Page Not Found{% endblock %} 4 | 5 | {% block content %} 6 |
7 |
8 |

404

9 |

Sorry. The requested page doesn't exist. Go home.

10 |
11 |
12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/skeleton/client/templates/errors/500.html: -------------------------------------------------------------------------------- 1 | {% extends "_base.html" %} 2 | 3 | {% block page_title %}- Server Error{% endblock %} 4 | 5 | {% block content %} 6 |
7 |
8 |

500

9 |

Sorry. Something went terribly wrong. Go home.

10 |
11 |
12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/skeleton/client/templates/footer.html: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/skeleton/client/templates/header.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/skeleton/client/templates/main/about.html: -------------------------------------------------------------------------------- 1 | {% extends "_base.html" %} 2 | 3 | {% block content %} 4 | 5 |
6 |
7 |

About

8 |
9 |
10 | 11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/skeleton/client/templates/main/home.html: -------------------------------------------------------------------------------- 1 | {% extends "_base.html" %} 2 | 3 | {% block content %} 4 | 5 |
6 |
7 |

Welcome!

8 |
9 |
10 | 11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/skeleton/client/templates/user/login.html: -------------------------------------------------------------------------------- 1 | {% extends '_base.html' %} 2 | {% import "bootstrap/wtf.html" as wtf %} 3 | 4 | {% block content %} 5 | 6 |
7 |

Please login

8 |
9 | 10 |
11 | 12 | 13 |
14 | 15 | {{ form.csrf_token }} 16 | {{ form.hidden_tag() }} 17 | {{ wtf.form_errors(form, hiddens="only") }} 18 | 19 | 20 |
21 | 22 | {{ wtf.form_field(form.email) }} 23 | {{ wtf.form_field(form.password) }} 24 | 25 | 26 |

27 |

Need to Register?

28 |
29 | 30 |
31 | 32 | 33 | {% endblock content %} 34 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/skeleton/client/templates/user/members.html: -------------------------------------------------------------------------------- 1 | {% extends "_base.html" %} 2 | {% block content %} 3 |

Welcome, {{ current_user.email }}!

4 |

This is the members-only page :)

5 | {% endblock %} 6 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/skeleton/client/templates/user/register.html: -------------------------------------------------------------------------------- 1 | {% extends '_base.html' %} 2 | {% import "bootstrap/wtf.html" as wtf %} 3 | 4 | {% block content %} 5 | 6 |
7 |

Please Register

8 |
9 | 10 |
11 | 12 | 13 |
14 | 15 | {{ form.csrf_token }} 16 | {{ form.hidden_tag() }} 17 | {{ wtf.form_errors(form, hiddens="only") }} 18 | 19 | 20 |
21 | 22 | {{ wtf.form_field(form.email) }} 23 | {{ wtf.form_field(form.password) }} 24 | {{ wtf.form_field(form.confirm) }} 25 | 26 | 27 |

28 |

Already have an account? Sign in.

29 | 30 |
31 | 32 |
33 | 34 | 35 | {% endblock content %} 36 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/skeleton/server/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | 4 | import os 5 | 6 | from flask import Flask, render_template 7 | from flask_login import LoginManager 8 | from flask_bcrypt import Bcrypt 9 | from flask_debugtoolbar import DebugToolbarExtension 10 | from flask_bootstrap import Bootstrap 11 | from flask_sqlalchemy import SQLAlchemy 12 | 13 | 14 | app = Flask( 15 | __name__, 16 | template_folder='../client/templates', 17 | static_folder='../client/static' 18 | ) 19 | 20 | app_settings = os.getenv('APP_SETTINGS', 'skeleton.server.config.DevelopmentConfig') 21 | app.config.from_object(app_settings) 22 | 23 | login_manager = LoginManager() 24 | login_manager.init_app(app) 25 | bcrypt = Bcrypt(app) 26 | toolbar = DebugToolbarExtension(app) 27 | bootstrap = Bootstrap(app) 28 | db = SQLAlchemy(app) 29 | 30 | from skeleton.server.user.views import user_blueprint 31 | from skeleton.server.main.views import main_blueprint 32 | app.register_blueprint(user_blueprint) 33 | app.register_blueprint(main_blueprint) 34 | 35 | from skeleton.server.models import User 36 | 37 | login_manager.login_view = "user.login" 38 | login_manager.login_message_category = 'danger' 39 | 40 | 41 | @login_manager.user_loader 42 | def load_user(user_id): 43 | return User.query.filter(User.id == int(user_id)).first() 44 | 45 | 46 | @app.errorhandler(401) 47 | def forbidden_page_401(error): 48 | return render_template("errors/401.html"), 401 49 | 50 | 51 | @app.errorhandler(403) 52 | def forbidden_page_403(error): 53 | return render_template("errors/403.html"), 403 54 | 55 | 56 | @app.errorhandler(404) 57 | def page_not_found(error): 58 | return render_template("errors/404.html"), 404 59 | 60 | 61 | @app.errorhandler(500) 62 | def server_error_page(error): 63 | return render_template("errors/500.html"), 500 64 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/skeleton/server/config.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | 4 | import os 5 | basedir = os.path.abspath(os.path.dirname(__file__)) 6 | 7 | 8 | class BaseConfig(object): 9 | """Base configuration.""" 10 | SECRET_KEY = 'my_precious' 11 | DEBUG = False 12 | BCRYPT_LOG_ROUNDS = 13 13 | WTF_CSRF_ENABLED = True 14 | DEBUG_TB_ENABLED = False 15 | DEBUG_TB_INTERCEPT_REDIRECTS = False 16 | SQLALCHEMY_TRACK_MODIFICATIONS = False 17 | SQLALCHEMY_DATABASE_URI = os.environ.get( 18 | 'DATABASE_URL', 'sqlite:///' + os.path.join(basedir, 'db.sqlite')) 19 | 20 | 21 | class DevelopmentConfig(BaseConfig): 22 | """Development configuration.""" 23 | DEBUG = True 24 | BCRYPT_LOG_ROUNDS = 4 25 | WTF_CSRF_ENABLED = False 26 | DEBUG_TB_ENABLED = True 27 | 28 | 29 | class TestingConfig(BaseConfig): 30 | """Testing configuration.""" 31 | DEBUG = True 32 | TESTING = True 33 | BCRYPT_LOG_ROUNDS = 4 34 | WTF_CSRF_ENABLED = False 35 | DEBUG_TB_ENABLED = False 36 | PRESERVE_CONTEXT_ON_EXCEPTION = False 37 | 38 | 39 | class ProductionConfig(BaseConfig): 40 | """Production configuration.""" 41 | SECRET_KEY = 'my_precious' 42 | DEBUG = False 43 | DEBUG_TB_ENABLED = False 44 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/skeleton/server/main/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter8/labs/flask-skeleton/skeleton/server/main/__init__.py -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/skeleton/server/main/views.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | 4 | from flask import render_template, Blueprint 5 | 6 | main_blueprint = Blueprint('main', __name__,) 7 | 8 | 9 | @main_blueprint.route('/') 10 | def home(): 11 | return render_template('main/home.html') 12 | 13 | 14 | @main_blueprint.route("/about/") 15 | def about(): 16 | return render_template("main/about.html") 17 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/skeleton/server/models.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | 4 | import datetime 5 | 6 | from skeleton.server import app, db, bcrypt 7 | 8 | 9 | class User(db.Model): 10 | 11 | __tablename__ = "users" 12 | 13 | id = db.Column(db.Integer, primary_key=True, autoincrement=True) 14 | email = db.Column(db.String(255), unique=True, nullable=False) 15 | password = db.Column(db.String(255), nullable=False) 16 | registered_on = db.Column(db.DateTime, nullable=False) 17 | admin = db.Column(db.Boolean, nullable=False, default=False) 18 | 19 | def __init__(self, email, password, admin=False): 20 | self.email = email 21 | self.password = bcrypt.generate_password_hash( 22 | password, app.config.get('BCRYPT_LOG_ROUNDS') 23 | ) 24 | self.registered_on = datetime.datetime.now() 25 | self.admin = admin 26 | 27 | def is_authenticated(self): 28 | return True 29 | 30 | def is_active(self): 31 | return True 32 | 33 | def is_anonymous(self): 34 | return False 35 | 36 | def get_id(self): 37 | return self.id 38 | 39 | def __repr__(self): 40 | return ''.format(self.email) 41 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/skeleton/server/user/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter8/labs/flask-skeleton/skeleton/server/user/__init__.py -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/skeleton/server/user/forms.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | 4 | from flask_wtf import Form 5 | from wtforms import StringField, PasswordField 6 | from wtforms.validators import DataRequired, Email, Length, EqualTo 7 | 8 | 9 | class LoginForm(Form): 10 | email = StringField('Email Address', [DataRequired(), Email()]) 11 | password = PasswordField('Password', [DataRequired()]) 12 | 13 | 14 | class RegisterForm(Form): 15 | email = StringField( 16 | 'Email Address', 17 | validators=[DataRequired(), Email(message=None), Length(min=6, max=40)]) 18 | password = PasswordField( 19 | 'Password', 20 | validators=[DataRequired(), Length(min=6, max=25)] 21 | ) 22 | confirm = PasswordField( 23 | 'Confirm password', 24 | validators=[ 25 | DataRequired(), 26 | EqualTo('password', message='Passwords must match.') 27 | ] 28 | ) 29 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/test-requirements.txt: -------------------------------------------------------------------------------- 1 | flake8==2.4.0 2 | Flask-Testing==0.4.2 3 | discover 4 | nose 5 | coverage==4.0.3 6 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter8/labs/flask-skeleton/tests/__init__.py -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/tests/base.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | 4 | from flask_testing import TestCase 5 | 6 | from skeleton.server import app, db 7 | from skeleton.server.models import User 8 | 9 | 10 | class BaseTestCase(TestCase): 11 | 12 | def create_app(self): 13 | app.config.from_object('skeleton.server.config.TestingConfig') 14 | return app 15 | 16 | def setUp(self): 17 | db.create_all() 18 | user = User(email="ad@min.com", password="admin_user") 19 | db.session.add(user) 20 | db.session.commit() 21 | 22 | def tearDown(self): 23 | db.session.remove() 24 | db.drop_all() 25 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/tests/test_main.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Cisco Systems, Inc. 2 | # All rights reserved. 3 | 4 | import unittest 5 | 6 | from base import BaseTestCase 7 | 8 | 9 | class TestMainBlueprint(BaseTestCase): 10 | 11 | def test_index(self): 12 | # Ensure Flask is setup. 13 | response = self.client.get('/', follow_redirects=True) 14 | self.assertEqual(response.status_code, 200) 15 | self.assertIn(b'Welcome!', response.data) 16 | self.assertIn(b'Register/Login', response.data) 17 | 18 | def test_footer(self): 19 | response = self.client.get('/', follow_redirects=True) 20 | self.assertEqual(response.status_code, 200) 21 | self.assertIn(b'GitLab Demo', response.data) 22 | 23 | def test_about(self): 24 | # Ensure about route behaves correctly. 25 | response = self.client.get('/about', follow_redirects=True) 26 | self.assertEqual(response.status_code, 200) 27 | self.assertIn(b'About', response.data) 28 | 29 | def test_404(self): 30 | # Ensure 404 error is handled. 31 | response = self.client.get('/404') 32 | self.assert404(response) 33 | self.assertTemplateUsed('errors/404.html') 34 | 35 | 36 | if __name__ == '__main__': 37 | unittest.main() 38 | -------------------------------------------------------------------------------- /chapter8/labs/flask-skeleton/tox.ini: -------------------------------------------------------------------------------- 1 | # Tox (http://tox.testrun.org/) is a tool for running tests 2 | # in multiple virtualenvs. This configuration file will run the 3 | # test suite on all supported python versions. To use it, "pip install tox" 4 | # and then run "tox" from this directory. 5 | 6 | [tox] 7 | # List the environment that will be run by default 8 | minversion = 1.6 9 | envlist = py27, py34, pep8, docs 10 | skipsdist = True 11 | 12 | [testenv] 13 | setenv = VIRTUAL_ENV={envdir} 14 | LANG=en_US.UTF-8 15 | LANGUAGE=en_US:en 16 | LC_ALL=C 17 | 18 | [testenv:py27] 19 | deps = -r{toxinidir}/test-requirements.txt 20 | -r{toxinidir}/requirements.txt 21 | 22 | 23 | commands = 24 | coverage run manage.py test 25 | coverage report -m 26 | 27 | [testenv:py34] 28 | deps = -r{toxinidir}/test-requirements.txt 29 | -r{toxinidir}/requirements.txt 30 | 31 | commands = 32 | coverage run manage.py test 33 | coverage report -m 34 | 35 | [testenv:pep8] 36 | sitepackages = False 37 | deps = -r{toxinidir}/test-requirements.txt 38 | commands = 39 | flake8 {posargs} 40 | 41 | [flake8] 42 | # E712 is ignored on purpose, since it is normal to use 'column == true' 43 | # in sqlalchemy. 44 | # H803 skipped on purpose per list discussion. 45 | # E125 is deliberately excluded. See https://github.com/jcrocholl/pep8/issues/126 46 | # The rest of the ignores are TODOs 47 | # New from hacking 0.9: E129, E131, E265, E713, H407, H405, H904 48 | # Stricter in hacking 0.9: F402 49 | # E251 Skipped due to https://github.com/jcrocholl/pep8/issues/301 50 | 51 | max-line-length=120 52 | exclude = .venv,.git,.tox,dist,doc,*lib/python*,*egg,build,tools 53 | 54 | [testenv:docs] 55 | deps= 56 | sphinx 57 | sphinx_rtd_theme 58 | commands = sphinx-build -W -b html doc/source doc/build 59 | -------------------------------------------------------------------------------- /chapter9/gif/k8s-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter9/gif/k8s-dashboard.png -------------------------------------------------------------------------------- /chapter9/labs/deployment/deployment_nginx.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: nginx-deployment 5 | labels: 6 | app: nginx 7 | spec: 8 | replicas: 3 9 | selector: 10 | matchLabels: 11 | app: nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: nginx 16 | spec: 17 | containers: 18 | - name: nginx 19 | image: nginx:1.12.2 20 | ports: 21 | - containerPort: 80 -------------------------------------------------------------------------------- /chapter9/labs/pod-basic/README.md: -------------------------------------------------------------------------------- 1 | # Pod 基础 2 | 3 | ``` 4 | $ kubectl get pods # 获取所有正在运行的POD 5 | $ kubectl get pods -o wide # 获取pod的更多信息,比如在哪台k8s机器上 6 | $ kubectl describe pod #获取一个POD的详细信息 7 | $ kubectl exec #在pod里的container里执行一个命令,如果这个pod有多个container,默认会在第一个里执行,或者通过-c去指定哪个 8 | 9 | ``` -------------------------------------------------------------------------------- /chapter9/labs/pod-basic/pod_busybox.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: busybox 5 | labels: 6 | app: busybox 7 | spec: 8 | containers: 9 | - name: busybox 10 | image: busybox 11 | 12 | -------------------------------------------------------------------------------- /chapter9/labs/pod-basic/pod_nginx.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: nginx 5 | labels: 6 | app: nginx 7 | spec: 8 | containers: 9 | - name: nginx 10 | image: nginx 11 | ports: 12 | - containerPort: 80 13 | -------------------------------------------------------------------------------- /chapter9/labs/replicas-set/rc_nginx.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ReplicationController 3 | metadata: 4 | name: nginx 5 | spec: 6 | replicas: 3 7 | selector: 8 | app: nginx 9 | template: 10 | metadata: 11 | name: nginx 12 | labels: 13 | app: nginx 14 | spec: 15 | containers: 16 | - name: nginx 17 | image: nginx 18 | ports: 19 | - containerPort: 80 20 | -------------------------------------------------------------------------------- /chapter9/labs/replicas-set/rs_nginx.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: ReplicaSet 3 | metadata: 4 | name: nginx 5 | labels: 6 | tier: frontend 7 | spec: 8 | replicas: 3 9 | selector: 10 | matchLabels: 11 | tier: frontend 12 | template: 13 | metadata: 14 | name: nginx 15 | labels: 16 | tier: frontend 17 | spec: 18 | containers: 19 | - name: nginx 20 | image: nginx 21 | ports: 22 | - containerPort: 80 23 | -------------------------------------------------------------------------------- /chapter9/labs/services/pod_busybox.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: busybox-pod 5 | labels: 6 | app: busybox 7 | spec: 8 | containers: 9 | - name: busybox-container 10 | image: busybox 11 | command: 12 | - sleep 13 | - "360000" -------------------------------------------------------------------------------- /chapter9/labs/services/pod_nginx.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: nginx-pod 5 | labels: 6 | app: nginx 7 | spec: 8 | containers: 9 | - name: nginx-container 10 | image: nginx 11 | ports: 12 | - name: nginx-port 13 | containerPort: 80 14 | -------------------------------------------------------------------------------- /chapter9/labs/services/service_nginx.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: nginx-service 5 | spec: 6 | ports: 7 | - port: 8080 8 | nodePort: 8080 9 | targetPort: nginx-port 10 | protocol: TCP 11 | selector: 12 | app: nginx 13 | type: NodePort -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/README.md: -------------------------------------------------------------------------------- 1 | Please follow the instructions for setting up Tectonic Sandbox at https://coreos.com/tectonic/sandbox 2 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/config-controller-1.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/config-controller-1.img -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/config-controller-1.vmdk: -------------------------------------------------------------------------------- 1 | # Disk DescriptorFile 2 | version=1 3 | CID=63dd1752 4 | parentCID=ffffffff 5 | createType="fullDevice" 6 | 7 | # Extent description 8 | RW 3000 FLAT "config-controller-1.img" 0 9 | 10 | # The disk Data Base 11 | #DDB 12 | 13 | ddb.virtualHWVersion = "4" 14 | ddb.adapterType="ide" 15 | ddb.geometry.cylinders="2" 16 | ddb.geometry.heads="16" 17 | ddb.geometry.sectors="63" 18 | ddb.uuid.image="814fbd0a-b9b3-4200-9896-b1539afccb58" 19 | ddb.uuid.parent="00000000-0000-0000-0000-000000000000" 20 | ddb.uuid.modification="00000000-0000-0000-0000-000000000000" 21 | ddb.uuid.parentmodification="00000000-0000-0000-0000-000000000000" 22 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/config-worker-1.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wujihua/docker-k8s-devops-master/16de7380c62b7ec3d7c9798b3c0b8b84ecfc222c/chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/config-worker-1.img -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/config-worker-1.vmdk: -------------------------------------------------------------------------------- 1 | # Disk DescriptorFile 2 | version=1 3 | CID=2d92ed7a 4 | parentCID=ffffffff 5 | createType="fullDevice" 6 | 7 | # Extent description 8 | RW 3000 FLAT "config-worker-1.img" 0 9 | 10 | # The disk Data Base 11 | #DDB 12 | 13 | ddb.virtualHWVersion = "4" 14 | ddb.adapterType="ide" 15 | ddb.geometry.cylinders="2" 16 | ddb.geometry.heads="16" 17 | ddb.geometry.sectors="63" 18 | ddb.uuid.image="78cca7b8-3199-46ea-b77f-c2c347dbaccf" 19 | ddb.uuid.parent="00000000-0000-0000-0000-000000000000" 20 | ddb.uuid.modification="00000000-0000-0000-0000-000000000000" 21 | ddb.uuid.parentmodification="00000000-0000-0000-0000-000000000000" 22 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/etc/ssl/etcd/ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDbjCCAlagAwIBAgICNIIwDQYJKoZIhvcNAQELBQAwWDEJMAcGA1UEBhMAMQkw 3 | BwYDVQQIDAAxCTAHBgNVBAcMADEJMAcGA1UEEQwAMQ0wCwYDVQQKDARldGNkMQkw 4 | BwYDVQQLDAAxEDAOBgNVBAMMB2V0Y2QtY2EwHhcNMTgwMzExMTAzNDM0WhcNMTkw 5 | MzExMTAzNDM0WjBYMQkwBwYDVQQGEwAxCTAHBgNVBAgMADEJMAcGA1UEBwwAMQkw 6 | BwYDVQQRDAAxDTALBgNVBAoMBGV0Y2QxCTAHBgNVBAsMADEQMA4GA1UEAwwHZXRj 7 | ZC1jYTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMiXu+bGHnbHIVaG 8 | 7rpBPdHfHjL0vxb9PuTDGhZM+WrqydIp7+2Ulb/XXm3oC5a5qojpVaxeZaMq5LGR 9 | 0GfWOKWTOoCzBgTIhRNZ3uBzoE7aDffX1oNnMR4zaKaaspwzWJLwbUWWNTiITvRl 10 | SnXGCt8Gvk09opJT1+I5GB/jDTjR1nzsvt68OHqdV1aAzp89R6EUtSM0gPgFZWc5 11 | phlLkVYBzKKi0rgVUiYp+gI0EszySvKllPX4glIEJkBtkbGoNWE29fI4htiA2/2w 12 | 7qsF6DxCgRjMwZ27EVYI66t43GZi0mFtyCaQySkWArp5AaLlbBC9qIurxkB0LOVt 13 | mNLiBU0CAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgKkMA8GA1UdEwEB/wQFMAMBAf8w 14 | HQYDVR0OBBYEFBIBQl9Udcxhq5KSR/SZfrJNs1dqMA0GCSqGSIb3DQEBCwUAA4IB 15 | AQAJICPz6LDlnuHM6Z9MJWu/9aN6H4+XgYRYP823Hiqw4c5B/E8oaEGr53I+/cBN 16 | 6bQsjBctamsvZKDKm1A3kAuIYptpAj/eXJe60yGZ6NWBlqgybEmteRTeD2NTUe5s 17 | BWesyTNBcWa3uCsOxTM9yTI/oPw5ftknH+t24apSzWKMG/DS2lq/sdBtKPKwSJfx 18 | n8hN+ZpPP7CJnLVgK5g/UywpNexnHSQ3YSpxfW7EDAZgJh9VaSJpBtcO+pcgSnVb 19 | dpyuDNLyiQZ7wdVHPQ0tkf/m+fC4a0xx9BPXgn05fD78D7Mt3UueSvYBLoYqzxkJ 20 | +diJ7jsaZCWIUUhFSeWxPK9X 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/etc/ssl/etcd/peer.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIEBzCCAu+gAwIBAgIDAIk1MA0GCSqGSIb3DQEBCwUAMFgxCTAHBgNVBAYTADEJ 3 | MAcGA1UECAwAMQkwBwYDVQQHDAAxCTAHBgNVBBEMADENMAsGA1UECgwEZXRjZDEJ 4 | MAcGA1UECwwAMRAwDgYDVQQDDAdldGNkLWNhMB4XDTE4MDMxMTEwMzQzNVoXDTE5 5 | MDMxMTEwMzQzNVowVTEJMAcGA1UEBhMAMQkwBwYDVQQIDAAxCTAHBgNVBAcMADEJ 6 | MAcGA1UEEQwAMQ0wCwYDVQQKDARldGNkMQkwBwYDVQQLDAAxDTALBgNVBAMMBGV0 7 | Y2QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDQ4gDCFzqwd9iEVnQk 8 | 7jqjmbMmjnl6dQLPGhgphnT6sHWp6A03D4rNAE8Qf7ygqK+WLDQkh7BPFvhoTCCL 9 | j8tqGEZAK+qHruPZH/5CbE7x+5oos+0OXm07p8s5hsYFkJ/RjSLNtAeOnP0HJdiQ 10 | e/T5bDUEv70diRHzGau6i1k8wJIHAxQdy0Ebf++gVGNzC2wWJ8WNdZogzb3mii5l 11 | uwiNvJ7jdi+ajzVoBUakbxycXjBD9BxLfOUf3OhMAdGxhBvF+ezkc/E3eMhffM89 12 | 3wSVAo03i78k8XBF9KsSmzlgTNoHj2vcx6A8oSOmGRTmPN1qhJAqD/CT3BfDIFVZ 13 | uSohAgMBAAGjgdwwgdkwDgYDVR0PAQH/BAQDAgUgMCAGA1UdJQEB/wQWMBQGCCsG 14 | AQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFBIBQl9U 15 | dcxhq5KSR/SZfrJNs1dqMHYGA1UdEQRvMG2CKSoua3ViZS1ldGNkLmt1YmUtc3lz 16 | dGVtLnN2Yy5jbHVzdGVyLmxvY2Fsgi5rdWJlLWV0Y2QtY2xpZW50Lmt1YmUtc3lz 17 | dGVtLnN2Yy5jbHVzdGVyLmxvY2FshwSsEQRlhwQKAwAPhwQKAwAUMA0GCSqGSIb3 18 | DQEBCwUAA4IBAQAwGPG8eRmD0HSqwSIcHZ8NI73FjUWHTikP8I9BDorW9Jk9n18g 19 | DFxXUkKOZSR3u3EeSQYLuohcvfL810nnGB5+uXqvnZAGo04Vu+wuCT/RmOB0OQd0 20 | EobIPrTUdwSmakUZHbndmi76I9r9B3VtmrLtjmDIY8F1GTltUnSBU4nU3nG+ThCy 21 | 3WmuCwpEYigum3zdlwp+KZ69m2fx3/7aa1v5ms1h9fBYtgjvyoeUaqYt92UOitaH 22 | xiUU5fwyxa4Ue/OXulSpam9vrhWE3VrSxd5DJ76aj9rRvI/XQgtu9Z+xwned8WWX 23 | 7eTiLzqh26EjgbhtFEOBWL6frPT1zWbkQKS4 24 | -----END CERTIFICATE----- 25 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/etc/ssl/etcd/peer.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEA0OIAwhc6sHfYhFZ0JO46o5mzJo55enUCzxoYKYZ0+rB1qegN 3 | Nw+KzQBPEH+8oKivliw0JIewTxb4aEwgi4/LahhGQCvqh67j2R/+QmxO8fuaKLPt 4 | Dl5tO6fLOYbGBZCf0Y0izbQHjpz9ByXYkHv0+Ww1BL+9HYkR8xmruotZPMCSBwMU 5 | HctBG3/voFRjcwtsFifFjXWaIM295oouZbsIjbye43Yvmo81aAVGpG8cnF4wQ/Qc 6 | S3zlH9zoTAHRsYQbxfns5HPxN3jIX3zPPd8ElQKNN4u/JPFwRfSrEps5YEzaB49r 7 | 3MegPKEjphkU5jzdaoSQKg/wk9wXwyBVWbkqIQIDAQABAoIBABOr9R5SSbis0LtF 8 | 2RJRTTxzESgkatRZiLYwYu4mN4YUcEBcFkKFODEuQkPvg7gtqrud1htKnBQWubY4 9 | 1SfPlvya5KLOf/vfQJ4GIU/oG1c2tsH2j/C2e9sOZlk4lBWaFTMK86gjuEJ6DmpJ 10 | 6idRRTToN+YGmKzbZ9FZLY8X6IOMA4MlS3BMY2wRtz+xG3vM5iT0Epltnce/5DLE 11 | 4VwT7fuBLZdqM0mjB9VaQtrF43BpKVJTIvbXegrS5Rn5hgUfOZJToSGyTvmCztmg 12 | JuQARmmjZb87igYvlTFBBNtW6YQlNo0MJBkwgZJ9KbdJ1woOd2K/RJgSeU6ZE67D 13 | z6lLmUECgYEA+ll2UcQt4SqFSInKivLUElfH5FKHkVG9II8qyafMe+TPCjolKLrh 14 | BuTAcWP4U/J+AE6JiOT9guVnZDONnN5kOpmXXp3sy4WEV5AxpmNpX692dRjGiPCI 15 | cGX7ORS5KgMO2UNvzACsdgGzyzciMHRFAw+yQmXSvPqpl82DwpmjuZ0CgYEA1Zjx 16 | ho5hqJdXF9lNfQvlpFOaIgn6LcAQSPLJPTcoste/6OtbiHTnXB9NyJmG84n++Y+x 17 | sqzoiMpDvvUsCRSbiYIcZed8AN7XuSD2hha4PXR8sKYZm6uiGTl5cNDD1CxZ7hci 18 | EMopponz+S6cCvDTymCEr1lua3dArG4Va+Gg3VUCgYEA72PUrGN3q7RJNw/ryeph 19 | uBiQYFg6ok8TFqtQMvxtoJsvD4yCM+xfeYQMMWFy+HMM4aY4BdtSP3S15S8W30YZ 20 | eZ+dCzDgWc0Wu9R6Zazx+jmCgH5sek3nafNawz55wR6jeEXwBZcvUrhWAKB75PGJ 21 | fF/qCWvslCDtQueWcuMPmFECgYAedQWTmz/fq1zW4LyE5SpkqSskSWnsFiP8UupR 22 | GUlrXwpVayINLiZDY49S2Fl+5qF98nhzMuahgr3wP8N8s/yNugjUmxJ6iUwXcNTW 23 | P+0bjj2tbrHeGbYuhJyFcq9J1N0p7xCDdmBECA3K7VOA1+BLTkH9QvJUzpdhPv08 24 | +dpXVQKBgG728ki8NMaiBmF8AMnel/t152vltQCN3wItyvJAqXE7bYQEeTNhZwqf 25 | CIoQv4udI9EAPJcaS+GlEWan7hXU28ThjfqImACTiolYeR0Fr7AHGK+50vM5wtYN 26 | Mnl3ILyLYZom6bSuVQYIGgnaUc6s5etBLajGEnlj+KwBjRd0cxD7 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/etc/ssl/etcd/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIEDzCCAvegAwIBAgICExowDQYJKoZIhvcNAQELBQAwWDEJMAcGA1UEBhMAMQkw 3 | BwYDVQQIDAAxCTAHBgNVBAcMADEJMAcGA1UEEQwAMQ0wCwYDVQQKDARldGNkMQkw 4 | BwYDVQQLDAAxEDAOBgNVBAMMB2V0Y2QtY2EwHhcNMTgwMzExMTAzNDM1WhcNMTkw 5 | MzExMTAzNDM1WjBVMQkwBwYDVQQGEwAxCTAHBgNVBAgMADEJMAcGA1UEBwwAMQkw 6 | BwYDVQQRDAAxDTALBgNVBAoMBGV0Y2QxCTAHBgNVBAsMADENMAsGA1UEAwwEZXRj 7 | ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKV4YXzknO+IZkMFkwyb 8 | r95bA9TPpfYw1bEYzWkhqw8w06zMvhjZpf7qeHd3RLDsKG5tj3iZE/Xaxmehv+B5 9 | K09jwjO/70repxh1Z0NWPuZpIm8fmwQS3FJrIUls82eKVCrpe+6o8v/B7eThGdKr 10 | E6QHbFjTf/uIBxg6wzihlSODWBu43pFqAKs6UN3qgIqjed7P+UUuy65Mi1T+szyj 11 | t9e8cVGtvbDOqJD+pOn41TqwQJUDLAngAuadV/echrry3wCAYWgWoBar7In35pEM 12 | IQavor6sf0+P5poO761dDfadOtzLyDKt/z/KE88O4JoHhnbBBORNm7iGwa1SnoId 13 | sP0CAwEAAaOB5TCB4jAOBgNVHQ8BAf8EBAMCBSAwFgYDVR0lAQH/BAwwCgYIKwYB 14 | BQUHAwEwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBQSAUJfVHXMYauSkkf0mX6y 15 | TbNXajCBiAYDVR0RBIGAMH6CCWxvY2FsaG9zdIIpKi5rdWJlLWV0Y2Qua3ViZS1z 16 | eXN0ZW0uc3ZjLmNsdXN0ZXIubG9jYWyCLmt1YmUtZXRjZC1jbGllbnQua3ViZS1z 17 | eXN0ZW0uc3ZjLmNsdXN0ZXIubG9jYWyHBH8AAAGHBKwRBGWHBAoDAA+HBAoDABQw 18 | DQYJKoZIhvcNAQELBQADggEBALkAJRmtVAUXQ12CIHLia/3Jlko4peTrtAKJ21c3 19 | kdtbLI9SKT2deKDOaGOhwH0BdGug0pI+icxyKZE2fEbZnU5NYzHDjJQFAWJW50lh 20 | lCWwcfd4lfrBi5o6DhmUaxPjTxyJEQMIodKUToRiCSZsxU1vDG+/r3lSKWRfRbBo 21 | ybml6V5+E7/RXhRSDH7hUuPyGIGjA1sFBFB2xqtzhvPJIwV8zKZBfhZtd6IDMHkA 22 | m6FZwWRfoYxHLoJJPAJHzU2lmxyzsUZiDEV8iQdP0jhf+f3IKzlzmfl/KdBYioWt 23 | pnkY83OxhwYrwRDhIRcDkYJfm18ZlKG+Hd2mE3ZuZfj8eGU= 24 | -----END CERTIFICATE----- 25 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/etc/ssl/etcd/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEpAIBAAKCAQEApXhhfOSc74hmQwWTDJuv3lsD1M+l9jDVsRjNaSGrDzDTrMy+ 3 | GNml/up4d3dEsOwobm2PeJkT9drGZ6G/4HkrT2PCM7/vSt6nGHVnQ1Y+5mkibx+b 4 | BBLcUmshSWzzZ4pUKul77qjy/8Ht5OEZ0qsTpAdsWNN/+4gHGDrDOKGVI4NYG7je 5 | kWoAqzpQ3eqAiqN53s/5RS7LrkyLVP6zPKO317xxUa29sM6okP6k6fjVOrBAlQMs 6 | CeAC5p1X95yGuvLfAIBhaBagFqvsiffmkQwhBq+ivqx/T4/mmg7vrV0N9p063MvI 7 | Mq3/P8oTzw7gmgeGdsEE5E2buIbBrVKegh2w/QIDAQABAoIBAG9mnmuRFj8Fm6Nf 8 | q2J/pmWS7P9nVRpsQlHamuA+tIWjn77kkM72KRV4EeaMO4jJVWcTB9ZvaMrKoWy/ 9 | rwiXSxtF1Ec23wmO4PxMflsNQ4eoHHCn3Jtff0lVqrFeUnjQ3l2Nl8xTnlWl4F2J 10 | VvNIDg8OmFks+ysCp5Qea7RCxL+E5rgZX0MvSmjyAQ6HcsYG2OJDLt/d0WRq2oOr 11 | Nn55CvhgXCkUlv5dIL64PagHsMPC42mx+vCySfNzdUklApvMY2t8sKaGxcvAopd6 12 | kwDYd6+JrNDyXn3UkSV8M8W5fvXYpHoVGsXckRpCYJP75XDK9+TZvnIKWrU6LXCr 13 | y2ZJGsECgYEAzvDUiVX9jDaHEgzehvHFzCWeAjt8Fx2j0uzykg4EeRcAqdJVhBj0 14 | e7YpQwQEoRLxVdYFiYesqVocdlQPvvd6vBCScvf8BZRATk7p5D7iqJcXOR5tjxGN 15 | k8QHDjQTnU6pJ9jAFWDuuM8XfhYeVKQN+f7tTNudh+fc5qdyVxzehiUCgYEAzLK3 16 | 6nJ4gJ2dOHpEibB7j1ZTvPndrhC7qiFYOpvU7ejsNkku+7bPv4tT17nB4iPZSVcL 17 | QSJI6xEemevme20vtSmOIF0Zf9EYIrQUY3l93ViNm2eBj7SwyXExtOEaKR68dxMT 18 | VzjL00aE9sQiini0iNw3is1T5qdtvfMU7TsBK/kCgYAFnHAW3TcHwz68VY7/F7Um 19 | SOrU4qoFsm8LvBMDtM+YPPBuql5ZO5f9dr39rDE38NyMWEZEKWKcIO5eov7eTbWN 20 | PeHKrkCuIgvwU6Fx5+abbaVajiGoXHB7TjhmwTC69jQN+YmTytIOPsdDSvQ9lUkv 21 | uyLSD65gzf+mXWnzRLwf5QKBgQCjRCjNJmBWtWAhG+RurgTfXsuLfwABRfdoyw/E 22 | L2a2G4HMCrMescEh1c8Z0V+DL3Svum2PlfjzBMSToERFTeEvbeWeiqM7/1pw05Ev 23 | hkeNtIO93+DG7ifThCVRT/m9snY/w0c52mM4MJb8+5NRPtVAE+V5ICw7XG97gda/ 24 | IMDegQKBgQCz6vflN2FHplq/BqO+55JpOPqBqppg0/dQavBYhKNgEd2hXs/2/Blp 25 | SsAsQenCXLu02m3Fq9hF7ZFTpc4B3GwgkWKxVYO37CeGTWdM0HLSopll0PJegOsd 26 | bnbKurbnaEhOwF6A2eXz9p9jPmrF3S8b6tf+NkA6tWognCsHFIG1Aw== 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/bootkube.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # When self-hosted etcd is enabled, bootkube places an static pod manifest in 4 | # /etc/kubernetes/manifests for Kubelet to boot a temporary etcd instance. 5 | # However, Kubelet might not have started yet and therefore the folder might 6 | # be missing for now, making bootkube crash. 7 | mkdir -p /etc/kubernetes/manifests/ 8 | 9 | # Move optional experimental manifests into bootkube friendly locations 10 | [ -d /opt/tectonic/experimental ] && mv /opt/tectonic/experimental/* /opt/tectonic/manifests/ && rm -r /opt/tectonic/experimental 11 | [ -d /opt/tectonic/bootstrap-experimental ] && mv /opt/tectonic/bootstrap-experimental/* /opt/tectonic/bootstrap-manifests/ && rm -r /opt/tectonic/bootstrap-experimental 12 | # Move network related manifests into bootkube friendly locations 13 | [ -d /opt/tectonic/net-manifests ] && mv /opt/tectonic/net-manifests/* /opt/tectonic/manifests/ && rm -r /opt/tectonic/net-manifests 14 | 15 | # shellcheck disable=SC2154 16 | /usr/bin/rkt run \ 17 | --trust-keys-from-https \ 18 | --volume assets,kind=host,source="$(pwd)" \ 19 | --mount volume=assets,target=/assets \ 20 | --volume etc-kubernetes,kind=host,source=/etc/kubernetes \ 21 | --mount volume=etc-kubernetes,target=/etc/kubernetes \ 22 | "quay.io/coreos/bootkube:v0.6.2" \ 23 | --net=host \ 24 | --dns=host \ 25 | --exec=/bootkube -- start --asset-dir=/assets 26 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/bootstrap-manifests/bootstrap-controller-manager.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: bootstrap-kube-controller-manager 5 | namespace: kube-system 6 | spec: 7 | containers: 8 | - name: kube-controller-manager 9 | image: quay.io/coreos/hyperkube:v1.7.5_coreos.1 10 | command: 11 | - ./hyperkube 12 | - controller-manager 13 | - --allocate-node-cidrs=true 14 | - --cluster-cidr=10.2.0.0/16 15 | - --cloud-provider= 16 | # no cloud provider config given 17 | - --configure-cloud-routes=false 18 | - --leader-elect=true 19 | - --kubeconfig=/etc/kubernetes/kubeconfig 20 | - --root-ca-file=/etc/kubernetes/bootstrap-secrets/ca.crt 21 | - --service-account-private-key-file=/etc/kubernetes/bootstrap-secrets/service-account.key 22 | volumeMounts: 23 | - name: etc-kubernetes 24 | mountPath: /etc/kubernetes 25 | readOnly: true 26 | - name: ssl-host 27 | mountPath: /etc/ssl/certs 28 | readOnly: true 29 | hostNetwork: true 30 | volumes: 31 | - name: etc-kubernetes 32 | hostPath: 33 | path: /etc/kubernetes 34 | - name: ssl-host 35 | hostPath: 36 | path: /usr/share/ca-certificates 37 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/bootstrap-manifests/bootstrap-scheduler.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: bootstrap-kube-scheduler 5 | namespace: kube-system 6 | spec: 7 | hostNetwork: true 8 | containers: 9 | - name: kube-scheduler 10 | image: quay.io/coreos/hyperkube:v1.7.5_coreos.1 11 | command: 12 | - ./hyperkube 13 | - scheduler 14 | - --kubeconfig=/etc/kubernetes/kubeconfig 15 | - --leader-elect=true 16 | volumeMounts: 17 | - name: etc-kubernetes 18 | mountPath: /etc/kubernetes 19 | readOnly: true 20 | volumes: 21 | - name: etc-kubernetes 22 | hostPath: 23 | path: /etc/kubernetes 24 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/manifests/kube-cloud-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: kube-cloud-cfg 5 | namespace: kube-system 6 | type: Opaque 7 | data: 8 | config: 9 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/manifests/kube-controller-manager-disruption.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy/v1beta1 2 | kind: PodDisruptionBudget 3 | metadata: 4 | name: kube-controller-manager 5 | namespace: kube-system 6 | spec: 7 | minAvailable: 1 8 | selector: 9 | matchLabels: 10 | tier: control-plane 11 | k8s-app: kube-controller-manager 12 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/manifests/kube-scheduler-disruption.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy/v1beta1 2 | kind: PodDisruptionBudget 3 | metadata: 4 | name: kube-scheduler 5 | namespace: kube-system 6 | spec: 7 | minAvailable: 1 8 | selector: 9 | matchLabels: 10 | tier: control-plane 11 | k8s-app: kube-scheduler 12 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/manifests/kube-system-rbac-role-binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1beta1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: system:default-sa 5 | subjects: 6 | - kind: ServiceAccount 7 | name: default 8 | namespace: kube-system 9 | roleRef: 10 | kind: ClusterRole 11 | name: cluster-admin 12 | apiGroup: rbac.authorization.k8s.io 13 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic-rkt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # shellcheck disable=SC2086,SC2154 4 | /usr/bin/rkt run \ 5 | --trust-keys-from-https \ 6 | --volume assets,kind=host,source="$(pwd)" \ 7 | --mount volume=assets,target=/assets \ 8 | quay.io/coreos/hyperkube:v1.7.5_coreos.1\ 9 | --net=host \ 10 | --dns=host \ 11 | --exec=/bin/bash -- /assets/tectonic.sh /assets/auth/kubeconfig /assets false 12 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/config.yaml: -------------------------------------------------------------------------------- 1 | kind: ConfigMap 2 | apiVersion: v1 3 | metadata: 4 | name: tectonic-config 5 | namespace: tectonic-system 6 | data: 7 | clusterID: "2c1d4631-887a-493b-a351-56eb1dd17510" 8 | clusterName: "vagrant" 9 | installerPlatform: "sandbox-virtualbox-macos" 10 | certificatesStrategy: "installerGeneratedCA" 11 | consoleBaseAddress: "https://console.tectonicsandbox.com" 12 | kubeAPIServerURL: "https://172.17.4.101:443" 13 | tectonicVersion: "1.7.5-tectonic.1" 14 | dexAPIHost: "tectonic-identity-api.tectonic-system.svc.cluster.local:5557" 15 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/console/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: tectonic-console 5 | namespace: tectonic-system 6 | labels: 7 | k8s-app: tectonic-console 8 | component: ui 9 | spec: 10 | selector: 11 | k8s-app: tectonic-console 12 | component: ui 13 | ports: 14 | - name: tectonic-console 15 | protocol: TCP 16 | port: 80 17 | targetPort: 8080 18 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/etcd/etcd-operator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | k8s-app: etcd-operator 6 | name: etcd-operator 7 | namespace: kube-system 8 | spec: 9 | strategy: 10 | type: RollingUpdate 11 | rollingUpdate: 12 | maxUnavailable: 1 13 | maxSurge: 1 14 | replicas: 1 15 | template: 16 | metadata: 17 | labels: 18 | k8s-app: etcd-operator 19 | spec: 20 | volumes: 21 | - name: debug-volume 22 | hostPath: 23 | path: /var/tmp 24 | containers: 25 | - env: 26 | - name: MY_POD_NAMESPACE 27 | valueFrom: 28 | fieldRef: 29 | fieldPath: metadata.namespace 30 | - name: MY_POD_NAME 31 | valueFrom: 32 | fieldRef: 33 | fieldPath: metadata.name 34 | - name: HOME 35 | value: /tmp 36 | image: quay.io/coreos/etcd-operator:v0.5.0 37 | name: etcd-operator 38 | command: 39 | - /usr/local/bin/etcd-operator 40 | - --debug-logfile-path=/var/tmp/etcd-operator/debug/debug.log 41 | volumeMounts: 42 | - mountPath: /var/tmp/etcd-operator/debug 43 | name: debug-volume 44 | nodeSelector: 45 | node-role.kubernetes.io/master: "" 46 | securityContext: 47 | runAsNonRoot: true 48 | runAsUser: 65534 49 | tolerations: 50 | - key: node-role.kubernetes.io/master 51 | operator: Exists 52 | effect: NoSchedule 53 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/heapster/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: heapster 5 | namespace: kube-system 6 | labels: 7 | kubernetes.io/cluster-service: "true" 8 | kubernetes.io/name: "Heapster" 9 | spec: 10 | selector: 11 | k8s-app: heapster 12 | ports: 13 | - port: 80 14 | targetPort: 8082 -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/identity/services.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: tectonic-identity 5 | namespace: tectonic-system 6 | labels: 7 | k8s-app: tectonic-identity 8 | component: identity 9 | spec: 10 | selector: 11 | k8s-app: tectonic-identity 12 | component: identity 13 | ports: 14 | - name: worker 15 | protocol: TCP 16 | port: 5556 17 | --- 18 | apiVersion: v1 19 | kind: Service 20 | metadata: 21 | name: tectonic-identity-api 22 | namespace: tectonic-system 23 | spec: 24 | selector: 25 | k8s-app: tectonic-identity 26 | component: identity 27 | ports: 28 | - name: api 29 | protocol: TCP 30 | port: 5557 31 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/ingress/default-backend/configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: tectonic-custom-error 5 | namespace: tectonic-system 6 | data: 7 | custom-http-errors: "404,500,503,504" 8 | server-name-hash-bucket-size: "1024" 9 | use-http2: "false" 10 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/ingress/default-backend/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: default-http-backend 5 | namespace: tectonic-system 6 | spec: 7 | replicas: 1 8 | template: 9 | metadata: 10 | labels: 11 | k8s-app: default-http-backend 12 | spec: 13 | terminationGracePeriodSeconds: 60 14 | containers: 15 | - name: default-http-backend 16 | # Any image is permissable as long as: 17 | # 1. It serves a 404 page at / 18 | # 2. It serves 200 on a /healthz endpoint 19 | image: quay.io/coreos/tectonic-error-server:1.0 20 | livenessProbe: 21 | httpGet: 22 | path: /healthz 23 | port: 8080 24 | scheme: HTTP 25 | initialDelaySeconds: 30 26 | timeoutSeconds: 5 27 | ports: 28 | - containerPort: 8080 29 | resources: 30 | limits: 31 | cpu: 10m 32 | memory: 20Mi 33 | requests: 34 | cpu: 10m 35 | memory: 20Mi 36 | imagePullSecrets: 37 | - name: coreos-pull-secret 38 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/ingress/default-backend/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: default-http-backend 5 | namespace: tectonic-system 6 | labels: 7 | k8s-app: default-http-backend 8 | spec: 9 | ports: 10 | - port: 80 11 | targetPort: 8080 12 | protocol: TCP 13 | name: http 14 | selector: 15 | k8s-app: default-http-backend 16 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/ingress/hostport/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | # keep it under 24 chars 5 | name: tectonic-lb 6 | namespace: tectonic-system 7 | labels: 8 | k8s-app: tectonic-lb 9 | component: ingress-controller 10 | spec: 11 | type: ClusterIP 12 | selector: 13 | k8s-app: tectonic-lb 14 | component: ingress-controller 15 | ports: 16 | - name: http 17 | protocol: TCP 18 | port: 80 19 | targetPort: 80 20 | - name: https 21 | protocol: TCP 22 | port: 443 23 | targetPort: 443 24 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/ingress/ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Ingress 3 | metadata: 4 | name: tectonic-ingress 5 | namespace: tectonic-system 6 | annotations: 7 | ingress.kubernetes.io/ssl-redirect: "true" 8 | ingress.kubernetes.io/use-port-in-redirects: "true" 9 | kubernetes.io/ingress.class: "tectonic" 10 | spec: 11 | tls: 12 | - hosts: 13 | - console.tectonicsandbox.com 14 | secretName: tectonic-ingress-tls-secret 15 | rules: 16 | - host: console.tectonicsandbox.com 17 | http: 18 | paths: 19 | - path: / 20 | backend: 21 | serviceName: tectonic-console 22 | servicePort: 80 23 | - path: /identity 24 | backend: 25 | serviceName: tectonic-identity 26 | servicePort: 5556 -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/ingress/nodeport/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | # keep it under 24 chars 5 | name: tectonic-lb 6 | namespace: tectonic-system 7 | labels: 8 | k8s-app: tectonic-lb 9 | component: ingress-controller 10 | spec: 11 | type: NodePort 12 | selector: 13 | k8s-app: tectonic-lb 14 | component: ingress-controller 15 | ports: 16 | - name: https 17 | protocol: TCP 18 | port: 443 19 | targetPort: 443 20 | nodePort: 32000 21 | - name: http 22 | protocol: TCP 23 | port: 80 24 | targetPort: 80 25 | nodePort: 32001 26 | - name: health 27 | protocol: TCP 28 | port: 10254 29 | targetPort: 10254 30 | nodePort: 32002 31 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: tectonic-system -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/rbac/binding-admin.yaml: -------------------------------------------------------------------------------- 1 | kind: ClusterRoleBinding 2 | apiVersion: rbac.authorization.k8s.io/v1beta1 3 | metadata: 4 | name: admin-user 5 | subjects: 6 | - kind: User 7 | name: admin@example.com 8 | - kind: ServiceAccount 9 | namespace: tectonic-system 10 | name: default 11 | roleRef: 12 | kind: ClusterRole 13 | name: cluster-admin 14 | apiGroup: rbac.authorization.k8s.io 15 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/rbac/binding-discovery.yaml: -------------------------------------------------------------------------------- 1 | kind: ClusterRoleBinding 2 | apiVersion: rbac.authorization.k8s.io/v1beta1 3 | metadata: 4 | name: discovery 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: system:discovery 9 | subjects: 10 | - kind: Group 11 | name: 'system:unauthenticated' 12 | - kind: Group 13 | name: 'system:authenticated' 14 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/rbac/role-admin.yaml: -------------------------------------------------------------------------------- 1 | kind: ClusterRole 2 | apiVersion: rbac.authorization.k8s.io/v1beta1 3 | metadata: 4 | name: admin 5 | rules: 6 | - apiGroups: ["*"] 7 | resources: ["*"] 8 | verbs: ["*"] 9 | - nonResourceURLs: ["*"] 10 | verbs: ["*"] 11 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/secrets/ca-cert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: tectonic-ca-cert-secret 5 | namespace: tectonic-system 6 | type: Opaque 7 | data: 8 | ca-cert: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURkakNDQWw2Z0F3SUJBZ0lDV3Mwd0RRWUpLb1pJaHZjTkFRRUxCUUF3WERFSk1BY0dBMVVFQmhNQU1Ra3cKQndZRFZRUUlEQUF4Q1RBSEJnTlZCQWNNQURFSk1BY0dBMVVFRVF3QU1SRXdEd1lEVlFRS0RBaGliMjkwYTNWaQpaVEVKTUFjR0ExVUVDd3dBTVJBd0RnWURWUVFEREFkcmRXSmxMV05oTUI0WERURTRNRE14TVRFd016UXpOVm9YCkRURTVNRE14TVRFd016UXpOVm93WERFSk1BY0dBMVVFQmhNQU1Ra3dCd1lEVlFRSURBQXhDVEFIQmdOVkJBY00KQURFSk1BY0dBMVVFRVF3QU1SRXdEd1lEVlFRS0RBaGliMjkwYTNWaVpURUpNQWNHQTFVRUN3d0FNUkF3RGdZRApWUVFEREFkcmRXSmxMV05oTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUE0TUtSClhJTEhqU3VPN1RqS3J3cjdhc1ZadjFvVUtKSjB0TnFJQW9TclJ6WUt3SVlwWGdUUmJrL3JLRVM2NEhqTDdaU2gKbDhHQTU1SXhCcE04OFFHTHl6ZUFFZTg3bkwyRnFJOU52eGdOVWxHUHYvOWxCU0pMSCtWU0paZnQwYktrMXEzYwpyUDU0MVZvdGgwa0VGRzRZdFI3QjZUbUlJamlNekF6Y2hlOHNsNHNvekdkVy9ocFRFVTRnOHkzTU9QbjVVMllpCmVTeDlUeUJtcll2d0FFc3JHUTdiSU02RWMwd25KV2dkOWJBV085K0Z6SExWbXIvVmFyeWZnaDVTeXJUT1BoNmwKOWQybDVJcXdYeEQzVko1ZWZDRUQzUTFUbjk0UWwxSCt0TVVBeHowajJ0L0JOakZ0VWlXVmErbnNFNTc1RU0rRwp6blhiZzJlbG9od3hvNDhYb1FJREFRQUJvMEl3UURBT0JnTlZIUThCQWY4RUJBTUNBcVF3RHdZRFZSMFRBUUgvCkJBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVWlMdVYxRFdRSmNMOEpkS1BOdmRNUmVxR1gyOHdEUVlKS29aSWh2Y04KQVFFTEJRQURnZ0VCQUUzMVhiN1k5VW9TcWd1d1RyeTJub3pnRit3cTkyYXBJR1BvQ2h2QzBBNHg1TWZNbUtnZgovVmlSQkRQanN0aHd2SVNmYlJBVlR6MnNzbWpJeW81SitZRjc5QlhqRDRKT2NrSnE3cnhNUzJ4UjA5VHpUYndKClZLbng1Q2IwLzhmWkVpeFhoaXNsWndqN0FVZE5NeXZZRUNiQmwwSWtJRmtYSHl4d3ZCazc3SzZwQ0JMZ2hMbzYKZ3VxSlNRd0w5Q0tnZFNpTEpkV1RydTdtNndKT3l1dFp6eWZGVUtSUWthYmZBek45S1hvUlpzd00xUXU2MnR2eQovcUxncGk2dG04OGtJN0ZzMmhLTWdiWjR3OXJuSERkaWNzTlFCWFNiejVzblBmYWE5NlFYMkRrSHlIUGkvNy8rCmVpUXJMUG54MlFpbXpveVRGS00zbnhwaXpUVE5OTmszNzRBPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== 9 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/secrets/pull.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "Secret", 4 | "type": "kubernetes.io/dockerconfigjson", 5 | "metadata": { 6 | "namespace": "tectonic-system", 7 | "name": "coreos-pull-secret" 8 | }, 9 | "data": { 10 | ".dockerconfigjson": "ewogICJhdXRocyI6IHsKICAgICJxdWF5LmlvIjogewogICAgICAiYXV0aCI6ICJZMjl5Wlc5ekszUmxZekpmYVdaaWRXZHNhMk5wZG1ObFpYSnpZbWRxWW5NeWIySjRaem95VTB4VlREUTRWbEZCTlVWRFJVNUNRMUJMUzBGV1VGQTBXVEpOVEZCUFdFYzVNbEpXUjAxSlMwTk5ORU16VmpZMlNUQkhUMDFEV1VOS1RFTllObEpUIiwKICAgICAgImVtYWlsIjogIiIKICAgIH0KICB9Cn0=" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/updater/app-version-kind.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: "apiextensions.k8s.io/v1beta1" 2 | kind: "CustomResourceDefinition" 3 | metadata: 4 | name: "appversions.tco.coreos.com" 5 | spec: 6 | group: "tco.coreos.com" 7 | version: "v1" 8 | names: 9 | plural: "appversions" 10 | kind: "AppVersion" 11 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/updater/app_versions/app-version-kubernetes.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tco.coreos.com/v1 2 | kind: AppVersion 3 | metadata: 4 | name: kubernetes 5 | namespace: tectonic-system 6 | labels: 7 | managed-by-channel-operator: "true" 8 | spec: 9 | desiredVersion: 1.7.5+tectonic.1 10 | paused: false 11 | status: 12 | currentVersion: 1.7.5+tectonic.1 13 | paused: false 14 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/updater/app_versions/app-version-tectonic-cluo.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tco.coreos.com/v1 2 | kind: AppVersion 3 | metadata: 4 | name: tectonic-cluo-operator 5 | namespace: tectonic-system 6 | labels: 7 | managed-by-channel-operator: "true" 8 | annotations: 9 | tectonic-operators.coreos.com/upgrade-behaviour: 'CreateOrUpgrade' 10 | spec: 11 | desiredVersion: 0.2.1 12 | paused: false 13 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/updater/app_versions/app-version-tectonic-cluster.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tco.coreos.com/v1 2 | kind: AppVersion 3 | metadata: 4 | name: tectonic-cluster 5 | namespace: tectonic-system 6 | labels: 7 | managed-by-channel-operator: "true" 8 | annotations: 9 | tectonic-operators.coreos.com/upgrade-behaviour: 'CreateOrUpgrade' 10 | spec: 11 | desiredVersion: 1.7.5+tectonic.1 12 | paused: false 13 | status: 14 | currentVersion: 1.7.5+tectonic.1 15 | paused: false 16 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/updater/app_versions/app-version-tectonic-etcd.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tco.coreos.com/v1 2 | kind: AppVersion 3 | metadata: 4 | name: tectonic-etcd 5 | namespace: tectonic-system 6 | labels: 7 | managed-by-channel-operator: "true" 8 | spec: 9 | desiredVersion: 0.0.2 10 | paused: false 11 | status: 12 | currentVersion: 0.0.2 13 | paused: false 14 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/updater/app_versions/app-version-tectonic-monitoring.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tco.coreos.com/v1 2 | kind: AppVersion 3 | metadata: 4 | name: tectonic-monitoring 5 | namespace: tectonic-system 6 | labels: 7 | managed-by-channel-operator: "true" 8 | spec: 9 | desiredVersion: 1.6.0 10 | paused: false 11 | status: 12 | currentVersion: 1.6.0 13 | paused: false 14 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/updater/cluster-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: "etcd.database.coreos.com/v1beta2" 2 | kind: "EtcdCluster" 3 | metadata: 4 | name: "kube-etcd" 5 | namespace: kube-system 6 | spec: 7 | size: 1 8 | version: "3.1.8" 9 | pod: 10 | resources: 11 | requests: 12 | cpu: 500m 13 | memory: 300Mi 14 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/updater/migration-status-kind.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: "apiextensions.k8s.io/v1beta1" 2 | kind: "CustomResourceDefinition" 3 | metadata: 4 | name: "migrationstatuses.kvo.coreos.com" 5 | spec: 6 | group: "kvo.coreos.com" 7 | version: "v1" 8 | names: 9 | plural: "migrationstatuses" 10 | kind: "MigrationStatus" 11 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/updater/node-agent.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: DaemonSet 3 | metadata: 4 | name: node-agent 5 | namespace: tectonic-system 6 | labels: 7 | k8s-app: node-agent 8 | spec: 9 | updateStrategy: 10 | rollingUpdate: 11 | maxUnavailable: 1 12 | type: RollingUpdate 13 | template: 14 | metadata: 15 | labels: 16 | k8s-app: node-agent 17 | spec: 18 | containers: 19 | - name: node-agent 20 | image: quay.io/coreos/node-agent:v1.7.5-kvo.3 21 | securityContext: 22 | privileged: true 23 | env: 24 | - name: NODE_NAME 25 | valueFrom: 26 | fieldRef: 27 | fieldPath: spec.nodeName 28 | volumeMounts: 29 | - name: systemd 30 | mountPath: /etc/systemd/system 31 | - name: var-run 32 | mountPath: /var/run 33 | - name: etc-kubernetes 34 | mountPath: /etc/kubernetes 35 | imagePullSecrets: 36 | - name: coreos-pull-secret 37 | tolerations: 38 | - key: "node-role.kubernetes.io/master" 39 | operator: "Exists" 40 | effect: "NoSchedule" 41 | volumes: 42 | - name: etc-kubernetes 43 | hostPath: 44 | path: /etc/kubernetes 45 | - name: systemd 46 | hostPath: 47 | path: /etc/systemd/system 48 | - name: var-run 49 | hostPath: 50 | path: /var/run 51 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/updater/operators/kube-version-operator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: kube-version-operator 5 | namespace: tectonic-system 6 | labels: 7 | k8s-app: kube-version-operator 8 | managed-by-channel-operator: "true" 9 | spec: 10 | replicas: 1 11 | selector: 12 | matchLabels: 13 | k8s-app: kube-version-operator 14 | template: 15 | metadata: 16 | labels: 17 | k8s-app: kube-version-operator 18 | tectonic-app-version-name: kubernetes 19 | spec: 20 | containers: 21 | - name: kube-version-operator 22 | image: quay.io/coreos/kube-version-operator:v1.7.5-kvo.12 23 | command: 24 | - /kube-version-operator 25 | - --cache-images=true 26 | - --version-mapping=/upgrade-spec.json 27 | imagePullSecrets: 28 | - name: coreos-pull-secret 29 | securityContext: 30 | runAsNonRoot: true 31 | runAsUser: 65534 32 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/updater/operators/tectonic-channel-operator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: tectonic-channel-operator 5 | namespace: tectonic-system 6 | labels: 7 | k8s-app: tectonic-channel-operator 8 | managed-by-channel-operator: "true" 9 | spec: 10 | replicas: 1 11 | selector: 12 | matchLabels: 13 | k8s-app: tectonic-channel-operator 14 | template: 15 | metadata: 16 | labels: 17 | k8s-app: tectonic-channel-operator 18 | tectonic-app-version-name: tectonic-cluster 19 | spec: 20 | containers: 21 | - name: tectonic-channel-operator 22 | image: quay.io/coreos/tectonic-channel-operator:0.5.4 23 | env: 24 | - name: CLUSTER_ID 25 | valueFrom: 26 | configMapKeyRef: 27 | name: tectonic-config 28 | key: clusterID 29 | resources: 30 | limits: 31 | cpu: 20m 32 | memory: 50Mi 33 | requests: 34 | cpu: 20m 35 | memory: 50Mi 36 | volumeMounts: 37 | - name: certs 38 | mountPath: /etc/ssl/certs 39 | restartPolicy: Always 40 | imagePullSecrets: 41 | - name: coreos-pull-secret 42 | securityContext: 43 | runAsNonRoot: true 44 | runAsUser: 65534 45 | volumes: 46 | - name: certs 47 | hostPath: 48 | path: /usr/share/ca-certificates 49 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/updater/operators/tectonic-cluo-operator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: tectonic-cluo-operator 5 | namespace: tectonic-system 6 | labels: 7 | k8s-app: tectonic-cluo-operator 8 | managed-by-channel-operator: "true" 9 | annotations: 10 | tectonic-operators.coreos.com/upgrade-behaviour: 'CreateOrUpgrade' 11 | spec: 12 | replicas: 1 13 | selector: 14 | matchLabels: 15 | k8s-app: tectonic-cluo-operator 16 | template: 17 | metadata: 18 | labels: 19 | k8s-app: tectonic-cluo-operator 20 | spec: 21 | containers: 22 | - name: tectonic-cluo-operator 23 | image: quay.io/coreos/tectonic-cluo-operator:v0.2.1 24 | command: 25 | - /tectonic-x-operator 26 | - --operator-name=tectonic-cluo-operator 27 | - --appversion-name=tectonic-cluo-operator 28 | resources: 29 | limits: 30 | cpu: 20m 31 | memory: 50Mi 32 | requests: 33 | cpu: 20m 34 | memory: 50Mi 35 | restartPolicy: Always 36 | imagePullSecrets: 37 | - name: coreos-pull-secret 38 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/updater/operators/tectonic-etcd-operator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: tectonic-etcd-operator 5 | namespace: tectonic-system 6 | labels: 7 | k8s-app: tectonic-etcd-operator 8 | managed-by-channel-operator: "true" 9 | spec: 10 | replicas: 1 11 | selector: 12 | matchLabels: 13 | k8s-app: tectonic-etcd-operator 14 | template: 15 | metadata: 16 | labels: 17 | k8s-app: tectonic-etcd-operator 18 | tectonic-app-version-name: tectonic-etcd 19 | spec: 20 | containers: 21 | - image: quay.io/coreos/tectonic-etcd-operator:v0.0.2 22 | name: tectonic-etcd-operator 23 | command: ["/usr/local/bin/tectonic-etcd-operator"] 24 | resources: 25 | limits: 26 | cpu: 100m 27 | memory: 128Mi 28 | requests: 29 | cpu: 20m 30 | memory: 50Mi 31 | restartPolicy: Always 32 | securityContext: 33 | runAsNonRoot: true 34 | runAsUser: 65534 35 | imagePullSecrets: 36 | - name: coreos-pull-secret 37 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/updater/operators/tectonic-prometheus-operator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: tectonic-prometheus-operator 5 | namespace: tectonic-system 6 | labels: 7 | k8s-app: tectonic-prometheus-operator 8 | managed-by-channel-operator: "true" 9 | spec: 10 | replicas: 1 11 | selector: 12 | matchLabels: 13 | k8s-app: tectonic-prometheus-operator 14 | template: 15 | metadata: 16 | labels: 17 | k8s-app: tectonic-prometheus-operator 18 | tectonic-app-version-name: tectonic-monitoring 19 | spec: 20 | containers: 21 | - image: quay.io/coreos/tectonic-prometheus-operator:v1.6.0 22 | name: tectonic-prometheus-operator 23 | args: 24 | - "-logtostderr=true" 25 | - "-v=4" 26 | resources: 27 | limits: 28 | cpu: 20m 29 | memory: 50Mi 30 | requests: 31 | cpu: 20m 32 | memory: 50Mi 33 | restartPolicy: Always 34 | securityContext: 35 | runAsNonRoot: true 36 | runAsUser: 65534 37 | terminationGracePeriodSeconds: 30 38 | imagePullSecrets: 39 | - name: coreos-pull-secret 40 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/updater/tectonic-channel-operator-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tco.coreos.com/v1 2 | kind: ChannelOperatorConfig 3 | metadata: 4 | name: default 5 | namespace: tectonic-system 6 | server: https://tectonic.update.core-os.net 7 | channel: tectonic-1.7-production 8 | appID: 6bc7b986-4654-4a0f-94b3-84ce6feb1db4 9 | automaticUpdate: false 10 | triggerUpdate: false 11 | triggerUpdateCheck: false 12 | updateCheckInterval: 2700 13 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/updater/tectonic-channel-operator-kind.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: "apiextensions.k8s.io/v1beta1" 2 | kind: "CustomResourceDefinition" 3 | metadata: 4 | name: "channeloperatorconfigs.tco.coreos.com" 5 | spec: 6 | group: "tco.coreos.com" 7 | version: "v1" 8 | names: 9 | plural: "channeloperatorconfigs" 10 | kind: "ChannelOperatorConfig" 11 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tectonic/updater/tectonic-monitoring-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: tectonic-monitoring 5 | namespace: tectonic-system 6 | data: 7 | config.yaml: |+ 8 | prometheusOperator: 9 | baseImage: quay.io/coreos/prometheus-operator 10 | prometheusConfigReloaderBaseImage: quay.io/coreos/prometheus-config-reloader 11 | configReloaderBaseImage: quay.io/coreos/configmap-reload 12 | prometheusK8s: 13 | baseImage: quay.io/prometheus/prometheus 14 | alertmanagerMain: 15 | baseImage: quay.io/prometheus/alertmanager 16 | ingress: 17 | baseAddress: console.tectonicsandbox.com 18 | auth: 19 | baseImage: quay.io/coreos/tectonic-monitoring-auth 20 | nodeExporter: 21 | baseImage: quay.io/prometheus/node-exporter 22 | kubeStateMetrics: 23 | baseImage: quay.io/coreos/kube-state-metrics 24 | addonResizerBaseImage: quay.io/coreos/addon-resizer 25 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tls/apiserver.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIEGTCCAwGgAwIBAgIDAIMQMA0GCSqGSIb3DQEBCwUAMFwxCTAHBgNVBAYTADEJ 3 | MAcGA1UECAwAMQkwBwYDVQQHDAAxCTAHBgNVBBEMADERMA8GA1UECgwIYm9vdGt1 4 | YmUxCTAHBgNVBAsMADEQMA4GA1UEAwwHa3ViZS1jYTAeFw0xODAzMTExMDM0MzVa 5 | Fw0xOTAzMTExMDM0MzVaMGYxCTAHBgNVBAYTADEJMAcGA1UECAwAMQkwBwYDVQQH 6 | DAAxCTAHBgNVBBEMADEUMBIGA1UECgwLa3ViZS1tYXN0ZXIxCTAHBgNVBAsMADEX 7 | MBUGA1UEAwwOa3ViZS1hcGlzZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw 8 | ggEKAoIBAQCyxb12nudwJ4N2JOb1+4y3jyPfcbDMcs8Et24ZCB22FIhhzjzjY6sa 9 | Y0zKbbHZcn8YzlXwV7EZhIIJjRzxTBqF8Bau11oYzHRFL8lw4ZzdnTGnk9VENzZP 10 | QTJlCZY68mkzJLNEwmGD7biV8BD2fZilkgbPqtsfUW1KWCEcxPEot8ZUSpRu3LA7 11 | mSiOFMnDZNvbvqQqN645D4wui6Ktlnq2ACnlZEiDVqBhhHVVf1R1HO3Qvi+zXXUx 12 | /hFrnYnw+ViVP8SRFwrGeRt0qzSIYHqDg/bHZHz0u/wz4R2ST80EJ/QHVOSJkPEd 13 | HOpjUbKZ5afl2TLb0lp/ZLuWF2WEFUBlAgMBAAGjgdkwgdYwDgYDVR0PAQH/BAQD 14 | AgWgMCAGA1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8E 15 | AjAAMB8GA1UdIwQYMBaAFIi7ldQ1kCXC/CXSjzb3TEXqhl9vMHMGA1UdEQRsMGqC 16 | Cmt1YmVybmV0ZXOCEmt1YmVybmV0ZXMuZGVmYXVsdIIWa3ViZXJuZXRlcy5kZWZh 17 | dWx0LnN2Y4Ika3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FshwSs 18 | EQRlhwQKAwABMA0GCSqGSIb3DQEBCwUAA4IBAQBaYzQkDP4RUS7tg6Vc1mZhMw2t 19 | iiR4QtEAGzbKcWYV74pB0GAv9Zm6jfL++TMgFfZFYegYr5pKVXNMEpuKpA3lbeBJ 20 | gZ8xz7/CSCYeV7YLa5T2h/wTR1k8qW7CTYeiVHTLTduYz6U4dhU9FB8OPw87+K79 21 | iSbZFg4MYm4JcwiSy/1xhWfTsMj4mZ4TlEi/RUAiG5htYmoxr7LEHFO0o2reM8KU 22 | 4mo6qjhcJ5k0hioLdgj0YshON0r1wYT52PDzcoaV+ZFscfYWlAUFUDhla30KZfhe 23 | YOnDWTGhUe0kF647xJ8+ir128/lt+jm6+TWozqL8Q5By/q5TZPkMUjH6kMYr 24 | -----END CERTIFICATE----- 25 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tls/apiserver.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEAssW9dp7ncCeDdiTm9fuMt48j33GwzHLPBLduGQgdthSIYc48 3 | 42OrGmNMym2x2XJ/GM5V8FexGYSCCY0c8UwahfAWrtdaGMx0RS/JcOGc3Z0xp5PV 4 | RDc2T0EyZQmWOvJpMySzRMJhg+24lfAQ9n2YpZIGz6rbH1FtSlghHMTxKLfGVEqU 5 | btywO5kojhTJw2Tb276kKjeuOQ+MLouirZZ6tgAp5WRIg1agYYR1VX9UdRzt0L4v 6 | s111Mf4Ra52J8PlYlT/EkRcKxnkbdKs0iGB6g4P2x2R89Lv8M+Edkk/NBCf0B1Tk 7 | iZDxHRzqY1GymeWn5dky29Jaf2S7lhdlhBVAZQIDAQABAoIBAALP944RK+Toyjmm 8 | lPeTsIAGwXK3cCeXOsiBNjswlH8TzZ10SCLvo3Zzz3ZzyVN5aKR0QofYaVHUctNB 9 | pA3ru5MV1tWDT8iKFt4rxUiAVB5sZaaUPcun7rPKe8d5IiLlQ2BpmGRhhnUz3S6G 10 | q02lZixcorzLnEze1BBSWJsCQiT40GheBFQJZlc/C+0IcZgxC8CmJRGqi3tgMg8f 11 | rGYHNnSPun5A6yCIHObWKhHQ+0dZ+oy+RH9VBNEtUcawJ8orTFL7BMVNfHCSwvKb 12 | 6oejsb9xrwKU6vjlTAx0WilH4M+Zz7c7Y2It/93CHzcABqyCxlhn25F+L88Kscs5 13 | qbp3PhUCgYEA49mULk+10sjg4xRF3QczEcGzrQIcYPC6KP82WzOiUcy1m63W5lXs 14 | KWGICFRHNQZ6guZT+gDwuCMS4y+e/6rizVVhQ965OfdKhe4A4jf76gqGltZlA70U 15 | YcNyXV892XXkCVVRM5gpyHJtGZTSYRRfmem2Vaxq0GpzD9CppqtjKt8CgYEAyNvx 16 | Eu1PfjAUGcE6SLKZmAU1/ehjhWstDfAVFmL1SAFUuO3z1oUB0mNKaobLGCYQ79Od 17 | zAT7Oid3e7PxA11oHO8V75u1CKmjZ78QVuTSd1wUWqlBofw+Vje4WADnOHcExPFO 18 | RwZp4Pep3PFyvGgcz14qUczjnaQW9QpX6AhggTsCgYAVu4wZurqiB00D+8wKIASr 19 | /ejQaLIiQPPQsz8RBeTGnpr35WXpBGsJK2dZPAiqsxp+X8/EudA8EAReLQ2iXz9Q 20 | zIMBgT3znHW8Po5RBXv+v9BElOB/sco+5PCEnW/9zPPaPAwJusrJdriXRw2l+tZ/ 21 | jL46f76UcILXEFUOM6y6ywKBgBw2MD0dUd4CeMBJUJtnYoVkrfm0y02xCQn9H6ke 22 | Sx9K+JBk86u80M2xHoGp3xrMNfLJgU9nn7XCV1jrpD15wCbYOfeGoj3OPeJThsL9 23 | rsYPC9jUDyDmYgcQGndZ4SAgL25OClWVhAeSIayjyR7HbMx/iGgm5A1/P645PrGb 24 | g5qDAoGBAMLjnPkpI5vhu+qVA6p4REUi/kwkNRQFkcaLmhiAZWZdVf76F7J2Nh12 25 | pKwEcREqxtcg8PLQ++9fDAbKemuYydW7pKJWUAP/QbuVdCOM2ZInFVL5jAsVU10l 26 | NEr75vVDfmZ56opWgnX516nxwOZahYRUsX+OFN6tDyBv6MI5ZxHY 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tls/ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDdjCCAl6gAwIBAgICWs0wDQYJKoZIhvcNAQELBQAwXDEJMAcGA1UEBhMAMQkw 3 | BwYDVQQIDAAxCTAHBgNVBAcMADEJMAcGA1UEEQwAMREwDwYDVQQKDAhib290a3Vi 4 | ZTEJMAcGA1UECwwAMRAwDgYDVQQDDAdrdWJlLWNhMB4XDTE4MDMxMTEwMzQzNVoX 5 | DTE5MDMxMTEwMzQzNVowXDEJMAcGA1UEBhMAMQkwBwYDVQQIDAAxCTAHBgNVBAcM 6 | ADEJMAcGA1UEEQwAMREwDwYDVQQKDAhib290a3ViZTEJMAcGA1UECwwAMRAwDgYD 7 | VQQDDAdrdWJlLWNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4MKR 8 | XILHjSuO7TjKrwr7asVZv1oUKJJ0tNqIAoSrRzYKwIYpXgTRbk/rKES64HjL7ZSh 9 | l8GA55IxBpM88QGLyzeAEe87nL2FqI9NvxgNUlGPv/9lBSJLH+VSJZft0bKk1q3c 10 | rP541Voth0kEFG4YtR7B6TmIIjiMzAzche8sl4sozGdW/hpTEU4g8y3MOPn5U2Yi 11 | eSx9TyBmrYvwAEsrGQ7bIM6Ec0wnJWgd9bAWO9+FzHLVmr/Varyfgh5SyrTOPh6l 12 | 9d2l5IqwXxD3VJ5efCED3Q1Tn94Ql1H+tMUAxz0j2t/BNjFtUiWVa+nsE575EM+G 13 | znXbg2elohwxo48XoQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAqQwDwYDVR0TAQH/ 14 | BAUwAwEB/zAdBgNVHQ4EFgQUiLuV1DWQJcL8JdKPNvdMReqGX28wDQYJKoZIhvcN 15 | AQELBQADggEBAE31Xb7Y9UoSqguwTry2nozgF+wq92apIGPoChvC0A4x5MfMmKgf 16 | /ViRBDPjsthwvISfbRAVTz2ssmjIyo5J+YF79BXjD4JOckJq7rxMS2xR09TzTbwJ 17 | VKnx5Cb0/8fZEixXhislZwj7AUdNMyvYECbBl0IkIFkXHyxwvBk77K6pCBLghLo6 18 | guqJSQwL9CKgdSiLJdWTru7m6wJOyutZzyfFUKRQkabfAzN9KXoRZswM1Qu62tvy 19 | /qLgpi6tm88kI7Fs2hKMgbZ4w9rnHDdicsNQBXSbz5snPfaa96QX2DkHyHPi/7/+ 20 | eiQrLPnx2QimzoyTFKM3nxpizTTNNNk374A= 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tls/ca.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEpAIBAAKCAQEA4MKRXILHjSuO7TjKrwr7asVZv1oUKJJ0tNqIAoSrRzYKwIYp 3 | XgTRbk/rKES64HjL7ZShl8GA55IxBpM88QGLyzeAEe87nL2FqI9NvxgNUlGPv/9l 4 | BSJLH+VSJZft0bKk1q3crP541Voth0kEFG4YtR7B6TmIIjiMzAzche8sl4sozGdW 5 | /hpTEU4g8y3MOPn5U2YieSx9TyBmrYvwAEsrGQ7bIM6Ec0wnJWgd9bAWO9+FzHLV 6 | mr/Varyfgh5SyrTOPh6l9d2l5IqwXxD3VJ5efCED3Q1Tn94Ql1H+tMUAxz0j2t/B 7 | NjFtUiWVa+nsE575EM+GznXbg2elohwxo48XoQIDAQABAoIBAH9JUT8+BTsKrw/j 8 | eM22/3mROGlo3z+26Yc+t4YNkl5q2Z38nNLVEbJSak/M1LSpVHxBD169RH5gyYj6 9 | u6mVgZDd5pbBkFYM8vPp7FLLkUfMTweh4JkOudLfcS0/JHz8mePGZNJH7zCMuHoE 10 | PN5BF5cDSzgEz/bpZbttkTn8oJlVM0ChC3QnzxL2jBOm30KUZJEQ70T9rZMSq9vk 11 | Yi6cv6P9xy1HSYOamFWp6Z9F/SJPjpjHOuKUUCBW+c47COC0ovyn3zofWofv62CR 12 | tgrOAnjmgFdePwiQMZQqv0qvEbTFsn+FKf/Oq+CXsjZncZC6LgrsRmgyA8+iOn/V 13 | bH/XbW0CgYEA9tsQfcH6CoXybVx2trUIHom4oIJtUmQilp1Eo0UeLXUyMX4hXA74 14 | FnHC0MaKH7eMFftilRimtkLrGKC4qsd9tXW7yXwHgIwUaRNf712+t35DE1VV9fWY 15 | FIfm2RmdVj1mt8KDSyGSg/0eRLtXEgPBRc/jT5QgBpMrtrFQVuhcsbcCgYEA6RX4 16 | P8H0w/16ycbMQMX2gmoDXX2QtY8bwVOheFD9UEtdSSOpuWmFfHIMiLxZbBift3ci 17 | pJsSkjU5+XP9h/uB1ww5T8Y1U5yiNNWrCjWZVmUtd0Jw2aRKrIXcHhlAkDnDDySp 18 | ZilO/hW4M9K2LlBDPVcocvwBuU89X7+cY/t9IWcCgYEAwT6sokX/380MAuCnblA5 19 | ku5tQfnYau9IxG9JFCc/gIaGTIhYxSBSxf84aweBiWK+n1azzdQGbhfkwtrOtaKF 20 | nlAUOZ6GoPMH51nreA8DBdIp4DClom4oJ6pb5QhQSvq2NpRnA6G8eOblkxi1CL03 21 | x9b+M4XZrEv5pIMaSW6NYfECgYBBwrsJcfVWnltYNkhGNhP4c2SDqft73eZcwvWZ 22 | dnAhiUHGctNdxlGs7Jhws4MfJktZfbk+a6nvqiizInBzPxhAzegVg7xj3Js/ANGC 23 | zeB3KZCMRyiDnwCacCHMNB+tET7hNNy+QAVTVllj9Z0EsAxocACvgD4URDDypKLA 24 | 6qFBHQKBgQDohK43pvBoBaY3ZuSp7+H3g6wMmxy8xwUkl6biHWx6vqpPdYYixZoH 25 | tlv2yyOOxr4xtUKAi7A3sNynAKWI1G4ORULgk+Pn4Beg4xC51J9LUHyhKYpurCDP 26 | bkQbagWYE8KF26UyY9MB8+Y1b5yF5Pk1dcEFTeXVENvEnPF/59bNhQ== 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tls/etcd-client-ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDbjCCAlagAwIBAgICNIIwDQYJKoZIhvcNAQELBQAwWDEJMAcGA1UEBhMAMQkw 3 | BwYDVQQIDAAxCTAHBgNVBAcMADEJMAcGA1UEEQwAMQ0wCwYDVQQKDARldGNkMQkw 4 | BwYDVQQLDAAxEDAOBgNVBAMMB2V0Y2QtY2EwHhcNMTgwMzExMTAzNDM0WhcNMTkw 5 | MzExMTAzNDM0WjBYMQkwBwYDVQQGEwAxCTAHBgNVBAgMADEJMAcGA1UEBwwAMQkw 6 | BwYDVQQRDAAxDTALBgNVBAoMBGV0Y2QxCTAHBgNVBAsMADEQMA4GA1UEAwwHZXRj 7 | ZC1jYTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMiXu+bGHnbHIVaG 8 | 7rpBPdHfHjL0vxb9PuTDGhZM+WrqydIp7+2Ulb/XXm3oC5a5qojpVaxeZaMq5LGR 9 | 0GfWOKWTOoCzBgTIhRNZ3uBzoE7aDffX1oNnMR4zaKaaspwzWJLwbUWWNTiITvRl 10 | SnXGCt8Gvk09opJT1+I5GB/jDTjR1nzsvt68OHqdV1aAzp89R6EUtSM0gPgFZWc5 11 | phlLkVYBzKKi0rgVUiYp+gI0EszySvKllPX4glIEJkBtkbGoNWE29fI4htiA2/2w 12 | 7qsF6DxCgRjMwZ27EVYI66t43GZi0mFtyCaQySkWArp5AaLlbBC9qIurxkB0LOVt 13 | mNLiBU0CAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgKkMA8GA1UdEwEB/wQFMAMBAf8w 14 | HQYDVR0OBBYEFBIBQl9Udcxhq5KSR/SZfrJNs1dqMA0GCSqGSIb3DQEBCwUAA4IB 15 | AQAJICPz6LDlnuHM6Z9MJWu/9aN6H4+XgYRYP823Hiqw4c5B/E8oaEGr53I+/cBN 16 | 6bQsjBctamsvZKDKm1A3kAuIYptpAj/eXJe60yGZ6NWBlqgybEmteRTeD2NTUe5s 17 | BWesyTNBcWa3uCsOxTM9yTI/oPw5ftknH+t24apSzWKMG/DS2lq/sdBtKPKwSJfx 18 | n8hN+ZpPP7CJnLVgK5g/UywpNexnHSQ3YSpxfW7EDAZgJh9VaSJpBtcO+pcgSnVb 19 | dpyuDNLyiQZ7wdVHPQ0tkf/m+fC4a0xx9BPXgn05fD78D7Mt3UueSvYBLoYqzxkJ 20 | +diJ7jsaZCWIUUhFSeWxPK9X 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tls/etcd-client.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDgjCCAmqgAwIBAgICX6swDQYJKoZIhvcNAQELBQAwWDEJMAcGA1UEBhMAMQkw 3 | BwYDVQQIDAAxCTAHBgNVBAcMADEJMAcGA1UEEQwAMQ0wCwYDVQQKDARldGNkMQkw 4 | BwYDVQQLDAAxEDAOBgNVBAMMB2V0Y2QtY2EwHhcNMTgwMzExMTAzNDM1WhcNMTkw 5 | MzExMTAzNDM1WjBVMQkwBwYDVQQGEwAxCTAHBgNVBAgMADEJMAcGA1UEBwwAMQkw 6 | BwYDVQQRDAAxDTALBgNVBAoMBGV0Y2QxCTAHBgNVBAsMADENMAsGA1UEAwwEZXRj 7 | ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANftKFvt6FqtrH72afMO 8 | E4YxIXELjAq2/EPeMrx5HpYOkEVEpU13LwrXWn0gcM6U/b0tY0MH/ngIqrPLsGJ1 9 | T5sfsZDXdCYIXYUYs93wwz4px6f/PxvspM3kjBx+y/Yqk2D3LUw+lZWXBMWnXKp9 10 | WbToVsnDjQLD/OJpRLSELDLj6aPbvw173RF6dqupurAdGyb/kG1mW6/hZrK9SsSN 11 | 1Tb9f04YJtibltlfazfeSe8oghH8Ycz5N7IjlxXG23KelmiZSFZzSXcyAYKwcHP9 12 | elKknUexmPojn8zCVyapY6/InZlAFdiwYJ8CDHXYNMfX7VPEiTQDzedZ4w/m7zyc 13 | KPcCAwEAAaNZMFcwDgYDVR0PAQH/BAQDAgUgMBYGA1UdJQEB/wQMMAoGCCsGAQUF 14 | BwMCMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUEgFCX1R1zGGrkpJH9Jl+sk2z 15 | V2owDQYJKoZIhvcNAQELBQADggEBACpPwgtzM/F7YsKyKQjy0otZ0adRcxLJTVXa 16 | /K6Ue9hVWfKISB8WNR77njfO7mdlxYgcqUg/5CUdhfzmQ97ps4rbQlDKdbcqKJxX 17 | 8FJl5wB+vW3B/igtyl61aHmByumGVMl4c554QZurSmiaz1vcbBq4B/PHqHuV+seP 18 | QC7u8uq761T0jvzWUzDkBHGKA39EXfwyHdZN1LlQlk5uhTo3EowqpRovhcRGb45M 19 | MKIvhZiPAc++DU8bwgOzOe8S2G6XfRYKlhwzCaFek6Ra0g5/1WWI/6JQYdhwHGky 20 | 5uU9kSOqQhFY1JuwwbIb8PR78kvZvMQeX4cUnQoamWs0sEf8sNk= 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tls/etcd-client.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEpAIBAAKCAQEA1+0oW+3oWq2sfvZp8w4ThjEhcQuMCrb8Q94yvHkelg6QRUSl 3 | TXcvCtdafSBwzpT9vS1jQwf+eAiqs8uwYnVPmx+xkNd0JghdhRiz3fDDPinHp/8/ 4 | G+ykzeSMHH7L9iqTYPctTD6VlZcExadcqn1ZtOhWycONAsP84mlEtIQsMuPpo9u/ 5 | DXvdEXp2q6m6sB0bJv+QbWZbr+Fmsr1KxI3VNv1/Thgm2JuW2V9rN95J7yiCEfxh 6 | zPk3siOXFcbbcp6WaJlIVnNJdzIBgrBwc/16UqSdR7GY+iOfzMJXJqljr8idmUAV 7 | 2LBgnwIMddg0x9ftU8SJNAPN51njD+bvPJwo9wIDAQABAoIBAQC0vfWMjeZzEPFV 8 | DVq+c0fwieuePrYouecLwFDj5tatcN9evAlKgLtF7eH231LN+XU0B2wRTf256DdL 9 | bPLmV6AdDziJL3Av7cyqfnUBEGm9/Sb8/vGKpFmHZwnJSHHeSuE2x3CJY9G+d70s 10 | 3dz5cRfIELulBCVi7T8fHlK+b+y3Yvlc16c2AFUOINSNYCX2ukrjFm1wsEUxHIjL 11 | GWf2Rz76wQpBIEvVHSdFglU5Og8JcC2MPJgMzgo8v3RwxT4TSLiQdTwjR/qVaUPe 12 | QY1VKDu5NO983QhJiyg9XibtgOdIyCb7IaicmogCYKB/nAWGucbnox7lyihRnjv5 13 | l5AkM68xAoGBAPrqA3NHskmB3Jiac9hdg3tmJNu4m6kvIjGdw/1mC/zODmMFjAr9 14 | S/O0uKVQdbo8rod7NIlCKqPA6mX8K0UaypJV+3HdL4Nhw+SQYjvp7fJl6uzS1IHw 15 | QucRH3TrgpNAKeO2zYgkQcpOZnYI4uKvP+qfEb9ayD1dUkLE6gR1OGcdAoGBANxN 16 | mAcEQa4mK7zxWmFCXlUEHMquQCWL8rCNaIoez9ikqpTeDZVqNPh2zdQ7gPnH0Nj6 17 | bjCfT8Dxd65oBtS7pJXaAv9XYBnCMo1SAFmF/lECxs76Gg7vR+RFEzBG2zFrK7R7 18 | 5pgg9lhIQswBn8ueuWpwCLURknvsV884k2NT0VAjAoGAAgtiF9BfvYWXXI71nq+0 19 | YI8GgdvROOGvb6QPcsMgGeE78Macy4Ig2k2Aq6gqLWhNK8FvPicR3d+2iToyyA9d 20 | 0y9sKxNYTcPAKt6aTk6rp6v47BETtjNU+DkFfphkqfp93OMibZeOCa3128RaxOoU 21 | pT7CkEKXGxjlkLG2Dm8+FGkCgYEAnhMrP/Wk70HCZovD7z/BEj2mLySDMK3PkTGW 22 | Tm03dFsLb1A57PlNUu9kV6HutMvUpqxjPo5Bms9osgNAy4ps2X2aYv+eHD2FKnQp 23 | fhMwXY6heshoxEibjEaoMx7Ujww4SwQQfR5BxSzsiRetQlz87EvBY7NdKYB3rWAK 24 | Gd59tYMCgYA0EinhHtaMwzZWqgSJ9SH5pPyz4DxExMKzm5C/wTU6jnXhNpKG1NDi 25 | cusox7tQqd9oJ4X5WesxcCzjien2Dy/2Up227kbxSBd+E14r1LJKdjv+LWyu+De2 26 | c1ZaZt9MeojTRXkcXLRWRT0PNDjKYSypQ3gy6Ix/Sr5SEzDaf/BfzQ== 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tls/etcd/peer.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIEBzCCAu+gAwIBAgIDAIk1MA0GCSqGSIb3DQEBCwUAMFgxCTAHBgNVBAYTADEJ 3 | MAcGA1UECAwAMQkwBwYDVQQHDAAxCTAHBgNVBBEMADENMAsGA1UECgwEZXRjZDEJ 4 | MAcGA1UECwwAMRAwDgYDVQQDDAdldGNkLWNhMB4XDTE4MDMxMTEwMzQzNVoXDTE5 5 | MDMxMTEwMzQzNVowVTEJMAcGA1UEBhMAMQkwBwYDVQQIDAAxCTAHBgNVBAcMADEJ 6 | MAcGA1UEEQwAMQ0wCwYDVQQKDARldGNkMQkwBwYDVQQLDAAxDTALBgNVBAMMBGV0 7 | Y2QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDQ4gDCFzqwd9iEVnQk 8 | 7jqjmbMmjnl6dQLPGhgphnT6sHWp6A03D4rNAE8Qf7ygqK+WLDQkh7BPFvhoTCCL 9 | j8tqGEZAK+qHruPZH/5CbE7x+5oos+0OXm07p8s5hsYFkJ/RjSLNtAeOnP0HJdiQ 10 | e/T5bDUEv70diRHzGau6i1k8wJIHAxQdy0Ebf++gVGNzC2wWJ8WNdZogzb3mii5l 11 | uwiNvJ7jdi+ajzVoBUakbxycXjBD9BxLfOUf3OhMAdGxhBvF+ezkc/E3eMhffM89 12 | 3wSVAo03i78k8XBF9KsSmzlgTNoHj2vcx6A8oSOmGRTmPN1qhJAqD/CT3BfDIFVZ 13 | uSohAgMBAAGjgdwwgdkwDgYDVR0PAQH/BAQDAgUgMCAGA1UdJQEB/wQWMBQGCCsG 14 | AQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFBIBQl9U 15 | dcxhq5KSR/SZfrJNs1dqMHYGA1UdEQRvMG2CKSoua3ViZS1ldGNkLmt1YmUtc3lz 16 | dGVtLnN2Yy5jbHVzdGVyLmxvY2Fsgi5rdWJlLWV0Y2QtY2xpZW50Lmt1YmUtc3lz 17 | dGVtLnN2Yy5jbHVzdGVyLmxvY2FshwSsEQRlhwQKAwAPhwQKAwAUMA0GCSqGSIb3 18 | DQEBCwUAA4IBAQAwGPG8eRmD0HSqwSIcHZ8NI73FjUWHTikP8I9BDorW9Jk9n18g 19 | DFxXUkKOZSR3u3EeSQYLuohcvfL810nnGB5+uXqvnZAGo04Vu+wuCT/RmOB0OQd0 20 | EobIPrTUdwSmakUZHbndmi76I9r9B3VtmrLtjmDIY8F1GTltUnSBU4nU3nG+ThCy 21 | 3WmuCwpEYigum3zdlwp+KZ69m2fx3/7aa1v5ms1h9fBYtgjvyoeUaqYt92UOitaH 22 | xiUU5fwyxa4Ue/OXulSpam9vrhWE3VrSxd5DJ76aj9rRvI/XQgtu9Z+xwned8WWX 23 | 7eTiLzqh26EjgbhtFEOBWL6frPT1zWbkQKS4 24 | -----END CERTIFICATE----- 25 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tls/etcd/peer.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEA0OIAwhc6sHfYhFZ0JO46o5mzJo55enUCzxoYKYZ0+rB1qegN 3 | Nw+KzQBPEH+8oKivliw0JIewTxb4aEwgi4/LahhGQCvqh67j2R/+QmxO8fuaKLPt 4 | Dl5tO6fLOYbGBZCf0Y0izbQHjpz9ByXYkHv0+Ww1BL+9HYkR8xmruotZPMCSBwMU 5 | HctBG3/voFRjcwtsFifFjXWaIM295oouZbsIjbye43Yvmo81aAVGpG8cnF4wQ/Qc 6 | S3zlH9zoTAHRsYQbxfns5HPxN3jIX3zPPd8ElQKNN4u/JPFwRfSrEps5YEzaB49r 7 | 3MegPKEjphkU5jzdaoSQKg/wk9wXwyBVWbkqIQIDAQABAoIBABOr9R5SSbis0LtF 8 | 2RJRTTxzESgkatRZiLYwYu4mN4YUcEBcFkKFODEuQkPvg7gtqrud1htKnBQWubY4 9 | 1SfPlvya5KLOf/vfQJ4GIU/oG1c2tsH2j/C2e9sOZlk4lBWaFTMK86gjuEJ6DmpJ 10 | 6idRRTToN+YGmKzbZ9FZLY8X6IOMA4MlS3BMY2wRtz+xG3vM5iT0Epltnce/5DLE 11 | 4VwT7fuBLZdqM0mjB9VaQtrF43BpKVJTIvbXegrS5Rn5hgUfOZJToSGyTvmCztmg 12 | JuQARmmjZb87igYvlTFBBNtW6YQlNo0MJBkwgZJ9KbdJ1woOd2K/RJgSeU6ZE67D 13 | z6lLmUECgYEA+ll2UcQt4SqFSInKivLUElfH5FKHkVG9II8qyafMe+TPCjolKLrh 14 | BuTAcWP4U/J+AE6JiOT9guVnZDONnN5kOpmXXp3sy4WEV5AxpmNpX692dRjGiPCI 15 | cGX7ORS5KgMO2UNvzACsdgGzyzciMHRFAw+yQmXSvPqpl82DwpmjuZ0CgYEA1Zjx 16 | ho5hqJdXF9lNfQvlpFOaIgn6LcAQSPLJPTcoste/6OtbiHTnXB9NyJmG84n++Y+x 17 | sqzoiMpDvvUsCRSbiYIcZed8AN7XuSD2hha4PXR8sKYZm6uiGTl5cNDD1CxZ7hci 18 | EMopponz+S6cCvDTymCEr1lua3dArG4Va+Gg3VUCgYEA72PUrGN3q7RJNw/ryeph 19 | uBiQYFg6ok8TFqtQMvxtoJsvD4yCM+xfeYQMMWFy+HMM4aY4BdtSP3S15S8W30YZ 20 | eZ+dCzDgWc0Wu9R6Zazx+jmCgH5sek3nafNawz55wR6jeEXwBZcvUrhWAKB75PGJ 21 | fF/qCWvslCDtQueWcuMPmFECgYAedQWTmz/fq1zW4LyE5SpkqSskSWnsFiP8UupR 22 | GUlrXwpVayINLiZDY49S2Fl+5qF98nhzMuahgr3wP8N8s/yNugjUmxJ6iUwXcNTW 23 | P+0bjj2tbrHeGbYuhJyFcq9J1N0p7xCDdmBECA3K7VOA1+BLTkH9QvJUzpdhPv08 24 | +dpXVQKBgG728ki8NMaiBmF8AMnel/t152vltQCN3wItyvJAqXE7bYQEeTNhZwqf 25 | CIoQv4udI9EAPJcaS+GlEWan7hXU28ThjfqImACTiolYeR0Fr7AHGK+50vM5wtYN 26 | Mnl3ILyLYZom6bSuVQYIGgnaUc6s5etBLajGEnlj+KwBjRd0cxD7 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tls/etcd/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIEDzCCAvegAwIBAgICExowDQYJKoZIhvcNAQELBQAwWDEJMAcGA1UEBhMAMQkw 3 | BwYDVQQIDAAxCTAHBgNVBAcMADEJMAcGA1UEEQwAMQ0wCwYDVQQKDARldGNkMQkw 4 | BwYDVQQLDAAxEDAOBgNVBAMMB2V0Y2QtY2EwHhcNMTgwMzExMTAzNDM1WhcNMTkw 5 | MzExMTAzNDM1WjBVMQkwBwYDVQQGEwAxCTAHBgNVBAgMADEJMAcGA1UEBwwAMQkw 6 | BwYDVQQRDAAxDTALBgNVBAoMBGV0Y2QxCTAHBgNVBAsMADENMAsGA1UEAwwEZXRj 7 | ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKV4YXzknO+IZkMFkwyb 8 | r95bA9TPpfYw1bEYzWkhqw8w06zMvhjZpf7qeHd3RLDsKG5tj3iZE/Xaxmehv+B5 9 | K09jwjO/70repxh1Z0NWPuZpIm8fmwQS3FJrIUls82eKVCrpe+6o8v/B7eThGdKr 10 | E6QHbFjTf/uIBxg6wzihlSODWBu43pFqAKs6UN3qgIqjed7P+UUuy65Mi1T+szyj 11 | t9e8cVGtvbDOqJD+pOn41TqwQJUDLAngAuadV/echrry3wCAYWgWoBar7In35pEM 12 | IQavor6sf0+P5poO761dDfadOtzLyDKt/z/KE88O4JoHhnbBBORNm7iGwa1SnoId 13 | sP0CAwEAAaOB5TCB4jAOBgNVHQ8BAf8EBAMCBSAwFgYDVR0lAQH/BAwwCgYIKwYB 14 | BQUHAwEwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBQSAUJfVHXMYauSkkf0mX6y 15 | TbNXajCBiAYDVR0RBIGAMH6CCWxvY2FsaG9zdIIpKi5rdWJlLWV0Y2Qua3ViZS1z 16 | eXN0ZW0uc3ZjLmNsdXN0ZXIubG9jYWyCLmt1YmUtZXRjZC1jbGllbnQua3ViZS1z 17 | eXN0ZW0uc3ZjLmNsdXN0ZXIubG9jYWyHBH8AAAGHBKwRBGWHBAoDAA+HBAoDABQw 18 | DQYJKoZIhvcNAQELBQADggEBALkAJRmtVAUXQ12CIHLia/3Jlko4peTrtAKJ21c3 19 | kdtbLI9SKT2deKDOaGOhwH0BdGug0pI+icxyKZE2fEbZnU5NYzHDjJQFAWJW50lh 20 | lCWwcfd4lfrBi5o6DhmUaxPjTxyJEQMIodKUToRiCSZsxU1vDG+/r3lSKWRfRbBo 21 | ybml6V5+E7/RXhRSDH7hUuPyGIGjA1sFBFB2xqtzhvPJIwV8zKZBfhZtd6IDMHkA 22 | m6FZwWRfoYxHLoJJPAJHzU2lmxyzsUZiDEV8iQdP0jhf+f3IKzlzmfl/KdBYioWt 23 | pnkY83OxhwYrwRDhIRcDkYJfm18ZlKG+Hd2mE3ZuZfj8eGU= 24 | -----END CERTIFICATE----- 25 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tls/etcd/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEpAIBAAKCAQEApXhhfOSc74hmQwWTDJuv3lsD1M+l9jDVsRjNaSGrDzDTrMy+ 3 | GNml/up4d3dEsOwobm2PeJkT9drGZ6G/4HkrT2PCM7/vSt6nGHVnQ1Y+5mkibx+b 4 | BBLcUmshSWzzZ4pUKul77qjy/8Ht5OEZ0qsTpAdsWNN/+4gHGDrDOKGVI4NYG7je 5 | kWoAqzpQ3eqAiqN53s/5RS7LrkyLVP6zPKO317xxUa29sM6okP6k6fjVOrBAlQMs 6 | CeAC5p1X95yGuvLfAIBhaBagFqvsiffmkQwhBq+ivqx/T4/mmg7vrV0N9p063MvI 7 | Mq3/P8oTzw7gmgeGdsEE5E2buIbBrVKegh2w/QIDAQABAoIBAG9mnmuRFj8Fm6Nf 8 | q2J/pmWS7P9nVRpsQlHamuA+tIWjn77kkM72KRV4EeaMO4jJVWcTB9ZvaMrKoWy/ 9 | rwiXSxtF1Ec23wmO4PxMflsNQ4eoHHCn3Jtff0lVqrFeUnjQ3l2Nl8xTnlWl4F2J 10 | VvNIDg8OmFks+ysCp5Qea7RCxL+E5rgZX0MvSmjyAQ6HcsYG2OJDLt/d0WRq2oOr 11 | Nn55CvhgXCkUlv5dIL64PagHsMPC42mx+vCySfNzdUklApvMY2t8sKaGxcvAopd6 12 | kwDYd6+JrNDyXn3UkSV8M8W5fvXYpHoVGsXckRpCYJP75XDK9+TZvnIKWrU6LXCr 13 | y2ZJGsECgYEAzvDUiVX9jDaHEgzehvHFzCWeAjt8Fx2j0uzykg4EeRcAqdJVhBj0 14 | e7YpQwQEoRLxVdYFiYesqVocdlQPvvd6vBCScvf8BZRATk7p5D7iqJcXOR5tjxGN 15 | k8QHDjQTnU6pJ9jAFWDuuM8XfhYeVKQN+f7tTNudh+fc5qdyVxzehiUCgYEAzLK3 16 | 6nJ4gJ2dOHpEibB7j1ZTvPndrhC7qiFYOpvU7ejsNkku+7bPv4tT17nB4iPZSVcL 17 | QSJI6xEemevme20vtSmOIF0Zf9EYIrQUY3l93ViNm2eBj7SwyXExtOEaKR68dxMT 18 | VzjL00aE9sQiini0iNw3is1T5qdtvfMU7TsBK/kCgYAFnHAW3TcHwz68VY7/F7Um 19 | SOrU4qoFsm8LvBMDtM+YPPBuql5ZO5f9dr39rDE38NyMWEZEKWKcIO5eov7eTbWN 20 | PeHKrkCuIgvwU6Fx5+abbaVajiGoXHB7TjhmwTC69jQN+YmTytIOPsdDSvQ9lUkv 21 | uyLSD65gzf+mXWnzRLwf5QKBgQCjRCjNJmBWtWAhG+RurgTfXsuLfwABRfdoyw/E 22 | L2a2G4HMCrMescEh1c8Z0V+DL3Svum2PlfjzBMSToERFTeEvbeWeiqM7/1pw05Ev 23 | hkeNtIO93+DG7ifThCVRT/m9snY/w0c52mM4MJb8+5NRPtVAE+V5ICw7XG97gda/ 24 | IMDegQKBgQCz6vflN2FHplq/BqO+55JpOPqBqppg0/dQavBYhKNgEd2hXs/2/Blp 25 | SsAsQenCXLu02m3Fq9hF7ZFTpc4B3GwgkWKxVYO37CeGTWdM0HLSopll0PJegOsd 26 | bnbKurbnaEhOwF6A2eXz9p9jPmrF3S8b6tf+NkA6tWognCsHFIG1Aw== 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tls/kubelet.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDnjCCAoagAwIBAgIDAM3zMA0GCSqGSIb3DQEBCwUAMFwxCTAHBgNVBAYTADEJ 3 | MAcGA1UECAwAMQkwBwYDVQQHDAAxCTAHBgNVBBEMADERMA8GA1UECgwIYm9vdGt1 4 | YmUxCTAHBgNVBAsMADEQMA4GA1UEAwwHa3ViZS1jYTAeFw0xODAzMTExMDM0MzVa 5 | Fw0xOTAzMTExMDM0MzVaMGIxCTAHBgNVBAYTADEJMAcGA1UECAwAMQkwBwYDVQQH 6 | DAAxCTAHBgNVBBEMADEXMBUGA1UECgwOc3lzdGVtOm1hc3RlcnMxCTAHBgNVBAsM 7 | ADEQMA4GA1UEAwwHa3ViZWxldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC 8 | ggEBALyB/fNKrOL5prSM5zKuf84bp4TrbFVaJbDikQki0HH+nuyaJCRvN1IPsgfR 9 | c0lw+2flK0XnXcP+FE2xABa6T26jhhMfOHnmq37Uwxolg4ghEjH6lEXaN2I2g1/8 10 | LIlDly9m0/zF0MfdZxMrpixJnakc2jCdf0fqpHHIb24/JkVPOnisPcNcKeoRyu9L 11 | qx79bsRhw/EiydPUeK4q/Kbp3m9uc2PfCTVl1vi/FV/U1WyyleWW8P7QrQfe6VS5 12 | xaeXEv4QQSht+ITH1B9z0sh0lixCiwpwoMMNyxqh/V58cFP48T/cB7GqlmFsIJf3 13 | AUJuCYcBo0NNS+HGzlvMe++/+HMCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgWgMCAG 14 | A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB8G 15 | A1UdIwQYMBaAFIi7ldQ1kCXC/CXSjzb3TEXqhl9vMA0GCSqGSIb3DQEBCwUAA4IB 16 | AQBzqKFKbY7Nb5AcwkkZkhkdCkieMK36EYMseRn9gEBz+aYPIdfra2xQ1y63CErB 17 | A3GxkexI5o1nTCKmTd1tfYA2OHo5b9lII4nD+XucQY87V9bdQ8S26WF/TbyHwQjc 18 | M2K1C5QcgeIqCHYYj6793DTS51ftT4JjVUNgmn+U3SCBmBI0fxRub0/Kz7ZuB/Y5 19 | oOAH9fJI24xOD8Ybo6lJO0m2ge53pTtUj/0F6AOwzKAS6rE3u+I4wyBl3AZllLoI 20 | VrOLyDDsPUV4MqNDuLmvO7gftR0NOQO2gVQ32HHJFhRMdbYSxWixdK5OVAnS4Cz/ 21 | voNSKC4x3FwFgrr2L6rXPwvt 22 | -----END CERTIFICATE----- 23 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tls/kubelet.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEogIBAAKCAQEAvIH980qs4vmmtIznMq5/zhunhOtsVVolsOKRCSLQcf6e7Jok 3 | JG83Ug+yB9FzSXD7Z+UrReddw/4UTbEAFrpPbqOGEx84eearftTDGiWDiCESMfqU 4 | Rdo3YjaDX/wsiUOXL2bT/MXQx91nEyumLEmdqRzaMJ1/R+qkcchvbj8mRU86eKw9 5 | w1wp6hHK70urHv1uxGHD8SLJ09R4rir8puneb25zY98JNWXW+L8VX9TVbLKV5Zbw 6 | /tCtB97pVLnFp5cS/hBBKG34hMfUH3PSyHSWLEKLCnCgww3LGqH9XnxwU/jxP9wH 7 | saqWYWwgl/cBQm4JhwGjQ01L4cbOW8x777/4cwIDAQABAoIBAHEBnLPU+H+5Ge7y 8 | 6UbAxW1RtsNAPtmMCTxZFolbjYpJEgzU+wW8hnVzY068iVhlmtFV2PM3GEb+cj2A 9 | 9oSpfCTfcujTto+dcQG/mpZ6Frfs23OKvIiDoOAHvgo0qp4/HssT4dGO5PJsD/a2 10 | HBBAsXtICKVMRZlfWOW9Os/km5TAOu38CUhDKOJlRktB7V+ES6eEi3yM6x83qWv0 11 | dv+o0JrIg3MFExSiSoFhi9LF25ntscR1ovQJ0KPBsScVosveRrQSWD6dT73NhSMp 12 | QOTTvok7dMnBT38D1ovbqPUZ529EiIaYz6aDDkX2eSd/5gUHgkPyiG52o47/3Fzv 13 | I7sgeEECgYEA3iSG6QzW9Tc/ieuc+8FxNjjk0JlG1/X72XFpYLpLwORig619OUxN 14 | hw+kQ/NbTK7onfwEOyiORqAL69fJ9CAz7czDvEHNj8YhV1CAyQwprmmJhnmU5ZZE 15 | kVkRG3VEKZTtL5sNahakuIpipcwFBUmiOjrJPpOouqt09mCBB38O0NUCgYEA2T0c 16 | rrW1oAu2GbTdEyD22pXpkMMivJCgbIujuHanSca5y1s0/psg+JKLzCFzp3+KMSKA 17 | KBcgpI7M9qd7JN8cjCE8l45xMSf3bEeIGOrQBJtnw2yW92Fp2PTlxHQskfWLu1Df 18 | XDCCDl1JmkuMJH7H555yYhK+dixXS5Hr5m3ZiCcCgYBvCSb+GlLf4yu5TrH7DOf/ 19 | yFRnCBZnICcwuwWHOddfpUiwtOkg2Mjvt5vN8zgxjkPro+qhf1YOazVKP2RMyEPs 20 | mytDUEjlko1bzXtyAshay5nYQ7FvSLshQ7nPVcAqYKxl3UTJQGQ5ccJ5SQ9BY1rZ 21 | bETnKHtwQv+FnxsfmhzXuQKBgGmBUa3UWHp7VZyUh44jw2AT0NTawMMd5pvxEbmj 22 | /slI97E5Abrp8pBm8/hXAsmFmsMUQ3O1D8h8BjWAz8DvjvjLp5bfuj+qbnMrJoEb 23 | gZ3LMBDsa0GIERUqk3DfD0pwG8YEmAY5FOEPE5EZQd3zqPjnrhvNiKzyCg+Mtio6 24 | jZyfAoGAKiP6HqCssd3vDy71mLh22Hk33EKKgm0xqQZAlC3GDbEpjwZFrf4pva18 25 | L88R7MKDpMX5fA4bVQtqSewyehzLSiVFB1dj54pcWJ1H6TtUDxE5GAEZB+US7HuH 26 | rqoU6LKcEcPZA2V31flfo7xFi1xKQMu1r3og74esaKYsGOFq458= 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tls/service-account.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEogIBAAKCAQEA1QKc8sSg4/MXRHyzPEaei92cy0eF18C1fiod0ZBMvOtUWJcv 3 | 9714H5LS/ZYjlA1mBhEaxreh+wmEfY7y5mtRQCS68/xbpnLLRmCifmXWJZn3Qq+t 4 | NDb8SkkfAMyh8HR20GNIavddBx89x9bc0L17YlsBzQkGY2TS875UbZVpSrot2bKk 5 | 2MbwqxN75qcUOhALf9GdpsjNg7WqVluPIAo7oa/qOxI5mhuEasu9g7JQioWar/3p 6 | mp7IQnuEyysEkaXEvkogUI7/swU52W+Kpm6vAWcvnWZX+oV6ijvLrSJj7yRSPper 7 | LOTN+OclWcifopolT0fjvoPeoyoJEVTgt6pqtQIDAQABAoIBAD9E2W1abheG+uBC 8 | 0dITf8A3gPz4L48YFFB3HghC/igXFiSCM6M4SdfG+piL4eF14Vnn9rYTkS9JcmsA 9 | 7LD4K1gMEOOrj2VvL2WmCl3Uzbi5dLIAEEg0FNfTxDuujGMplKjs9HOhKaaV5vnW 10 | nhv6TA24zl4iUh1vsyDm5ZjvCilBfMCqt73pyQFhiT2W/Oh6UmaS6CpWgVjBGrBA 11 | 8THzlMheD0AKPGAER/e914IjuVreOastqI9NEuNOrSdFN1Qw6Pilo7dSpK7jUXZh 12 | mT3ucHLKX2L4UqMpLQxdSiRGRFd06LGIwFxyFBGz5Z4gJCo9e5ClOCA5HHa9P5mD 13 | xpXdQ0ECgYEA9MPwB2monIEEwedkX0PsuKtTFF0ZHsdocxE9optd7hgE8z/+plw/ 14 | hlujJfS16/SPi/Vb86K0yA8SCswVWTGN/Y3B1yzfmeu2n0cqgMYcYVKNQqbKGZiJ 15 | aTqkvERnHn1NdoZG2nc0ePrvH/hYOzCf2sghRouLDhm7zdKoByWwSx0CgYEA3smL 16 | DygihmmffG9bm8wXPUAbIVnn68Q9LciHI+YqVW3a8fSqXFG1fHD6rZmfQ2JwxuEK 17 | 9oIVr7X7crYeBpK4u5HeeTUQ896cYAAKmZJdon3dmwpXQgupvR+VgG+J11jV74vL 18 | EdGCxQro9XDvKl1jPWAHb4uzFAfKXSNvK3Q0cnkCgYBHihlW4U/x5lfQoOQaYA0J 19 | cLHIqulTsK7bqvdb1pNeqtCPlG3GjAHZMGGAD4U4oPNv0df9Xtn9+0GnvDylJDG/ 20 | ITa9wJTeNSHcbf2DQ+Q5odo91+gMESRgiE5r5IZLSA5jDR4abmr8zUMlEf4f1rdy 21 | R7pKFzEefvEAWIjaBe8AFQKBgBAyvS6b726wbU0h15pLS4FDkPVq0Qb+XKhghRri 22 | GD/f3eRrsptFwZlLqZ5HpiHDHYoIQMDNkoAVDjQ385TsxAu3PmK3rgTdMad1OVAT 23 | KUWwOxWTueZubKf4jOkqsu36YoupMVmZTxW+hlOaI3mEErwaqE++64VQT7FX6zRQ 24 | naOZAoGAYtmOlq/JeeLP0dBoPOsj76EbCZKr1TBVGWxOJyD6+XXR4TR26I2I3+RO 25 | 493p3UQUOYbntlAcjX5MjIrT4T1w4D6wpbnnYfFQA4hYlphED7F9XD2DuESTIH4t 26 | 8ICnz+3lpew8k9siQPsg75gE1DiC5klK0ibVkHF2ETCCxG78Aik= 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/tectonic/tls/service-account.pub: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1QKc8sSg4/MXRHyzPEae 3 | i92cy0eF18C1fiod0ZBMvOtUWJcv9714H5LS/ZYjlA1mBhEaxreh+wmEfY7y5mtR 4 | QCS68/xbpnLLRmCifmXWJZn3Qq+tNDb8SkkfAMyh8HR20GNIavddBx89x9bc0L17 5 | YlsBzQkGY2TS875UbZVpSrot2bKk2MbwqxN75qcUOhALf9GdpsjNg7WqVluPIAo7 6 | oa/qOxI5mhuEasu9g7JQioWar/3pmp7IQnuEyysEkaXEvkogUI7/swU52W+Kpm6v 7 | AWcvnWZX+oV6ijvLrSJj7yRSPperLOTN+OclWcifopolT0fjvoPeoyoJEVTgt6pq 8 | tQIDAQAB 9 | -----END PUBLIC KEY----- 10 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/templates/ca-cert.tmpl: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: tectonic-ca-cert-secret 5 | namespace: tectonic-system 6 | type: Opaque 7 | data: 8 | ca-cert: {{CA_CRT}} 9 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/templates/config.tmpl: -------------------------------------------------------------------------------- 1 | kind: ConfigMap 2 | apiVersion: v1 3 | metadata: 4 | name: tectonic-config 5 | namespace: tectonic-system 6 | data: 7 | clusterID: "{{UUID}}" 8 | clusterName: "vagrant" 9 | installerPlatform: "sandbox-virtualbox-{{OS}}" 10 | certificatesStrategy: "installerGeneratedCA" 11 | consoleBaseAddress: "https://console.tectonicsandbox.com" 12 | kubeAPIServerURL: "https://172.17.4.101:443" 13 | tectonicVersion: "1.7.5-tectonic.1" 14 | dexAPIHost: "tectonic-identity-api.tectonic-system.svc.cluster.local:5557" 15 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/templates/configmap.tmpl: -------------------------------------------------------------------------------- 1 | kind: ConfigMap 2 | apiVersion: v1 3 | metadata: 4 | name: tectonic-identity 5 | namespace: tectonic-system 6 | data: 7 | issuer: https://console.tectonicsandbox.com/identity 8 | consoleClientID: tectonic-console 9 | consoleSecret: {{CONSOLE_SECRET}} 10 | kubectlClientID: tectonic-kubectl 11 | kubectlSecret: {{KUBECTL_SECRET}} 12 | config.yaml: | 13 | issuer: https://console.tectonicsandbox.com/identity 14 | storage: 15 | type: kubernetes 16 | config: 17 | inCluster: true 18 | web: 19 | http: 0.0.0.0:5556 20 | grpc: 21 | addr: 0.0.0.0:5557 22 | tlsCert: /etc/tectonic-identity-grpc-server-secret/tls-cert 23 | tlsKey: /etc/tectonic-identity-grpc-server-secret/tls-key 24 | tlsClientCA: /etc/tectonic-identity-grpc-server-secret/ca-cert 25 | frontend: 26 | theme: 'tectonic' 27 | issuer: 'Tectonic Identity' 28 | oauth2: 29 | skipApprovalScreen: true 30 | staticClients: 31 | - id: tectonic-console 32 | redirectURIs: 33 | - 'https://console.tectonicsandbox.com/auth/callback' 34 | - 'https://console.tectonicsandbox.com/prometheus/auth/callback' 35 | - 'https://console.tectonicsandbox.com/alertmanager/auth/callback' 36 | - 'https://console.tectonicsandbox.com/grafana/auth/callback' 37 | name: 'Tectonic Console' 38 | secret: {{CONSOLE_SECRET}} 39 | - id: tectonic-kubectl 40 | public: true 41 | trustedPeers: 42 | - tectonic-console 43 | name: 'Kubectl' 44 | secret: {{KUBECTL_SECRET}} 45 | enablePasswordDB: true 46 | staticPasswords: 47 | - email: "admin@example.com" 48 | hash: "$2a$10$rQ13TGgO3wP3QPFVzFt8ReIjb5Tb7WxVMIuc54Lwu2v446vrDjy06" 49 | username: "admin" 50 | userID: "{{USER_ID}}" 51 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/templates/identity-grpc-client.tmpl: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: tectonic-identity-grpc-client-secret 5 | namespace: tectonic-system 6 | type: Opaque 7 | data: 8 | tls-cert: {{CLIENT_CRT}} 9 | tls-key: {{CLIENT_KEY}} 10 | ca-cert: {{CA_CRT}} 11 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/templates/identity-grpc-server.tmpl: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: tectonic-identity-grpc-server-secret 5 | namespace: tectonic-system 6 | type: Opaque 7 | data: 8 | tls-cert: {{SERVER_CRT}} 9 | tls-key: {{SERVER_KEY}} 10 | ca-cert: {{CA_CRT}} 11 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/templates/ingress-tls.tmpl: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: tectonic-ingress-tls-secret 5 | namespace: tectonic-system 6 | type: Opaque 7 | data: 8 | tls.crt: {{INGRESS_CRT}} 9 | tls.key: {{INGRESS_KEY}} 10 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/templates/kube-apiserver-secret.tmpl: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: kube-apiserver 5 | namespace: kube-system 6 | type: Opaque 7 | data: 8 | apiserver.key: {{APISERVER_KEY}} 9 | apiserver.crt: {{APISERVER_CRT}} 10 | service-account.pub: {{SERVICE_ACCOUNT_PUB}} 11 | ca.crt: {{CA_CRT}} 12 | etcd-client-ca.crt: {{ETCD_CA_CRT}} 13 | etcd-client.crt: {{ETCD_CLIENT_CRT}} 14 | etcd-client.key: {{ETCD_CLIENT_KEY}} 15 | oidc-ca.crt: {{OIDC_CA_CRT}} 16 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/templates/kube-controller-manager-secret.tmpl: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: kube-controller-manager 5 | namespace: kube-system 6 | type: Opaque 7 | data: 8 | service-account.key: {{SERVICE_ACCOUNT_KEY}} 9 | ca.crt: {{CA_CRT}} 10 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/templates/kubeconfig.tmpl: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Config 3 | clusters: 4 | - name: vagrant 5 | cluster: 6 | server: https://172.17.4.101:443 7 | certificate-authority-data: {{CA_CERT}} 8 | users: 9 | - name: kubelet 10 | user: 11 | client-certificate-data: {{CLIENT_CERT}} 12 | client-key-data: {{CLIENT_KEY}} 13 | contexts: 14 | - context: 15 | cluster: vagrant 16 | user: kubelet 17 | -------------------------------------------------------------------------------- /chapter9/tectonic-sandbox-1.7.5-tectonic.1/provisioning/templates/tectonic-monitoring-auth-secret.tmpl: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: tectonic-monitoring-auth 5 | namespace: tectonic-system 6 | data: 7 | cookie_secret: {{COOKIE_SECRET}} 8 | --------------------------------------------------------------------------------