Add join-scripts endpoint
* Adds initial join-scripts API * Updates resiliency test to leverage API for joining Change-Id: Ibe0d42b8f4f4a3e1f6f102dee85a22cb8f78f8ec
This commit is contained in:
parent
6caf7fb54d
commit
b4d9596468
@ -38,7 +38,7 @@ static.labels
|
|||||||
Used to set configuration options in the generated script
|
Used to set configuration options in the generated script
|
||||||
|
|
||||||
Responses
|
Responses
|
||||||
- 204 No Content: Scripts generated successfully
|
- 200 OK: Script returned as response body
|
||||||
- 400 Bad Request: One or more query parameters is missing or misspelled
|
- 400 Bad Request: One or more query parameters is missing or misspelled
|
||||||
|
|
||||||
|
|
||||||
|
@ -80,6 +80,16 @@ class Builder:
|
|||||||
def build_node(self, node_document, *, output_dir):
|
def build_node(self, node_document, *, output_dir):
|
||||||
node_name = node_document['metadata']['name']
|
node_name = node_document['metadata']['name']
|
||||||
LOG.info('Building script for node %s', node_name)
|
LOG.info('Building script for node %s', node_name)
|
||||||
|
script = self.build_node_script(node_name)
|
||||||
|
|
||||||
|
_write_script(output_dir, _join_name(node_name), script)
|
||||||
|
|
||||||
|
if self.validators:
|
||||||
|
validate_script = self._build_node_validate_script(node_name)
|
||||||
|
_write_script(output_dir, 'validate-%s.sh' % node_name,
|
||||||
|
validate_script)
|
||||||
|
|
||||||
|
def build_node_script(self, node_name):
|
||||||
sub_config = self.config.extract_node_config(node_name)
|
sub_config = self.config.extract_node_config(node_name)
|
||||||
file_spec_paths = [
|
file_spec_paths = [
|
||||||
f['path'] for f in self.config.get_path('HostSystem:files', [])
|
f['path'] for f in self.config.get_path('HostSystem:files', [])
|
||||||
@ -88,20 +98,17 @@ class Builder:
|
|||||||
tarball = renderer.build_tarball_from_roles(
|
tarball = renderer.build_tarball_from_roles(
|
||||||
config=sub_config, roles=['common', 'join'], file_specs=file_specs)
|
config=sub_config, roles=['common', 'join'], file_specs=file_specs)
|
||||||
|
|
||||||
script = renderer.render_template(
|
return renderer.render_template(
|
||||||
sub_config,
|
sub_config,
|
||||||
template='scripts/join.sh',
|
template='scripts/join.sh',
|
||||||
context={
|
context={
|
||||||
'tarball': tarball
|
'tarball': tarball
|
||||||
})
|
})
|
||||||
|
|
||||||
_write_script(output_dir, _join_name(node_name), script)
|
def _build_node_validate_script(self, node_name):
|
||||||
|
sub_config = self.config.extract_node_config(node_name)
|
||||||
if self.validators:
|
return renderer.render_template(
|
||||||
validate_script = renderer.render_template(
|
sub_config, template='scripts/validate-join.sh')
|
||||||
sub_config, template='scripts/validate-join.sh')
|
|
||||||
_write_script(output_dir, 'validate-%s.sh' % node_name,
|
|
||||||
validate_script)
|
|
||||||
|
|
||||||
|
|
||||||
def _fetch_tar_content(*, url, path):
|
def _fetch_tar_content(*, url, path):
|
||||||
|
@ -2,6 +2,7 @@ from . import exceptions, logging, validation
|
|||||||
import copy
|
import copy
|
||||||
import jinja2
|
import jinja2
|
||||||
import jsonpath_ng
|
import jsonpath_ng
|
||||||
|
import requests
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
__all__ = ['Configuration']
|
__all__ = ['Configuration']
|
||||||
@ -32,6 +33,16 @@ class Configuration:
|
|||||||
|
|
||||||
return cls(documents=documents, **kwargs)
|
return cls(documents=documents, **kwargs)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_design_ref(cls, design_ref):
|
||||||
|
response = requests.get(design_ref)
|
||||||
|
response.raise_for_status()
|
||||||
|
|
||||||
|
documents = list(yaml.safe_load_all(response.text))
|
||||||
|
validation.check_schemas(documents)
|
||||||
|
|
||||||
|
return cls(documents=documents)
|
||||||
|
|
||||||
def __getitem__(self, path):
|
def __getitem__(self, path):
|
||||||
value = self.get_path(path)
|
value = self.get_path(path)
|
||||||
if value:
|
if value:
|
||||||
@ -125,6 +136,10 @@ class Configuration:
|
|||||||
return data
|
return data
|
||||||
return default
|
return default
|
||||||
|
|
||||||
|
def append(self, item):
|
||||||
|
validation.check_schema(item)
|
||||||
|
self.documents.append(item)
|
||||||
|
|
||||||
|
|
||||||
def _matches_filter(document, *, schema, labels):
|
def _matches_filter(document, *, schema, labels):
|
||||||
matches = True
|
matches = True
|
||||||
|
@ -16,6 +16,7 @@ import falcon
|
|||||||
|
|
||||||
from promenade.control.base import BaseResource, PromenadeRequest
|
from promenade.control.base import BaseResource, PromenadeRequest
|
||||||
from promenade.control.health_api import HealthResource
|
from promenade.control.health_api import HealthResource
|
||||||
|
from promenade.control.join_scripts import JoinScriptsResource
|
||||||
from promenade.control.middleware import (AuthMiddleware, ContextMiddleware,
|
from promenade.control.middleware import (AuthMiddleware, ContextMiddleware,
|
||||||
LoggingMiddleware)
|
LoggingMiddleware)
|
||||||
from promenade import exceptions as exc
|
from promenade import exceptions as exc
|
||||||
@ -37,6 +38,7 @@ def start_api():
|
|||||||
v1_0_routes = [
|
v1_0_routes = [
|
||||||
# API for managing region data
|
# API for managing region data
|
||||||
('/health', HealthResource()),
|
('/health', HealthResource()),
|
||||||
|
('/join-scripts', JoinScriptsResource()),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Set up the 1.0 routes
|
# Set up the 1.0 routes
|
||||||
|
95
promenade/control/join_scripts.py
Normal file
95
promenade/control/join_scripts.py
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
# Copyright 2017 AT&T Intellectual Property. All other rights reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
from promenade.control.base import BaseResource
|
||||||
|
from promenade.builder import Builder
|
||||||
|
from promenade.config import Configuration
|
||||||
|
from promenade import logging
|
||||||
|
import falcon
|
||||||
|
import kubernetes
|
||||||
|
import random
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class JoinScriptsResource(BaseResource):
|
||||||
|
"""
|
||||||
|
Lists the versions supported by this API
|
||||||
|
"""
|
||||||
|
|
||||||
|
def on_get(self, req, resp):
|
||||||
|
design_ref = req.get_param('design_ref', required=True)
|
||||||
|
ip = req.get_param('ip', required=True)
|
||||||
|
hostname = req.get_param('hostname', required=True)
|
||||||
|
|
||||||
|
dynamic_labels = _get_param_list(req, 'labels.dynamic')
|
||||||
|
static_labels = _get_param_list(req, 'labels.static')
|
||||||
|
|
||||||
|
join_ip = _get_join_ip()
|
||||||
|
|
||||||
|
config = Configuration.from_design_ref(design_ref)
|
||||||
|
node_document = {
|
||||||
|
'schema': 'promenade/KubernetesNode/v1',
|
||||||
|
'metadata': {
|
||||||
|
'name': hostname,
|
||||||
|
'schema': 'metadata/Document/v1',
|
||||||
|
'layeringDefinition': {
|
||||||
|
'abstract': False,
|
||||||
|
'layer': 'site'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'data': {
|
||||||
|
'hostname': hostname,
|
||||||
|
'ip': ip,
|
||||||
|
'join_ip': join_ip,
|
||||||
|
'labels': {
|
||||||
|
'dynamic': dynamic_labels,
|
||||||
|
'static': static_labels,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
config.append(node_document)
|
||||||
|
|
||||||
|
builder = Builder(config)
|
||||||
|
script = builder.build_node_script(hostname)
|
||||||
|
|
||||||
|
resp.body = script
|
||||||
|
resp.content_type = 'text/x-shellscript'
|
||||||
|
resp.status = falcon.HTTP_200
|
||||||
|
|
||||||
|
|
||||||
|
def _get_join_ip():
|
||||||
|
# TODO(mark-burnett): Handle errors
|
||||||
|
kubernetes.config.load_incluster_config()
|
||||||
|
client = kubernetes.client.CoreV1Api()
|
||||||
|
response = client.list_node(label_selector='kubernetes-apiserver=enabled')
|
||||||
|
|
||||||
|
# Ignore bandit false positive: B311:blacklist
|
||||||
|
# The choice of which master to join to is a load-balancing concern, not a
|
||||||
|
# security concern.
|
||||||
|
return random.choice(list(map(_extract_ip, response.items))) # nosec
|
||||||
|
|
||||||
|
|
||||||
|
def _extract_ip(item):
|
||||||
|
for address in item.status.addresses:
|
||||||
|
if address.type == 'InternalIP':
|
||||||
|
return address.address
|
||||||
|
|
||||||
|
|
||||||
|
def _get_param_list(req, name):
|
||||||
|
values = req.get_param_as_list(name)
|
||||||
|
if values:
|
||||||
|
return values
|
||||||
|
else:
|
||||||
|
return []
|
@ -33,6 +33,8 @@ def insert_charts_into_bundler(bundler):
|
|||||||
for root, _dirnames, filenames in os.walk(
|
for root, _dirnames, filenames in os.walk(
|
||||||
'/opt/promenade/charts', followlinks=True):
|
'/opt/promenade/charts', followlinks=True):
|
||||||
for source_filename in filenames:
|
for source_filename in filenames:
|
||||||
|
if _source_file_is_excluded(source_filename):
|
||||||
|
continue
|
||||||
source_path = os.path.join(root, source_filename)
|
source_path = os.path.join(root, source_filename)
|
||||||
destination_path = os.path.join('etc/genesis/armada/assets/charts',
|
destination_path = os.path.join('etc/genesis/armada/assets/charts',
|
||||||
os.path.relpath(
|
os.path.relpath(
|
||||||
@ -139,6 +141,10 @@ def _default_no_proxy(network_config):
|
|||||||
return ','.join(include)
|
return ','.join(include)
|
||||||
|
|
||||||
|
|
||||||
|
def _source_file_is_excluded(source_filename):
|
||||||
|
return source_filename.endswith('.tgz')
|
||||||
|
|
||||||
|
|
||||||
def _yaml_safe_dump_all(documents):
|
def _yaml_safe_dump_all(documents):
|
||||||
f = io.StringIO()
|
f = io.StringIO()
|
||||||
yaml.safe_dump_all(documents, f)
|
yaml.safe_dump_all(documents, f)
|
||||||
|
@ -4,7 +4,8 @@ jinja2==2.9.6
|
|||||||
jsonpath-ng==1.4.3
|
jsonpath-ng==1.4.3
|
||||||
jsonschema==2.6.0
|
jsonschema==2.6.0
|
||||||
keystonemiddleware==4.17.0
|
keystonemiddleware==4.17.0
|
||||||
oslo.context==2.14.0
|
kubernetes==3.0.0
|
||||||
|
oslo.context==2.19.2
|
||||||
pastedeploy==1.5.2
|
pastedeploy==1.5.2
|
||||||
pbr==3.0.1
|
pbr==3.0.1
|
||||||
pyyaml==3.12
|
pyyaml==3.12
|
||||||
|
@ -1,24 +1,28 @@
|
|||||||
Babel==2.5.1
|
Babel==2.5.1
|
||||||
|
cachetools==2.0.1
|
||||||
certifi==2017.7.27.1
|
certifi==2017.7.27.1
|
||||||
chardet==3.0.4
|
chardet==3.0.4
|
||||||
click==6.7
|
click==6.7
|
||||||
debtcollector==1.18.0
|
debtcollector==1.18.0
|
||||||
decorator==4.1.2
|
decorator==4.1.2
|
||||||
falcon==1.2.0
|
falcon==1.2.0
|
||||||
|
google-auth==1.2.0
|
||||||
idna==2.6
|
idna==2.6
|
||||||
|
ipaddress==1.0.18
|
||||||
iso8601==0.1.12
|
iso8601==0.1.12
|
||||||
Jinja2==2.9.6
|
Jinja2==2.9.6
|
||||||
jsonpath-ng==1.4.3
|
jsonpath-ng==1.4.3
|
||||||
jsonschema==2.6.0
|
jsonschema==2.6.0
|
||||||
keystoneauth1==3.2.0
|
keystoneauth1==3.2.0
|
||||||
keystonemiddleware==4.17.0
|
keystonemiddleware==4.17.0
|
||||||
|
kubernetes==3.0.0
|
||||||
MarkupSafe==1.0
|
MarkupSafe==1.0
|
||||||
monotonic==1.4
|
monotonic==1.4
|
||||||
msgpack-python==0.4.8
|
msgpack-python==0.4.8
|
||||||
netaddr==0.7.19
|
netaddr==0.7.19
|
||||||
netifaces==0.10.6
|
netifaces==0.10.6
|
||||||
oslo.config==5.0.0
|
oslo.config==5.0.0
|
||||||
oslo.context==2.14.0
|
oslo.context==2.19.2
|
||||||
oslo.i18n==3.18.0
|
oslo.i18n==3.18.0
|
||||||
oslo.log==3.32.0
|
oslo.log==3.32.0
|
||||||
oslo.serialization==2.21.2
|
oslo.serialization==2.21.2
|
||||||
@ -27,6 +31,8 @@ PasteDeploy==1.5.2
|
|||||||
pbr==3.0.1
|
pbr==3.0.1
|
||||||
ply==3.10
|
ply==3.10
|
||||||
positional==1.2.1
|
positional==1.2.1
|
||||||
|
pyasn1==0.3.7
|
||||||
|
pyasn1-modules==0.1.5
|
||||||
pycadf==2.6.0
|
pycadf==2.6.0
|
||||||
pyinotify==0.9.6
|
pyinotify==0.9.6
|
||||||
pyparsing==2.2.0
|
pyparsing==2.2.0
|
||||||
@ -37,9 +43,11 @@ pytz==2017.3
|
|||||||
PyYAML==3.12
|
PyYAML==3.12
|
||||||
requests==2.18.4
|
requests==2.18.4
|
||||||
rfc3986==1.1.0
|
rfc3986==1.1.0
|
||||||
|
rsa==3.4.2
|
||||||
six==1.11.0
|
six==1.11.0
|
||||||
stevedore==1.27.1
|
stevedore==1.27.1
|
||||||
urllib3==1.22
|
urllib3==1.22
|
||||||
uWSGI==2.0.15
|
uWSGI==2.0.15
|
||||||
WebOb==1.7.3
|
WebOb==1.7.3
|
||||||
|
websocket-client==0.40.0
|
||||||
wrapt==1.10.11
|
wrapt==1.10.11
|
||||||
|
@ -8,6 +8,7 @@ source "$LIB_DIR"/const.sh
|
|||||||
source "$LIB_DIR"/etcd.sh
|
source "$LIB_DIR"/etcd.sh
|
||||||
source "$LIB_DIR"/kube.sh
|
source "$LIB_DIR"/kube.sh
|
||||||
source "$LIB_DIR"/log.sh
|
source "$LIB_DIR"/log.sh
|
||||||
|
source "$LIB_DIR"/nginx.sh
|
||||||
source "$LIB_DIR"/promenade.sh
|
source "$LIB_DIR"/promenade.sh
|
||||||
source "$LIB_DIR"/registry.sh
|
source "$LIB_DIR"/registry.sh
|
||||||
source "$LIB_DIR"/ssh.sh
|
source "$LIB_DIR"/ssh.sh
|
||||||
|
18
tools/g2/lib/nginx.sh
Normal file
18
tools/g2/lib/nginx.sh
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
nginx_down() {
|
||||||
|
REGISTRY_ID=$(docker ps -qa -f name=promenade-nginx)
|
||||||
|
if [ "x${REGISTRY_ID}" != "x" ]; then
|
||||||
|
log Removing nginx server
|
||||||
|
docker rm -fv "${REGISTRY_ID}" &>> "${LOG_FILE}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
nginx_up() {
|
||||||
|
log Starting nginx server to serve configuration files
|
||||||
|
mkdir -p "${TEMP_DIR}/nginx"
|
||||||
|
docker run -d \
|
||||||
|
-p 7777:80 \
|
||||||
|
--restart=always \
|
||||||
|
--name promenade-nginx \
|
||||||
|
-v "${TEMP_DIR}/nginx:/usr/share/nginx/html:ro" \
|
||||||
|
nginx:stable &>> "${LOG_FILE}"
|
||||||
|
}
|
@ -29,18 +29,42 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Join Masters",
|
"name": "Join Masters",
|
||||||
"script": "join-masters.sh",
|
"script": "join-nodes.sh",
|
||||||
"arguments": [
|
"arguments": [
|
||||||
"n1",
|
"-v", "n0",
|
||||||
"n2",
|
"-n", "n1",
|
||||||
"n3"
|
"-n", "n2",
|
||||||
|
"-n", "n3",
|
||||||
|
"-l", "calico-etcd=enabled",
|
||||||
|
"-l", "kubernetes-apiserver=enabled",
|
||||||
|
"-l", "kubernetes-controller-manager=enabled",
|
||||||
|
"-l", "kubernetes-etcd=enabled",
|
||||||
|
"-l", "kubernetes-scheduler=enabled",
|
||||||
|
"-l", "ucp-control-plane=enabled",
|
||||||
|
"-e", "kubernetes n0 genesis n1 n2 n3",
|
||||||
|
"-e", "calico n0 n0 n1 n2 n3"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Reprovision Genesis",
|
"name": "Teardown Genesis",
|
||||||
"script": "reprovision-genesis.sh",
|
"script": "teardown-nodes.sh",
|
||||||
"arguments": [
|
"arguments": [
|
||||||
"n1 n2 n3"
|
"-v", "n1",
|
||||||
|
"-n", "n0",
|
||||||
|
"-r",
|
||||||
|
"-e", "kubernetes n1 n1 n2 n3",
|
||||||
|
"-e", "calico n1 n1 n2 n3"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Join n0 as Worker",
|
||||||
|
"script": "join-nodes.sh",
|
||||||
|
"arguments": [
|
||||||
|
"-v", "n1",
|
||||||
|
"-n", "n0",
|
||||||
|
"-l", "ucp-control-plane=enabled",
|
||||||
|
"-e", "kubernetes n1 n1 n2 n3",
|
||||||
|
"-e", "calico n1 n1 n2 n3"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -29,18 +29,42 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Join Masters",
|
"name": "Join Masters",
|
||||||
"script": "join-masters.sh",
|
"script": "join-nodes.sh",
|
||||||
"arguments": [
|
"arguments": [
|
||||||
"n1",
|
"-v", "n0",
|
||||||
"n2",
|
"-n", "n1",
|
||||||
"n3"
|
"-n", "n2",
|
||||||
|
"-n", "n3",
|
||||||
|
"-l", "calico-etcd=enabled",
|
||||||
|
"-l", "kubernetes-apiserver=enabled",
|
||||||
|
"-l", "kubernetes-controller-manager=enabled",
|
||||||
|
"-l", "kubernetes-etcd=enabled",
|
||||||
|
"-l", "kubernetes-scheduler=enabled",
|
||||||
|
"-l", "ucp-control-plane=enabled",
|
||||||
|
"-e", "kubernetes n0 genesis n1 n2 n3",
|
||||||
|
"-e", "calico n0 n0 n1 n2 n3"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Reprovision Genesis",
|
"name": "Teardown Genesis",
|
||||||
"script": "reprovision-genesis.sh",
|
"script": "teardown-nodes.sh",
|
||||||
"arguments": [
|
"arguments": [
|
||||||
"n1 n2 n3"
|
"-v", "n1",
|
||||||
|
"-n", "n0",
|
||||||
|
"-r",
|
||||||
|
"-e", "kubernetes n1 n1 n2 n3",
|
||||||
|
"-e", "calico n1 n1 n2 n3"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Join n0 as Worker",
|
||||||
|
"script": "join-nodes.sh",
|
||||||
|
"arguments": [
|
||||||
|
"-v", "n1",
|
||||||
|
"-n", "n0",
|
||||||
|
"-l", "ucp-control-plane=enabled",
|
||||||
|
"-e", "kubernetes n1 n1 n2 n3",
|
||||||
|
"-e", "calico n1 n1 n2 n3"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1,50 +0,0 @@
|
|||||||
{
|
|
||||||
"configuration": [
|
|
||||||
"examples/basic"
|
|
||||||
],
|
|
||||||
"stages": [
|
|
||||||
{
|
|
||||||
"name": "Gate Setup",
|
|
||||||
"script": "gate-setup.sh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Build Image",
|
|
||||||
"script": "build-image.sh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Generate Certificates",
|
|
||||||
"script": "generate-certificates.sh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Build Scripts",
|
|
||||||
"script": "build-scripts.sh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Create VMs",
|
|
||||||
"script": "create-vms.sh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Genesis",
|
|
||||||
"script": "genesis.sh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Join Masters",
|
|
||||||
"script": "join-masters.sh",
|
|
||||||
"arguments": [
|
|
||||||
"n1"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Hard Reboot Cluster",
|
|
||||||
"script": "hard-reboot-cluster.sh"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"vm": {
|
|
||||||
"memory": 2048,
|
|
||||||
"names": [
|
|
||||||
"n0",
|
|
||||||
"n1"
|
|
||||||
],
|
|
||||||
"vcpus": 2
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
{
|
|
||||||
"configuration": [
|
|
||||||
"examples/complete"
|
|
||||||
],
|
|
||||||
"stages": [
|
|
||||||
{
|
|
||||||
"name": "Gate Setup",
|
|
||||||
"script": "gate-setup.sh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Build Image",
|
|
||||||
"script": "build-image.sh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Generate Certificates",
|
|
||||||
"script": "generate-certificates.sh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Build Scripts",
|
|
||||||
"script": "build-scripts.sh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Create VMs",
|
|
||||||
"script": "create-vms.sh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Genesis",
|
|
||||||
"script": "genesis.sh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Join Masters",
|
|
||||||
"script": "join-masters.sh",
|
|
||||||
"arguments": [
|
|
||||||
"n1"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Reprovision Genesis",
|
|
||||||
"script": "reprovision-genesis.sh",
|
|
||||||
"arguments": [
|
|
||||||
"n1"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Hard Reboot Cluster",
|
|
||||||
"script": "hard-reboot-cluster.sh"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"vm": {
|
|
||||||
"memory": 8096,
|
|
||||||
"names": [
|
|
||||||
"n0",
|
|
||||||
"n1"
|
|
||||||
],
|
|
||||||
"vcpus": 4
|
|
||||||
}
|
|
||||||
}
|
|
@ -18,3 +18,5 @@ docker run --rm -t \
|
|||||||
--validators \
|
--validators \
|
||||||
-o scripts \
|
-o scripts \
|
||||||
config/*.yaml
|
config/*.yaml
|
||||||
|
|
||||||
|
cat "${TEMP_DIR}"/config/*.yaml > "${TEMP_DIR}/nginx/promenade.yaml"
|
||||||
|
@ -8,6 +8,10 @@ source "${GATE_UTILS}"
|
|||||||
registry_up
|
registry_up
|
||||||
registry_populate
|
registry_populate
|
||||||
|
|
||||||
|
# NginX for serving config files in the absence of Deckhand
|
||||||
|
nginx_down
|
||||||
|
nginx_up
|
||||||
|
|
||||||
# SSH setup
|
# SSH setup
|
||||||
ssh_setup_declare
|
ssh_setup_declare
|
||||||
|
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
if [ $# -le 0 ]; then
|
|
||||||
echo "Must specify at least one vm to join"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
source "${GATE_UTILS}"
|
|
||||||
|
|
||||||
JOIN_TARGETS="${*}"
|
|
||||||
|
|
||||||
for NAME in ${JOIN_TARGETS}; do
|
|
||||||
rsync_cmd "${TEMP_DIR}"/scripts/*"${NAME}"* "${NAME}:/root/promenade/"
|
|
||||||
|
|
||||||
ssh_cmd "${NAME}" "/root/promenade/join-${NAME}.sh"
|
|
||||||
ssh_cmd "${NAME}" "/root/promenade/validate-${NAME}.sh"
|
|
||||||
|
|
||||||
# NOTE(mark-burnett): Ensure disk cache is flushed after join.
|
|
||||||
ssh_cmd "${NAME}" sync
|
|
||||||
done
|
|
||||||
|
|
||||||
validate_cluster n0
|
|
||||||
|
|
||||||
validate_etcd_membership kubernetes n0 genesis "${*}"
|
|
||||||
validate_etcd_membership calico n0 n0 "${*}"
|
|
77
tools/g2/stages/join-nodes.sh
Executable file
77
tools/g2/stages/join-nodes.sh
Executable file
@ -0,0 +1,77 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
source "${GATE_UTILS}"
|
||||||
|
|
||||||
|
declare -a ETCD_CLUSTERS
|
||||||
|
declare -a LABELS
|
||||||
|
declare -a NODES
|
||||||
|
|
||||||
|
while getopts "e:l:n:v:" opt; do
|
||||||
|
case "${opt}" in
|
||||||
|
e)
|
||||||
|
ETCD_CLUSTERS+=("${OPTARG}")
|
||||||
|
;;
|
||||||
|
l)
|
||||||
|
LABELS+=("${OPTARG}")
|
||||||
|
;;
|
||||||
|
n)
|
||||||
|
NODES+=("${OPTARG}")
|
||||||
|
;;
|
||||||
|
v)
|
||||||
|
VIA=${OPTARG}
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown option"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift $((OPTIND-1))
|
||||||
|
|
||||||
|
if [ $# -gt 0 ]; then
|
||||||
|
echo "Unknown arguments specified: ${*}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
SCRIPT_DIR="${TEMP_DIR}/curled-scripts"
|
||||||
|
|
||||||
|
echo Etcd Clusters: "${ETCD_CLUSTERS[@]}"
|
||||||
|
echo Labels: "${LABELS[@]}"
|
||||||
|
echo Nodes: "${NODES[@]}"
|
||||||
|
|
||||||
|
render_curl_url() {
|
||||||
|
NAME=${1}
|
||||||
|
shift
|
||||||
|
LABELS=(${@})
|
||||||
|
|
||||||
|
LABEL_PARAMS=
|
||||||
|
for label in "${LABELS[@]}"; do
|
||||||
|
LABEL_PARAMS+="&labels.dynamic=${label}"
|
||||||
|
done
|
||||||
|
|
||||||
|
BASE_URL="http://promenade-api.ucp.svc.cluster.local/api/v1.0/join-scripts"
|
||||||
|
DESIGN_REF="design_ref=http://192.168.77.1:7777/promenade.yaml"
|
||||||
|
HOST_PARAMS="hostname=${NAME}&ip=$(config_vm_ip "${NAME}")"
|
||||||
|
|
||||||
|
echo "'${BASE_URL}?${DESIGN_REF}&${HOST_PARAMS}${LABEL_PARAMS}'"
|
||||||
|
}
|
||||||
|
|
||||||
|
mkdir -p "${SCRIPT_DIR}"
|
||||||
|
|
||||||
|
for NAME in "${NODES[@]}"; do
|
||||||
|
log Building join script for node "${NAME}"
|
||||||
|
|
||||||
|
ssh_cmd "${VIA}" curl "$(render_curl_url "${NAME}" "${LABELS[@]}")" > "${SCRIPT_DIR}/join-${NAME}.sh"
|
||||||
|
chmod 755 "${SCRIPT_DIR}/join-${NAME}.sh"
|
||||||
|
|
||||||
|
log Joining node "${NAME}"
|
||||||
|
rsync_cmd "${SCRIPT_DIR}/join-${NAME}.sh" "${NAME}:/root/promenade/"
|
||||||
|
ssh_cmd "${NAME}" "/root/promenade/join-${NAME}.sh"
|
||||||
|
done
|
||||||
|
|
||||||
|
for etcd_validation_string in "${ETCD_CLUSTERS[@]}"; do
|
||||||
|
IFS=' ' read -a etcd_validation_args <<<"${etcd_validation_string}"
|
||||||
|
validate_etcd_membership "${etcd_validation_args[@]}"
|
||||||
|
done
|
51
tools/g2/stages/teardown-nodes.sh
Executable file
51
tools/g2/stages/teardown-nodes.sh
Executable file
@ -0,0 +1,51 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
source "${GATE_UTILS}"
|
||||||
|
|
||||||
|
declare -a ETCD_CLUSTERS
|
||||||
|
declare -a NODES
|
||||||
|
|
||||||
|
RECREATE=0
|
||||||
|
|
||||||
|
while getopts "e:n:rv:" opt; do
|
||||||
|
case "${opt}" in
|
||||||
|
e)
|
||||||
|
ETCD_CLUSTERS+=("${OPTARG}")
|
||||||
|
;;
|
||||||
|
n)
|
||||||
|
NODES+=("${OPTARG}")
|
||||||
|
;;
|
||||||
|
r)
|
||||||
|
RECREATE=1
|
||||||
|
;;
|
||||||
|
v)
|
||||||
|
VIA=${OPTARG}
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown option"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift $((OPTIND-1))
|
||||||
|
|
||||||
|
if [ $# -gt 0 ]; then
|
||||||
|
echo "Unknown arguments specified: ${*}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
for NAME in "${NODES[@]}"; do
|
||||||
|
log Tearing down node "${NAME}"
|
||||||
|
promenade_teardown_node "${NAME}" "${VIA}"
|
||||||
|
vm_clean "${NAME}"
|
||||||
|
if [[ ${RECREATE} == "1" ]]; then
|
||||||
|
vm_create "${NAME}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
for etcd_validation_string in "${ETCD_CLUSTERS[@]}"; do
|
||||||
|
IFS=' ' read -a etcd_validation_args <<<"${etcd_validation_string}"
|
||||||
|
validate_etcd_membership "${etcd_validation_args[@]}"
|
||||||
|
done
|
@ -14,3 +14,4 @@ source "${GATE_UTILS}"
|
|||||||
vm_clean_all
|
vm_clean_all
|
||||||
net_clean
|
net_clean
|
||||||
registry_down
|
registry_down
|
||||||
|
nginx_down
|
||||||
|
Loading…
x
Reference in New Issue
Block a user