├── .buildscript
├── deploy_snapshot.sh
└── settings.xml
├── .gitignore
├── .travis.yml
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── clocker.bom
├── common
├── catalog
│ ├── catalog.bom
│ ├── common
│ │ ├── ca.bom
│ │ ├── common.bom
│ │ ├── haproxy-template.bom
│ │ └── haproxy.bom
│ └── docker
│ │ └── docker.bom
├── examples
│ └── ca.yaml
├── pom.xml
├── resources
│ ├── common
│ │ └── certificate-functions.sh
│ └── icons
│ │ ├── centos.png
│ │ ├── docker.png
│ │ ├── haproxy.png
│ │ └── openssl.png
└── tests
│ └── docker
│ ├── common.tests.bom
│ ├── docker.tests.bom
│ └── tests.bom
├── feature
├── pom.xml
└── src
│ └── main
│ └── feature
│ └── feature.xml
├── kubernetes
├── catalog
│ ├── catalog.bom
│ └── kubernetes
│ │ ├── kubernetes.bom
│ │ ├── plugins.bom
│ │ └── pods.bom
├── examples
│ ├── kubernetes-minimal.yaml
│ └── kubernetes.yaml
├── pom.xml
├── resources
│ ├── icons
│ │ ├── calico.png
│ │ ├── flannel.png
│ │ ├── kubernetes.png
│ │ ├── openshift.png
│ │ └── prometheus.png
│ └── kubernetes
│ │ ├── basic_auth.csv
│ │ ├── kube-dns.yaml
│ │ ├── kubernetes-dashboard.yaml
│ │ ├── policy-controller.yaml
│ │ └── prometheus.yaml
└── tests
│ └── kubernetes
│ ├── kubernetes.tests.bom
│ ├── tests.default.bom
│ └── tests.no-shared-security-group.bom
├── pom.xml
└── swarm
├── catalog
├── catalog.bom
└── swarm
│ └── swarm.bom
├── examples
├── custom-swarm.yaml
├── swarm-byon.yaml
├── swarm-minimal.yaml
├── swarm-using-external-resources.yaml
└── swarm.yaml
├── pom.xml
├── resources
└── icons
│ └── swarm.png
└── tests
└── swarm
├── swarm.tests.bom
├── tests_with_shared_group.bom
└── tests_without_shared_group.bom
/.buildscript/deploy_snapshot.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Deploy jars to Sonatype's snapshot repo.
4 | #
5 | # Adapted from https://coderwall.com/p/9b_lfq and
6 | # http://benlimmer.com/2013/12/26/automatically-publish-javadoc-to-gh-pages-with-travis-ci/
7 |
8 | SLUG="brooklyncentral/clocker"
9 | BRANCH="master"
10 |
11 | set -e
12 |
13 | if [ "$TRAVIS_REPO_SLUG" != "$SLUG" ]; then
14 | echo "Skipping snapshot deployment: wrong repository. Expected '$SLUG' but was '$TRAVIS_REPO_SLUG'."
15 | elif [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
16 | echo "Skipping snapshot deployment: was pull request."
17 | elif [ "$TRAVIS_BRANCH" != "$BRANCH" ]; then
18 | echo "Skipping snapshot deployment: wrong branch. Expected '$BRANCH' but was '$TRAVIS_BRANCH'."
19 | else
20 | echo "Deploying snapshot..."
21 | mvn clean deploy --settings=".buildscript/settings.xml" -Dmaven.test.skip=true
22 | echo "Snapshot deployed!"
23 | fi
24 |
--------------------------------------------------------------------------------
/.buildscript/settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | sonatype-nexus-snapshots
5 | ${env.CI_DEPLOY_USERNAME}
6 | ${env.CI_DEPLOY_PASSWORD}
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .classpath
2 | .project
3 | .settings
4 | eclipsebin
5 |
6 | bin
7 | gen
8 | out
9 | lib
10 |
11 | test-output
12 |
13 | target
14 | pom.xml.*
15 | release.properties
16 |
17 | .idea/*
18 | *.iml
19 | *.ipr
20 | *.iws
21 | classes
22 |
23 | *.log*
24 | obj
25 | *.swp
26 | .DS_Store
27 | *.swp
28 |
29 | .vagrant
30 | brooklyn-clocker/
31 | external-resources/
32 |
33 | .checkstyle
34 |
35 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | # Copyright 2014-2015 by Cloudsoft Corporation Limited
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | sudo: false
16 |
17 | script: mvn clean install
18 |
19 | after_success:
20 | - .buildscript/deploy_snapshot.sh
21 |
22 | env:
23 | global:
24 | - secure: "NfjzLpDuRQozk7CXxiR+u9brsDn6j5CnAUwS0VGgVnGfR6p3TazemlhXCyDsYHzvc2CDm/R61lRe0KJ81ahUlDt6aQucjMfgRA1GOYJy9GuQQsIisr91bOrs3p1frsb0iYxqPU9Rp9uhhu6aG1Hk26hWu7uPR8wKlF0MX3v/QmY="
25 | - secure: "L/iMDibl60hJX1Gax0n0mxNFbrIJ2Sg+KfagWEVpI0EgjF5VtwYkE+d0bTnC5jH/HpyDfA5SdnXMcSAyxcePJg2YHzk+bf2+55pc+os29dVSXRbL87bPJb9Rjl0IvxBOjREOXTLsA50ARnmrJElbAhYAdHJR0RaGhtRvQMiWpmA="
26 |
27 | cache:
28 | directories:
29 | - $HOME/.m2
30 | notifications:
31 | email:
32 | - andrew.kennedy@cloudsoft.io
33 | - andrea.turli@cloudsoft.io
34 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | Contributing to Clocker
2 | ====
3 |
4 | Clocker is part of the [Brooklyn Central](https://github.com/brooklyncentral/) family of contributions to the [Apache Brooklyn](http://brooklyn.incubator.apache.org/) project,
5 | sponsored by [Cloudsoft](http://www.cloudsoftcorp.com/).
6 |
7 | All contributions are licensed under the [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0) license. Contributors should ensure they have permission from
8 | the owner or or own the copyright themselves, for any submission.
9 |
10 | Please read the [wiki](https://github.com/brooklyncentral/clocker/wiki) to find out more, or email us at [clocker@cloudsoft.io](mailto:clocker@cloudsoft.io).
11 |
12 | Thanks!
13 |
14 | _Andrew Kennedy_ [**@grkvlt**](http://github.com/grkvlt/) / [abstractvisitorpattern.co.uk](http://blog.abstractvisitorpattern.co.uk)
15 |
16 | ----
17 | Copyright 2014-2015 by Cloudsoft Corporation and licensed under CC-BY-SA 4.0
18 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://travis-ci.org/brooklyncentral/clocker)
2 |
3 | # Clocker
4 |
5 | The current release is **2.0.0**, available in Maven Central. For more
6 | information, see the [official Clocker site](http://www.clocker.io/), including
7 | [documentation](http://www.clocker.io/docs/) and [tutorials](http://www.clocker.io/tutorials/).
8 |
9 | The development version is **2.1.0-SNAPSHOT**, available in the Sonatype Open-Source
10 | repository. To install this, follow the instructions below.
11 |
12 | ## Overview
13 |
14 | Clocker for [Apache Brooklyn](https://brooklyn.apache.org/) is a set of open
15 | source, Apache Licensed tools designed to make working with [Docker](https://www.docker.com/)
16 | containers as simple as a few clicks. Clocker contains [Brooklyn blueprints](http://brooklyn.apache.org/v/latest/start/blueprints.html)
17 | to enable deployment and management of [Docker Swarm](https://www.docker.com/products/docker-swarm)
18 | and [Kubernetes](http://kubernetes.io/) clusters.
19 |
20 | You will find the source code for the blueprints in this repository.
21 |
22 | * [Docker](./common/catalog/docker/)
23 | * [Swarm](./swarm/catalog/swarm/)
24 | * [Kubernetes](./kubernetes/catalog/kubernetes/)
25 |
26 | ## Getting Started
27 |
28 | ### Add Clocker to Brooklyn (Karaf Edition)
29 |
30 | Add catalog entries using the YAML below:
31 |
32 | ```YAML
33 | brooklyn.catalog:
34 | brooklyn.libraries:
35 | - "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.etcd&a=brooklyn-etcd&v=2.7.0-SNAPSHOT"
36 | - "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-common&v=2.1.0-SNAPSHOT"
37 | - "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-swarm&v=2.1.0-SNAPSHOT"
38 | - "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-kubernetes&v=2.1.0-SNAPSHOT"
39 | items:
40 | - classpath://io.brooklyn.clocker.swarm:swarm/catalog.bom
41 | - classpath://io.brooklyn.clocker.kubernetes:kubernetes/catalog.bom
42 | ```
43 |
44 | ### Add Clocker to Brooklyn (Classic Edition)
45 |
46 | You must add the following JARs to `./lib/dropins`:
47 |
48 | * [brooklyn-etcd](https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.etcd&a=brooklyn-etcd&v=2.7.0-SNAPSHOT)
49 | * [common](https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-common&v=2.1.0-SNAPSHOT)
50 | * [swarm](https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-swarm&v=2.1.0-SNAPSHOT)
51 | * [kubernetes](https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-kubernetes&v=2.1.0-SNAPSHOT)
52 |
53 | Then add the catalog entries using the following YAML:
54 |
55 | ```YAML
56 | brooklyn.catalog:
57 | items:
58 | - classpath://swarm/catalog.bom
59 | - classpath://kubernetes/catalog.bom
60 | ```
61 |
62 | ## Copyright
63 |
64 | The following icon images have been used, and their use here is believed to be
65 | acceptable under their licensing terms or fair use doctrine. The source URLs
66 | and other links given contain more details:
67 |
68 | - [`common/resources/icons/centos.png`](https://commons.wikimedia.org/wiki/File:Centos-logo-light.svg) Remixed version of freely available logo
69 | - [`common/resources/icons/docker.png`](https://www.docker.com/brand-guidelines) Icon taken from media kit
70 | - [`common/resources/icons/haproxy.png`](https://pbs.twimg.com/profile_images/737664607301566464/pmfqGAYU.jpg) Fair use of logo from Twitter account for open source project
71 | - [`common/resources/icons/openssl.png`](https://commons.wikimedia.org/wiki/File:OpenSSL_logo.png) Public domain image
72 | - [`swarm/resources/icons/swarm.png`](https://www.docker.com/sites/default/files/docker-swarm-hero2.png) Fair use of image from and also found in Docker media kit
73 | - [`kubernetes/resources/icons/calico.png`](https://github.com/projectcalico/calico/blob/master/images/favicon.png) APACHE 2.0 image
74 | - [`kubernetes/resources/icons/flannel.png`](https://github.com/coreos/flannel/blob/master/logos/flannel-horizontal-color.png) APACHE 2.0 image
75 | - [`kubernetes/resources/icons/kubernetes.png`](https://raw.githubusercontent.com/kubernetes/kubernetes/master/logo/logo.png) APACHE 2.0 image
76 | - [`kubernetes/resources/icons/prometheus.png`](https://github.com/prometheus/docs/blob/master/static/prometheus_logo.png) APACHE 2.0 image
77 | - [`kubernetes/resources/icons/openshift.png`](https://github.com/openshift/origin-web-console/blob/e7a0c0a8f703d5429f70b78223abb31856a66670/app/images/openshift-logo.svg) APACHE 2.0 image
78 |
--------------------------------------------------------------------------------
/clocker.bom:
--------------------------------------------------------------------------------
1 | brooklyn.catalog:
2 | brooklyn.libraries:
3 | - "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.etcd&a=brooklyn-etcd&v=2.5.0-SNAPSHOT"
4 | - "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-common&v=2.1.0-SNAPSHOT"
5 | - "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-swarm&v=2.1.0-SNAPSHOT"
6 | - "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-kubernetes&v=2.1.0-SNAPSHOT"
7 | items:
8 | - classpath://io.brooklyn.clocker.swarm:swarm/catalog.bom
9 | - classpath://io.brooklyn.clocker.kubernetes:kubernetes/catalog.bom
10 |
--------------------------------------------------------------------------------
/common/catalog/catalog.bom:
--------------------------------------------------------------------------------
1 | brooklyn.catalog:
2 | items:
3 | - classpath://common/common.bom
4 | - classpath://common/ca.bom
5 | - classpath://common/haproxy.bom
6 | - classpath://docker/docker.bom
7 |
--------------------------------------------------------------------------------
/common/catalog/common/ca.bom:
--------------------------------------------------------------------------------
1 | brooklyn.catalog:
2 | version: "2.1.0-SNAPSHOT" # CLOCKER_VERSION
3 | publish:
4 | description: |
5 | An X.509 Certificate Authority tool using OpenSSL
6 | license_code: APACHE-2.0
7 |
8 | items:
9 |
10 | - id: ca-server
11 | name: "Certificate Authority Server"
12 | description: |
13 | An X.509 Certificate Authority tool with a simple REST API.
14 |
15 | Request creation of a certificate for a client with a POST request to
16 | '/generate/{nodeName}' with nodeName set to the IP address of the node.
17 | Download the CA certificate, client certificate and private key with GET
18 | requests to '/cert/{nodeName}/ca.pem' '/cert/{nodeName}/cert.pem' and
19 | '/cert/{nodeName}/key.pem'
20 | itemType: entity
21 | iconUrl: classpath://io.brooklyn.clocker.common:icons/openssl.png
22 | item:
23 | type: centos-software-process
24 | name: "authority"
25 |
26 | brooklyn.parameters:
27 | - name: ca.server.port
28 | label: "CA Server Port"
29 | description: |
30 | The external port the CA Server web service listens on
31 | type: integer
32 | default: 8080
33 |
34 | brooklyn.config:
35 | shell.env:
36 | COUNTRY: $brooklyn:config("country")
37 | STATE: $brooklyn:config("state")
38 | LOCALITY: $brooklyn:config("locality")
39 | ORGANIZATION_NAME: $brooklyn:config("organization.name")
40 | ORGANIZATION_UNIT: $brooklyn:config("organization.unit")
41 | COMMON_NAME: $brooklyn:config("common.name")
42 | EMAIL_ADDRESS: $brooklyn:config("email.address")
43 | CHALLENGE_PASSWORD: $brooklyn:config("challenge.password")
44 | OPTIONAL_COMPANY_NAME: $brooklyn:config("optional.company.name")
45 | CA_SERVER_PORT: $brooklyn:config("ca.server.port")
46 | INSTALL_DIR: $brooklyn:attributeWhenReady("install.dir")
47 | NODE_PATH:
48 | $brooklyn:formatString:
49 | - "%s/node_modules"
50 | - $brooklyn:attributeWhenReady("install.dir")
51 |
52 | install.command: |
53 | echo "[CLOCKER] Install OpenSSL"
54 | sudo yum install -y openssl
55 |
56 | echo "[CLOCKER] Install Node.js webapp prerequisites"
57 | curl --silent --location https://rpm.nodesource.com/setup_6.x | sudo bash -
58 | sudo yum install -y install nodejs
59 | npm config set prefix ${INSTALL_DIR}
60 | npm install express@4.13
61 |
62 | customize.command: |
63 | echo "[CLOCKER] Set up Bash OpenSSL scripts"
64 | cat > functions.sh <<-'EOF'
65 | function setup_structure() {
66 | sed -e "/copy_extensions/s/^# *//" -e "/^dir/c dir = $(pwd)" -e '/^#unique/s/#//' /etc/pki/tls/openssl.cnf > openssl.cnf
67 | mkdir certs crl newcerts private
68 | openssl rand -hex 16 > serial
69 | touch index.txt
70 | }
71 |
72 | function self_sign_ca_certificate () {
73 | echo "[CLOCKER] Generate a CA root certificate"
74 | openssl genrsa -out private/cakey.pem 2048
75 | openssl req -config openssl.cnf -new -key private/cakey.pem -days 1825 -out ca.csr <<-EOC
76 | ${COUNTRY:-.}
77 | ${STATE:-.}
78 | ${LOCALITY:-.}
79 | ${ORGANIZATION_NAME:-.}
80 | ${ORGANIZATION_UNIT:-.}
81 | ${COMMON_NAME:-'*'}
82 | ${EMAIL_ADDRESS:-.}
83 | ${CHALLENGE_PASSWORD:-.}
84 | ${OPTIONAL_COMPANY_NAME:-.}
85 | EOC
86 | yes | openssl ca -config openssl.cnf -selfsign -in ca.csr -out ca.pem -policy policy_anything -extensions v3_ca
87 | }
88 |
89 | function sign_cert () {
90 | csr_file=$1
91 | yes | openssl ca -config openssl.cnf -cert ca.pem -extensions usr_cert -policy policy_anything -in ${csr_file}
92 | }
93 | EOF
94 |
95 |
96 | cat > sign_cert.sh <<-'EOF'
97 | #!/usr/bin/env bash
98 | source functions.sh
99 | temp_request=$(mktemp)
100 |
101 | # cat all input to the temp request file
102 | cat > ${temp_request}
103 |
104 | sign_cert ${temp_request} || {
105 | res=$?
106 | echo Error signing certificate
107 | exit res
108 | }
109 | EOF
110 | chmod +x sign_cert.sh
111 |
112 | source functions.sh
113 |
114 | setup_structure
115 |
116 | echo "[CLOCKER] Set up Node.js web service"
117 | cat > webserver.js <<-EOF
118 | var http = require('http');
119 | var fs = require('fs');
120 | var express = require('express');
121 | const spawn = require('child_process').spawn;
122 |
123 | const PORT=${CA_SERVER_PORT};
124 |
125 | var server = express();
126 | server.use('/cacert', express.static('cacert'));
127 | server.post("/sign", function(request, response) {
128 | console.log("POST received on " + request.url);
129 | var proc = spawn('./sign_cert.sh');
130 | request.pipe(proc.stdin);
131 | proc.stdout.pipe(response);
132 | });
133 |
134 | server.listen(PORT, function(req, res){
135 | console.log("Server listening on port %s", PORT);
136 | });
137 | EOF
138 |
139 | self_sign_ca_certificate
140 | mkdir cacert
141 | cp ca.pem cacert
142 |
143 | launch.command: |
144 | nohup node webserver.js > webserver.out 2> webserver.err & echo $! > ${PID_FILE}
145 |
146 | checkRunning.command: |
147 | ps -p $(cat ${PID_FILE})
148 |
149 | stop.command: |
150 | kill -9 $(cat ${PID_FILE})
151 |
152 | brooklyn.initializers:
153 | - type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
154 | brooklyn.config:
155 | name: ca.cert
156 | description: |
157 | Present the CA certificate for the ca-server
158 | command: |
159 | [ -f ca.pem ] && cat ca.pem
160 | - type: org.apache.brooklyn.core.effector.ssh.SshCommandEffector
161 | brooklyn.config:
162 | name: generate
163 | description: |
164 | Generate public certificate and private key for a node
165 | parameters:
166 | nodeName:
167 | description: |
168 | IP address for the node
169 | command: |
170 | source functions.sh
171 | generate $(pwd) ${nodeName}
172 | - type: org.apache.brooklyn.core.effector.ssh.SshCommandEffector
173 | brooklyn.config:
174 | name: sign
175 | description: Take an X.509 Certificate Signing Request and return the signed certificate
176 | parameters:
177 | csr:
178 | description: Text of an X.509 Certificate Signing Request in PEM format
179 | command: |
180 | source functions.sh
181 | temp_request=$(mktemp)
182 | echo "$csr" >> ${temp_request}
183 | sign_cert ${temp_request} && rm -f ${temp_request}
184 |
185 | brooklyn.enrichers:
186 | - type: org.apache.brooklyn.enricher.stock.Transformer
187 | brooklyn.config:
188 | enricher.triggerSensors:
189 | - host.address
190 | enricher.targetSensor: $brooklyn:sensor("main.uri")
191 | enricher.targetValue:
192 | $brooklyn:formatString:
193 | - "http://%s:%d"
194 | - $brooklyn:attributeWhenReady("host.address")
195 | - $brooklyn:config("ca.server.port")
196 |
--------------------------------------------------------------------------------
/common/catalog/common/common.bom:
--------------------------------------------------------------------------------
1 | brooklyn.catalog:
2 | version: "2.1.0-SNAPSHOT" # CLOCKER_VERSION
3 | publish:
4 | description: |
5 | Resources for common Apache Brooklyn entities
6 | license_code: APACHE-2.0
7 |
8 | items:
9 | - id: conditional-entity
10 | name: "Conditional Entity"
11 | description: |
12 | An entity that creates a child only if a configuration key is set
13 | itemType: entity
14 | item:
15 | type: org.apache.brooklyn.entity.stock.ConditionalEntity
16 | id: conditional-entity
17 |
18 | - id: child-software-process
19 | name: "Child Software Process"
20 | description: |
21 | A child entity that executes commands to run a process
22 | itemType: entity
23 | item:
24 | type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess
25 | id: child-software-process
26 |
27 | - id: empty-software-process
28 | name: "Empty Software Process"
29 | description: |
30 | A startable entity to group child entities
31 | itemType: entity
32 | item:
33 | type: org.apache.brooklyn.entity.software.base.EmptySoftwareProcess
34 | id: empty-software-process
35 |
36 | - id: centos-software-process
37 | name: "CentOS Software Process"
38 | description: |
39 | An entity that executes commands to run a process
40 |
41 | Uses a CentOS 7.x Virtual Machine
42 | itemType: entity
43 | iconUrl: classpath://io.brooklyn.clocker.common:icons/centos.png
44 | item:
45 | type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess
46 | id: centos-software-process
47 | brooklyn.config:
48 | dontRequireTtyForSudo: true
49 | provisioning.properties:
50 | osFamily: centos
51 | osVersionRegex: 7
52 |
--------------------------------------------------------------------------------
/common/catalog/common/haproxy-template.bom:
--------------------------------------------------------------------------------
1 | brooklyn.catalog:
2 | items:
3 | - id: ca-server-template
4 | name: "Certificate Authority Server"
5 | description: |
6 | An X.509 Certificate Authority tool using OpenSSL
7 | itemType: template
8 | iconUrl: classpath://io.brooklyn.clocker.common:icons/openssl.png
9 | item:
10 | services:
11 | - type: ca-server
12 |
13 | - id: haproxy-load-balancer-template
14 | name: "HAProxy Load Balancer"
15 | description: |
16 | HAProxy load balancer entity
17 | itemType: template
18 | iconUrl: classpath://io.brooklyn.clocker.common:icons/haproxy.png
19 | item:
20 | services:
21 | - type: haproxy-load-balancer
--------------------------------------------------------------------------------
/common/catalog/common/haproxy.bom:
--------------------------------------------------------------------------------
1 | brooklyn.catalog:
2 | version: "2.1.0-SNAPSHOT" # CLOCKER_VERSION
3 | publish:
4 | description: |
5 | HAProxy load balancer
6 | license_code: APACHE-2.0
7 |
8 | items:
9 |
10 | - id: haproxy-load-balancer
11 | name: "HAProxy Load Balancer"
12 | description: |
13 | HAProxy load balancer entity
14 | itemType: entity
15 | iconUrl: classpath://io.brooklyn.clocker.common:icons/haproxy.png
16 | item:
17 | type: centos-software-process
18 | name: "haproxy-load-balancer"
19 |
20 | brooklyn.parameters:
21 | - name: haproxy.version
22 | label: "HAProxy Version"
23 | description: |
24 | The HAProxy version to install
25 | type: string
26 | default: "1.6.7"
27 | - name: haproxy.port
28 | label: "HAProxy Port"
29 | description: |
30 | Port that HAProxy should listen on
31 | type: integer
32 | default: 8000
33 | - name: haproxy.protocol
34 | label: "HAProxy Protocol"
35 | description: |
36 | Protocol to forward (either http or https)
37 | type: string
38 | default: "http"
39 | - name: haproxy.bind.options
40 | label: "HAProxy Bind Options"
41 | description: |
42 | Extra bind configuration such as TLS certificate paths
43 | type: string
44 |
45 | brooklyn.config:
46 | haproxy.bind.options:
47 |
48 | shell.env:
49 | HOST_ADDRESS: $brooklyn:attributeWhenReady("host.address")
50 | SUBNET_ADDRESS: $brooklyn:attributeWhenReady("host.subnet.address")
51 | INSTALL_DIR: $brooklyn:attributeWhenReady("install.dir")
52 | RUN_DIR: $brooklyn:attributeWhenReady("run.dir")
53 | HAPROXY_VERSION: $brooklyn:config("haproxy.version")
54 | HAPROXY_PORT: $brooklyn:config("haproxy.port")
55 | HAPROXY_PROTOCOL: $brooklyn:config("haproxy.protocol")
56 | HAPROXY_BIND_OPTIONS: $brooklyn:config("haproxy.bind.options")
57 |
58 | install.command: |
59 | sudo yum install -y kernel-headers --disableexcludes=all
60 | sudo yum install -y gcc make openssl-devel wget util-linux
61 | haproxy_major_minor=$(echo ${HAPROXY_VERSION} | cut -d. -f1,2)
62 | wget "http://www.haproxy.org/download/${haproxy_major_minor}/src/haproxy-${HAPROXY_VERSION}.tar.gz"
63 | tar zxf haproxy-${HAPROXY_VERSION}.tar.gz
64 | cd haproxy-${HAPROXY_VERSION}
65 | make TARGET=linux26 USE_OPENSSL=true
66 | sudo cp haproxy /usr/bin
67 |
68 | customize.command: |
69 | cat > haproxy.conf <<-EOF
70 | global
71 | daemon
72 | maxconn 256
73 | pidfile ${PID_FILE}
74 | defaults
75 | option http-server-close
76 | timeout connect 5000ms
77 | timeout client 60s
78 | timeout server 60s
79 | frontend www-${HAPROXY_PROTOCOL}
80 | bind *:${HAPROXY_PORT} ${HAPROXY_BIND_OPTIONS}
81 | reqadd X-Forwarded-Proto:\ ${HAPROXY_PROTOCOL}
82 | default_backend servers
83 | mode tcp
84 | option tcplog
85 | log 127.0.0.1 syslog
86 | EOF
87 | echo "backend servers" > servers.conf
88 |
89 | launch.command: |
90 | haproxy -f haproxy.conf -f servers.conf -c &&
91 | haproxy -D -f haproxy.conf -f servers.conf -sf $(cat ${PID_FILE})
92 |
93 | brooklyn.initializers:
94 | - type: org.apache.brooklyn.core.effector.ssh.SshCommandEffector
95 | brooklyn.config:
96 | name: configureEndpoints
97 | description: |
98 | Generate HAProxy configuration from endpoint list
99 | shell.env:
100 | HAPROXY_PROTOCOL: $brooklyn:config("haproxy.protocol")
101 | HAPROXY_ENDPOINTS: $brooklyn:attributeWhenReady("haproxy.endpoints")
102 | ENTITY_ID: $brooklyn:attributeWhenReady("entity.id")
103 | command: |
104 | set -x
105 | command -v haproxy >/dev/null 2>&1 || { echo >&2 "HAProxy is not installed yet. Exiting quietly."; exit 0; }
106 | (
107 | flock 9
108 | cat > ${RUN_DIR}/servers.conf <<-EOF
109 | backend servers
110 | EOF
111 | if [ "${HAPROXY_PROTOCOL}" == "http" ]; then
112 | cat >> ${RUN_DIR}/servers.conf <<-EOF
113 | mode http
114 | option httpchk
115 | EOF
116 | fi
117 | cat >> ${RUN_DIR}/servers.conf <<-EOF
118 | balance roundrobin
119 | EOF
120 | for endpoint in $(echo ${HAPROXY_ENDPOINTS} | tr ',' ' ') ; do
121 | if [ "${HAPROXY_PROTOCOL}" == "http" ]; then
122 | echo " server node$((++n)) ${endpoint} check" >> ${RUN_DIR}/servers.conf
123 | else
124 | echo " server node$((++n)) ${endpoint} maxconn 32 ssl ca-file ${RUN_DIR}/ca.pem crt ${RUN_DIR}/cert.pem" >> ${RUN_DIR}/servers.conf
125 | fi
126 | done
127 | old_pid=$(cat ${RUN_DIR}/pid.txt)
128 | if [ ! -z $old_pid ]; then
129 | haproxy -D -f ${RUN_DIR}/haproxy.conf -f ${RUN_DIR}/servers.conf -st ${old_pid} 9>/dev/null
130 | # wait for the old process to die before leaving the critical section
131 | while test -d /proc/${old_pid} 2> /dev/null; do echo >&2 "waiting for ${old_pid} to die" ; sleep 1; done
132 | else
133 | echo >&2 "no previous process to wait for"
134 | fi
135 | ) 9>> /tmp/configure.${ENTITY_ID}.lock
136 |
137 | brooklyn.policies:
138 | - type: org.apache.brooklyn.policy.InvokeEffectorOnSensorChange
139 | brooklyn.config:
140 | effector: configureEndpoints
141 | sensor: $brooklyn:sensor("haproxy.endpoints")
142 | - type: org.apache.brooklyn.policy.InvokeEffectorOnSensorChange
143 | brooklyn.config:
144 | effector: configureEndpoints
145 | sensor: $brooklyn:sensor("service.isUp")
146 |
147 | brooklyn.enrichers:
148 | # Publish host+port as main.uri
149 | - type: org.apache.brooklyn.enricher.stock.Transformer
150 | brooklyn.config:
151 | uniqueTag: haproxy-endpoint-publisher
152 | enricher.triggerSensors:
153 | - $brooklyn:sensor("host.name")
154 | enricher.targetSensor: $brooklyn:sensor("org.apache.brooklyn.core.entity.Attributes", "main.uri")
155 | enricher.targetValue:
156 | $brooklyn:formatString:
157 | - "%s://%s:%d"
158 | - $brooklyn:config("haproxy.protocol")
159 | - $brooklyn:attributeWhenReady("host.name")
160 | - $brooklyn:config("haproxy.port")
161 |
--------------------------------------------------------------------------------
/common/catalog/docker/docker.bom:
--------------------------------------------------------------------------------
1 | brooklyn.catalog:
2 | version: "2.1.0-SNAPSHOT" # CLOCKER_VERSION
3 | publish:
4 | description: |
5 | Resources for working with Docker Engine from Apache Brooklyn
6 | license_code: APACHE-2.0
7 | overview: README.md
8 | qa: tests/docker.tests.bom
9 |
10 | items:
11 | - classpath://common/common.bom
12 | - classpath://common/ca.bom
13 |
14 | - id: docker-engine
15 | name: "Docker Engine"
16 | description: |
17 | The engine for running Docker containers
18 | itemType: entity
19 | iconUrl: classpath://io.brooklyn.clocker.common:icons/docker.png
20 | item:
21 | type: centos-software-process
22 | id: docker-engine
23 |
24 | brooklyn.parameters:
25 | - name: docker.package
26 | label: "Docker Package"
27 | description: |
28 | The Docker Engine package to install
29 | type: string
30 | - name: docker.version
31 | label: "Docker Version"
32 | description: |
33 | The Docker Engine version to install
34 | type: string
35 | - name: docker.repository.url
36 | label: "Docker Repository URL"
37 | description: |
38 | The Docker repository URL to use for installation
39 | type: string
40 | - name: docker.gpgkey.url
41 | label: "Docker GPG Key URL"
42 | description: |
43 | The Docker GPG key URL to use to authenticate the installation
44 | type: string
45 | - name: docker.additionaloptions
46 | label: "Docker Additional Options"
47 | description: |
48 | The additional options to pass to the engine on startup
49 | type: string
50 | - name: image.preinstall
51 | label: "Image Pre-install"
52 | description: |
53 | A docker hub image id to pull after installation
54 | type: string
55 | default: brooklyncentral/centos:7
56 |
57 | brooklyn.initializers:
58 | - type: org.apache.brooklyn.entity.machine.AddMachineMetrics
59 | - type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
60 | brooklyn.config:
61 | name: docker.version
62 | period: 5m
63 | command: |
64 | docker info | grep "^Server Version" | sed -e "s/^Server Version: //"
65 | - type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
66 | brooklyn.config:
67 | name: docker.container.count
68 | period: 1m
69 | targetType: integer
70 | command: |
71 | docker ps -q | wc -l
72 |
73 | brooklyn.config:
74 | defaultDisplayName: "docker-engine"
75 |
76 | image.preinstall: brooklyncentral/centos:7
77 |
78 | shell.env:
79 | DOCKER_ADDITIONAL_OPTIONS: $brooklyn:config("docker.additionaloptions")
80 | HOST_NAME: $brooklyn:attributeWhenReady("host.name")
81 | HOST_ADDRESS: $brooklyn:attributeWhenReady("host.address")
82 | DOCKER_IMAGE_PREINSTALL: $brooklyn:config("image.preinstall")
83 | DOCKER_PACKAGE: $brooklyn:config("docker.package")
84 | DOCKER_VERSION: $brooklyn:config("docker.version")
85 | DOCKER_REPOSITORY_URL: $brooklyn:config("docker.repository.url")
86 | DOCKER_GPG_KEY_URL: $brooklyn:config("docker.gpgkey.url")
87 | ENTITY_ID: $brooklyn:attributeWhenReady("entity.id")
88 | APPLICATION_ID: $brooklyn:attributeWhenReady("application.id")
89 | CLOCKER_VERSION: "2.1.0-SNAPSHOT"
90 |
91 | install.command: |
92 | set -e # need all commands to execute successfully
93 |
94 | sudo yum -y update
95 |
96 | echo "[CLOCKER] Configuring package manager"
97 | if [[ "${DOCKER_REPOSITORY_URL}" && "${DOCKER_GPG_KEY_URL}" ]] ; then
98 | # Commercially Supported Docker Engine
99 | sudo rpm --import "${DOCKER_GPG_KEY_URL}"
100 | sudo yum install -y yum-utils
101 | sudo yum-config-manager --add-repo "${DOCKER_REPOSITORY_URL}"
102 | else
103 | # Open-Source Docker Engine
104 | sudo tee /etc/yum.repos.d/docker.repo <<-EOF
105 | [dockerrepo]
106 | name=Docker Repository
107 | baseurl=https://yum.dockerproject.org/repo/main/centos/\$releasever/
108 | enabled=1
109 | gpgcheck=1
110 | gpgkey=https://yum.dockerproject.org/gpg
111 | EOF
112 | fi
113 | if [[ "${DOCKER_VERSION}" ]] ; then
114 | sudo yum -y install ${DOCKER_PACKAGE:-docker-engine}-${DOCKER_VERSION}
115 | else
116 | sudo yum -y install ${DOCKER_PACKAGE:-docker-engine}
117 | fi
118 |
119 | echo "[CLOCKER] Setting up Docker systemd service"
120 | sudo mkdir -p /etc/systemd/system/docker.service.d
121 | sudo tee /etc/systemd/system/docker.service.d/docker.conf <<-EOF
122 | [Service]
123 | # Need to clear the default first and then set a custom value
124 | ExecStart=
125 | ExecStart=/usr/bin/docker daemon \
126 | -H unix:///var/run/docker.sock \
127 | --api-cors-header="*" \
128 | --config-file /etc/systemd/system/docker.service.d/daemon.json \
129 | ${DOCKER_ADDITIONAL_OPTIONS}
130 | ExecStartPost=/usr/bin/chown ${USER}:docker /var/run/docker.sock
131 | EOF
132 | sudo tee /etc/systemd/system/docker.service.d/daemon.json <<-EOF
133 | {
134 | "labels": [
135 | "org.label-schema.schema-version=1.0",
136 | "org.label-schema.version=${CLOCKER_VERSION}",
137 | "org.label-schema.name=${HOST_ADDRESS}",
138 | "io.brooklyn.clocker.entity=${ENTITY_ID}",
139 | "io.brooklyn.clocker.application=${APPLICATION_ID}"
140 | ]
141 | }
142 | EOF
143 |
144 | if sudo systemctl list-unit-files | grep "rngd" ; then
145 | echo "[CLOCKER] Fix 100% CPU issue on some VMs"
146 | sudo service rngd stop || true
147 | sudo systemctl disable rngd.service
148 | fi
149 |
150 | sudo systemctl enable docker.service
151 | sudo systemctl daemon-reload
152 |
153 | post.install.command: |
154 | echo "[CLOCKER] Setting up user and group for Docker"
155 | sudo groupadd -f docker
156 | sudo usermod -aG docker ${USER}
157 |
158 | launch.command: |
159 | sudo service docker start &&
160 | ( [ -z "${DOCKER_IMAGE_PREINSTALL}" ] ||
161 | docker images --format="{{.Repository}}:{{.Tag}}" | grep -q "${DOCKER_IMAGE_PREINSTALL}" ||
162 | docker pull ${DOCKER_IMAGE_PREINSTALL} )
163 |
164 | stop.command: |
165 | sudo service docker stop
166 |
167 | checkRunning.command: |
168 | sudo service docker status
169 |
170 | # ensure docker running before starting children
171 | childStartMode: foreground_late
172 |
173 | - id: docker-engine-tls
174 | name: "Docker Engine with TLS"
175 | description: |
176 | A docker-engine customised with TLS
177 | itemType: entity
178 | iconUrl: classpath://io.brooklyn.clocker.common:icons/docker.png
179 | item:
180 | type: docker-engine
181 |
182 | brooklyn.parameters:
183 | - name: docker.port
184 | label: "Docker Port"
185 | description: |
186 | The TCP port for Docker to listen on
187 | type: integer
188 | default: 2376
189 | - name: docker.bindaddress
190 | label: "Docker Bind Address"
191 | description: |
192 | The docker network address to to listen on.
193 | type: string
194 | default: 0.0.0.0
195 | - name: ca.request.root.url
196 | label: "CA Request Root URL"
197 | description: |
198 | Optional root URL for a CA server.
199 |
200 | Use this or set the configuration for the certificate and key
201 | URLs separately.
202 | type: string
203 | - name: ca.cert.url
204 | label: "CA Certificate URL"
205 | description: |
206 | Optional URL for the CA certificate
207 | type: string
208 | - name: ca.cert
209 | label: "CA Certificate"
210 | description: |
211 | Optional CA certificate data
212 | type: string
213 | - name: node.cert.url
214 | label: "Node Certificate URL"
215 | description: |
216 | Optional URL for the TLS certificate for this Docker engine
217 | type: string
218 | - name: private.key.url
219 | label: "Private Key URL"
220 | description: |
221 | Optional URL for the private key of this Docker engine
222 | type: string
223 |
224 | brooklyn.enrichers:
225 | - type: org.apache.brooklyn.enricher.stock.Transformer
226 | brooklyn.config:
227 | uniqueTag: docker-public-endpoint-generator
228 | enricher.suppressDuplicates: false
229 | enricher.triggerSensors:
230 | - $brooklyn:sensor("host.address")
231 | enricher.targetSensor: $brooklyn:sensor("docker.endpoint.public")
232 | enricher.targetValue:
233 | $brooklyn:formatString:
234 | - "%s:%d"
235 | - $brooklyn:attributeWhenReady("host.address")
236 | - $brooklyn:config("docker.port")
237 | - type: org.apache.brooklyn.enricher.stock.Transformer
238 | brooklyn.config:
239 | uniqueTag: docker-endpoint-generator
240 | enricher.suppressDuplicates: false
241 | enricher.triggerSensors:
242 | - $brooklyn:sensor("host.subnet.address")
243 | enricher.targetSensor: $brooklyn:sensor("docker.endpoint")
244 | enricher.targetValue:
245 | $brooklyn:formatString:
246 | - "%s:%d"
247 | - $brooklyn:attributeWhenReady("host.subnet.address")
248 | - $brooklyn:config("docker.port")
249 | - type: org.apache.brooklyn.enricher.stock.Transformer
250 | brooklyn.config:
251 | uniqueTag: docker-url-generator
252 | enricher.suppressDuplicates: false
253 | enricher.triggerSensors:
254 | - $brooklyn:sensor("docker.endpoint")
255 | enricher.targetSensor: $brooklyn:sensor("docker.url")
256 | enricher.targetValue:
257 | $brooklyn:formatString:
258 | - "tcp://%s"
259 | - $brooklyn:attributeWhenReady("docker.endpoint")
260 |
261 | brooklyn.config:
262 | docker.cert.path:
263 | $brooklyn:formatString:
264 | - "%s/.certs"
265 | - $brooklyn:attributeWhenReady("install.dir")
266 | docker.tlsoptions:
267 | $brooklyn:formatString:
268 | - >-
269 | --tlsverify
270 | --tlscacert=%1$s/ca.pem
271 | --tlscert=%1$s/cert.pem
272 | --tlskey=%1$s/key.pem
273 | - $brooklyn:config("docker.cert.path")
274 | docker.additionaloptions.docker-engine-tls:
275 | $brooklyn:formatString:
276 | - "-H %s %s"
277 | - $brooklyn:attributeWhenReady("docker.bind.url")
278 | - $brooklyn:config("docker.tlsoptions")
279 | docker.additionaloptions: $brooklyn:config("docker.additionaloptions.docker-engine-tls")
280 | shell.env:
281 | CA_REQUEST_ROOT_URL: $brooklyn:config("ca.request.root.url")
282 | CA_CERT: $brooklyn:config("ca.cert")
283 | CA_CERT_URL: $brooklyn:config("ca.cert.url")
284 | NODE_CERT_URL: $brooklyn:config("node.cert.url")
285 | PRIV_KEY_URL: $brooklyn:config("private.key.url")
286 | HOST_ADDRESS: $brooklyn:attributeWhenReady("host.address")
287 | SUBNET_ADDRESS: $brooklyn:attributeWhenReady("host.subnet.address")
288 | INSTALL_DIR: $brooklyn:attributeWhenReady("install.dir")
289 | TLS_OPTIONS: $brooklyn:config("docker.tlsoptions")
290 | DOCKER_ENDPOINT: $brooklyn:attributeWhenReady("docker.endpoint")
291 | DOCKER_HOST: $brooklyn:attributeWhenReady("docker.url")
292 | DOCKER_TLS_VERIFY: true
293 | DOCKER_CERT_PATH: $brooklyn:config("docker.cert.path")
294 | latch.preInstall.resources: $brooklyn:entity("ca-server").attributeWhenReady("service.isUp")
295 | files.preinstall:
296 | "classpath://io.brooklyn.clocker.common:common/certificate-functions.sh": certificate-functions.sh
297 | customize.command: |
298 | set -e
299 | source ${INSTALL_DIR}/certificate-functions.sh
300 |
301 | echo "[CLOCKER] Creating ${DOCKER_CERT_PATH}"
302 | mkdir -p ${DOCKER_CERT_PATH}
303 |
304 | if [ "${CA_REQUEST_ROOT_URL}" ] ; then
305 | #echo "$CA_CERT" > ${DOCKER_CERT_PATH}/ca.pem # commented out until after we get back to this.
306 | getcert ${CA_REQUEST_ROOT_URL}/cacert/ca.pem ${DOCKER_CERT_PATH}/ca.pem
307 |
308 | generate_key ${DOCKER_CERT_PATH}/key.pem
309 | generate_conf ${DOCKER_CERT_PATH}/csr.cnf ${HOST_ADDRESS} ${SUBNET_ADDRESS}
310 | generate_csr ${DOCKER_CERT_PATH}/csr.cnf ${DOCKER_CERT_PATH}/key.pem ${DOCKER_CERT_PATH}/csr.pem
311 |
312 | echo "[CLOCKER] Requesting certificate from ${CA_REQUEST_ROOT_URL}"
313 | curl -X POST --data-binary @${DOCKER_CERT_PATH}/csr.pem ${CA_REQUEST_ROOT_URL}/sign > ${DOCKER_CERT_PATH}/cert.pem
314 | echo "[CLOCKER] Certifcate for ${HOST_ADDRESS} received"
315 | else
316 | echo "[CLOCKER] Downloading certificates from configuration settings"
317 | getcert ${CA_CERT_URL} > ${DOCKER_CERT_PATH}/ca.pem
318 | getcert ${NODE_CERT_URL} > ${DOCKER_CERT_PATH}/cert.pem
319 | getcert ${PRIV_KEY_URL} > ${DOCKER_CERT_PATH}/key.pem
320 | fi
321 | # TODO verify certs with openssl
322 | test -f ${DOCKER_CERT_PATH}/ca.pem || failwith "Failed to obtain ca.pem"
323 | test -f ${DOCKER_CERT_PATH}/cert.pem || failwith "Failed to obtain cert.pem"
324 | test -f ${DOCKER_CERT_PATH}/key.pem || failwith "Failed to obtain key.pem"
325 | post.customize.command: |
326 | echo "[CLOCKER] Set up Docker environment variables with TLS"
327 | if ! grep docker_client ${HOME}/.bashrc ; then
328 | echo ". docker_client.rc" >> ${HOME}/.bashrc
329 | fi
330 | cat > ${HOME}/docker_client.rc <<-EOF
331 | DOCKER_TLS_VERIFY=${DOCKER_TLS_VERIFY}
332 | DOCKER_CERT_PATH=${DOCKER_CERT_PATH}
333 | DOCKER_HOST=${DOCKER_HOST}
334 | export DOCKER_TLS_VERIFY DOCKER_CERT_PATH DOCKER_HOST
335 | EOF
336 |
337 | brooklyn.initializers:
338 | - type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
339 | brooklyn.config:
340 | name: docker.csr
341 | period: 5m
342 | command: |
343 | cat ${DOCKER_CERT_PATH}/csr.pem
344 | - type: org.apache.brooklyn.core.sensor.StaticSensor
345 | brooklyn.config:
346 | name: docker.bind.url
347 | static.value:
348 | $brooklyn:formatString:
349 | - "tcp://%s:%d"
350 | - $brooklyn:config("docker.bindaddress")
351 | - $brooklyn:config("docker.port")
352 |
353 | - id: docker-engine-with-resilience
354 | name: "Docker Engine with Resilience"
355 | description: |
356 | A docker-engine configured with resilience policies
357 | itemType: entity
358 | iconUrl: classpath://io.brooklyn.clocker.common:icons/docker.png
359 | item:
360 | type: docker-engine-tls
361 |
362 | brooklyn.parameters:
363 | - name: docker.recovery.stabilizationDelay
364 | label: "Stabilization Delay"
365 | description: |
366 | Time period for which the service must be consistently in the same state to trigger an action.
367 | Should be long enough that a restart will not trigger failure
368 | type: org.apache.brooklyn.util.time.Duration
369 | default: 5m
370 | - name: docker.recovery.failOnRecurringFailuresInThisDuration
371 | label: "Fail Duration"
372 | description: |
373 | Reports entity as failed if it fails two or more times in this time window
374 | type: org.apache.brooklyn.util.time.Duration
375 | default: 15m
376 |
377 | brooklyn.policies:
378 | - type: org.apache.brooklyn.policy.ha.ServiceRestarter
379 | brooklyn.config:
380 | failOnRecurringFailuresInThisDuration:
381 | $brooklyn:config("docker.recovery.failOnRecurringFailuresInThisDuration")
382 |
383 | brooklyn.enrichers:
384 | - type: org.apache.brooklyn.policy.ha.ServiceFailureDetector
385 | brooklyn.config:
386 | serviceOnFire.stabilizationDelay:
387 | $brooklyn:config("docker.recovery.stabilizationDelay")
388 | entityFailed.stabilizationDelay:
389 | $brooklyn:config("docker.recovery.stabilizationDelay")
390 | entityRecovered.stabilizationDelay:
391 | $brooklyn:config("docker.recovery.stabilizationDelay")
392 |
393 | - id: docker-engine-container
394 | name: "Docker Container"
395 | description: |
396 | An easy way to launch a Docker container, as a child of a Docker Engine.
397 | itemType: entity
398 | iconUrl: classpath://io.brooklyn.clocker.common:icons/docker.png
399 | item:
400 | type: centos-software-process
401 |
402 | brooklyn.parameters:
403 | - name: image.details
404 | label: "Image Details"
405 | description: |
406 | The Docker Container image details.
407 |
408 | Either the name of a Docker Hub image or the id of an image that has
409 | been pulled and is available on the Engine already.
410 | type: string
411 |
412 | brooklyn.config:
413 | dontRequireTtyForSudo: true
414 |
415 | # TODO advertise container id as a sensor.
416 |
417 | shell.env:
418 | IMAGE_DETAILS: $brooklyn:config("image.details")
419 |
420 | launch.command: |
421 | docker run -d ${IMAGE_DETAILS}
422 |
423 | checkRunning.command: |
424 | result="$(docker ps | grep ${IMAGE_DETAILS} | wc -l)"
425 | if [ $result -ne 0 ]; then exit 0; else exit 1; fi;
426 |
427 | - id: docker-vm-container
428 | name: "Docker Entity"
429 | description: |
430 | An easy way to launch a single Docker container on a VM
431 | itemType: entity
432 | item:
433 | type: docker-engine
434 |
435 | brooklyn.parameters:
436 | - name: docker.image
437 | label: "Docker Image"
438 | description: |
439 | The docker image to use when running the container
440 | - name: docker.run.arguments
441 | label: "Docker Run Arguments"
442 | description: |
443 | Arguments to pass to the docker run command
444 | - name: docker.run.volumes
445 | label: "Container Volumns"
446 | type: java.util.List
447 | description: |
448 | List of volumes to mount. Items follow the documented docker format
449 | for the '-v' option
450 | default: [ ]
451 | - name: docker.run.env
452 | label: "Container Environment"
453 | type: java.util.Map
454 | description: |
455 | Map of environment variables to pass to the container
456 | default: { }
457 | - name: docker.restart
458 | label: "Restart policy"
459 | description: |
460 | Restart policy on the container. One of no, on-failure[:max-retries],
461 | always or unless-stopped
462 | - name: docker.run.additionaloptions
463 | label: "Run Additional Options"
464 | description: |
465 | Additional options to pass to the 'docker run' command
466 |
467 | brooklyn.config:
468 | defaultDisplayName: $brooklyn:config("docker.image")
469 | image.preinstall:
470 |
471 | shell.env:
472 | DOCKER_IMAGE: $brooklyn:config("docker.image")
473 | DOCKER_RUN_ARGUMENTS: $brooklyn:config("docker.run.arguments")
474 | DOCKER_RUN_VOLUMES: $brooklyn:config("docker.run.volumes")
475 | DOCKER_RUN_ENV: $brooklyn:config("docker.run.env")
476 | DOCKER_RESTART: $brooklyn:config("docker.restart")
477 | DOCKER_RUN_ADDITIONAL_OPTIONS: $brooklyn:config("docker.run.additionaloptions")
478 |
479 | pre.install.command: |
480 | sudo yum -y install epel-release
481 | sudo yum -y install jq
482 |
483 | pre.launch.command: |
484 | if [ -z "${DOCKER_IMAGE}" ]; then
485 | echo "[CLOCKER] 'docker.image' not configured on the entity" >&2
486 | exit 1
487 | fi
488 |
489 | post.launch.command: |
490 | set -e
491 | # Won't escape quotes in the arguments, but those are not expected
492 | function parse_docker_volumes {
493 | echo ${DOCKER_RUN_VOLUMES} |
494 | jq -r '["-v \"" + .[] + "\" "] | add'
495 | }
496 | function parse_docker_env {
497 | echo ${DOCKER_RUN_ENV} |
498 | jq -r 'to_entries | map("-e \"" + .key + "=" + .value + "\" ") | add'
499 | }
500 | rm -f "${PID_FILE}" # docker won't overwrite
501 | DOCKER="docker run -d --cidfile \"${PID_FILE}\" --net=host"
502 | [[ $DOCKER_RUN_VOLUMES != [] ]] && DOCKER="${DOCKER} $( parse_docker_volumes )"
503 | [[ $DOCKER_RUN_ENV != {} ]] && DOCKER="${DOCKER} $( parse_docker_env )"
504 | DOCKER="${DOCKER} --restart=${DOCKER_RESTART:-unless-stopped}"
505 | [ "${DOCKER_RUN_ADDITIONAL_OPTIONS}" ] && DOCKER="${DOCKER} ${DOCKER_RUN_ADDITIONAL_OPTIONS}"
506 | DOCKER="${DOCKER} \"${DOCKER_IMAGE}\""
507 | [ "${DOCKER_RUN_ARGUMENTS}" ] && DOCKER="${DOCKER} ${DOCKER_RUN_ARGUMENTS}"
508 | echo "${DOCKER}"
509 | echo "${DOCKER}" | bash
510 |
511 | checkRunning.command: |
512 | STATE=$(docker inspect --format "{{ .State.Status }}" $(cat "${PID_FILE}"))
513 | sudo service docker status && [ "${STATE}" = "running" ]
514 |
515 | stop.command: |
516 | docker stop $(cat "${PID_FILE}")
517 | sudo service docker stop
518 | rm -f "${PID_FILE}"
519 |
520 | brooklyn.initializers:
521 | - type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
522 | brooklyn.config:
523 | name: container.id
524 | period: 5m
525 | targetType: String
526 | command: |
527 | test -f pid.txt &&
528 | cat pid.txt
529 | - type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
530 | brooklyn.config:
531 | name: container.stats.cpu.percent
532 | period: 1m
533 | targetType: double
534 | command: |
535 | test -f pid.txt &&
536 | ( docker stats --no-stream --format "table {{.CPUPerc}}" $(cat pid.txt) |
537 | sed -n '2s/%//p' )
538 | - type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
539 | brooklyn.config:
540 | name: container.stats.memory.percent
541 | period: 1m
542 | targetType: double
543 | command: |
544 | test -f pid.txt &&
545 | ( docker stats --no-stream --format "table {{.MemPerc}}" $(cat pid.txt) |
546 | sed -n '2s/%//p' )
547 |
548 | - id: docker-container-entity
549 | name: "Docker Container"
550 | description: |
551 | An easy way to launch a Docker container
552 | itemType: entity
553 | iconUrl: classpath://io.brooklyn.clocker.common:icons/docker.png
554 | item:
555 | type: org.apache.brooklyn.container.entity.docker.DockerContainer
556 | brooklyn.parameters:
557 | - name: docker.container.imageName
558 | label: "Docker Container Image Name"
559 | description: |
560 | The name of the image to use when starting the Docker container
561 | type: string
562 | - name: docker.container.inboundPorts
563 | label: "Docker Container Inbound Ports"
564 | description: |
565 | A list of ports to be opened for inbound access to the container
566 | type: java.util.List
567 | - name: docker.container.environment
568 | label: "Docker Container Environmrnt"
569 | description: |
570 | A map of the environment variables to be set when launching the Docker container
571 | type: java.util.Map
572 |
--------------------------------------------------------------------------------
/common/examples/ca.yaml:
--------------------------------------------------------------------------------
1 | id: ca
2 | name: "Certificate Authority"
3 | description: |
4 | Standalone Certificate Authority server.
5 |
6 | location:
7 | jclouds:softlayer:
8 | region: ams01
9 |
10 | services:
11 | - type: ca-server
12 | id: ca-server
13 | name: "ca-server"
14 |
--------------------------------------------------------------------------------
/common/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 |
8 | io.brooklyn.clocker
9 | clocker-parent
10 | 2.1.0-SNAPSHOT
11 |
12 |
13 | Clocker :: Common
14 | clocker-common
15 | bundle
16 |
17 |
18 |
19 |
20 | catalog
21 | false
22 |
23 |
24 | resources
25 | false
26 |
27 |
28 | tests
29 | false
30 | tests
31 |
32 |
33 |
34 |
35 |
36 | org.codehaus.mojo
37 | build-helper-maven-plugin
38 |
39 |
40 | attach-artifact
41 | package
42 |
43 | attach-artifact
44 |
45 |
46 |
47 |
48 | ${project.basedir}/catalog/docker/docker.bom
49 | bom
50 | docker
51 |
52 |
53 | ${project.basedir}/catalog/common/ca.bom
54 | bom
55 | ca
56 |
57 |
58 | ${project.basedir}/catalog/common/haproxy.bom
59 | bom
60 | haproxy
61 |
62 |
63 | ${project.basedir}/catalog/common/haproxy-template.bom
64 | bom
65 | haproxy-template
66 |
67 |
68 | ${project.basedir}/catalog/common/common.bom
69 | bom
70 | common
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/common/resources/common/certificate-functions.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | function generate_key () {
4 | openssl genrsa -out $1 2048
5 | }
6 |
7 | function generate_conf () {
8 | local CNF=$1
9 | shift 1
10 | local ix=0
11 | cat > ${CNF} <<-EOF
12 | [ req ]
13 | req_extensions=v3_req
14 | distinguished_name=req_distinguished_name
15 |
16 | [ req_distinguished_name ]
17 | commonName = Common Name (eg, your name or your server\'s hostname)
18 | commonName_max = 64
19 |
20 | [ v3_req ]
21 | subjectAltName = @alt_names
22 |
23 | [ alt_names ]
24 | EOF
25 |
26 | while [ $# -gt 0 ] ; do
27 | ix=$(( $ix + 1 ))
28 | echo "IP.${ix} = $1" >> ${CNF}
29 | shift 1
30 | done
31 | }
32 |
33 | function generate_csr () {
34 | openssl req -config $1 -new -key $2 -days 1825 -subj "/CN=$(hostname)" -out $3
35 | }
36 |
37 | function failwith() {
38 | local err=$?
39 | 1>&2 echo "[CLOCKER] $1"
40 | exit $err
41 | }
42 |
43 | function getcert() {
44 | local url=$1
45 | local file=$2
46 | curl -L ${url} --output ${file} --write-out "%{http_code}" | grep 200 ||
47 | failwith "${file} not received from CA"
48 | }
49 |
--------------------------------------------------------------------------------
/common/resources/icons/centos.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brooklyncentral/clocker/e1ff91d4959d2238efcf78569d600f95273730d4/common/resources/icons/centos.png
--------------------------------------------------------------------------------
/common/resources/icons/docker.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brooklyncentral/clocker/e1ff91d4959d2238efcf78569d600f95273730d4/common/resources/icons/docker.png
--------------------------------------------------------------------------------
/common/resources/icons/haproxy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brooklyncentral/clocker/e1ff91d4959d2238efcf78569d600f95273730d4/common/resources/icons/haproxy.png
--------------------------------------------------------------------------------
/common/resources/icons/openssl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brooklyncentral/clocker/e1ff91d4959d2238efcf78569d600f95273730d4/common/resources/icons/openssl.png
--------------------------------------------------------------------------------
/common/tests/docker/common.tests.bom:
--------------------------------------------------------------------------------
1 | brooklyn.catalog:
2 | version: "2.1.0-SNAPSHOT" # CLOCKER_VERSION
3 | iconUrl: https://raw.githubusercontent.com/docker-library/docs/c350af05d3fac7b5c3f6327ac82fe4d990d8729c/docker/logo.png
4 | license_code: APACHE-2.0
5 |
6 | items:
7 | - id: test-case
8 | item:
9 | type: org.apache.brooklyn.test.framework.TestCase
10 |
11 | - id: ssh-test
12 | item:
13 | type: org.apache.brooklyn.test.framework.TestSshCommand
14 |
15 | - id: sensor-test
16 | item:
17 | type: org.apache.brooklyn.test.framework.TestSensor
18 | # sensor: name
19 |
20 | - id: assert-up-initial
21 | item:
22 | type: org.apache.brooklyn.test.framework.TestSensor
23 | name: "TEST [service.isUp] IS [true]"
24 | sensor: service.isUp
25 | brooklyn.parameters:
26 | - name: timeout.initialStartup
27 | description: The timeout for provisioning, installing and launching the app-under-test.
28 | type: org.apache.brooklyn.util.time.Duration
29 | default: 1h
30 | brooklyn.config:
31 | timeout: $brooklyn:config("timeout.initialStartup")
32 | assert:
33 | - equals: true
34 |
35 | - id: assert-up
36 | item:
37 | type: sensor-test
38 | name: "TEST [service.isUp] IS [true]"
39 | sensor: service.isUp
40 | assert:
41 | - equals: true
42 |
43 | - id: assert-down
44 | item:
45 | type: sensor-test
46 | name: TEST [service.isUp] IS [false]
47 | sensor: service.isUp
48 | assert:
49 | - equals: false
50 |
51 | - id: assert-running
52 | item:
53 | type: sensor-test
54 | name: "TEST [service.state] IS [running]"
55 | sensor: service.state
56 | assert:
57 | - matches: running
58 |
59 | - id: assert-failed
60 | item:
61 | type: sensor-test
62 | name: "TEST [service.state] IS [on-fire]"
63 | sensor: service.state
64 | assert:
65 | - matches: on-fire
66 |
67 | - id: test-stop-machine
68 | item:
69 | name: "Invoke [stop] effector (machine)"
70 | type: org.apache.brooklyn.test.framework.TestEffector
71 | effector: stop
72 |
73 | - id: test-stop
74 | item:
75 | type: test-stop-machine
76 |
77 | - id: test-stop-process
78 | item:
79 | name: "Invoke [stop] effector (process)"
80 | type: org.apache.brooklyn.test.framework.TestEffector
81 | effector: stop
82 | brooklyn.config:
83 | params:
84 | stopMachineMode: NEVER
85 |
86 | - id: test-start
87 | item:
88 | name: "Invoke [start] effector"
89 | type: org.apache.brooklyn.test.framework.TestEffector
90 | effector: start
91 |
92 | - id: test-restart
93 | item:
94 | name: "Invoke [restart] effector"
95 | type: org.apache.brooklyn.test.framework.TestEffector
96 | effector: restart
97 |
98 | - id: test-restart-process
99 | item:
100 | name: "Invoke [restart] effector (process)"
101 | type: org.apache.brooklyn.test.framework.TestEffector
102 | effector: restart
103 | params:
104 | restartMachine: false
105 |
106 | - id: test-restart-machine
107 | item:
108 | name: "Invoke [restart] effector (machine)"
109 | type: org.apache.brooklyn.test.framework.TestEffector
110 | effector: restart
111 | params:
112 | restartMachine: true
113 |
114 | - id: test-http-status-200
115 | item:
116 | name: "Check HTTP Response Status Code"
117 | type: org.apache.brooklyn.test.framework.TestHttpCall
118 | brooklyn.config:
119 | applyAssertionTo: status
120 | assert:
121 | - isEqualTo: 200
122 |
123 | - id: test-http-body
124 | item:
125 | name: "Check HTTP Response Body"
126 | type: org.apache.brooklyn.test.framework.TestHttpCall
127 | brooklyn.config:
128 | applyAssertionTo: body
129 |
130 | - id: test-reachable
131 | item:
132 | name: "TEST endpoint reachable"
133 | type: org.apache.brooklyn.test.framework.TestEndpointReachable
134 |
135 | - id: loop-test-case
136 | item:
137 | name: "Loop over members"
138 | type: org.apache.brooklyn.test.framework.LoopOverGroupMembersTestCase
139 |
140 | - id: ssh-cmd-restart
141 | item:
142 | type: ssh-test
143 | name: "Restart Machine"
144 | brooklyn.config:
145 | command: |
146 | nohup sudo bash -c "sleep 5; shutdown -r now" &
147 |
148 | - id: test-docker-client
149 | item:
150 | type: centos-software-process
151 | name: "test-docker-client"
152 |
153 | brooklyn.config:
154 | pre.install.command: |
155 | echo "[TEST] Install docker so we can use it as a client"
156 | sudo tee /etc/yum.repos.d/docker.repo <<-EOF
157 | [dockerrepo]
158 | name=Docker Repository
159 | baseurl=https://yum.dockerproject.org/repo/main/centos/\$releasever/
160 | enabled=1
161 | gpgcheck=1
162 | gpgkey=https://yum.dockerproject.org/gpg
163 | EOF
164 |
165 | install.command: |
166 | sudo yum -y update
167 | sudo yum -y install docker-engine
168 |
169 | launch.command: |
170 | while true ; do sleep 3600; done & echo $! > ${PID_FILE}
171 |
172 | - id: test-docker-client-with-tls
173 | item:
174 | type: test-docker-client
175 | name: "test-docker-client-with-tls"
176 |
177 | brooklyn.parameters:
178 | - name: docker.url
179 | description: URL of the docker endpoint
180 | - name: ca.url
181 | description: URL of the CA server
182 | - name: client.address
183 | description: Public address of this test client
184 |
185 | brooklyn.config:
186 | shell.env:
187 | INSTALL_DIR: $brooklyn:attributeWhenReady("install.dir")
188 | DOCKER_HOST: $brooklyn:config("docker.url")
189 | DOCKER_TLS_VERIFY: true
190 | DOCKER_CERT_PATH:
191 | $brooklyn:formatString:
192 | - "%s/.certs"
193 | - $brooklyn:attributeWhenReady("install.dir")
194 | IP: $brooklyn:config("client.address")
195 | CA: $brooklyn:config("ca.url")
196 |
197 | customize.command: |
198 | set -e
199 | CERT_DIR=${INSTALL_DIR}/.certs
200 | echo [TEST] Generating certificate request in ${CERT_DIR}
201 | mkdir -p ${CERT_DIR}
202 | openssl genrsa -out ${CERT_DIR}/key.pem 2048
203 | # provide defaults for most prompts as '.' below, meaning 'ignore'. CN is '*'
204 | openssl req -new -key ${CERT_DIR}/key.pem -days 1825 -out ${CERT_DIR}/csr.pem <<-EOF
205 | .
206 | .
207 | .
208 | .
209 | .
210 | *
211 | .
212 | .
213 | .
214 | EOF
215 | echo [TEST] Getting certificates from ${CA}
216 | curl -L ${CA}/cacert/ca.pem --output ${CERT_DIR}/ca.pem
217 | curl -X POST --data-binary @${CERT_DIR}/csr.pem ${CA}/sign > ${CERT_DIR}/cert.pem
218 | if ! grep docker_client ${HOME}/.bashrc ; then
219 | echo ". docker_client.rc" >> ${HOME}/.bashrc
220 | fi
221 | cat > ${HOME}/docker_client.rc <<-EOF
222 | export DOCKER_TLS_VERIFY=true
223 | export DOCKER_CERT_PATH=${DOCKER_CERT_PATH}
224 | export DOCKER_HOST=${DOCKER_HOST}
225 | EOF
226 |
227 | - id: test-connect-fails-without-tls
228 | item:
229 | type: ssh-test
230 | name: "Verify Connect Fails without TLS"
231 | command: |
232 | unset DOCKER_TLS_VERIFY
233 | unset DOCKER_CERT_PATH
234 | docker ps -a
235 | assertStatus:
236 | equals: 1
237 | assertErr:
238 | notEmpty: true
239 |
240 | - id: preinstall-image-tests
241 | name: Preinstalled Image Tests
242 | description: Tests on the default Docker image
243 | item:
244 | type: test-case
245 |
246 | brooklyn.parameters:
247 | - name: timeout.initialStartup
248 | description: |
249 | The timeout for provisioning, installing and launching the application
250 | under test.
251 | type: org.apache.brooklyn.util.time.Duration
252 | default: 1h
253 | - name: timeout.runtimeAssertion
254 | type: org.apache.brooklyn.util.time.Duration
255 | description: |
256 | The timeout for any other operation e.g. invoking an effector or
257 | waiting for a sensor to be updated.
258 | default: 15m
259 |
260 | brooklyn.config:
261 | image.preinstall: brooklyncentral/centos:7
262 |
263 | brooklyn.children:
264 | - type: ssh-test
265 | name: "TEST-1 docker stock image"
266 | brooklyn.config:
267 | # Should already be pulled by the docker-engine blueprint
268 | shell.env:
269 | IMAGE_PREINSTALLED: $brooklyn:config("image.preinstall")
270 | command: |
271 | docker images --format "{{.Repository}}:{{.Tag}}" |
272 | grep "${IMAGE_PREINSTALLED}"
273 | assert.status:
274 | equals: 0
275 | - type: ssh-test
276 | name: "TEST-2 Remove pre-installed image"
277 | brooklyn.config:
278 | # Should already be pulled by the docker-engine blueprint
279 | shell.env:
280 | IMAGE_PREINSTALLED: $brooklyn:config("image.preinstall")
281 | command: |
282 | docker rmi "${IMAGE_PREINSTALLED}"
283 | assert.status:
284 | equals: 0
285 | - type: test-restart
286 | name: "TEST-3 Restart to re-download image"
287 | - type: ssh-test
288 | name: "TEST-4 docker re-downloads stock images"
289 | brooklyn.config:
290 | # Should already be pulled by the docker-engine blueprint
291 | shell.env:
292 | IMAGE_PREINSTALLED: $brooklyn:config("image.preinstall")
293 | command: |
294 | docker images --format "{{.Repository}}:{{.Tag}}" |
295 | grep "${IMAGE_PREINSTALLED}"
296 | assert.status:
297 | equals: 0
298 |
299 | - id: no-preinstall-image-tests
300 | name: Empty Preinstalled Image Tests
301 | description: Tests empty image.preinstall will skip pull
302 | item:
303 | type: test-case
304 |
305 | brooklyn.parameters:
306 | - name: timeout.initialStartup
307 | description: |
308 | The timeout for provisioning, installing and launching the application
309 | under test.
310 | type: org.apache.brooklyn.util.time.Duration
311 | default: 1h
312 | - name: timeout.runtimeAssertion
313 | type: org.apache.brooklyn.util.time.Duration
314 | description: |
315 | The timeout for any other operation e.g. invoking an effector or
316 | waiting for a sensor to be updated.
317 | default: 15m
318 |
319 | brooklyn.children:
320 | - type: ssh-test
321 | name: "TEST-1 no docker images"
322 | brooklyn.config:
323 | command: |
324 | # Only header expected
325 | [ "$(docker images | wc -l)" -eq "1" ]
326 | assert.status:
327 | equals: 0
328 |
329 | ###
330 | # Tests that we can deploy a Docker Engine. We assert that it reports success, is reachable
331 | # and basic health checks (via Docker CLI) also report success.
332 | ##
333 | - id: docker-engine-test
334 | name: "Docker Engine test"
335 | description: Test that Docker Engine is deployed correctly
336 | item:
337 | type: test-case
338 |
339 | brooklyn.parameters:
340 | - name: timeout.initialStartup
341 | description: |
342 | The timeout for provisioning, installing and launching the application
343 | under test.
344 | type: org.apache.brooklyn.util.time.Duration
345 | default: 1h
346 | - name: timeout.runtimeAssertion
347 | type: org.apache.brooklyn.util.time.Duration
348 | description: |
349 | The timeout for any other operation e.g. invoking an effector or
350 | waiting for a sensor to be updated.
351 | default: 15m
352 |
353 | brooklyn.children:
354 | # Basic startup tests
355 | - type: assert-up
356 | name: "TEST-1-1 assert-up"
357 | timeout: $brooklyn:config("timeout.initialStartup")
358 | - type: assert-running
359 | name: "TEST-1-2 assert-running"
360 | timeout: $brooklyn:config("timeout.initialStartup")
361 | - type: ssh-test
362 | name: "TEST-1-3 docker CLI commands succeed"
363 | brooklyn.config:
364 | command: |
365 | docker ps
366 |
367 | # Test image pull and delete
368 | - type: test-case
369 | name: "TEST-2 image pull and delete"
370 |
371 | brooklyn.children:
372 | - type: ssh-test
373 | name: "TEST-2-1 docker pull"
374 | command: |
375 | docker pull redis
376 | - type: ssh-test
377 | name: "TEST-2-2 docker images added"
378 | command: |
379 | docker images
380 | assertOut:
381 | contains: redis
382 | - type: ssh-test
383 | name: "TEST-2-3 docker rmi"
384 | command: |
385 | docker rmi redis
386 | - type: ssh-test
387 | name: "TEST-2-4 docker images removed"
388 | command: |
389 | docker images | grep -c redis
390 | assertOut:
391 | equals: "0"
392 |
393 | # Test starting and stopping and restarting a container
394 | - type: test-case
395 | name: "TEST-3 docker containers"
396 |
397 | brooklyn.children:
398 | - type: ssh-test
399 | name: "TEST-3-1 docker run MongoDB"
400 | command: |
401 | docker pull mongo:latest
402 | docker run -d --name "test-MongoDB" mongo
403 | - type: ssh-test
404 | name: "TEST-3-2 docker ps MongoDB is up"
405 | command: |
406 | docker ps
407 | assertOut:
408 | contains: test-MongoDB
409 | - type: ssh-test
410 | name: "TEST-3-4 docker stop MongoDB"
411 | command: |
412 | docker stop test-MongoDB
413 | - type: ssh-test
414 | name: "TEST-3-5 docker ps MongoDB is stopped"
415 | command: |
416 | docker ps | grep -c test-MongoDB
417 | assertOut:
418 | equals: "0"
419 | - type: ssh-test
420 | name: "TEST-3-6 docker start MongoDB"
421 | command: |
422 | docker start test-MongoDB
423 | - type: ssh-test
424 | name: "TEST-3-7 docker ps MongoDB is up again"
425 | command: |
426 | docker ps
427 | assertOut:
428 | contains: test-MongoDB
429 |
430 | # Test building from a dockerfile
431 | - type: test-case
432 | name: "TEST-3-8 building from a dockerfile"
433 | brooklyn.children:
434 | - type: ssh-test
435 | name: "TEST-3-8a Setup Dockerfile"
436 | command: |
437 | mkdir test_dockerfile_dir
438 | printf "FROM ubuntu\nRUN echo hello world" > test_dockerfile_dir/Dockerfile
439 | - type: ssh-test
440 | name: "TEST-3-8b docker build"
441 | command: |
442 | docker build -t test_dockerfile:latest test_dockerfile_dir
443 | - type: ssh-test
444 | name: "TEST-3-8c docker images built"
445 | command: |
446 | docker images
447 | assertOut:
448 | contains: test_dockerfile
449 |
450 | - type: ssh-test
451 | name: "TEST-3-9 docker remove MongoDB"
452 | command: |
453 | docker rm -f test-MongoDB
454 | assertOut:
455 | contains: test-MongoDB
456 |
457 | ###
458 | # Tests that we can deploy a Docker Engine along with a long-running container.
459 | # We assert that the container comes up (according to the CLI command `docker ps`).
460 | ##
461 | - id: docker-engine-and-container-test
462 | name: "TEST-4 Docker Engine and Container test"
463 | description: |
464 | Test that can run a container on the Docker Engine
465 | item:
466 | type: test-case
467 |
468 | brooklyn.parameters:
469 | - name: timeout.initialStartup
470 | description: |
471 | The timeout for provisioning, installing and launching the application
472 | under test.
473 | type: org.apache.brooklyn.util.time.Duration
474 | default: 1h
475 | - name: timeout.runtimeAssertion
476 | type: org.apache.brooklyn.util.time.Duration
477 | description: |
478 | The timeout for any other operation e.g. invoking an effector or
479 | waiting for a sensor to be updated.
480 | default: 15m
481 |
482 | brooklyn.children:
483 | - type: assert-up
484 | name: "TEST-4-1 assert-up"
485 | brooklyn.config:
486 | timeout: $brooklyn:config("timeout.initialStartup")
487 | - type: ssh-test
488 | name: "TEST-4-2 assert-running"
489 | brooklyn.config:
490 | command: |
491 | docker ps
492 | assert.out:
493 | contains: brooklyncentral/centos:7
494 |
--------------------------------------------------------------------------------
/common/tests/docker/docker.tests.bom:
--------------------------------------------------------------------------------
1 | brooklyn.catalog:
2 | version: "2.1.0-SNAPSHOT" # CLOCKER_VERSION
3 | iconUrl: https://raw.githubusercontent.com/docker-library/docs/c350af05d3fac7b5c3f6327ac82fe4d990d8729c/docker/logo.png
4 | dependsOn:
5 | - tests/common.tests.bom
6 | license_code: APACHE-2.0
7 |
8 | items:
9 |
10 | - id: docker-vm-container-happy-test
11 | name: Docker Entity tests
12 | description: Tests of wrapper-vm docker
13 | itemType: entity
14 | item:
15 | type: org.apache.brooklyn.entity.stock.BasicApplication
16 | name: Docker Entity test happy path
17 |
18 | brooklyn.config:
19 | timeout: 1h
20 |
21 | brooklyn.children:
22 | - type: docker-vm-container
23 | name: Docker Entity
24 | id: docker-entity
25 | brooklyn.config:
26 | # brooklyncentral/centos:7 fails because it tries to bind to the already reserved (by the host) port 22
27 | docker.image: redis:latest
28 |
29 | my.server.port: 6379
30 |
31 | - type: test-case
32 | name: Docker Entity tests
33 | targetId: docker-entity
34 | brooklyn.children:
35 | - type: assert-up-initial
36 | name: "TEST-01 check service is running"
37 | - type: test-stop-process
38 | name: "TEST-02 stop process"
39 | - type: test-start
40 | name: "TEST-03 start process"
41 | - type: test-restart-process
42 | name: "TEST-04 restart process"
43 | - type: test-case
44 | name: "TEST-05 reboot machine"
45 | brooklyn.children:
46 | - type: ssh-cmd-restart
47 | - type: assert-failed
48 | - type: assert-up
49 | - type: assert-running
50 | - type: test-reachable
51 | name: "TEST-06 check service is reachable"
52 | brooklyn.config:
53 | endpoint:
54 | $brooklyn:formatString:
55 | - "%s:6379"
56 | - $brooklyn:entity("docker-entity").attributeWhenReady("host.address")
57 |
58 | - id: docker-vm-container-run-options
59 | name: Docker Entity run options tests
60 | description: Tests of wrapper-vm docker
61 | itemType: entity
62 | item:
63 | type: org.apache.brooklyn.entity.stock.BasicApplication
64 | name: Docker Entity test run options
65 |
66 | brooklyn.config:
67 | timeout: 1h
68 |
69 | brooklyn.children:
70 | - type: docker-vm-container
71 | name: Docker Entity
72 | id: docker-vm-entity-run-options
73 | brooklyn.config:
74 | docker.image: busybox:1.24
75 | docker.run.arguments: /bin/nc -ll -p 1234 -e /bin/ls
76 | docker.run.volumes:
77 | - /tmp/vol1:/vol1
78 | - named:/named1
79 | - named:/named2
80 | docker.run.env:
81 | k1: v1
82 | k2: v2
83 | some weird key: multi space var
84 | docker.run.additionaloptions: >-
85 | --label "additional=option"
86 |
87 | my.server.port: 1234
88 |
89 | - type: test-case
90 | name: Docker Entity run options tests
91 | targetId: docker-vm-entity-run-options
92 | brooklyn.children:
93 | - type: assert-up
94 | name: "TEST-01 check service is running"
95 | brooklyn.parameters:
96 | - name: timeout.initialStartup
97 | description: The timeout for provisioning, installing and launching the app-under-test.
98 | type: org.apache.brooklyn.util.time.Duration
99 | default: 1h
100 | brooklyn.config:
101 | timeout: $brooklyn:config("timeout.initialStartup")
102 | - type: ssh-test
103 | name: "TEST-02 container arguments applied"
104 | brooklyn.config:
105 | env:
106 | CONTAINER_ID: $brooklyn:entity("docker-vm-entity-run-options").attributeWhenReady("container.id")
107 | command: |
108 | COMMAND=$(docker inspect --format "{{ .Path }} {{ .Args }}" ${CONTAINER_ID})
109 | [ "${COMMAND}" = "/bin/nc [-ll -p 1234 -e /bin/ls]" ]
110 | - type: ssh-test
111 | name: "TEST-03 volume arguments applied"
112 | brooklyn.config:
113 | env:
114 | CONTAINER_ID: $brooklyn:entity("docker-vm-entity-run-options").attributeWhenReady("container.id")
115 | command: |
116 | ACTUAL=$(docker inspect --format "{{range .Mounts }}{{ .Name }}, {{ .Source }}, {{ .Destination }}
117 | {{ end }}" ${CONTAINER_ID} | sort)
118 | echo "ACTUAL=$ACTUAL"
119 | EXPECTED=$(printf "\nnamed, /var/lib/docker/volumes/named/_data, /named1\nnamed, /var/lib/docker/volumes/named/_data, /named2\n, /tmp/vol1, /vol1")
120 | [ "${ACTUAL}" = "${EXPECTED}" ]
121 | - type: ssh-test
122 | name: "TEST-04 environment arguments applied"
123 | brooklyn.config:
124 | env:
125 | CONTAINER_ID: $brooklyn:entity("docker-vm-entity-run-options").attributeWhenReady("container.id")
126 | command: |
127 | ACTUAL=$(docker inspect --format "{{ .Config.Env }}" ${CONTAINER_ID})
128 | echo "ACTUAL=$ACTUAL"
129 | [ "${ACTUAL}" = "[k1=v1 k2=v2 some weird key=multi space var]" ]
130 | - type: ssh-test
131 | name: "TEST-05 default restart policy applied"
132 | brooklyn.config:
133 | env:
134 | CONTAINER_ID: $brooklyn:entity("docker-vm-entity-run-options").attributeWhenReady("container.id")
135 | command: |
136 | ACTUAL=$(docker inspect --format "{{ .HostConfig.RestartPolicy.Name }}" ${CONTAINER_ID})
137 | echo "ACTUAL=$ACTUAL"
138 | [ "${ACTUAL}" = "unless-stopped" ]
139 | - type: ssh-test
140 | name: "TEST-06 Additional Options"
141 | brooklyn.config:
142 | env:
143 | CONTAINER_ID: $brooklyn:entity("docker-vm-entity-run-options").attributeWhenReady("container.id")
144 | command: |
145 | ACTUAL=$(docker inspect --format "{{ .Config.Labels.additional }}" ${CONTAINER_ID})
146 | echo "ACTUAL=$ACTUAL"
147 | [ "${ACTUAL}" = "option" ]
148 | - type: test-reachable
149 | name: "TEST-07 Check service is reachable"
150 | brooklyn.config:
151 | endpoint:
152 | $brooklyn:formatString:
153 | - "%s:1234"
154 | - $brooklyn:entity("docker-vm-entity-run-options").attributeWhenReady("host.address")
155 |
156 | # TODO Unused, need to express that start effector is expected to fail
157 | - id: docker-vm-container-fails-test
158 | name: Docker Entity test failure on image exit
159 | description: Tests of wrapper-vm docker
160 | itemType: entity
161 | item:
162 | type: org.apache.brooklyn.entity.stock.BasicApplication
163 | name: Docker Entity test no image configured
164 | brooklyn.children:
165 | # Doesn't propagate failures
166 | - type: org.apache.brooklyn.entity.stock.BasicEntity
167 | name: Ignore failure wrapper
168 | brooklyn.children:
169 | - type: docker-vm-container
170 | name: Docker Entity
171 | id: docker-entity-no-image
172 |
173 | - type: test-case
174 | name: Docker Entity tests
175 | targetId: docker-entity-no-image
176 | brooklyn.children:
177 | - type: test-start
178 | brooklyn.parameters:
179 | - name: timeout.initialStartup
180 | description: The timeout for provisioning, installing and launching the app-under-test.
181 | type: org.apache.brooklyn.util.time.Duration
182 | default: 1h
183 | brooklyn.config:
184 | timeout: $brooklyn:config("timeout.initialStartup")
185 |
186 | # TODO Unused, need to express that start effector is expected to fail
187 | - id: docker-vm-container-exits-test
188 | name: Docker Entity test failure on image exit
189 | description: Tests of wrapper-vm docker
190 | itemType: entity
191 | item:
192 | type: org.apache.brooklyn.entity.stock.BasicApplication
193 | name: Docker Entity test image exits immediately failure
194 |
195 | brooklyn.config:
196 | timeout: 1h
197 |
198 | brooklyn.children:
199 | # Doesn't propagate failures
200 | - type: org.apache.brooklyn.entity.stock.BasicEntity
201 | name: Ignore failure wrapper
202 | brooklyn.children:
203 | - type: docker-vm-container
204 | name: Docker Entity
205 | id: docker-entity-exits
206 | brooklyn.config:
207 | docker.image: busybox:1.24
208 |
209 | - type: test-case
210 | name: Docker Entity tests
211 | targetId: docker-entity-exits
212 | brooklyn.children:
213 | - type: test-start
214 | brooklyn.parameters:
215 | - name: timeout.initialStartup
216 | description: The timeout for provisioning, installing and launching the app-under-test.
217 | type: org.apache.brooklyn.util.time.Duration
218 | default: 1h
219 | brooklyn.config:
220 | timeout: $brooklyn:config("timeout.initialStartup")
221 | - id: docker-vm-container-tests
222 | item:
223 | name: Docker VM Wrapper tests
224 | type: org.apache.brooklyn.entity.stock.BasicApplication
225 | brooklyn.children:
226 | - type: docker-vm-container-happy-test
227 | - type: docker-vm-container-run-options
228 | #- type: docker-vm-container-fails-test
229 | #- type: docker-vm-container-exits-test
230 |
231 | - id: docker-preinstall-tests
232 | name: Preinstalled Image Tests
233 | description: Tests of pre-installed Docker image
234 | itemType: entity
235 | item:
236 | type: org.apache.brooklyn.test.framework.TestCase
237 |
238 | brooklyn.children:
239 |
240 | - type: docker-engine
241 | name: Docker Engine
242 | id: preinstall-engine
243 |
244 | - type: preinstall-image-tests
245 | name: Preinstalled Image Tests
246 | targetId: preinstall-engine
247 |
248 | - id: docker-no-preinstall-tests
249 | name: Preinstalled image tests
250 | description: Tests of pre-installed Docker image
251 | itemType: entity
252 | item:
253 | type: org.apache.brooklyn.test.framework.TestCase
254 |
255 | brooklyn.children:
256 |
257 | - type: docker-engine
258 | name: Docker Engine
259 | id: no-preinstall-engine
260 | brooklyn.config:
261 | image.preinstall:
262 |
263 | - type: no-preinstall-image-tests
264 | name: Empty Preinstalled Image Tests
265 | targetId: no-preinstall-engine
266 |
267 | - id: docker-engine-tests
268 | name: Docker Engine Tests without TLS
269 | description: Tests on Docker Engine without TLS
270 | itemType: entity
271 | item:
272 | type: org.apache.brooklyn.test.framework.TestCase
273 |
274 | brooklyn.children:
275 |
276 | - type: docker-engine
277 | name: Docker Engine
278 | id: docker-engine
279 |
280 | - type: docker-engine-test
281 | name: Test Docker Engine
282 | targetId: docker-engine
283 |
284 | - type: docker-engine
285 | id: docker-engine-with-centos
286 | name: Docker Engine with Centos Container
287 | brooklyn.children:
288 | - type: docker-engine-container
289 | image.details: brooklyncentral/centos:7
290 |
291 | - type: docker-engine-and-container-test
292 | name: Test Docker with Container
293 | targetId: docker-engine-with-centos
294 |
295 | - id: docker-engine-tls-tests
296 | name: Docker Engine Tests with TLS
297 | description: Tests on Docker Engine with TLS
298 | itemType: entity
299 | item:
300 | type: org.apache.brooklyn.test.framework.TestCase
301 |
302 | brooklyn.children:
303 |
304 | # A CA server
305 | - type: ca-server
306 | name: CA
307 | id: ca-server
308 |
309 | # the engine protected by TLS
310 | - type: docker-engine-tls
311 | name: Docker Engine with TLS
312 | id: docker-engine-tls
313 | brooklyn.config:
314 | latch.customize: $brooklyn:entity("ca-server").attributeWhenReady("service.isUp")
315 | ca.request.root.url:
316 | $brooklyn:formatString:
317 | - "%s:%d"
318 | - $brooklyn:entity("ca-server").attributeWhenReady("host.address")
319 | - $brooklyn:entity("ca-server").config("ca.server.port")
320 |
321 |
322 | # A client for talking to the engine
323 | - type: test-docker-client-with-tls
324 | name: Docker client with TLS
325 | id: tls-client
326 | brooklyn.config:
327 | latch.customize: $brooklyn:entity("ca-server").attributeWhenReady("service.isUp")
328 | client.address: $brooklyn:attributeWhenReady("host.address")
329 | ca.url: $brooklyn:entity("ca-server").attributeWhenReady("main.uri")
330 | docker.url:
331 | $brooklyn:formatString:
332 | - "tcp://%s:%s/"
333 | - $brooklyn:entity("docker-engine-tls").attributeWhenReady("host.address")
334 | - $brooklyn:entity("docker-engine-tls").config("docker.port")
335 |
336 | - type: docker-engine-test
337 | name: Test Docker over TLS
338 | targetId: tls-client
339 |
--------------------------------------------------------------------------------
/common/tests/docker/tests.bom:
--------------------------------------------------------------------------------
1 | brooklyn.catalog:
2 | version: "2.1.0-SNAPSHOT" # CLOCKER_VERSION
3 | iconUrl: https://raw.githubusercontent.com/docker-library/docs/471fa6e4cb58062ccbf91afc111980f9c7004981/swarm/logo.png
4 | dependsOn:
5 | - tests/docker.tests.bom
6 | - tests/swarm.tests.bom
7 | license_code: APACHE-2.0
8 |
9 | items:
10 | - id: docker-engine-common-tests
11 | name: "Docker Engine Common Tests"
12 | description: |
13 | Tests on Docker Engine with and without TLS, and on Swarm (with TLS)
14 | itemType: template
15 | item:
16 | brooklyn.config:
17 | timeout: 1h
18 | timeout.initialStartup: 1h
19 | timeout.runtimeAssertion: 1h
20 |
21 | services:
22 | - type: docker-engine-tests
23 | name: Docker Engine Tests
24 | - type: docker-engine-tls-tests
25 | name: Docker Engine TLS Tests
26 | - type: docker-preinstall-tests
27 | name: Docker Pre-install Tests
28 | - type: docker-vm-container-tests
29 | name: Docker VM Container Tests
30 |
--------------------------------------------------------------------------------
/feature/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | clocker-parent
7 | io.brooklyn.clocker
8 | 2.1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | clocker-feature
13 | Clocker :: Feature
14 | feature
15 |
16 |
17 |
18 |
19 | org.apache.karaf.tooling
20 | karaf-maven-plugin
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/feature/src/main/feature/feature.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 | mvn:io.brooklyn.etcd/brooklyn-etcd/${brooklyn-etcd.version}/xml/features
8 |
9 |
10 | clocker-dependencies
11 | clocker-common
12 | clocker-kubernetes
13 | clocker-swarm
14 |
15 |
16 |
17 | mvn:${project.groupId}/clocker-common/${project.version}
18 |
19 |
20 |
21 | mvn:${project.groupId}/clocker-kubernetes/${project.version}
22 |
23 |
24 |
25 | mvn:${project.groupId}/clocker-swarm/${project.version}
26 |
27 |
28 |
29 | brooklyn-etcd
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/kubernetes/catalog/catalog.bom:
--------------------------------------------------------------------------------
1 | brooklyn.catalog:
2 | items:
3 | - classpath://kubernetes/plugins.bom
4 | - classpath://kubernetes/pods.bom
5 | - classpath://kubernetes/kubernetes.bom
6 |
7 | - id: kubernetes-cluster-template
8 | name: "Kubernetes Cluster"
9 | description: |
10 | Kubernetes cluster with a master node and worker nodes
11 | iconUrl: classpath://io.brooklyn.clocker.kubernetes:icons/kubernetes.png
12 | itemType: template
13 | item:
14 | services:
15 | - type: kubernetes-cluster-application
16 | id: kubernetes-cluster-application
17 | name: "kubernetes-cluster-application"
18 |
--------------------------------------------------------------------------------
/kubernetes/catalog/kubernetes/plugins.bom:
--------------------------------------------------------------------------------
1 | brooklyn.catalog:
2 | version: "2.1.0-SNAPSHOT" # CLOCKER_VERSION
3 | publish:
4 | description: |
5 | Resources for working with Docker Engine plugins from Apache Brooklyn
6 | license_code: APACHE-2.0
7 |
8 | items:
9 |
10 | - id: flannel-network-agent
11 | name: "Flannel Network Agent"
12 | description: |
13 | The Flannel virtual network agent
14 | itemType: entity
15 | iconUrl: classpath://io.brooklyn.clocker.kubernetes:icons/flannel.png
16 | item:
17 | type: child-software-process
18 | name: "flannel-network-agent"
19 |
20 | brooklyn.parameters:
21 | - name: flannel.version
22 | label: "Flannel Version"
23 | description: |
24 | The Flannel version to install
25 | type: string
26 | default: "0.6.2"
27 | - name: flannel.network
28 | label: "Flannel Network"
29 | description: |
30 | The Flannel network CIDR
31 | type: string
32 | default: "10.0.0.0/8"
33 | - name: flannel.subnet.size
34 | label: "Flannel Subnet Size"
35 | description: |
36 | The size of the subnet CIDRs to be created
37 | type: integer
38 | default: 20
39 | - name: flannel.transport
40 | label: "Flannel Transport"
41 | description: |
42 | The Flannel backend transport mechanism. Can be any of: 'udp',
43 | 'vxlan', 'host-gw', 'aws-vpc', 'gce' or 'alloc'.
44 | type: string
45 | default: "udp"
46 | - name: flannel.interface
47 | label: "Flannel Interface"
48 | description: |
49 | The Flannel interface for host to host traffic
50 | type: string
51 | default: "eth0"
52 | - name: etcd.client.version
53 | label: "Etcd Client Version"
54 | description: |
55 | The etcd client version to install
56 | type: string
57 | default: "3.0.3"
58 | - name: etcd.endpoints
59 | label: "Etcd Endpoints"
60 | description: |
61 | The URLs for an etcd KV store
62 | type: string
63 |
64 | brooklyn.config:
65 | install.unique_label:
66 | $brooklyn:formatString:
67 | - "plugin-flannel-%s"
68 | - $brooklyn:config("flannel.version")
69 |
70 | shell.env:
71 | ETCD_VERSION: $brooklyn:config("etcd.client.version")
72 | ETCD_ENDPOINTS: $brooklyn:config("etcd.endpoints")
73 | FLANNEL_VERSION: $brooklyn:config("flannel.version")
74 | FLANNEL_ADDRESS_RANGE: $brooklyn:config("flannel.network")
75 | FLANNEL_SUBNET_SIZE: $brooklyn:config("flannel.subnet.size")
76 | FLANNEL_TRANSPORT: $brooklyn:config("flannel.transport")
77 | FLANNEL_IFACE: $brooklyn:config("flannel.interface")
78 | HOST_ADDRESS: $brooklyn:parent().attributeWhenReady("host.address")
79 | HOST_SUBNET_ADDRESS: $brooklyn:parent().attributeWhenReady("host.subnet.address")
80 | FLANNEL_ETCD_PREFIX: "/io.cloudsoft/clocker/flannel"
81 |
82 | install.command: |
83 | wget https://github.com/coreos/flannel/releases/download/v${FLANNEL_VERSION}/flanneld-amd64
84 | chmod 755 flanneld-amd64
85 | sudo cp flanneld-amd64 /usr/bin/flanneld
86 | wget https://github.com/coreos/etcd/releases/download/v${ETCD_VERSION}/etcd-v${ETCD_VERSION}-linux-amd64.tar.gz
87 | tar zxvf etcd-v${ETCD_VERSION}-linux-amd64.tar.gz etcd-v${ETCD_VERSION}-linux-amd64/etcdctl
88 | sudo cp etcd-v${ETCD_VERSION}-linux-amd64/etcdctl /usr/bin
89 | sudo mkdir -p /var/run/flannel
90 |
91 | customize.command: |
92 | echo "[CLOCKER] Reset bridge and NAT configuration"
93 | ip link | grep docker0 && (
94 | sudo ip link set dev docker0 down
95 | sudo ip link delete docker0
96 | )
97 | sudo iptables -F -t nat
98 |
99 | echo "[CLOCKER] Configure Flannel for ${FLANNEL_TRANSPORT}"
100 | if [ "${FLANNEL_TRANSPORT}" == "vxlan" ] ; then
101 | FLANNEL_TRANSPORT_OPTS=", \"VNI\":1"
102 | fi
103 | cat > flannel.json <<-EOF
104 | {
105 | "Network": "${FLANNEL_ADDRESS_RANGE}",
106 | "SubnetLen": ${FLANNEL_SUBNET_SIZE},
107 | "Backend": {
108 | "Type": "${FLANNEL_TRANSPORT}"${FLANNEL_TRANSPORT_OPTS}
109 | }
110 | }
111 | EOF
112 | etcdctl --peers ${ETCD_ENDPOINTS} mk ${FLANNEL_ETCD_PREFIX}/config < flannel.json || etcdctl --peers ${ETCD_ENDPOINTS} get ${FLANNEL_ETCD_PREFIX}/config
113 |
114 | sudo -E tee /etc/systemd/system/flannel.service <<-EOF
115 | [Unit]
116 | Description=Flannel Overlay Agent
117 | After=network.target
118 | Before=docker.service
119 | [Service]
120 | ExecStart=/usr/bin/flanneld \
121 | -etcd-endpoints=${ETCD_ENDPOINTS} \
122 | -etcd-prefix=${FLANNEL_ETCD_PREFIX} \
123 | --iface ${FLANNEL_IFACE} \
124 | --ip-masq \
125 | --subnet-file=/var/run/flannel/subnet.env \
126 | --public-ip=${HOST_SUBNET_ADDRESS}
127 | Type=notify
128 | [Install]
129 | WantedBy=multi-user.target
130 | RequiredBy=docker.service
131 | EOF
132 |
133 | launch.command: |
134 | sudo systemctl daemon-reload
135 | sudo systemctl enable flannel
136 | sudo systemctl start flannel
137 |
138 | checkRunning.command: |
139 | sudo systemctl status flannel
140 |
141 | brooklyn.initializers:
142 | - type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
143 | brooklyn.config:
144 | name: flannel.mtu
145 | description: |
146 | The MTU for the Flannel network
147 | targetType: integer
148 | command: |
149 | source /var/run/flannel/subnet.env && echo ${FLANNEL_MTU}
150 | - type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
151 | brooklyn.config:
152 | name: flannel.subnet
153 | description: |
154 | The Flannel subnet address range
155 | targetType: string
156 | command: |
157 | source /var/run/flannel/subnet.env && echo ${FLANNEL_SUBNET}
158 |
159 | - id: calico-cni-plugin
160 | name: "Calico CNI Plugin"
161 | description: |
162 | The Project Calico plugin for CNI
163 | itemType: entity
164 | iconUrl: classpath://io.brooklyn.clocker.kubernetes:icons/calico.png
165 | item:
166 | type: child-software-process
167 | name: "calico-network-plugin"
168 |
169 | brooklyn.parameters:
170 | - name: calico.version
171 | label: "Calico Version"
172 | description: |
173 | The Project Calico driver version
174 | type: string
175 | default: "0.22.0"
176 | - name: cni.version
177 | label: "CNI Version"
178 | description: |
179 | The CNI version
180 | type: string
181 | default: "0.3.0"
182 | - name: calico.cni.version
183 | label: "Calico CNI Version"
184 | description: |
185 | The Project Calico CNI version
186 | type: string
187 | default: "1.4.2"
188 | - name: etcd.endpoints
189 | label: "Etcd Endpoints"
190 | description: |
191 | The URLs for an etcd KV store
192 | type: string
193 |
194 | brooklyn.config:
195 | install.unique_label:
196 | $brooklyn:formatString:
197 | - "plugin-calico-cni-%s-%s"
198 | - $brooklyn:config("calico.version")
199 | - $brooklyn:config("calico.cni.version")
200 |
201 | shell.env:
202 | CALICO_VERSION: $brooklyn:config("calico.version")
203 | CALICO_CNI_VERSION: $brooklyn:config("calico.cni.version")
204 | CNI_VERSION: $brooklyn:config("cni.version")
205 | ETCD_ENDPOINTS: $brooklyn:config("etcd.endpoints")
206 | HOST_ADDRESS: $brooklyn:parent().attributeWhenReady("host.address")
207 | HOST_SUBNET_ADDRESS: $brooklyn:parent().attributeWhenReady("host.subnet.address")
208 | ENTITY_ID: $brooklyn:parent().attributeWhenReady("entity.id")
209 |
210 | install.command: |
211 | wget https://github.com/projectcalico/calico-containers/releases/download/v${CALICO_VERSION}/calicoctl
212 | chmod +x calicoctl
213 | sudo mv calicoctl /usr/bin
214 | sudo mkdir -p /opt/cni/bin
215 | wget https://github.com/containernetworking/cni/releases/download/v${CNI_VERSION}/cni-v${CNI_VERSION}.tgz
216 | sudo tar --strip-components=1 -xvzf cni-v${CNI_VERSION}.tgz -C /opt/cni/bin
217 | wget https://github.com/projectcalico/calico-cni/releases/download/v${CALICO_CNI_VERSION}/calico
218 | wget https://github.com/projectcalico/calico-cni/releases/download/v${CALICO_CNI_VERSION}/calico-ipam
219 | chmod +x calico calico-ipam
220 | sudo mv calico calico-ipam /opt/cni/bin
221 | docker pull calico/node:v${CALICO_VERSION}
222 | sudo yum install -y ipset
223 | sudo modprobe ip6_tables
224 | sudo modprobe xt_set
225 |
226 | customize.command: |
227 | sudo mkdir -p /etc/cni/net.d
228 |
229 | launch.command: |
230 | sudo -E tee /etc/systemd/system/calico-node.service <<-EOF
231 | [Unit]
232 | Description=Calico Node
233 | After=docker.service
234 | Requires=docker.service
235 | [Service]
236 | User=root
237 | PermissionsStartOnly=true
238 | Environment="ETCD_ENDPOINTS=${ETCD_ENDPOINTS}"
239 | Environment="CALICO_NETWORKING=false"
240 | Environment="HOSTNAME=${HOST_SUBNET_ADDRESS}"
241 | Environment="FELIX_FELIXHOSTNAME=${HOST_SUBNET_ADDRESS}"
242 | Environment="NO_DEFAULT_POOLS=true"
243 | ExecStart=/usr/bin/calicoctl node \
244 | --ip=${HOST_SUBNET_ADDRESS} \
245 | --no-pull \
246 | --node-image=calico/node:v${CALICO_VERSION} \
247 | --detach=false
248 | Restart=always
249 | RestartSec=10
250 | [Install]
251 | WantedBy=multi-user.target
252 | EOF
253 | sudo systemctl daemon-reload
254 | sudo systemctl enable calico-node
255 | sudo systemctl start calico-node
256 |
257 | checkRunning.command: |
258 | unset DOCKER_HOST
259 | sudo systemctl status calico-node
260 |
--------------------------------------------------------------------------------
/kubernetes/catalog/kubernetes/pods.bom:
--------------------------------------------------------------------------------
1 | brooklyn.catalog:
2 | version: "2.1.0-SNAPSHOT" # CLOCKER_VERSION
3 | publish:
4 | description: |
5 | Resources for working with Kubernetes Pod deployments from Apache Brooklyn
6 | license_code: APACHE-2.0
7 |
8 | items:
9 | - id: kubernetes-pod
10 | name: "Kubernetes Pod"
11 | description: |
12 | A Kubernetes YAML pod deployment
13 | itemType: entity
14 | iconUrl: classpath://io.brooklyn.clocker.kubernetes:icons/kubernetes.png
15 | item:
16 | type: child-software-process
17 |
18 | brooklyn.parameters:
19 | - name: kubernetes.pod.file
20 | label: "Kubernetes Pod File"
21 | type: string
22 | - name: kubernetes.pod.namespace
23 | label: "Kubernetes Pod Namespace"
24 | type: string
25 | default: "default"
26 | - name: kubernetes.pod.name
27 | label: "Kubernetes Pod Name"
28 | type: string
29 | - name: template.substitutions
30 | label: "Template Substitutions"
31 | type: java.util.Map
32 |
33 | brooklyn.config:
34 | install.unique_label:
35 | $brooklyn:formatString:
36 | - "pod-%s-%s"
37 | - $brooklyn:config("kubernetes.pod.name")
38 | - $brooklyn:entity("kubernetes-cluster").config("kubernetes.version")
39 |
40 | templates.install:
41 | $brooklyn:config("kubernetes.pod.file"): "pod.yaml"
42 |
43 | shell.env:
44 | NAME: $brooklyn:config("kubernetes.pod.name")
45 | NAMESPACE: $brooklyn:config("kubernetes.pod.namespace")
46 | INSTALL_DIR: $brooklyn:attributeWhenReady("install.dir")
47 |
48 | pre.install.command: |
49 | mkdir -p ${INSTALL_DIR}
50 |
51 | install.command: |
52 | kubectl get namespace ${NAMESPACE} ||
53 | ( kubectl create namespace ${NAMESPACE} || true )
54 |
55 | launch.command: |
56 | kubectl create -f ${INSTALL_DIR}/pod.yaml
57 |
58 | checkRunning.command: |
59 | kubectl get pod --namespace=${NAMESPACE} -l app=${NAME} |
60 | grep "Pending\|ContainerCreating\|Running"
61 |
62 | brooklyn.initializers:
63 | - type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
64 | brooklyn.config:
65 | name: kubernetes.pod.name
66 | description: |
67 | Kubernetes pod name
68 | targetType: string
69 | command: |
70 | kubectl get pod --namespace=${NAMESPACE} -l app=${NAME} --output=jsonpath='{range .items[0]}{.metadata.name}'
71 | - type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
72 | brooklyn.config:
73 | name: kubernetes.pod.status
74 | description: |
75 | Kubernetes pod status
76 | targetType: string
77 | command: |
78 | kubectl get pod --namespace=${NAMESPACE} -l app=${NAME} -o wide | grep ${NAME}
79 | - type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
80 | brooklyn.config:
81 | name: kubernetes.pod.node
82 | description: |
83 | Kubernetes host IP address for the service
84 | targetType: string
85 | command: |
86 | kubectl get pod --namespace=${NAMESPACE} -l app=${NAME} --output=jsonpath='{range .items[0]}{.status.hostIP}'
87 | - type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
88 | brooklyn.config:
89 | name: kubernetes.service.port
90 | description: |
91 | Kubernetes exposed NodePort for a service
92 | targetType: integer
93 | command: |
94 | kubectl get service ${NAME} --namespace=${NAMESPACE} --output=jsonpath='{range .spec.ports[0]}{.nodePort}'
95 | - type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
96 | brooklyn.config:
97 | name: kubernetes.pod.phase
98 | description: |
99 | Kubernetes pod status phase
100 | targetType: string
101 | command: |
102 | kubectl get pod --namespace=${NAMESPACE} -l app=${NAME} --output=jsonpath='{range .items[0]}{.status.phase}'
103 |
104 | brooklyn.enrichers:
105 | - type: org.apache.brooklyn.enricher.stock.Transformer
106 | brooklyn.config:
107 | uniqueTag: kubernetes-pod-url-publisher
108 | enricher.triggerSensors:
109 | - $brooklyn:sensor("kubernetes.pod.node")
110 | - $brooklyn:sensor("kubernetes.service.port")
111 | enricher.targetSensor: $brooklyn:sensor("kubernetes.service.url")
112 | enricher.targetValue:
113 | $brooklyn:formatString:
114 | - "http://%s:%d/"
115 | - $brooklyn:attributeWhenReady("kubernetes.pod.node")
116 | - $brooklyn:attributeWhenReady("kubernetes.service.port")
117 | - type: org.apache.brooklyn.enricher.stock.Propagator
118 | brooklyn.config:
119 | uniqueTag: kubernetes-pod-url-propagator
120 | enricher.propagating.sensorMapping:
121 | $brooklyn:sensor("kubernetes.service.url"):
122 | $brooklyn:sensor("org.apache.brooklyn.core.entity.Attributes", "main.uri")
123 |
124 | - id: kube-dns-pod
125 | name: "KubeDNS Pod"
126 | description: |
127 | KubeDNS service pod
128 | itemType: entity
129 | iconUrl: classpath://io.brooklyn.clocker.kubernetes:icons/kubernetes.png
130 | item:
131 | type: kubernetes-pod
132 |
133 | brooklyn.config:
134 | kubernetes.pod.name: "kube-dns"
135 | kubernetes.pod.file: "classpath://io.brooklyn.clocker.kubernetes:kubernetes/kube-dns.yaml"
136 | kubernetes.pod.namespace: "kube-system"
137 |
138 | template.substitutions:
139 | kubernetes_url: $brooklyn:entity("kubernetes-cluster").attributeWhenReady("kubernetes.url")
140 | replicas: $brooklyn:entity("kubernetes-cluster").config("kubernetes.initial.size")
141 | dns_service_ip: $brooklyn:entity("kubernetes-cluster").config("kubernetes.dns.address")
142 | dns_service_domain: $brooklyn:entity("kubernetes-cluster").config("kubernetes.dns.domain")
143 |
144 | - id: kubernetes-dashboard-pod
145 | name: "Kubernetes Dashboard Pod"
146 | description: |
147 | Kubernetes dashboard UI service pod
148 | itemType: entity
149 | iconUrl: classpath://io.brooklyn.clocker.kubernetes:icons/kubernetes.png
150 | item:
151 | type: kubernetes-pod
152 |
153 | brooklyn.config:
154 | kubernetes.pod.name: "kubernetes-dashboard"
155 | kubernetes.pod.file: "classpath://io.brooklyn.clocker.kubernetes:kubernetes/kubernetes-dashboard.yaml"
156 | kubernetes.pod.namespace: "kube-system"
157 |
158 | template.substitutions:
159 | kubernetes_url: $brooklyn:entity("kubernetes-cluster").attributeWhenReady("kubernetes.url")
160 |
161 | - id: calico-policy-controller-pod
162 | name: "Calico Policy Controller Pod"
163 | description: |
164 | Calico policy controller pod
165 | itemType: entity
166 | iconUrl: classpath://io.brooklyn.clocker.kubernetes:icons/calico.png
167 | item:
168 | type: kubernetes-pod
169 |
170 | brooklyn.config:
171 | kubernetes.pod.name: "policy-controller"
172 | kubernetes.pod.file: "classpath://io.brooklyn.clocker.kubernetes:kubernetes/policy-controller.yaml"
173 | kubernetes.pod.namespace: "kube-system"
174 |
175 | template.substitutions:
176 | kubernetes_url: $brooklyn:entity("kubernetes-cluster").attributeWhenReady("kubernetes.url")
177 | etcd_endpoints: $brooklyn:entity("etcd-cluster").attributeWhenReady("etcd.urls")
178 |
179 | - id: prometheus-pod
180 | name: "Prometheus Monitoring Pod"
181 | description: |
182 | Prometheus monitoring service pod
183 | itemType: entity
184 | iconUrl:
185 | iconUrl: classpath://io.brooklyn.clocker.kubernetes:icons/prometheus.png
186 | item:
187 | type: kubernetes-pod
188 |
189 | brooklyn.config:
190 | kubernetes.pod.name: "prometheus"
191 | kubernetes.pod.file: "classpath://io.brooklyn.clocker.kubernetes:kubernetes/prometheus.yaml"
192 | kubernetes.pod.namespace: "kube-system"
193 |
194 | template.substitutions:
195 | kubernetes_url: $brooklyn:entity("kubernetes-cluster").attributeWhenReady("kubernetes.url")
196 |
--------------------------------------------------------------------------------
/kubernetes/examples/kubernetes-minimal.yaml:
--------------------------------------------------------------------------------
1 | id: kubernetes-minimal
2 | name: "Kubernetes Cluster"
3 | description: |
4 | Uses the default settings for configuring Kubernetes, apart from the initial
5 | size of the cluster of worker nodes.
6 |
7 | Deploys on AWS using only the default Kubernetes entity configuration. Requires
8 | a security group to be deined in the AWS region or VPC, which should be
9 | set in the 'templateOptions' of the location, as seen below.
10 |
11 | location:
12 | jclouds:aws-ec2:
13 | region: eu-central-1
14 | privateKeyFile: "~/.ssh/kubernetes.pem"
15 | loginUser.privateKeyFile: "~/.ssh/kubernetes.pem"
16 | keyPair: "kubernetes"
17 | templateOptions:
18 | securityGroups:
19 | - "kubernetes"
20 |
21 | services:
22 | - type: kubernetes-cluster-application
23 | name: "kubernetes-aws-ec2"
24 | brooklyn.config:
25 | kubernetes.initial.size: 2
26 | kubernetes.sharedsecuritygroup.create: true
27 |
--------------------------------------------------------------------------------
/kubernetes/examples/kubernetes.yaml:
--------------------------------------------------------------------------------
1 | id: kubernetes
2 | name: "Kubernetes Cluster"
3 | description: |
4 | Includes built-in etcd discovery cluster and TLS protected Docker.
5 |
6 | Deploys on CentOS 7 VMs in SoftLayer, on a single VLAN segment.
7 |
8 | location:
9 | jclouds:softlayer:
10 | region: ams01
11 | identity: xxxxxxxx
12 | credential: XXXXXXXX
13 | privateKeyFile: ~/.ssh/softlayer.pem
14 | customizers:
15 | - $brooklyn:object:
16 | type: org.apache.brooklyn.location.jclouds.softlayer.SoftLayerSameVlanLocationCustomizer
17 | brooklyn.config:
18 | softlayer.vlan.scopeUid: "kubernetes"
19 |
20 | services:
21 | - type: kubernetes-cluster-application
22 | id: kubernetes
23 | name: "kubernetes"
24 | brooklyn.config:
25 | kubernetes.debug: true
26 | kubernetes.version: 1.4.3
27 | start.timeout: 30m
28 | kubernetes.master.size: 2
29 | kubernetes.initial.size: 4
30 | kubernetes.max.size: 16
31 | etcd.initial.size: 3
32 | kubernetes.apiserver.port: 8000
33 | kubernetes.scaling.cpu.limit: 0.80
34 | kubernetes.recovery.stabilizationDelay: 30s
35 | kubernetes.recovery.failOnRecurringFailuresInThisDuration: 300000
36 | docker.recovery.stabilizationDelay: 30s
37 | docker.recovery.failOnRecurringFailuresInThisDuration: 5m
38 | kubernetes.pod.cidr: "10.250.0.0/16"
39 | kubernetes.minRam: 10g
40 | kubernetes.minCores: 4
41 | provisioning.properties:
42 | minRam: 2g
43 | minCores: 1
44 |
--------------------------------------------------------------------------------
/kubernetes/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 |
8 | io.brooklyn.clocker
9 | clocker-parent
10 | 2.1.0-SNAPSHOT
11 |
12 |
13 | Clocker :: Kubernetes
14 | clocker-kubernetes
15 | bundle
16 |
17 |
18 |
19 |
20 | catalog
21 | false
22 |
23 |
24 | resources
25 | false
26 |
27 |
28 | external-resources
29 | false
30 |
31 |
32 | tests
33 | false
34 | tests
35 |
36 |
37 |
38 |
39 |
40 | org.codehaus.mojo
41 | build-helper-maven-plugin
42 |
43 |
44 | attach-artifact
45 | package
46 |
47 | attach-artifact
48 |
49 |
50 |
51 |
52 | ${project.basedir}/catalog/kubernetes/kubernetes.bom
53 | bom
54 | kubernetes
55 |
56 |
57 | ${project.basedir}/catalog/kubernetes/pods.bom
58 | bom
59 | pods
60 |
61 |
62 | ${project.basedir}/catalog/kubernetes/plugins.bom
63 | bom
64 | plugins
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/kubernetes/resources/icons/calico.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brooklyncentral/clocker/e1ff91d4959d2238efcf78569d600f95273730d4/kubernetes/resources/icons/calico.png
--------------------------------------------------------------------------------
/kubernetes/resources/icons/flannel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brooklyncentral/clocker/e1ff91d4959d2238efcf78569d600f95273730d4/kubernetes/resources/icons/flannel.png
--------------------------------------------------------------------------------
/kubernetes/resources/icons/kubernetes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brooklyncentral/clocker/e1ff91d4959d2238efcf78569d600f95273730d4/kubernetes/resources/icons/kubernetes.png
--------------------------------------------------------------------------------
/kubernetes/resources/icons/openshift.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brooklyncentral/clocker/e1ff91d4959d2238efcf78569d600f95273730d4/kubernetes/resources/icons/openshift.png
--------------------------------------------------------------------------------
/kubernetes/resources/icons/prometheus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brooklyncentral/clocker/e1ff91d4959d2238efcf78569d600f95273730d4/kubernetes/resources/icons/prometheus.png
--------------------------------------------------------------------------------
/kubernetes/resources/kubernetes/basic_auth.csv:
--------------------------------------------------------------------------------
1 | guest,guest,1001
2 | p4ssw0rd,admin,1002
3 | pr0m3th3us,prometheus,1003
--------------------------------------------------------------------------------
/kubernetes/resources/kubernetes/kube-dns.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: kube-dns
5 | namespace: kube-system
6 | labels:
7 | app: kube-dns
8 | name: kube-dns-service
9 | kubernetes.io/cluster-service: "true"
10 | kubernetes.io/name: "KubeDNS"
11 | spec:
12 | selector:
13 | app: kube-dns
14 | clusterIP: ${config['template.substitutions']['dns_service_ip']}
15 | ports:
16 | - name: dns
17 | port: 53
18 | protocol: UDP
19 | - name: dns-tcp
20 | port: 53
21 | protocol: TCP
22 | ---
23 | apiVersion: v1
24 | kind: ReplicationController
25 | metadata:
26 | name: kube-dns
27 | namespace: kube-system
28 | labels:
29 | app: kube-dns
30 | name: kube-dns-replicationcontroller
31 | version: v20
32 | kubernetes.io/cluster-service: "true"
33 | spec:
34 | replicas: ${config['template.substitutions']['replicas']}
35 | selector:
36 | app: kube-dns
37 | version: v20
38 | template:
39 | metadata:
40 | labels:
41 | app: kube-dns
42 | version: v20
43 | kubernetes.io/cluster-service: "true"
44 | annotations:
45 | scheduler.alpha.kubernetes.io/critical-pod: ''
46 | scheduler.alpha.kubernetes.io/tolerations: '[{"key":"CriticalAddonsOnly", "operator":"Exists"}]'
47 | spec:
48 | containers:
49 | - name: kubedns
50 | image: gcr.io/google_containers/kubedns-amd64:1.8
51 | resources:
52 | limits:
53 | cpu: 100m
54 | memory: 170Mi
55 | requests:
56 | cpu: 100m
57 | memory: 70Mi
58 | livenessProbe:
59 | httpGet:
60 | path: /healthz
61 | port: 8080
62 | scheme: HTTP
63 | initialDelaySeconds: 60
64 | timeoutSeconds: 5
65 | successThreshold: 1
66 | failureThreshold: 5
67 | readinessProbe:
68 | httpGet:
69 | path: /readiness
70 | port: 8081
71 | scheme: HTTP
72 | initialDelaySeconds: 30
73 | timeoutSeconds: 5
74 | args:
75 | - --domain=${config['template.substitutions']['dns_service_domain']}.local.
76 | - --dns-port=10053
77 | - --kube-master-url=${config['template.substitutions']['kubernetes_url']}
78 | ports:
79 | - containerPort: 10053
80 | name: dns-local
81 | protocol: UDP
82 | - containerPort: 10053
83 | name: dns-tcp-local
84 | protocol: TCP
85 | - name: dnsmasq
86 | image: gcr.io/google_containers/kube-dnsmasq-amd64:1.3
87 | args:
88 | - --cache-size=1000
89 | - --no-resolv
90 | - --server=127.0.0.1#10053
91 | ports:
92 | - containerPort: 53
93 | name: dns
94 | protocol: UDP
95 | - containerPort: 53
96 | name: dns-tcp
97 | protocol: TCP
98 | - name: healthz
99 | image: gcr.io/google_containers/exechealthz-amd64:1.1
100 | resources:
101 | limits:
102 | cpu: 10m
103 | memory: 50Mi
104 | requests:
105 | cpu: 10m
106 | memory: 50Mi
107 | args:
108 | - >-
109 | -cmd=nslookup kubernetes.default.svc.${config['template.substitutions']['dns_service_domain']}.local 127.0.0.1 > /dev/null &&
110 | nslookup kubernetes.default.svc.${config['template.substitutions']['dns_service_domain']}.local 127.0.0.1:10053 > /dev/null
111 | - -port=8080
112 | - -quiet
113 | ports:
114 | - containerPort: 8080
115 | protocol: TCP
116 | dnsPolicy: Default
--------------------------------------------------------------------------------
/kubernetes/resources/kubernetes/kubernetes-dashboard.yaml:
--------------------------------------------------------------------------------
1 | kind: Deployment
2 | apiVersion: extensions/v1beta1
3 | metadata:
4 | name: kubernetes-dashboard
5 | namespace: kube-system
6 | labels:
7 | app: kubernetes-dashboard
8 | name: kubernetes-dashboard-deployment
9 | version: v1.4.1
10 | spec:
11 | replicas: 1
12 | selector:
13 | matchLabels:
14 | app: kubernetes-dashboard
15 | template:
16 | metadata:
17 | labels:
18 | app: kubernetes-dashboard
19 | annotations:
20 | scheduler.alpha.kubernetes.io/critical-pod: ''
21 | scheduler.alpha.kubernetes.io/tolerations: '[{"key":"CriticalAddonsOnly", "operator":"Exists"}]'
22 | spec:
23 | containers:
24 | - name: kubernetes-dashboard
25 | image: gcr.io/google_containers/kubernetes-dashboard-amd64:v1.4.1
26 | imagePullPolicy: Always
27 | ports:
28 | - containerPort: 9090
29 | protocol: TCP
30 | args:
31 | - --apiserver-host=${config['template.substitutions']['kubernetes_url']}
32 | livenessProbe:
33 | httpGet:
34 | path: /
35 | port: 9090
36 | initialDelaySeconds: 30
37 | timeoutSeconds: 30
38 | ---
39 | kind: Service
40 | apiVersion: v1
41 | metadata:
42 | name: kubernetes-dashboard
43 | namespace: kube-system
44 | labels:
45 | app: kubernetes-dashboard
46 | name: kubernetes-dashboard-service
47 | spec:
48 | type: NodePort
49 | ports:
50 | - port: 80
51 | targetPort: 9090
52 | selector:
53 | app: kubernetes-dashboard
54 |
--------------------------------------------------------------------------------
/kubernetes/resources/kubernetes/policy-controller.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: extensions/v1beta1
2 | kind: ReplicaSet
3 | metadata:
4 | name: policy-controller
5 | namespace: kube-system
6 | labels:
7 | app: policy-controller
8 | name: policy-controller-pod
9 | version: "v0.3.0"
10 | kubernetes.io/cluster-service: "true"
11 | projectcalico.org/app: "policy-controller"
12 | spec:
13 | replicas: 1
14 | selector:
15 | matchLabels:
16 | app: policy-controller
17 | kubernetes.io/cluster-service: "true"
18 | template:
19 | metadata:
20 | name: policy-controller
21 | namespace: kube-system
22 | labels:
23 | app: policy-controller
24 | kubernetes.io/cluster-service: "true"
25 | spec:
26 | hostNetwork: true
27 | containers:
28 | - name: policy-controller
29 | image: calico/kube-policy-controller:v0.3.0
30 | env:
31 | - name: ETCD_ENDPOINTS
32 | value: "${config['template.substitutions']['etcd_endpoints']}"
33 | - name: K8S_API
34 | value: "${config['template.substitutions']['kubernetes_url']}"
35 | - name: LEADER_ELECTION
36 | value: "true"
37 | - name: CONFIGURE_ETC_HOSTS
38 | value: "true"
39 | - name: leader-elector
40 | image: quay.io/calico/leader-elector:v0.1.0
41 | imagePullPolicy: IfNotPresent
42 | args:
43 | - "--election=calico-policy-election"
44 | - "--election-namespace=kube-system"
45 | - "--http=127.0.0.1:4040"
46 | volumeMounts:
47 | - mountPath: "/kubeconfig"
48 | name: kubeconfig
49 | volumes:
50 | - name: kubeconfig
51 | hostPath:
52 | path: "/etc/kubernetes/kubeconfig"
53 |
--------------------------------------------------------------------------------
/kubernetes/resources/kubernetes/prometheus.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: prometheus
5 | namespace: kube-system
6 | labels:
7 | app: prometheus
8 | name: prometheus-service
9 | annotations:
10 | prometheus.io/scrape: 'true'
11 | spec:
12 | selector:
13 | app: prometheus
14 | type: NodePort
15 | ports:
16 | - name: prometheus
17 | protocol: TCP
18 | port: 9090
19 | nodePort: 30900
20 | ---
21 | apiVersion: extensions/v1beta1
22 | kind: Deployment
23 | metadata:
24 | name: prometheus
25 | namespace: kube-system
26 | labels:
27 | app: prometheus
28 | name: prometheus-deployment
29 | spec:
30 | replicas: 1
31 | template:
32 | metadata:
33 | labels:
34 | app: prometheus
35 | spec:
36 | containers:
37 | - image: quay.io/prometheus/prometheus:v1.1.3
38 | name: prometheus
39 | command:
40 | - "/bin/prometheus"
41 | args:
42 | - "-config.file=/etc/prometheus/prometheus.yml"
43 | - "-storage.local.path=/prometheus"
44 | - "-storage.local.retention=24h"
45 | ports:
46 | - name: web
47 | containerPort: 9090
48 | protocol: TCP
49 | volumeMounts:
50 | - mountPath: "/prometheus"
51 | name: data
52 | - mountPath: "/etc/prometheus"
53 | name: config-volume
54 | resources:
55 | requests:
56 | cpu: 100m
57 | memory: 100Mi
58 | limits:
59 | cpu: 500m
60 | memory: 2500Mi
61 | volumes:
62 | - name: data
63 | emptyDir: {}
64 | - name: config-volume
65 | configMap:
66 | name: prometheus-config
67 | ---
68 | apiVersion: v1
69 | kind: ConfigMap
70 | metadata:
71 | name: prometheus-config
72 | namespace: kube-system
73 | data:
74 | prometheus.yml: |-
75 | global:
76 | scrape_interval: 30s
77 | scrape_timeout: 30s
78 | scrape_configs:
79 | - job_name: 'prometheus'
80 | static_configs:
81 | - targets:
82 | - localhost:9090
83 | - job_name: 'kubernetes-cluster'
84 | kubernetes_sd_configs:
85 | - api_servers:
86 | - ${config['template.substitutions']['kubernetes_url']}
87 | basic_auth:
88 | username: prometheus
89 | password: pr0m3th3us
90 | role: apiserver
91 | - job_name: 'kubernetes-nodes'
92 | kubernetes_sd_configs:
93 | - api_servers:
94 | - ${config['template.substitutions']['kubernetes_url']}
95 | basic_auth:
96 | username: prometheus
97 | password: pr0m3th3us
98 | role: node
99 | relabel_configs:
100 | - action: labelmap
101 | regex: __meta_kubernetes_node_label_(.+)
102 | - source_labels: [__meta_kubernetes_role]
103 | action: replace
104 | target_label: kubernetes_role
105 | - source_labels: [__address__]
106 | regex: (.*):10250
107 | replacement: ${r"${1}:10255"}
108 | target_label: __address__
109 | - job_name: 'kubernetes-service-endpoints'
110 | kubernetes_sd_configs:
111 | - api_servers:
112 | - ${config['template.substitutions']['kubernetes_url']}
113 | basic_auth:
114 | username: prometheus
115 | password: pr0m3th3us
116 | role: endpoint
117 | relabel_configs:
118 | - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
119 | action: keep
120 | regex: true
121 | - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
122 | action: replace
123 | target_label: __scheme__
124 | regex: (https?)
125 | - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
126 | action: replace
127 | target_label: __metrics_path__
128 | regex: (.+)
129 | - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
130 | action: replace
131 | target_label: __address__
132 | regex: (.+)(?::\d+);(\d+)
133 | replacement: ${r"${1}:${2}"}
134 | - action: labelmap
135 | regex: __meta_kubernetes_service_label_(.+)
136 | - source_labels: [__meta_kubernetes_service_namespace]
137 | action: replace
138 | target_label: kubernetes_namespace
139 | - source_labels: [__meta_kubernetes_service_name]
140 | action: replace
141 | target_label: kubernetes_name
--------------------------------------------------------------------------------
/kubernetes/tests/kubernetes/kubernetes.tests.bom:
--------------------------------------------------------------------------------
1 | brooklyn.catalog:
2 | items:
3 | - https://github.com/brooklyncentral/common-catalog-utils/releases/download/v0.1.0/common.tests.bom
4 | - id: kubernetes-cluster-tests
5 | version: "2.1.0-SNAPSHOT" # CLOCKER_VERSION
6 | itemType: template
7 | iconUrl: https://twitter.com/kubernetesio/profile_image?size=original
8 | name: Kubernetes Cluster Tests
9 | item:
10 | services:
11 | - type: kubernetes-cluster-template
12 | id: k8s-cluster
13 | - type: org.apache.brooklyn.test.framework.TestCase
14 | name: K8S Smoke Tests
15 | brooklyn.config:
16 | timeout: 1h
17 | targetId: k8s-cluster
18 | brooklyn.children:
19 | - type: assert-up-and-running-initial
20 | name: "1. K8S cluster up and running"
21 | - type: assert-reachable
22 | name: "2. K8S UI Reachable"
23 | brooklyn.config:
24 | endpointSensor: main.uri
25 | timeout: 5m
26 | - type: org.apache.brooklyn.test.framework.TestSensor
27 | name: "3. Size of kubernetes master cluster is 3"
28 | targetId: kubernetes-master-cluster
29 | sensor: group.members.count
30 | assert:
31 | equals: 3
32 | - type: org.apache.brooklyn.test.framework.SimpleShellCommandTest
33 | name: "4. Kill a master node"
34 | target: $brooklyn:entity("kubernetes-master-notfirst")
35 | command: |
36 | nohup sudo bash -c 'sleep 10 && shutdown -h -t0 now' &
37 | - type: org.apache.brooklyn.test.framework.TestSensor
38 | name: "5. Size of kubernetes master cluster increased to 4"
39 | targetId: kubernetes-master-cluster
40 | sensor: group.members.count
41 | assert:
42 | equals: 4
43 | - type: org.apache.brooklyn.test.framework.TestSensor
44 | name: "6. Size of kubernetes master cluster decreased to 3"
45 | targetId: kubernetes-master-cluster
46 | sensor: group.members.count
47 | assert:
48 | equals: 3
49 | - type: org.apache.brooklyn.test.framework.TestSensor
50 | name: "7. Size of kubernetes worker cluster is 3"
51 | targetId: kubernetes-worker-cluster
52 | sensor: group.members.count
53 | assert:
54 | equals: 3
55 | - type: org.apache.brooklyn.test.framework.SimpleShellCommandTest
56 | name: "8. Kill a worker node"
57 | target: $brooklyn:entity("kubernetes-worker")
58 | command: |
59 | nohup sudo bash -c 'sleep 10 && shutdown -h -t0 now' &
60 | - type: org.apache.brooklyn.test.framework.TestSensor
61 | name: "9. Size of kubernetes worker cluster increased to 4"
62 | targetId: kubernetes-worker-cluster
63 | sensor: group.members.count
64 | assert:
65 | equals: 4
66 | - type: org.apache.brooklyn.test.framework.TestSensor
67 | name: "10. Size of kubernetes worker cluster decreased to 3"
68 | targetId: kubernetes-worker-cluster
69 | sensor: group.members.count
70 | assert:
71 | equals: 3
72 | - type: invoke-effector
73 | name: "11. kubectl create deployment [A]"
74 | target: $brooklyn:entity("kubernetes-master")
75 | effector: kubectl
76 | params:
77 | args: 'run workload-a --image=brooklyncentral/centos:7 --replicas=1 --port=22'
78 | - type: org.apache.brooklyn.test.framework.SimpleShellCommandTest
79 | name: "12. kubectl create deployment [B]"
80 | target: $brooklyn:entity("kubernetes-master")
81 | assertStatus:
82 | equals: 0
83 | command: |
84 | kubectl run workload-b --image=brooklyncentral/centos:7 --replicas=1 --port=22
85 | - type: org.apache.brooklyn.test.framework.SimpleShellCommandTest
86 | name: "13. Assert [A] running"
87 | target: $brooklyn:entity("kubernetes-master-notfirst")
88 | command: |
89 | kubectl get pods | grep -i running
90 | assertOut:
91 | contains: 'workload-a'
92 | - type: org.apache.brooklyn.test.framework.SimpleShellCommandTest
93 | name: "14. Assert [B] running"
94 | target: $brooklyn:entity("kubernetes-master-notfirst")
95 | command: |
96 | kubectl get pods | grep -i running
97 | assertOut:
98 | contains: 'workload-b'
99 | - type: org.apache.brooklyn.test.framework.SimpleShellCommandTest
100 | name: "15. Test ICMP [A -> B]"
101 | target: $brooklyn:entity("kubernetes-master")
102 | command: |
103 | POD_A="$(kubectl get pods -o wide | grep workload-a | tr -s ' ' | cut -d ' ' -f1)"
104 | IP_B="$(kubectl get pods -o wide | grep workload-b | tr -s ' ' | cut -d ' ' -f6)"
105 | kubectl exec ${POD_A} -- ping -c 1 ${IP_B}
106 | assertOut:
107 | contains: '1 received'
108 | - type: org.apache.brooklyn.test.framework.SimpleShellCommandTest
109 | name: "16. Test ICMP [B -> A]"
110 | target: $brooklyn:entity("kubernetes-master")
111 | command: |
112 | POD_B="$(kubectl get pods -o wide | grep workload-b | tr -s ' ' | cut -d ' ' -f1)"
113 | IP_A="$(kubectl get pods -o wide | grep workload-a | tr -s ' ' | cut -d ' ' -f6)"
114 | kubectl exec ${POD_B} -- ping -c 1 ${IP_A}
115 | assertOut:
116 | contains: '1 received'
117 | - type: org.apache.brooklyn.test.framework.SimpleShellCommandTest
118 | name: "17. Install Netcat"
119 | target: $brooklyn:entity("kubernetes-master")
120 | command: |
121 | POD_A="$(kubectl get pods -o wide | grep workload-a | tr -s ' ' | cut -d ' ' -f1)"
122 | POD_B="$(kubectl get pods -o wide | grep workload-b | tr -s ' ' | cut -d ' ' -f1)"
123 | kubectl exec ${POD_A} -- yum install -y nc
124 | kubectl exec ${POD_B} -- yum install -y nc
125 | - type: org.apache.brooklyn.test.framework.SimpleShellCommandTest
126 | name: "18. Check TCP"
127 | target: $brooklyn:entity("kubernetes-master")
128 | command: |
129 | POD_A="$(kubectl get pods -o wide | grep workload-a | tr -s ' ' | cut -d ' ' -f1)"
130 | POD_B="$(kubectl get pods -o wide | grep workload-b | tr -s ' ' | cut -d ' ' -f1)"
131 | IP_A="$(kubectl get pods -o wide | grep workload-a | tr -s ' ' | cut -d ' ' -f6)"
132 | kubectl exec ${POD_A} -- bash -c "nohup nc -l -k 5000 >> /tmp/nohup.out 2>&1" &
133 | kubectl exec ${POD_A} -- bash -c "echo connect_from_A | nc -C localhost 5000"
134 | kubectl exec ${POD_B} -- bash -c "echo connect_from_B | nc -C ${IP_A} 5000"
135 | kubectl exec ${POD_A} -- cat /tmp/nohup.out | tr -d "\n\r"
136 | assertOut:
137 | contains: 'connect_from_Aconnect_from_B'
138 | - type: org.apache.brooklyn.test.framework.SimpleShellCommandTest
139 | name: "19. Check UDP"
140 | target: $brooklyn:entity("kubernetes-master")
141 | command: |
142 | POD_A="$(kubectl get pods -o wide | grep workload-a | tr -s ' ' | cut -d ' ' -f1)"
143 | POD_B="$(kubectl get pods -o wide | grep workload-b | tr -s ' ' | cut -d ' ' -f1)"
144 | IP_A="$(kubectl get pods -o wide | grep workload-a | tr -s ' ' | cut -d ' ' -f6)"
145 | kubectl exec ${POD_A} -- bash -c "nohup nc -u -l 5000 >> /tmp/nohup2.out 2>&1" &
146 | kubectl exec ${POD_A} -- bash -c "echo connect_from_A | nc -u -C localhost 5000"
147 | kubectl exec ${POD_A} -- bash -c "nohup nc -u -l 5001 >> /tmp/nohup2.out 2>&1" &
148 | kubectl exec ${POD_B} -- bash -c "echo connect_from_B | nc -u -C ${IP_A} 5001"
149 | kubectl exec ${POD_A} -- cat /tmp/nohup2.out | tr -d "\n\r"
150 | assertOut:
151 | contains: 'connect_from_Aconnect_from_B'
152 | - type: org.apache.brooklyn.test.framework.SimpleShellCommandTest
153 | name: "20. Kill deployments [A,B]"
154 | target: $brooklyn:entity("kubernetes-master")
155 | command: |
156 | kubectl delete deployment workload-a
157 | kubectl delete deployment workload-b
158 | - type: org.apache.brooklyn.test.framework.SimpleShellCommandTest
159 | name: "21. Assert [A,B] NOT running"
160 | target: $brooklyn:entity("kubernetes-master")
161 | command: |
162 | kubectl get deployments | grep workload- | wc -l
163 | assertOut:
164 | contains: '0'
165 | - type: org.apache.brooklyn.test.framework.TestSshCommand
166 | name: "22. Check Prometheus UI is Reachable"
167 | brooklyn.config:
168 | targetId: prometheus
169 | timeout: 1m
170 | shell.env:
171 | K8S_SERVICE_PORT: $brooklyn:entity("prometheus").attributeWhenReady("kubernetes.service.port")
172 | HOST_SUBNET_ADDRESS: $brooklyn:entity("prometheus").attributeWhenReady("host.subnet.address")
173 | command: |
174 | set -e
175 | sudo yum install -y curl
176 | curl -I --max-time 60 "http://${HOST_SUBNET_ADDRESS}:${K8S_SERVICE_PORT}"
177 | assertStatus:
178 | equals: 0
179 |
--------------------------------------------------------------------------------
/kubernetes/tests/kubernetes/tests.default.bom:
--------------------------------------------------------------------------------
1 | brooklyn.catalog:
2 | version: "2.1.0-SNAPSHOT" # CLOCKER_VERSION
3 | iconUrl: https://twitter.com/kubernetesio/profile_image?size=original
4 | license_code: APACHE-2.0
5 | dependsOn:
6 | - tests/kubernetes.tests.bom
7 | items:
8 | - id: kubernetes-tests-default
9 | name: "Clocker Kubernetes Tests (DEFAULT)"
10 | description: |
11 | Tests on Kubernetes
12 | itemType: template
13 | item:
14 | brooklyn.config:
15 | timeout: 1h
16 | timeout.initialStartup: 1h
17 | timeout.runtimeAssertion: 1h
18 | kubernetes.master.size: 3
19 | kubernetes.initial.size: 3
20 | kubernetes.max.size: 5
21 | etcd.initial.size: 3
22 | kubernetes.version: 1.4.3
23 | kubernetes.cluster.name: clocker
24 | kubernetes.pod.cidr: 172.16.0.0/16
25 | kubernetes.apiserver.port: 8080
26 | kubernetes.sharedsecuritygroup.create: true
27 | kubernetes.minRam: 2000
28 | kubernetes.minCores: 1
29 | autoscaler.resizeUpStabilizationDelay: 60s
30 | kubernetes.scaling.cpu.limit: 2.0
31 | services:
32 | - type: kubernetes-cluster-tests
33 |
--------------------------------------------------------------------------------
/kubernetes/tests/kubernetes/tests.no-shared-security-group.bom:
--------------------------------------------------------------------------------
1 | brooklyn.catalog:
2 | version: "2.1.0-SNAPSHOT" # CLOCKER_VERSION
3 | iconUrl: https://twitter.com/kubernetesio/profile_image?size=original
4 | license_code: APACHE-2.0
5 | dependsOn:
6 | - tests/kubernetes.tests.bom
7 | items:
8 | - id: kubernetes-tests-no-shared-security-group
9 | name: "Clocker Kubernetes Tests (NO SHARED SECURITY GROUP)"
10 | description: |
11 | Tests on Kubernetes
12 | itemType: template
13 | item:
14 | brooklyn.config:
15 | timeout: 1h
16 | timeout.initialStartup: 1h
17 | timeout.runtimeAssertion: 1h
18 | kubernetes.master.size: 3
19 | kubernetes.initial.size: 3
20 | kubernetes.max.size: 5
21 | etcd.initial.size: 3
22 | kubernetes.version: 1.4.3
23 | kubernetes.cluster.name: clocker
24 | kubernetes.pod.cidr: 172.16.0.0/16
25 | kubernetes.apiserver.port: 8080
26 | kubernetes.sharedsecuritygroup.create: false
27 | kubernetes.minRam: 2000
28 | kubernetes.minCores: 1
29 | autoscaler.resizeUpStabilizationDelay: 60s
30 | services:
31 | - type: kubernetes-cluster-tests
32 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | io.brooklyn.clocker
8 | clocker-parent
9 | pom
10 | 2.1.0-SNAPSHOT
11 |
12 | Clocker
13 | Apache Brooklyn blueprints to deploy and manage Docker environments
14 | https://github.com/brooklyncentral/clocker
15 |
16 |
17 | 0.1.3
18 | 2.7.0-SNAPSHOT
19 | 1.4
20 |
21 | 4.0.8
22 | 3.2.0
23 | 2.8.2
24 | 3.6.1
25 | 3.0.2
26 | 1.6
27 | UTF-8
28 | UTF-8
29 | 1.0
30 | 2.5.2
31 |
32 |
33 |
34 | common
35 | swarm
36 | kubernetes
37 | feature
38 |
39 |
40 |
41 | https://github.com/brooklyncentral/clocker
42 | scm:git:https://github.com/brooklyncentral/clocker.git
43 | scm:git:git@github.com:brooklyncentral/clocker.git
44 | HEAD
45 |
46 |
47 |
48 | GitHub Issues
49 | https://github.com/brooklyncentral/clocker/issues
50 |
51 |
52 |
53 |
54 | Apache 2.0
55 | http://www.apache.org/licenses/LICENSE-2.0.txt
56 |
57 |
58 |
59 |
60 |
61 |
62 | Andrew Kennedy
63 | https://github.com/grkvlt
64 |
65 | founder
66 |
67 |
68 |
69 | Aled Sage
70 | https://github.com/aledsage
71 |
72 |
73 | Mark McKenna
74 | https://github.com/m4rkmckenna
75 |
76 |
77 |
78 |
79 |
80 | sonatype-nexus-snapshots
81 | Sonatype Nexus Snapshots
82 | https://oss.sonatype.org/content/repositories/snapshots/
83 |
84 |
85 |
86 |
87 |
88 | sonatype-nexus-snapshots
89 | Sonatype Nexus Snapshots
90 | https://oss.sonatype.org/content/repositories/snapshots
91 |
92 | false
93 |
94 |
95 | true
96 |
97 |
98 |
99 |
100 |
101 |
102 | sonatype-oss-releases
103 | https://oss.sonatype.org/content/repositories/releases/
104 |
105 |
106 | sonatype-oss-snapshots
107 | https://oss.sonatype.org/content/repositories/snapshots
108 |
109 | false
110 |
111 |
112 | true
113 |
114 |
115 |
116 | apache-snapshots
117 | https://repository.apache.org/content/repositories/snapshots
118 |
119 | false
120 |
121 |
122 | true
123 |
124 |
125 |
126 |
127 | cloudsoft-releases
128 | http://ccweb.cloudsoftcorp.com/maven/libs-release-local/
129 |
130 |
131 | cloudsoft-snapshots
132 | http://ccweb.cloudsoftcorp.com/maven/libs-snapshot-local/
133 |
134 | false
135 |
136 |
137 | true
138 |
139 |
140 |
141 | cloudsoft-developers
142 | http://developers.cloudsoftcorp.com/download/maven2/
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 | org.apache.maven.plugins
151 | maven-compiler-plugin
152 | ${maven-compiler-plugin.version}
153 |
154 |
155 | org.apache.felix
156 | maven-bundle-plugin
157 | ${maven-bundle-plugin.version}
158 |
159 |
160 | org.apache.maven.plugins
161 | maven-deploy-plugin
162 | ${maven-deploy-plugin.version}
163 |
164 |
165 | org.codehaus.mojo
166 | buildnumber-maven-plugin
167 | ${buildnumber-maven-plugin.version}
168 |
169 |
170 | org.apache.maven.plugins
171 | maven-jar-plugin
172 | ${maven-jar-plugin.version}
173 |
174 |
175 | org.apache.maven.plugins
176 | maven-install-plugin
177 | ${maven-install-plugin.version}
178 |
179 |
180 | org.apache.maven.plugins
181 | maven-gpg-plugin
182 | ${maven-gpg-plugin.version}
183 |
184 |
185 | org.apache.karaf.tooling
186 | karaf-maven-plugin
187 | ${karaf-maven-plugin.version}
188 | true
189 |
190 |
191 | org.codehaus.mojo
192 | wagon-maven-plugin
193 | ${wagon-maven-plugin.version}
194 |
195 |
196 |
197 |
198 |
199 |
200 | org.apache.maven.plugins
201 | maven-compiler-plugin
202 |
203 | 1.8
204 | 1.8
205 |
206 |
207 |
208 | org.codehaus.mojo
209 | buildnumber-maven-plugin
210 |
211 | true
212 |
213 |
214 |
215 | validate
216 |
217 | create
218 |
219 |
220 |
221 |
222 |
223 | org.apache.felix
224 | maven-bundle-plugin
225 | true
226 |
227 |
228 | bundle-manifest
229 | process-classes
230 |
231 | manifest
232 |
233 |
234 |
235 |
236 |
237 | ${buildNumber}
238 | ${scmBranch}
239 |
240 |
241 |
242 |
243 | org.apache.maven.plugins
244 | maven-install-plugin
245 |
248 | 2.5.2
249 |
250 |
251 |
252 |
253 |
254 |
255 | sonatype-release
256 |
257 |
258 | brooklyn.deployTo
259 | sonatype
260 |
261 |
262 |
263 |
264 | sonatype-nexus-staging
265 | Nexus Release Repository
266 | https://oss.sonatype.org/service/local/staging/deploy/maven2/
267 |
268 |
269 | sonatype-nexus-snapshots
270 | Sonatype Nexus Snapshots
271 | https://oss.sonatype.org/content/repositories/snapshots/
272 |
273 |
274 |
275 |
276 |
277 | org.apache.maven.plugins
278 | maven-gpg-plugin
279 | ${maven-gpg-plugin.version}
280 |
281 |
282 | sign-artifacts
283 | verify
284 |
285 | sign
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
--------------------------------------------------------------------------------
/swarm/catalog/catalog.bom:
--------------------------------------------------------------------------------
1 | brooklyn.catalog:
2 | items:
3 | - classpath://swarm/swarm.bom
4 |
--------------------------------------------------------------------------------
/swarm/examples/custom-swarm.yaml:
--------------------------------------------------------------------------------
1 | id: custom-swarm
2 | name: "Docker Swarm Cluster"
3 | description: |
4 | A custom Docker Swarm using a Consul cluster for discovery.
5 |
6 | This is intended to illustrate the process of composing a blueprint to
7 | create a Swarm, using pre-defined entities. For this purpose it uses both
8 | entities from the catalog for the Swarm and the CA server, and entities
9 | defined elsewhere for the Consul discovery cluster.
10 |
11 | See for the Consul blueprints.
12 |
13 | location:
14 | jclouds:softlayer:
15 | region: ams01
16 |
17 | services:
18 | - type: org.apache.brooklyn.entity.stock.BasicApplication
19 | id: swarm
20 | name: "swarm"
21 | brooklyn.enrichers:
22 | - type: org.apache.brooklyn.enricher.stock.Propagator
23 | brooklyn.config:
24 | producer: $brooklyn:child("swarm-cluster")
25 | propagating:
26 | - $brooklyn:sensor("swarm.url")
27 | brooklyn.children:
28 | - type: ca-server
29 | id: ca-server
30 | name: "ca-server"
31 | - type: consul-cluster
32 | id: consul-cluster
33 | name: "consul-cluster"
34 | brooklyn.config:
35 | initialSize: 3
36 | brooklyn.enrichers:
37 | - type: org.apache.brooklyn.enricher.stock.Transformer
38 | brooklyn.config:
39 | enricher.triggerSensors:
40 | - $brooklyn:sensor("cluster.nodeip.string")
41 | enricher.targetSensor: $brooklyn:sensor("consul.url")
42 | enricher.targetValue:
43 | $brooklyn:formatString:
44 | - "consul://%s"
45 | - $brooklyn:attributeWhenReady("cluster.nodeip.string")
46 | - type: docker-swarm-cluster
47 | id: swarm-cluster
48 | name: "swarm-cluster"
49 | brooklyn.config:
50 | swarm.manager.size: 3
51 | swarm.initial.size: 3
52 | swarm.max.size: 3
53 | swarm.discovery.url: $brooklyn:entity("consul-cluster").attributeWhenReady("consul.url")
54 | docker.discovery.url: $brooklyn:entity("consul-cluster").attributeWhenReady("consul.url")
55 | latch.launch: $brooklyn:entity("consul-cluster").attributeWhenReady("service.isUp")
56 | latch.customize: $brooklyn:entity("ca-server").attributeWhenReady("service.isUp")
57 | ca.request.root.url: $brooklyn:entity("ca-server").attributeWhenReady("main.uri")
58 |
--------------------------------------------------------------------------------
/swarm/examples/swarm-byon.yaml:
--------------------------------------------------------------------------------
1 | id: swarm-byon
2 | name: "Docker Swarm Cluster"
3 | description: |
4 | Deploys to existing VMs (for example, that have been created using
5 | Vagrant) using the given BYON configuration. Ensure that enough VMs
6 | are available for the given maximum size of the Swarm cluster.
7 |
8 | location:
9 | byon:
10 | displayName: swarm-vagrant
11 | loginUser: vagrant
12 | user: vagrant
13 | privateKeyFile: ~/.ssh/swarm.pem
14 | loginUser.privateKeyFile: ~/.ssh/swarm.pem
15 | hosts:
16 | - 192.168.50.0/27
17 |
18 | services:
19 | - type: docker-swarm
20 | id: swarm
21 | name: "swarm"
22 | brooklyn.config:
23 | start.timeout: 30m
24 | swarm.initial.size: 5
25 | swarm.max.size: 10
26 | swarm.manager.size: 3
27 | etcd.initial.size: 3
28 | swarm.port: 4444
29 | swarm.defaultnetwork: "swarm"
30 | swarm.scaling.cpu.limit: 0.99
31 | docker.recovery.stabilizationDelay: 10s
32 | docker.recovery.failOnRecurringFailuresInThisDuration: 5m
33 |
--------------------------------------------------------------------------------
/swarm/examples/swarm-minimal.yaml:
--------------------------------------------------------------------------------
1 | id: swarm-minimal
2 | name: "Docker Swarm Cluster"
3 | description: |
4 | Uses the default settings for configuring the Swarm, apart from the initial
5 | size of the cluster of Docker Engine nodes.
6 |
7 | Deploys on AWS using only the default Swarm entity configuration. Requires
8 | a security group to be deined in the AWS region or VPC, which should be
9 | set in the 'templateOptions' of the location, as seen below. The VMs
10 | must also have iptables disabled, which is accomplished by setting the
11 | 'stopIptables' configuration key to 'true' on the Swarm entity.
12 |
13 | location:
14 | jclouds:aws-ec2:
15 | region: eu-central-1
16 | privateKeyFile: "~/.ssh/swarm.pem"
17 | loginUser.privateKeyFile: "~/.ssh/swarm.pem"
18 | keyPair: "swarm"
19 | templateOptions:
20 | securityGroups:
21 | - "swarm"
22 |
23 | services:
24 | - type: docker-swarm
25 | name: "swarm-aws-ec2"
26 | brooklyn.config:
27 | stopIptables: true
28 | swarm.initial.size: 2
29 | swarm.sharedsecuritygroup.create: true
30 |
--------------------------------------------------------------------------------
/swarm/examples/swarm-using-external-resources.yaml:
--------------------------------------------------------------------------------
1 | id: swarm-using-external-resources
2 | name: "Docker Swarm Cluster with Load-Balancer"
3 | description: |
4 | This uses an existing discovery mechanism (an Etcd cluster) and must be
5 | provided with URLs to download the TLS certificates and private keys for
6 | each Swarm node.
7 |
8 | Note the same URL will be used for each Swarm node so the certificate
9 | will have to be suitable for use on all of them, typically a wildcard
10 | certifiate.
11 |
12 | Deploys on CentOS 7 VMs.
13 |
14 | location:
15 | jclouds:softlayer:
16 | region: ams01
17 |
18 | services:
19 | - type: docker-swarm-cluster
20 | id: swarm
21 | name: "swarm"
22 | brooklyn.config:
23 | swarm.manager.size: 3
24 | swarm.initial.size: 3
25 | swarm.max.size: 5
26 | swarm.discovery.url: etcd://10.10.10.123:2380/
27 | docker.discovery.url: etcd://10.10.10.123:2380/
28 | ca.cert.url: http://10.10.10.101:8080/default/ca.pem
29 | node.cert.url: http://10.10.10.101:8080/default/cert.pem
30 | private.key.url: http://10.10.10.101:8080/default/key.pem
31 |
--------------------------------------------------------------------------------
/swarm/examples/swarm.yaml:
--------------------------------------------------------------------------------
1 | id: swarm
2 | name: "Docker Swarm Cluster"
3 | description: |
4 | Includes built-in etcd discovery cluster, TLS protected endpoints,
5 | HAProxy load balancer for Swarm managers and a CA server to create
6 | certificates for the Swarm and etcd nodes and the load balancer.
7 |
8 | Deploys on CentOS 7 VMs in SoftLayer, on a single VLAN segment.
9 |
10 | location:
11 | jclouds:softlayer:
12 | region: ams01
13 | identity: xxxxxxxx
14 | credential: XXXXXXXX
15 | privateKeyFile: ~/.ssh/softlayer.pem
16 | customizers:
17 | - $brooklyn:object:
18 | type: org.apache.brooklyn.location.jclouds.softlayer.SoftLayerSameVlanLocationCustomizer
19 | brooklyn.config:
20 | softlayer.vlan.scopeUid: "swarm"
21 |
22 | services:
23 | - type: docker-swarm
24 | id: swarm
25 | name: "swarm"
26 | brooklyn.config:
27 | start.timeout: 30m
28 | swarm.initial.size: 8
29 | swarm.max.size: 16
30 | swarm.manager.size: 3
31 | etcd.initial.size: 3
32 | swarm.port: 4000
33 | swarm.defaultnetwork: "swarm"
34 | swarm.scaling.cpu.limit: 0.80
35 | swarm.strategy: "binpack"
36 | swarm.overcommit: 0.50
37 | docker.recovery.stabilizationDelay: 10s
38 | docker.recovery.failOnRecurringFailuresInThisDuration: 5m
39 | swarm.minRam: 32g
40 | swarm.minCores: 4
41 | provisioning.properties:
42 | minRam: 2g
43 | minCores: 1
44 |
--------------------------------------------------------------------------------
/swarm/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 |
8 | io.brooklyn.clocker
9 | clocker-parent
10 | 2.1.0-SNAPSHOT
11 |
12 |
13 | Clocker :: Swarm
14 | clocker-swarm
15 | bundle
16 |
17 |
18 |
19 |
20 | catalog
21 | false
22 |
23 |
24 | resources
25 | false
26 |
27 |
28 | tests
29 | false
30 | tests
31 |
32 |
33 |
34 |
35 |
36 | org.codehaus.mojo
37 | build-helper-maven-plugin
38 |
39 |
40 | attach-artifact
41 | package
42 |
43 | attach-artifact
44 |
45 |
46 |
47 |
48 | ${project.basedir}/catalog/swarm/swarm.bom
49 | bom
50 | swarm
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/swarm/resources/icons/swarm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brooklyncentral/clocker/e1ff91d4959d2238efcf78569d600f95273730d4/swarm/resources/icons/swarm.png
--------------------------------------------------------------------------------
/swarm/tests/swarm/swarm.tests.bom:
--------------------------------------------------------------------------------
1 | brooklyn.catalog:
2 | version: "2.1.0-SNAPSHOT" # CLOCKER_VERSION
3 | iconUrl: https://raw.githubusercontent.com/docker-library/docs/471fa6e4cb58062ccbf91afc111980f9c7004981/swarm/logo.png
4 | dependsOn:
5 | - tests/common.tests.bom
6 | - tests/docker.tests.bom
7 | license_code: APACHE-2.0
8 |
9 | items:
10 | - id: test-docker-run-pulls
11 | item:
12 | type: test-case
13 | description: |
14 | Test that Docker Swarm cluster can pull containers from Docker Hub
15 | automatically
16 | brooklyn.children:
17 | - type: ssh-test
18 | command: |
19 | set -e
20 | docker rmi --force busybox || true
21 | ! docker images | grep busybox
22 | docker run --rm busybox echo "Hello from busybox-image" | grep busybox-image
23 | docker images | grep busybox
24 | assertStatus:
25 | equals: 0
26 | assertOut:
27 | contains: "busybox-image"
28 |
29 | - id: test-swarm-networking
30 | item:
31 | type: test-case
32 | description: |
33 | Test Swarm networking between containers on different hosts, using
34 | shared Docker overlay network
35 | brooklyn.parameters:
36 | - network.name
37 | brooklyn.children:
38 | - type: ssh-test
39 | name: "TEST-06-1 Test network exists"
40 | brooklyn.config:
41 | shell.env:
42 | NETWORK_NAME: $brooklyn:config("network.name")
43 | command: |
44 | echo "[TEST] Checking ID of network ${NETWORK_NAME}"
45 | docker network inspect --format "{{.ID}}" ${NETWORK_NAME}
46 | assertStatus:
47 | equals: 0
48 | assertErr:
49 | isEmpty: true
50 | - type: ssh-test
51 | name: "TEST-06-2 Test network properties"
52 | brooklyn.config:
53 | shell.env:
54 | NETWORK_NAME: $brooklyn:config("network.name")
55 | command: |
56 | echo "[TEST] Create container on ${NETWORK_NAME} network"
57 | docker run -di --name workload_A --net ${NETWORK_NAME} brooklyncentral/centos:7 /bin/bash
58 | CONTAINER_NETWORK_ID=$(docker inspect --format "{{.NetworkSettings.Networks.${NETWORK_NAME}.NetworkID}}" workload_A)
59 | NETWORK_ID=$(docker network inspect --format "{{.ID}}" ${NETWORK_NAME})
60 | docker rm -f workload_A
61 | [[ "${CONTAINER_NETWORK_ID}" == "${NETWORK_ID}" ]]
62 | assertStatus:
63 | equals: 0
64 | assertErr:
65 | isEmpty: true
66 | - type: ssh-test
67 | name: "TEST-06-3 Test same network connectivity"
68 | brooklyn.config:
69 | shell.env:
70 | NETWORK_NAME: $brooklyn:config("network.name")
71 | command: |
72 | echo "[TEST] Creating two containers on ${NETWORK_NAME} network"
73 | docker run -di --name workload_B --net ${NETWORK_NAME} brooklyncentral/centos:7 /bin/bash
74 | docker run -di --name workload_C --net ${NETWORK_NAME} -e affinity:container!=workload_B brooklyncentral/centos:7 /bin/bash
75 | docker exec workload_B ping -W 10 -c 4 workload_C.${NETWORK_NAME}
76 | docker exec workload_C ping -W 10 -c 4 workload_B.${NETWORK_NAME}
77 | docker rm -f workload_B
78 | docker rm -f workload_C
79 | assertOut:
80 | - contains:
81 | $brooklyn:formatString:
82 | - "--- workload_B.%s ping statistics ---\n4 packets transmitted, 4 received"
83 | - $brooklyn:config("network.name")
84 | - contains:
85 | $brooklyn:formatString:
86 | - "--- workload_C.%s ping statistics ---\n4 packets transmitted, 4 received"
87 | - $brooklyn:config("network.name")
88 | assertErr:
89 | isEmpty: true
90 | - type: ssh-test
91 | name: "TEST-06-4 Test different network connectivity failure"
92 | brooklyn.config:
93 | shell.env:
94 | NETWORK_NAME: $brooklyn:config("network.name")
95 | command: |
96 | echo "[TEST] Creating two containers on different networks"
97 | docker run -di --name workload_D --net ${NETWORK_NAME} brooklyncentral/centos:7 /bin/bash
98 | docker run -di --name workload_E --net bridge -e affinity:container!=workload_D brooklyncentral/centos:7 /bin/bash
99 | WORKLOAD_D_IP=$(docker inspect --format "{{.NetworkSettings.Networks.${NETWORK_NAME}.IPAddress}}" workload_D)
100 | docker exec workload_E ping -W 10 -c 4 workload_D.${NETWORK_NAME} || true
101 | docker exec workload_E ping -W 10 -c 4 ${WORKLOAD_D_IP} || true
102 | docker rm -f workload_D
103 | docker rm -f workload_E
104 | assertErr:
105 | contains:
106 | $brooklyn:formatString:
107 | - "ping: workload_D.%s: Name or service not known"
108 | - $brooklyn:config("network.name")
109 | assertOut:
110 | contains: "ping statistics ---\n4 packets transmitted, 0 received"
111 |
112 | - id: test-swarm-scale-up
113 | item:
114 | type: test-case
115 | description: |
116 | Test Swarm can be scaled up
117 | brooklyn.children:
118 | - type: sensor-test
119 | name: "TEST-07-1 Initial Size of cluster is 2"
120 | targetId: docker-swarm-nodes
121 | sensor: group.members.count
122 | assert:
123 | equals: 2
124 | - type: ssh-test
125 | name: "TEST-07-2 Create load on server"
126 | brooklyn.config:
127 | command: |
128 | echo "[TEST] Creating load"
129 | docker run -di --name TEST_7_2_LOAD_1 -e affinity:container!=TEST_7_2_LOAD_2 brooklyncentral/centos:7 /bin/bash
130 | docker run -di --name TEST_7_2_LOAD_2 -e affinity:container!=TEST_7_2_LOAD_1 brooklyncentral/centos:7 /bin/bash
131 | docker exec -d TEST_7_2_LOAD_1 dd if=/dev/zero of=/dev/null
132 | docker exec -d TEST_7_2_LOAD_2 dd if=/dev/zero of=/dev/null
133 | - type: sensor-test
134 | name: "TEST-07-3 Final Size of cluster is 3"
135 | targetId: docker-swarm-nodes
136 | timeout: 20m
137 | sensor: group.members.count
138 | assert:
139 | equals: 3
140 | - type: ssh-test
141 | name: "TEST-07-4 Tear down load"
142 | brooklyn.config:
143 | command: |
144 | echo "[TEST] Removing load"
145 | docker rm -f TEST_7_2_LOAD_1
146 | docker rm -f TEST_7_2_LOAD_2
147 |
148 | - id: test-swarm-etcd-tls
149 | item:
150 | type: ssh-test
151 | name: "TEST-08-1 Swarm Etcd uses TLS"
152 | brooklyn.config:
153 | shell.env:
154 | ETCD_ENDPOINT_LIST: $brooklyn:entity("etcd-cluster").attributeWhenReady("etcd.endpoints")
155 | CERT_PATH:
156 | $brooklyn:formatString:
157 | - "%s/.certs"
158 | - $brooklyn:entity("swarm-client").attributeWhenReady("install.dir")
159 | command: |
160 | set -e
161 | for endpoint in ${ETCD_ENDPOINT_LIST//,/ } ; do
162 | ! curl https://${endpoint}/version --fail
163 | ! curl http://${endpoint}/version --fail
164 | curl --cacert "${CERT_PATH}/ca.pem" \
165 | --cert "${CERT_PATH}/cert.pem" \
166 | --key "${CERT_PATH}/key.pem" \
167 | --fail \
168 | https://${endpoint}/version
169 | done
170 |
171 | - id: test-swarm-restart
172 | item:
173 | type: test-case
174 | description: |
175 | Restart Swarm member (node/manager)
176 | brooklyn.children:
177 | - type: ssh-cmd-restart
178 | - type: assert-failed
179 | - type: assert-up
180 |
181 | - id: test-swarm-node-restart
182 | item:
183 | type: test-case
184 | brooklyn.children:
185 | - type: loop-test-case
186 | name: "TEST-09-1 Restart Swarm node"
187 | brooklyn.config:
188 | targetId: docker-swarm-nodes
189 | test.spec:
190 | $brooklyn:entitySpec:
191 | type: test-swarm-restart
192 | - type: loop-test-case
193 | name: "TEST-09-2 Restart Swarm manager"
194 | brooklyn.config:
195 | targetId: docker-swarm-managers
196 | test.spec:
197 | $brooklyn:entitySpec:
198 | type: test-swarm-restart
199 | - type: ssh-test
200 | name: "TEST-09-3 Assert Healthy Swarm"
201 | brooklyn.config:
202 | command:
203 | $brooklyn:formatString:
204 | - |
205 | NODES=$(docker info | grep "Nodes:")
206 | echo "${NODES}"
207 | [ "${NODES}" = "Nodes: %d" ]
208 | - $brooklyn:entity("docker-swarm-nodes").attributeWhenReady("group.members.count")
209 |
210 | - id: swarm-node-replacement-test
211 | name: Swarm Node Replace
212 | description: |
213 | Tests restarting and replacing failed swarm nodes
214 | itemType: entity
215 | item:
216 | type: test-case
217 | brooklyn.children:
218 | - type: assert-up
219 | name: TEST-10 Wait for Swarm to deploy
220 | targetId: swarm-cluster
221 | - type: cluster
222 | name: TEST-10 Swarm Node Lazy Holder
223 | id: node-to-fail-lazy-holder
224 | brooklyn.config:
225 | dynamiccluster.memberspec:
226 | $brooklyn:entitySpec:
227 | # At the time an entity is created out of the spec the swarm-node should already exist
228 | type: org.apache.brooklyn.entity.stock.BasicEntity
229 | id: node-to-fail-holder
230 | name: Swarm Node Holder
231 | brooklyn.initializers:
232 | - type: org.apache.brooklyn.core.sensor.StaticSensor
233 | brooklyn.config:
234 | name: node-to-fail
235 | # Pick one node to fail and cache it
236 | static.value: $brooklyn:entity("swarm-node")
237 | targetType: org.apache.brooklyn.api.entity.Entity
238 | - type: org.apache.brooklyn.core.sensor.StaticSensor
239 | brooklyn.config:
240 | name: initial-cluster-size
241 | static.value: $brooklyn:entity("docker-swarm-nodes").attributeWhenReady("group.members.count")
242 | targetType: Integer
243 | - type: org.apache.brooklyn.core.sensor.StaticSensor
244 | brooklyn.config:
245 | name: service.isUp
246 | static.value: true
247 | targetType: Boolean
248 |
249 | - type: test-case
250 | name: TEST-10 Asserts
251 | id: swarm-node-replacement-test
252 | brooklyn.config:
253 | target: $brooklyn:entity("node-to-fail-holder").attributeWhenReady("node-to-fail")
254 | brooklyn.children:
255 | - type: assert-up
256 | name: TEST-10-01. Wait for Swarm Node Holder
257 | target: $brooklyn:entity("node-to-fail-lazy-holder")
258 | - type: assert-up
259 | name: TEST-10-02. Wait for Swarm Node
260 | - type: ssh-test
261 | name: TEST-10-03. Fail Swarm Node
262 | brooklyn.config:
263 | command: |
264 | SWARM_ID=$(docker ps --filter name=swarm --format '{{ .ID }}' --no-trunc)
265 | if [ -z "${SWARM_ID}" ]; then
266 | echo "Swarm container not running" >&2
267 | exit 1
268 | fi
269 | docker rm -f ${SWARM_ID}
270 | - type: assert-down
271 | name: TEST-10-04. Check Failed
272 | - type: assert-up
273 | name: TEST-10-05. Check Recovered
274 | - type: ssh-test
275 | name: TEST-10-06. Re-Fail Swarm Node
276 | brooklyn.config:
277 | command: |
278 | # Wait for stabilization delay - 10s
279 | sleep 15
280 |
281 | SWARM_ID=$(docker ps --filter name=swarm --format '{{ .ID }}' --no-trunc)
282 | if [ -z "${SWARM_ID}" ]; then
283 | echo "Swarm container not running" >&2
284 | exit 1
285 | fi
286 | docker rm -f ${SWARM_ID}
287 | - type: assert-down
288 | name: TEST-10-07. Check Failed
289 | - type: sensor-test
290 | name: TEST-10-08. Check spinning up replacement
291 | brooklyn.config:
292 | target: $brooklyn:entity("docker-swarm-nodes")
293 | sensor: group.members.count
294 | timeout: $brooklyn:config("timeout.initialStartup")
295 | assert:
296 | - notEqual: $brooklyn:entity("node-to-fail-holder").attributeWhenReady("initial-cluster-size")
297 | - type: sensor-test
298 | name: TEST-10-09. Check failed node removed
299 | brooklyn.config:
300 | target: $brooklyn:entity("docker-swarm-nodes")
301 | sensor: group.members.count
302 | timeout: $brooklyn:config("timeout.initialStartup")
303 | assert:
304 | - equals: $brooklyn:entity("node-to-fail-holder").attributeWhenReady("initial-cluster-size")
305 | - type: sensor-test
306 | name: TEST-10-10. Check failed node unmanaged
307 | brooklyn.config:
308 | sensor: service.state
309 | assert:
310 | - matches: stopped
311 | - type: assert-running
312 | name: TEST-10-11. Check cluster healthy
313 | brooklyn.config:
314 | target: $brooklyn:entity("docker-swarm-nodes")
315 |
316 | # swarm manager failover tests
317 | - id: test-swarm-manager-failover
318 | item:
319 | type: test-case
320 | description: |
321 | Test Swarm manager failover behaviour
322 | brooklyn.children:
323 | - type: sensor-test
324 | name: "TEST-11-1 Size of manager cluster is 3"
325 | targetId: docker-swarm-managers
326 | sensor: group.members.count
327 | assert:
328 | equals: 3
329 | - type: test-stop-machine
330 | name: "TEST-11-2 Kill one node"
331 | target: $brooklyn:entity("docker-swarm-managers").attributeWhenReady("cluster.first.entity")
332 | - type: ssh-test
333 | name: "TEST-11-3 Manager endpoints active now 2"
334 | targetId: swarm-client
335 | brooklyn.config:
336 | shell.env:
337 | SWARM_ENDPOINTS: $brooklyn:entity("docker-swarm-managers").attributeWhenReady("swarm.endpoints")
338 | command: |
339 | echo ${SWARM_ENDPOINTS} | tr ',' ' ' | wc -w
340 | assertStatus:
341 | equals: 0
342 | assertOut:
343 | contains: "2"
344 | - type: ssh-test
345 | name: "TEST-11-4 Can still connect"
346 | timeout: 20m
347 | targetId: swarm-client
348 | brooklyn.config:
349 | command: |
350 | docker run -i hello-world
351 | assertStatus:
352 | equals: 0
353 | assertOut:
354 | contains: "Hello from Docker!"
355 | - type: ssh-test
356 | name: "TEST-11-5 Check load balancer"
357 | timeout: 20m
358 | targetId: swarm-client
359 | brooklyn.config:
360 | shell.env:
361 | HAPROXY_URL:
362 | $brooklyn:entity("swarm-manager-load-balancer").attributeWhenReady("swarm.url")
363 | CERT_PATH:
364 | $brooklyn:formatString:
365 | - "%s/.certs"
366 | - $brooklyn:entity("swarm-client").attributeWhenReady("install.dir")
367 | command: |
368 | SWARM_URL=${HAPROXY_URL/tcp/https}
369 | curl --cacert "${CERT_PATH}/ca.pem" \
370 | --cert "${CERT_PATH}/cert.pem" \
371 | --key "${CERT_PATH}/key.pem" \
372 | ${SWARM_URL}/_ping
373 | assertStatus:
374 | equals: 0
375 | assertOut:
376 | equals: "OK"
377 |
378 | - id: docker-swarm-tests
379 | name: Docker Swarm Tests
380 | description: |
381 | Tests on Docker Swarm over TLS
382 | itemType: entity
383 | item:
384 | type: test-case
385 | name: "docker-swarm-tests"
386 |
387 | brooklyn.config:
388 | timeout: 1h
389 | timeout.initialStartup: 1h
390 | timeout.runtimeAssertion: 1h
391 | swarm.initial.size: 2
392 | swarm.manager.size: 3
393 | etcd.initial.size: 2
394 | swarm.max.size: 5
395 | swarm.scaling.cpu.limit: 0.95
396 | swarm.defaultnetwork: "brooklyn"
397 | swarm.port: 4000
398 | docker.recovery.stabilizationDelay: 10s
399 | docker.recovery.failOnRecurringFailuresInThisDuration: 5m
400 |
401 | brooklyn.children:
402 | - type: docker-swarm
403 | id: swarm
404 | name: "swarm"
405 | description: |
406 | The swarm to test
407 |
408 | - type: test-docker-client-with-tls
409 | id: swarm-client
410 | name: "swarm-client"
411 | description: |
412 | A client for talking to the swarm
413 | brooklyn.config:
414 | latch.customize: $brooklyn:entity("swarm").attributeWhenReady("service.isUp")
415 | client.address: $brooklyn:attributeWhenReady("host.address")
416 | ca.url: $brooklyn:entity("ca-server").attributeWhenReady("main.uri")
417 | docker.url: $brooklyn:entity("swarm").attributeWhenReady("swarm.url")
418 |
419 | - type: test-case
420 | name: "swarm-test-suite"
421 | brooklyn.children:
422 | - type: test-case
423 | name: "GROUP-1 Test Swarm entity"
424 | brooklyn.config:
425 | targetId: swarm
426 | brooklyn.children:
427 | - type: assert-up
428 | name: "TEST-01 Assert up"
429 | - type: assert-running
430 | name: "TEST-02 Assert running"
431 | - type: test-case
432 | name: "GROUP-2 Test Swarm client"
433 | brooklyn.config:
434 | targetId: swarm-client
435 | latch.start: $brooklyn:entity("swarm-client").attributeWhenReady("service.isUp")
436 | brooklyn.children:
437 | - type: test-swarm-scale-up
438 | name: "TEST-03 Test Swarm scale up"
439 | - type: swarm-node-replacement-test
440 | name: "TEST-04 Test Swarm node replace"
441 | - type: test-swarm-manager-failover
442 | name: "TEST-05 Test Swarm failover"
443 | - type: test-connect-fails-without-tls
444 | name: "TEST-06 Test connect fails without TLS"
445 | - type: docker-engine-test
446 | name: "TEST-07 Test Swarm over TLS"
447 | description: |
448 | Runs the docker tests against the swarm
449 | - type: test-docker-run-pulls
450 | name: "TEST-08 Test docker run pulls"
451 | - type: test-swarm-networking
452 | name: "TEST-09 Test Swarm networking"
453 | brooklyn.config:
454 | network.name: $brooklyn:component("swarm").config("swarm.defaultnetwork")
455 | - type: test-swarm-etcd-tls
456 | name: "TEST-10 Test Swarm etcd TLS"
457 | brooklyn.config:
458 | ca.url: $brooklyn:entity("ca-server").attributeWhenReady("main.uri")
459 |
460 |
--------------------------------------------------------------------------------
/swarm/tests/swarm/tests_with_shared_group.bom:
--------------------------------------------------------------------------------
1 | brooklyn.catalog:
2 | version: "2.1.0-SNAPSHOT" # CLOCKER_VERSION
3 | iconUrl: https://raw.githubusercontent.com/docker-library/docs/471fa6e4cb58062ccbf91afc111980f9c7004981/swarm/logo.png
4 | dependsOn:
5 | - tests/docker.tests.bom
6 | - tests/swarm.tests.bom
7 | license_code: APACHE-2.0
8 |
9 | items:
10 | - id: docker-and-swarm-engine-tests
11 | name: "Docker Engine and Swarm Tests"
12 | description: |
13 | Tests on Docker Engine with and without TLS, and on Swarm (with TLS)
14 | itemType: template
15 | item:
16 | brooklyn.config:
17 | timeout: 90m
18 | timeout.initialStartup: 1h
19 | timeout.runtimeAssertion: 1h
20 | swarm.sharedsecuritygroup.create: true
21 | swarm.minRam: 2000
22 | swarm.minCores: 1
23 |
24 | services:
25 | - type: docker-swarm-tests
26 |
--------------------------------------------------------------------------------
/swarm/tests/swarm/tests_without_shared_group.bom:
--------------------------------------------------------------------------------
1 | brooklyn.catalog:
2 | version: "2.1.0-SNAPSHOT" # CLOCKER_VERSION
3 | iconUrl: https://raw.githubusercontent.com/docker-library/docs/471fa6e4cb58062ccbf91afc111980f9c7004981/swarm/logo.png
4 | dependsOn:
5 | - tests/docker.tests.bom
6 | - tests/swarm.tests.bom
7 | license_code: APACHE-2.0
8 |
9 | items:
10 | - id: docker-and-swarm-engine-tests
11 | name: "Docker Engine and Swarm Tests"
12 | description: |
13 | Tests on Docker Engine with and without TLS, and on Swarm (with TLS)
14 | itemType: template
15 | item:
16 | brooklyn.config:
17 | timeout: 90m
18 | timeout.initialStartup: 1h
19 | timeout.runtimeAssertion: 1h
20 | swarm.sharedsecuritygroup.create: false
21 | swarm.minRam: 2000
22 | swarm.minCores: 1
23 |
24 | services:
25 | - type: docker-swarm-tests
26 |
--------------------------------------------------------------------------------