Commit bb0e67be authored by Alfonso Orta's avatar Alfonso Orta

Merge branch 'develop' into 'staging'

Develop

See merge request !8
parents 21ce2a62 4cd08851
tosca_definitions_version: tosca_simple_yaml_1_0
description: TOSCA template
topology_template:
node_templates:
compute:
properties:
disk_size: "120 GB"
mem_size: "7 GB"
num_cores: 4
os: Ubuntu 18.04
user_name: vm_user
interfaces:
Standard:
create: dumy.yaml
type: tosca.nodes.QC.VM.Compute
compute_1:
properties:
disk_size: "120 GB"
mem_size: "7 GB"
num_cores: 4
os: Ubuntu 18.04
user_name: vm_user
interfaces:
Standard:
create: dumy.yaml
type: tosca.nodes.QC.VM.Compute
topology:
properties:
domain: Ireland
provider: EC2
requirements:
- vm:
capability: tosca.capabilities.QC.VM
node: compute
relationship: tosca.relationships.DependsOn
- vm:
capability: tosca.capabilities.QC.VM
node: compute_1
relationship: tosca.relationships.DependsOn
interfaces:
CloudsStorm:
delete:
inputs:
code_type: SEQ
object_type: SubTopology
hscale:
inputs:
code_type: SEQ
object_type: SubTopology
provision:
inputs:
code_type: SEQ
object_type: SubTopology
start:
inputs:
code_type: SEQ
object_type: SubTopology
stop:
inputs:
code_type: SEQ
object_type: SubTopology
type: tosca.nodes.QC.VM.topology
artifacts:
provisioned_files:
required: false
type: "string"
imports:
- nodes: https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/nodes.yaml
- data: https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/data.yml
- capabilities: https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/capabilities.yaml
- policies: https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/policies.yaml
- interfaces: https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/interfaces.yml
tosca_definitions_version: tosca_simple_yaml_1_0
description: TOSCA template
topology_template:
node_templates:
compute:
properties:
disk_size: "40 GB"
mem_size: "17500 MB"
num_cores: 2
os: Ubuntu 18.04
user_name: vm_user
interfaces:
Standard:
create: dumy.yaml
type: tosca.nodes.QC.VM.Compute
compute_1:
properties:
disk_size: "40 GB"
mem_size: "17500 MB"
num_cores: 2
os: Ubuntu 18.04
user_name: vm_user
interfaces:
Standard:
create: dumy.yaml
type: tosca.nodes.QC.VM.Compute
topology:
properties:
domain: Ireland
provider: EC2
requirements:
- vm:
capability: tosca.capabilities.QC.VM
node: compute
relationship: tosca.relationships.DependsOn
- vm:
capability: tosca.capabilities.QC.VM
node: compute_1
relationship: tosca.relationships.DependsOn
interfaces:
CloudsStorm:
delete:
inputs:
code_type: SEQ
object_type: SubTopology
hscale:
inputs:
code_type: SEQ
object_type: SubTopology
provision:
inputs:
code_type: SEQ
object_type: SubTopology
start:
inputs:
code_type: SEQ
object_type: SubTopology
stop:
inputs:
code_type: SEQ
object_type: SubTopology
type: tosca.nodes.QC.VM.topology
artifacts:
provisioned_files:
required: false
type: "string"
imports:
- nodes: https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/nodes.yaml
- data: https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/data.yml
- capabilities: https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/capabilities.yaml
- policies: https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/policies.yaml
- interfaces: https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/interfaces.yml
tosca_definitions_version: "tosca_simple_yaml_1_0"
topology_template:
node_templates:
compute:
properties:
disk_size: "120 GB"
mem_size: "7 GB"
num_cores: 4
os: "Ubuntu 18.04"
user_name: "vm_user"
interfaces:
Standard:
create: dumy.yaml
type: tosca.nodes.QC.VM.Compute
#compute_1:
#properties:
#disk_size: "40000 MB"
#mem_size: "1000 MB"
#num_cores: 1
#os: "Ubuntu 18.04"
#user_name: "vm_user"
#interfaces:
#Standard:
#create: "dumy.yaml"
#type: "tosca.nodes.QC.VM.Compute"
topology:
properties:
domain: "Ireland"
provider: "EC2"
requirements:
#- vm:
#capability: "tosca.capabilities.QC.VM"
#node: "compute"
#relationship: "tosca.relationships.DependsOn"
- vm:
capability: "tosca.capabilities.QC.VM"
node: "compute_1"
relationship: "tosca.relationships.DependsOn"
interfaces:
CloudsStorm:
delete:
inputs:
code_type: "SEQ"
object_type: "SubTopology"
hscale:
inputs:
code_type: "SEQ"
object_type: "SubTopology"
provision:
inputs:
code_type: "SEQ"
object_type: "SubTopology"
start:
inputs:
code_type: "SEQ"
object_type: "SubTopology"
stop:
inputs:
code_type: "SEQ"
object_type: "SubTopology"
type: "tosca.nodes.QC.VM.topology"
artifacts:
provisioned_files:
required: false
type: "string"
description: "TOSCA example"
imports:
- nodes: "https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/nodes.yaml"
- data: "https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/data.yml"
- capabilities: "https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/capabilities.yaml"
- policies: "https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/policies.yaml"
- interfaces: "https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/interfaces.yml"
tosca_definitions_version: tosca_simple_yaml_1_0
topology_template:
node_templates:
compute:
properties:
num_cores: 2
disk_size: 20 GB
mem_size: 4098 MB
os: Ubuntu 18.04
user_name: vm_user
interfaces:
Standard:
create: dumy.yaml
type: tosca.nodes.QC.VM.Compute
topology:
properties:
domain: Iraland
provider: EC2
requirements:
- vm:
capability: tosca.capabilities.QC.VM
node: compute
relationship: tosca.relationships.DependsOn
interfaces:
CloudsStorm:
delete:
inputs:
code_type: SEQ
object_type: SubTopology
hscale:
inputs:
code_type: SEQ
object_type: SubTopology
provision:
inputs:
code_type: SEQ
object_type: SubTopology
start:
inputs:
code_type: SEQ
object_type: SubTopology
stop:
inputs:
code_type: SEQ
object_type: SubTopology
type: tosca.nodes.QC.VM.topology
description: TOSCA template
imports:
- nodes: https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/nodes.yaml
- data: https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/data.yml
- capabilities: https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/capabilities.yaml
- policies: https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/policies.yaml
- interfaces: https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/interfaces.yml
#!/bin/bash
TOSCA_ID="5f8eb46c8ff9431bd55e931a"
BASE_URL="https://fry.lab.uvalight.net:30001/manager/"
USERNAME=deploy_tester
PASSWORD=edvbafeabvafdb
#
# # curl -s -D - -k -u $USERNAME:$PASSWORD -X GET "$BASE_URL/tosca_template/$TOSCA_ID" &> tosca_output
# RESPONSE=`cat tosca_output | head -n 1 | cut '-d ' '-f2'`
#
# if [ $RESPONSE != "200" ];
# then
# cat tosca_output
# exit -1
# fi
# TOSCA_CONTENTS=`cat tosca_output | tail -n +11`
# echo $TOSCA_CONTENTS
#
#
# # curl -s -D - -k -u $USERNAME:$PASSWORD -X GET "$BASE_URL/provisioner/provision/$TOSCA_ID" &> provision_output
# RESPONSE=`cat provision_output | head -n 1 | cut '-d ' '-f2'`
#
# if [ $RESPONSE != "200" ];
# then
# cat provision_output
# exit -1
# fi
# PROVISION_ID=`cat provision_output | tail -n +11`
# PROVISION_ID=5f8ec0a68ff9431bd55e931e
# echo $PROVISION_ID
#
#
# curl -s -D - -k -u $USERNAME:$PASSWORD -X GET "$BASE_URL/deployer/deploy/$PROVISION_ID" &> deploy_output
# RESPONSE=`cat deploy_output | head -n 1 | cut '-d ' '-f2'`
#
# if [ $RESPONSE != "200" ];
# then
# cat deploy_output
# exit -1
# fi
# DEPLOY_ID=`cat deploy_output | tail -n +11`
# echo $DEPLOY_ID
#
# #
#
# # curl -u $USERNAME:$PASSWORD -X GET "$BASE_URL/tosca_template/$DEPLOY_ID"
# #
# # curl -u $USERNAME:$PASSWORD -X DELETE "$BASE_URL/tosca_template/$DEPLOY_ID"
#
#
...@@ -84,20 +84,20 @@ def handle_delivery(message): ...@@ -84,20 +84,20 @@ def handle_delivery(message):
tosca_helper = ToscaHelper(sure_tosca_base_url, tosca_template_path) tosca_helper = ToscaHelper(sure_tosca_base_url, tosca_template_path)
# nodes_to_deploy = tosca_helper.get_application_nodes() # nodes_to_deploy = tosca_helper.get_application_nodes()
nodes_pairs = tosca_helper.get_deployment_node_pairs() nodes = tosca_helper.get_deployment_node_pipeline()
deployService = DeployService(semaphore_base_url=semaphore_base_url, semaphore_username=semaphore_username, deployService = DeployService(semaphore_base_url=semaphore_base_url, semaphore_username=semaphore_username,
semaphore_password=semaphore_password, vms=tosca_helper.get_vms()) semaphore_password=semaphore_password, vms=tosca_helper.get_vms())
try: try:
for node_pair in nodes_pairs: for node in nodes:
updated_node = deployService.deploy(node_pair) updated_node = deployService.deploy(node)
if isinstance(updated_node, list): if isinstance(updated_node, list):
for node in updated_node: for node in updated_node:
tosca_template_dict = tosca_helper.set_node(node,tosca_template_dict) tosca_template_dict = tosca_helper.set_node(node,tosca_template_dict)
logger.info("tosca_template_dict :" + json.dumps(tosca_template_dict)) # logger.info("tosca_template_dict :" + json.dumps(tosca_template_dict))
else: else:
tosca_template_dict = tosca_helper.set_node(updated_node, tosca_template_dict) tosca_template_dict = tosca_helper.set_node(updated_node, tosca_template_dict)
logger.info("tosca_template_dict :" + json.dumps(tosca_template_dict)) # logger.info("tosca_template_dict :" + json.dumps(tosca_template_dict))
response = {'toscaTemplate': tosca_template_dict} response = {'toscaTemplate': tosca_template_dict}
output_current_milli_time = int(round(time.time() * 1000)) output_current_milli_time = int(round(time.time() * 1000))
...@@ -114,7 +114,7 @@ def handle_delivery(message): ...@@ -114,7 +114,7 @@ def handle_delivery(message):
def threaded_function(args): def threaded_function(args):
while not done: while not done:
connection.process_data_events() connection.process_data_events()
sleep(5) sleep(8)
if __name__ == "__main__": if __name__ == "__main__":
......
import copy
import json
import logging
import os
import os.path
import tempfile
import time
import yaml
import re # noqa: F401
from pathlib import Path
import unittest
import sure_tosca_client
from sure_tosca_client import Configuration, ApiClient
from sure_tosca_client.api import default_api
from service.deploy_service import DeployService
from service.tosca_helper import ToscaHelper
class TestDeployer(unittest.TestCase):
def test(self):
logger = logging.getLogger(__name__)
message_file_path = str(Path.home()) + '/Downloads/message_deploy_request.json'
if os.path.isfile(message_file_path):
with open(message_file_path, 'r') as stream:
parsed_json_message = json.load(stream)
# owner = parsed_json_message['owner']
tosca_file_name = 'tosca_template'
tosca_template_dict = parsed_json_message['toscaTemplate']
tmp_path = tempfile.mkdtemp()
tosca_template_path = tmp_path + os.path.sep + 'toscaTemplate.yml'
with open(tosca_template_path, 'w') as outfile:
yaml.dump(tosca_template_dict, outfile, default_flow_style=False)
sure_tosca_base_url = 'http://127.0.0.1:8081/tosca-sure/1.0.0'
semaphore_base_url = 'http://127.0.0.1:3000/api'
tosca_service_is_up = ToscaHelper.service_is_up(sure_tosca_base_url)
semaphore_is_up = ToscaHelper.service_is_up(semaphore_base_url)
if tosca_service_is_up and semaphore_is_up:
tosca_helper = ToscaHelper(sure_tosca_base_url,tosca_template_path)
self.assertIsNotNone(tosca_helper.doc_id)
nodes_to_deploy = tosca_helper.get_application_nodes()
self.assertIsNotNone(nodes_to_deploy)
nodes_pairs = tosca_helper.get_deployment_node_pairs()
self.assertIsNotNone(nodes_pairs)
username = 'admin'
deployService = DeployService(polemarch_base_url=polemarch_base_url,polemarch_username=username,polemarch_password='admin',
semaphore_base_url=semaphore_base_url,semaphore_username=username,semaphore_password='password')
for node_pair in nodes_pairs:
deployService.deploy(node_pair)
def get_tosca_file(self, file_name):
tosca_path = "../../TOSCA/"
input_tosca_file_path = tosca_path + '/' + file_name
if not os.path.exists(input_tosca_file_path):
tosca_path = "../TOSCA/"
input_tosca_file_path = tosca_path + '/' + file_name
dir_path = os.path.dirname(os.path.realpath(__file__))
self.assertEqual(True, os.path.exists(input_tosca_file_path),
'Starting from: ' + dir_path + ' Input TOSCA file: ' + input_tosca_file_path + ' not found')
return input_tosca_file_path
if __name__ == '__main__':
import unittest
unittest.main()
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
#namespace: kubernetes-dashboard
namespace: default
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
#namespace: kubernetes-dashboard
namespace: default
#kube-system
# Copyright 2017 The Kubernetes Authors.
#
# 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.
apiVersion: v1
kind: Namespace
metadata:
name: kubernetes-dashboard
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
type: NodePort
ports:
- port: 8443
nodePort: 30443
selector:
k8s-app: kubernetes-dashboard
---
apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-certs
namespace: kubernetes-dashboard
type: Opaque
---
apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-csrf
namespace: kubernetes-dashboard
type: Opaque
data:
csrf: ""
---
apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-key-holder
namespace: kubernetes-dashboard
type: Opaque
---
kind: ConfigMap
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-settings
namespace: kubernetes-dashboard
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
rules:
# Allow Dashboard to get, update and delete Dashboard exclusive secrets.
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs", "kubernetes-dashboard-csrf"]
verbs: ["get", "update", "delete"]
# Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["kubernetes-dashboard-settings"]
verbs: ["get", "update"]
# Allow Dashboard to get metrics.
- apiGroups: [""]
resources: ["services"]
resourceNames: ["heapster", "dashboard-metrics-scraper"]
verbs: ["proxy"]
- apiGroups: [""]
resources: ["services/proxy"]
resourceNames: ["heapster", "http:heapster:", "https:heapster:", "dashboard-metrics-scraper", "http:dashboard-metrics-scraper"]
verbs: ["get"]
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
rules:
# Allow Metrics Scraper to get metrics from the Metrics server
- apiGroups: ["metrics.k8s.io"]
resources: ["pods", "nodes"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kubernetes-dashboard
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kubernetes-dashboard
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: kubernetes-dashboard
template:
metadata:
labels:
k8s-app: kubernetes-dashboard
spec:
containers:
- name: kubernetes-dashboard
image: kubernetesui/dashboard:v2.0.0-rc3
imagePullPolicy: Always
ports:
- containerPort: 8443
protocol: TCP
args:
- --auto-generate-certificates
- --namespace=kubernetes-dashboard
# Uncomment the following line to manually specify Kubernetes API server Host
# If not specified, Dashboard will attempt to auto discover the API server and connect
# to it. Uncomment only if the default does not work.
# - --apiserver-host=http://my-address:port
volumeMounts:
- name: kubernetes-dashboard-certs
mountPath: /certs
# Create on-disk volume to store exec logs
- mountPath: /tmp
name: tmp-volume
livenessProbe:
httpGet:
scheme: HTTPS
path: /
port: 8443
initialDelaySeconds: 30
timeoutSeconds: 30
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsUser: 1001
runAsGroup: 2001
volumes:
- name: kubernetes-dashboard-certs
secret:
secretName: kubernetes-dashboard-certs
- name: tmp-volume
emptyDir: {}
serviceAccountName: kubernetes-dashboard
nodeSelector:
"beta.kubernetes.io/os": linux
# Comment the following tolerations if Dashboard must not be deployed on master
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
---
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: dashboard-metrics-scraper
name: dashboard-metrics-scraper
namespace: kubernetes-dashboard
spec:
ports:
- port: 8000
targetPort: 8000
selector:
k8s-app: dashboard-metrics-scraper
---
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
k8s-app: dashboard-metrics-scraper
name: dashboard-metrics-scraper
namespace: kubernetes-dashboard
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: dashboard-metrics-scraper
template:
metadata:
labels:
k8s-app: dashboard-metrics-scraper
annotations:
seccomp.security.alpha.kubernetes.io/pod: 'runtime/default'
spec:
containers:
- name: dashboard-metrics-scraper
image: kubernetesui/metrics-scraper:v1.0.3
ports:
- containerPort: 8000
protocol: TCP
livenessProbe:
httpGet:
scheme: HTTP
path: /
port: 8000
initialDelaySeconds: 30
timeoutSeconds: 30
volumeMounts:
- mountPath: /tmp
name: tmp-volume
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsUser: 1001
runAsGroup: 2001
serviceAccountName: kubernetes-dashboard
nodeSelector:
"beta.kubernetes.io/os": linux
# Comment the following tolerations if Dashboard must not be deployed on master
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
volumes:
- name: tmp-volume
emptyDir: {}
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: NAME
name: NAME
namespace: default
spec:
selector:
matchLabels:
app: NAME
replicas: 1
template:
metadata:
labels:
app: NAME
spec:
containers:
- image: IMAGE_NAME
name: NAME
ports:
- containerPort: PORT
env:
- name: ENV_NAME
value: ENV_VAL
apiVersion: v1
kind: Service
metadata:
labels:
app: NAME
name: NAME
namespace: default
spec:
type: NodePort
ports:
- port: CONTAINER_PORT
nodePort: NODE_PORT
selector:
app: NAME
pika==1.1.0 pika==1.1.0
names==0.3.0 names==0.3.0
networkx==2.4 networkx==2.4
requests==2.23.0 # requests==2.23.0
wheel==0.34.2 wheel==0.34.2
pyyaml==5.3.1 pyyaml==5.3.1
matplotlib==3.2.1 matplotlib==3.3.0
# ansible==2.9.6 ansible==2.9.11
certifi==2020.4.5.1 # certifi==2020.4.5.1
six==1.14.0 six==1.14.0
python_dateutil==2.8.1 python_dateutil==2.8.1
setuptools==46.1.3 # setuptools==46.1.3
urllib3==1.25.8 # urllib3==1.25.8
kubernetes==11.0.0 kubernetes==11.0.0
\ No newline at end of file
import base64 import base64
import configparser
import logging import logging
from time import sleep from time import sleep
import datetime import datetime
...@@ -29,8 +30,7 @@ class AnsibleService: ...@@ -29,8 +30,7 @@ class AnsibleService:
self.repository_id = None self.repository_id = None
self.template_id = None self.template_id = None
def execute(self, nodes_pair, interface_type, vms, env_vars=None): def execute(self, application, interface_type, vms, env_vars=None):
application = nodes_pair[1]
name = application.name name = application.name
desired_state = None desired_state = None
tasks_outputs = {} tasks_outputs = {}
...@@ -43,7 +43,8 @@ class AnsibleService: ...@@ -43,7 +43,8 @@ class AnsibleService:
if desired_state: if desired_state:
now = datetime.datetime.now() now = datetime.datetime.now()
project_id = self.semaphore_helper.create_project(application.name + '_' + str(now)) project_id = self.semaphore_helper.create_project(application.name + '_' + str(now))
inventory_contents = yaml.dump(self.build_yml_inventory(vms), default_flow_style=False) inventory_dict = self.build_inventory(vms, application_name=application.name)
inventory_contents = yaml.dump(inventory_dict, default_flow_style=False)
private_key = self.get_private_key(vms) private_key = self.get_private_key(vms)
key_id = self.semaphore_helper.create_ssh_key(application.name, project_id, private_key) key_id = self.semaphore_helper.create_ssh_key(application.name, project_id, private_key)
inventory_id = self.semaphore_helper.create_inventory(application.name, project_id, key_id, inventory_id = self.semaphore_helper.create_inventory(application.name, project_id, key_id,
...@@ -53,19 +54,41 @@ class AnsibleService: ...@@ -53,19 +54,41 @@ class AnsibleService:
create = interface['create'] create = interface['create']
inputs = create['inputs'] inputs = create['inputs']
git_url = inputs['repository'] git_url = inputs['repository']
if 'resources' in inputs:
playbook_names = inputs['resources'] playbook_names = inputs['resources']
for playbook_name in playbook_names: for playbook_name in playbook_names:
environment_id = None environment_id = None
if env_vars: if env_vars:
environment_id = self.semaphore_helper.create_environment(project_id, name, env_vars) environment_id = self.semaphore_helper.create_environment(project_id, name, env_vars)
task_id = self.run_task(name, project_id, key_id, git_url, inventory_id, playbook_name, arguments = None
environment_id=environment_id) if application.name == 'gluster_fs' or application.name == 'glusterfs' or application.name == 'tic':
if self.semaphore_helper.get_task(project_id, task_id).status != 'success': for vm in vms:
attributes = vm.node_template.attributes
if attributes['role'] == 'master':
master_ip = attributes['public_ip']
break break
# logger.info('playbook: ' + playbook_name + ' task_id: ' + str(task_id)) arguments = '["-u","vm_user","--extra-vars","gluster_cluster_host0=\'' + master_ip \
+ '\' gluster_cluster_volume=\'gfs0\' devmode=\'false\' ' \
'device_path=\'/dev/xvdh\' gfs_size=\'15G\'"]'
task_id = self.run_task(name, project_id, key_id, git_url, inventory_id, playbook_name,
environment_id=environment_id, arguments=arguments)
count = 0
while self.semaphore_helper.get_task(project_id, task_id).status != 'success':
task_id = self.run_task(name, project_id, key_id, git_url, inventory_id, playbook_name,
environment_id=environment_id, arguments=arguments)
count += 1
if count >= 3:
msg = ' '
for out in self.semaphore_helper.get_task_outputs(project_id, task_id):
msg = msg + ' ' + out.output
raise Exception(
'Task: ' + playbook_name + ' failed. ' + self.semaphore_helper.get_task(project_id,
task_id).status + ' Output: ' + msg)
tasks_outputs[task_id] = self.semaphore_helper.get_task_outputs(project_id, task_id) tasks_outputs[task_id] = self.semaphore_helper.get_task_outputs(project_id, task_id)
if 'configure' in interface and self.semaphore_helper.get_task(project_id, task_id).status == 'success': if 'configure' in interface and self.semaphore_helper.get_task(project_id,
task_id).status == 'success' and 'resources' in inputs:
configure = interface['configure'] configure = interface['configure']
inputs = configure['inputs'] inputs = configure['inputs']
git_url = inputs['repository'] git_url = inputs['repository']
...@@ -77,34 +100,50 @@ class AnsibleService: ...@@ -77,34 +100,50 @@ class AnsibleService:
task_id = self.run_task(name, project_id, key_id, git_url, inventory_id, playbook_name, task_id = self.run_task(name, project_id, key_id, git_url, inventory_id, playbook_name,
environment_id=environment_id) environment_id=environment_id)
if self.semaphore_helper.get_task(project_id, task_id).status != 'success': if self.semaphore_helper.get_task(project_id, task_id).status != 'success':
break msg = ''
for out in self.semaphore_helper.get_task_outputs(project_id, task_id):
msg = msg + out.output
raise Exception(
'Task: ' + playbook_name + ' failed. ' + self.semaphore_helper.get_task(project_id,
task_id).status + ' Output: ' + msg)
# logger.info('playbook: ' + playbook_name + ' task_id: ' + str(task_id)) # logger.info('playbook: ' + playbook_name + ' task_id: ' + str(task_id))
tasks_outputs[task_id] = self.semaphore_helper.get_task_outputs(project_id, task_id) tasks_outputs[task_id] = self.semaphore_helper.get_task_outputs(project_id, task_id)
return tasks_outputs return tasks_outputs
def build_yml_inventory(self, vms): def build_inventory(self, vms, application_name=None):
# loader = DataLoader() # loader = DataLoader()
# inventory = InventoryManager(loader=loader) # inventory = InventoryManager(loader=loader)
# variable_manager = VariableManager() # variable_manager = VariableManager()
vars = {}
# vars ['ansible_ssh_common_args'] = '"-o StrictHostKeyChecking=no"'
vars['ansible_ssh_user'] = vms[0].node_template.properties['user_name']
vars['ansible_python_interpreter'] = '/usr/bin/python3'
if application_name == 'gluster_fs' or application_name == 'glusterfs':
return self.build_glusterfs_inventory(vms, vars)
if application_name == 'tic':
return self.build_tic_inventory(vms, vars)
inventory = {} inventory = {}
all = {} all = {}
vars = {'ansible_ssh_common_args': '-o StrictHostKeyChecking=no'}
vars['ansible_ssh_user'] = vms[0].node_template.properties['user_name']
children = {} children = {}
for vm in vms: for vm in vms:
attributes = vm.node_template.attributes attributes = vm.node_template.attributes
role = attributes['role'] roles = []
roles.append(attributes['role'])
public_ip = attributes['public_ip'] public_ip = attributes['public_ip']
for role in roles:
if role not in children: if role not in children:
hosts = {} hosts = {}
else: else:
hosts = children[role] hosts = children[role]
host = {} host = {}
host[public_ip] = vars host[public_ip] = vars
if 'hosts' in hosts:
hosts['hosts'][public_ip] = vars
else:
hosts['hosts'] = host hosts['hosts'] = host
children[role] = hosts children[role] = hosts
# inventory.add_group(role)
# inventory.add_host(public_ip,group=role)
all['children'] = children all['children'] = children
inventory['all'] = all inventory['all'] = all
return inventory return inventory
...@@ -113,12 +152,13 @@ class AnsibleService: ...@@ -113,12 +152,13 @@ class AnsibleService:
private_key = vms[0].node_template.attributes['user_key_pair']['keys']['private_key'] private_key = vms[0].node_template.attributes['user_key_pair']['keys']['private_key']
return base64.b64decode(private_key).decode('utf-8').replace(r'\n', '\n') return base64.b64decode(private_key).decode('utf-8').replace(r'\n', '\n')
def run_task(self, name, project_id, key_id, git_url, inventory_id, playbook_name, environment_id=None): def run_task(self, name, project_id, key_id, git_url, inventory_id, playbook_name, environment_id=None,
arguments=None):
logger.info('project_id: ' + str(project_id) + ' task name: ' + str( logger.info('project_id: ' + str(project_id) + ' task name: ' + str(
name) + ' git url: ' + git_url + ' playbook: ' + playbook_name) name) + ' git url: ' + git_url + ' playbook: ' + playbook_name)
self.repository_id = self.semaphore_helper.create_repository(name, project_id, key_id, git_url) self.repository_id = self.semaphore_helper.create_repository(name, project_id, key_id, git_url)
template_id = self.semaphore_helper.create_template(project_id, key_id, inventory_id, self.repository_id, template_id = self.semaphore_helper.create_template(project_id, key_id, inventory_id, self.repository_id,
playbook_name) playbook_name, arguments)
task_id = self.semaphore_helper.execute_task(project_id, template_id, playbook_name, task_id = self.semaphore_helper.execute_task(project_id, template_id, playbook_name,
environment_id=environment_id) environment_id=environment_id)
task = self.semaphore_helper.get_task(project_id, task_id) task = self.semaphore_helper.get_task(project_id, task_id)
...@@ -129,5 +169,76 @@ class AnsibleService: ...@@ -129,5 +169,76 @@ class AnsibleService:
if last_status != this_status: if last_status != this_status:
logger.info('task name: ' + name + ', task status: ' + str(task.status)) logger.info('task name: ' + name + ', task status: ' + str(task.status))
last_status = this_status last_status = this_status
sleep(3) sleep(6)
return task_id return task_id
def build_glusterfs_inventory(self, vms, vars):
inventory = {}
all = {}
children = {}
gfs_count = 1
for vm in vms:
attributes = vm.node_template.attributes
roles = []
roles.append('gfscluster')
public_ip = attributes['public_ip']
vm_vars = {'ansible_host': public_ip}
vm_vars.update(vars)
for role in roles:
if role not in children:
hosts = {}
else:
hosts = children[role]
if 'hosts' in hosts:
hosts['hosts']['gfs' + str(gfs_count)] = vm_vars
else:
host = {}
host['gfs' + str(gfs_count)] = vm_vars
hosts['hosts'] = host
gfs_count += 1
children[role] = hosts
all['children'] = children
inventory['all'] = all
return inventory
def build_tic_inventory(self, vms, vars):
inventory = {}
all = {}
children = {}
for vm in vms:
attributes = vm.node_template.attributes
public_ip = attributes['public_ip']
vm_vars = {'ansible_host': public_ip}
vm_vars.update(vars)
roles = []
if attributes['role'] == 'master':
roles.append('swarm_manager_prime')
roles.append('swarm_managers')
elif attributes['role'] == 'worker':
roles.append('swarm_workers')
fabric_count = 0
for role in roles:
if role not in children:
hosts = {}
else:
hosts = children[role]
if 'hosts' in hosts:
if role == 'swarm_manager_prime' or role == 'swarm_managers':
host = {'hlf' + str(fabric_count): vm_vars}
else:
fabric_count += 1
host = {'hlf' + str(fabric_count): vm_vars}
hosts['hosts'] = host
else:
if role == 'swarm_manager_prime' or role == 'swarm_managers':
host = {'hlf' + str(fabric_count): vm_vars}
else:
fabric_count += 1
host = {'hlf' + str(fabric_count): vm_vars}
hosts['hosts'] = host
children[role] = hosts
all['children'] = children
inventory['all'] = all
return inventory
...@@ -29,30 +29,33 @@ class DeployService: ...@@ -29,30 +29,33 @@ class DeployService:
self.master_ip = vm.node_template.attributes['public_ip'] self.master_ip = vm.node_template.attributes['public_ip']
break break
def deploy(self,nodes_pair): def deploy(self, application):
target = nodes_pair[0] # target = nodes_pair[0]
source = nodes_pair[1] # source = nodes_pair[1]
interface_types = tosca_helper.get_interface_types(source) interface_types = tosca_helper.get_interface_types(application)
if interface_types: if interface_types:
ansible_service = AnsibleService(self.semaphore_base_url, self.semaphore_username, self.semaphore_password) ansible_service = AnsibleService(self.semaphore_base_url, self.semaphore_username, self.semaphore_password)
env_vars = self.get_env_vars(nodes_pair) env_vars = self.get_env_vars(application)
if 'Standard' in interface_types: if 'Standard' in interface_types:
task_outputs = ansible_service.execute(nodes_pair, 'Standard', self.vms, env_vars=env_vars) task_outputs = ansible_service.execute(application, 'Standard', self.vms, env_vars=env_vars)
source = self.set_attributes(task_outputs,source) application = self.set_attributes(task_outputs, application)
if 'Kubernetes' in interface_types: if 'Kubernetes' in interface_types:
task_outputs = ansible_service.execute(nodes_pair, 'Kubernetes', self.vms, env_vars=env_vars) task_outputs = ansible_service.execute(application, 'Kubernetes', self.vms, env_vars=env_vars)
source = self.set_attributes(task_outputs,source) application = self.set_attributes(task_outputs, application)
return application
return source def get_env_vars(self, source):
# target = nodes_pair[0]
def get_env_vars(self, nodes_pair): # source = nodes_pair[1]
target = nodes_pair[0]
source = nodes_pair[1]
env_vars = {'K8s_NAMESPACE': 'default'} env_vars = {'K8s_NAMESPACE': 'default'}
if source.node_template.type == 'tosca.nodes.QC.Container.Application.Docker': if source.node_template.type == 'tosca.nodes.QC.Container.Application.Docker':
env_vars['DOCKER_IMAGE'] = source.node_template.artifacts['image']['file'] env_vars['DOCKER_IMAGE'] = source.node_template.artifacts['image']['file']
env_vars['DOCKER_SERVICE_NAME'] = source.name env_vars['DOCKER_SERVICE_NAME'] = source.name
env_vars['CONTAINER_PORT'] = '80'
if 'ports' in source.node_template.properties:
env_vars['CONTAINER_PORT'] = source.node_template.properties['ports'][0].split(':')[1] env_vars['CONTAINER_PORT'] = source.node_template.properties['ports'][0].split(':')[1]
if 'environment' in source.node_template.properties:
env_vars['DOCKER_ENV_VARIABLES'] = source.node_template.properties['environment']
return env_vars return env_vars
def set_attributes(self, task_outputs,source): def set_attributes(self, task_outputs,source):
...@@ -62,6 +65,8 @@ class DeployService: ...@@ -62,6 +65,8 @@ class DeployService:
source = self.set_kubernetes_attributes(source=source,task_outputs=task_outputs) source = self.set_kubernetes_attributes(source=source,task_outputs=task_outputs)
if source.node_template.type == 'tosca.nodes.QC.Container.Application.Docker': if source.node_template.type == 'tosca.nodes.QC.Container.Application.Docker':
source = self.set_docker_attributes(source=source, task_outputs=task_outputs) source = self.set_docker_attributes(source=source, task_outputs=task_outputs)
if source.node_template.type == 'tosca.nodes.QC.Application.TIC':
source = self.set_tic_attributes(source=source, task_outputs=task_outputs)
# lst = list(nodes_pair) # lst = list(nodes_pair)
# lst[1] = source # lst[1] = source
# nodes_pair = tuple(lst) # nodes_pair = tuple(lst)
...@@ -154,6 +159,9 @@ class DeployService: ...@@ -154,6 +159,9 @@ class DeployService:
attributes['dashboard_url'] = dashboard_url attributes['dashboard_url'] = dashboard_url
logger.info('source.node_template.attributes: ' + str(attributes)) logger.info('source.node_template.attributes: ' + str(attributes))
return source return source
raise Exception(
'Did not find k8s_services and/or k8s_dashboard_token')
return None
def set_docker_attributes(self, source, task_outputs): def set_docker_attributes(self, source, task_outputs):
attributes = source.node_template.attributes attributes = source.node_template.attributes
...@@ -169,3 +177,13 @@ class DeployService: ...@@ -169,3 +177,13 @@ class DeployService:
attributes['service_url'] = service_url attributes['service_url'] = service_url
logger.info('source.node_template.attributes: ' + str(attributes)) logger.info('source.node_template.attributes: ' + str(attributes))
return source return source
def set_tic_attributes(self, source, task_outputs):
attributes = source.node_template.attributes
if 'service_urls' not in source.node_template.attributes:
service_urls = []
attributes['service_urls'] = service_urls
for port in ['8090','9000','9090']:
service_urls.append('http://' + self.master_ip + ':' + str(port))
attributes['service_urls'] = service_urls
return source
...@@ -5,6 +5,8 @@ import urllib.request ...@@ -5,6 +5,8 @@ import urllib.request
from sure_tosca_client import Configuration, ApiClient, NodeTemplate from sure_tosca_client import Configuration, ApiClient, NodeTemplate
from sure_tosca_client.api import default_api from sure_tosca_client.api import default_api
import networkx as nx
import matplotlib.pyplot as plt
class ToscaHelper: class ToscaHelper:
...@@ -38,22 +40,30 @@ class ToscaHelper: ...@@ -38,22 +40,30 @@ class ToscaHelper:
def get_application_nodes(self): def get_application_nodes(self):
return self.tosca_client.get_node_templates(self.doc_id, type_name='tosca.nodes.QC.Application') return self.tosca_client.get_node_templates(self.doc_id, type_name='tosca.nodes.QC.Application')
def get_deployment_node_pairs(self): def get_deployment_node_pipeline(self):
nodes_to_deploy = self.get_application_nodes() nodes_to_deploy = self.get_application_nodes()
nodes_pairs = [] G = nx.DiGraph()
sorted_nodes = []
for node in nodes_to_deploy: for node in nodes_to_deploy:
related_nodes = self.tosca_client.get_related_nodes(self.doc_id,node.name) related_nodes = self.tosca_client.get_related_nodes(self.doc_id,node.name)
for related_node in related_nodes: for related_node in related_nodes:
# We need to deploy the docker orchestrator on the VMs not the topology. G.add_edge(node.name, related_node.name)
# But the topology is directly connected to the orchestrator not the VMs. # # We need to deploy the docker orchestrator on the VMs not the topology.
# So we explicitly get the VMs # # But the topology is directly connected to the orchestrator not the VMs.
# I don't like this solution but I can't think of something better. # # So we explicitly get the VMs
if related_node.node_template.type == 'tosca.nodes.QC.VM.topology': # # I don't like this solution but I can't think of something better.
vms = self.get_vms() # if related_node.node_template.type == 'tosca.nodes.QC.VM.topology':
related_node = vms # vms = self.get_vms()
pair = (related_node, node) # related_node = vms
nodes_pairs.append(pair) # pair = (related_node, node)
return nodes_pairs # nodes_pairs.append(pair)
sorted_graph = sorted(G.in_degree, key=lambda x: x[1], reverse=True)
for node_tuple in sorted_graph:
node_name = node_tuple[0]
for node in nodes_to_deploy:
if node.name == node_name:
sorted_nodes.append(node)
return sorted_nodes
@classmethod @classmethod
def service_is_up(cls, url): def service_is_up(cls, url):
......
...@@ -48,7 +48,7 @@ class TestDeployer(unittest.TestCase): ...@@ -48,7 +48,7 @@ class TestDeployer(unittest.TestCase):
self.assertIsNotNone(tosca_helper.doc_id) self.assertIsNotNone(tosca_helper.doc_id)
nodes_to_deploy = tosca_helper.get_application_nodes() nodes_to_deploy = tosca_helper.get_application_nodes()
self.assertIsNotNone(nodes_to_deploy) self.assertIsNotNone(nodes_to_deploy)
nodes_pairs = tosca_helper.get_deployment_node_pairs() nodes_pairs = tosca_helper.get_deployment_node_pipeline()
self.assertIsNotNone(nodes_pairs) self.assertIsNotNone(nodes_pairs)
username = 'admin' username = 'admin'
......
-----BEGIN CERTIFICATE-----
MIIFRTCCAy2gAwIBAgIUSdwxBIoIhEgH/uLa8RI2rwg/XZ4wDQYJKoZIhvcNAQEL
BQAwMjEOMAwGA1UECgwFcWNkaXMxDjAMBgNVBAsMBXFjZGlzMRAwDgYDVQQDDAd1
bmEubmwvMB4XDTIwMDUxMTE0MDE1NVoXDTIwMDYxMDE0MDE1NVowMjEOMAwGA1UE
CgwFcWNkaXMxDjAMBgNVBAsMBXFjZGlzMRAwDgYDVQQDDAd1bmEubmwvMIICIjAN
BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsvBagSRSfrFgk9EYWXcRZUNnyBTW
h6GrbWYAfdnMvG2Xih//aaeMC+GqYCox207wKpmM0hocTuFxLA6j1qjY81U6TAtu
6OsJamsotT/587ov6/jkeoE0SfOPoFr+SsXWjvc4LBFR6Htm8qPyDxbVTeJbzs13
JnGhbWzoiUJCg3a5TR25mS4Jvem/YhbClARdpC3JgqQTBzq4BBSUKODFYxtQJNgF
62pXI29c3/DWIi/vxXwJeX+gRiaNezAuKRAFu37CdCaOEO0kTL5zj8Elm0AJzkUk
sxpC/NRYOqJmRVUc0qQxqzmNkWC5Zsbx9G6mfuxwNWhEJg1/eEwr5zKEDFl2VrC8
BnUV4Xisd1TQoFfdfgCmngY2O3LQaAy2LMI9J8FNStTZxP55S7QWKGF0wOTjbuDj
l3al5pAIqoQabA7PH1NtAJlQ15+8IudWLpjKrWF/eETj43ymgXfZR1S1Ct2ZTg5j
Yk5D9iCiqjKtt5uAYzKUc2eApTycmQ7jA/r5Ei0Qm1eeCobymeSUvC9SUwdqDwIQ
AB9T1HsAGY3rj56AZnhZPKMv2cY1CZz8TtQk4TrC8vcf92E6pqoD+vbE5gzyfoGW
MbDxAyqQNDiCLjoP4QL7mfAIRJ4SRGaFtIwtgdoalzGry4kojM3eX4YyLgYKcANy
/BLdzW5P1sxRW5cCAwEAAaNTMFEwHQYDVR0OBBYEFKPlVennli4sJhjlohRhtsYp
sJmeMB8GA1UdIwQYMBaAFKPlVennli4sJhjlohRhtsYpsJmeMA8GA1UdEwEB/wQF
MAMBAf8wDQYJKoZIhvcNAQELBQADggIBAKQBBAjdHDhfSLzdeTDyK1hX5KrWNCuV
1b9TiNUb88E0qrlnYVezw+/R3B36KwT9C7svk8HhaQZwnveQLWjs7HuK6CU7AUdJ
kW67bxNyIEH92p8VwIj7fPPEazNkALMUyzIcYWnULsaOZC22GQrIvbTsjH76q1IG
E0toNzja0992xxewI9h/Fk8Oy7v3w26kDRBx5vPCn43XQzhQMCNPdG4w3j/v4BQP
4jqPCHOBKDmAbXygzBQmzp2Zwnq1wVrlEiqERzXEGmcY4Jilt08CClRLhjs2+Rrj
ZHuAQVa8ULY3mgv3sptloeHMCcHEmNU93pDwYdug7/VEJ1rKeczFPOzjKaUDt4lx
uj3Wg3sN9wdCOKu4mCXZZjq7YRGkZtrNB+0XjIQbA/fG/jzvfQZQiGbrvEOjAplP
PY32ssRR+itgZ3UdhW6ALNmoIRbiq+igsCEytXB62eE4RkRkn+IEm7Hf5ub6z4d6
BBG3+BjlvYVyVwvp6aqtMqbfj8wS/147Bv9d4j6FSPbY4PyN8qzWHK4QvMhSmtSj
v8ENzbrhj0FE42FvaOOtLqWnxsXwrJ5oIj3reBKdNcZ07vnPy/GikcrIS1219aOa
dQrdXi4GfWogqNqTGCOOqbEjkLOmjOo6YTuqXkZH+Eg4hqucjf2VJEqUqsV3QKjf
SoaoXQYjAzNj
-----END CERTIFICATE-----
version: '3' version: '3'
services: services:
rabbit: #nginx:
image: rabbitmq:3.8-management #image: nginx
ports: #volumes:
- "5671-5672:5671-5672" #- ./nginx.conf:/etc/nginx/nginx.conf
- "15672:15672" #- ./cert.pem:/etc/nginx/cert.pem
- "4369:4369" #- ./privkey.pem:/etc/nginx/privkey.pem
- "15671:15671" ##- ./www:/data/www
#ports:
#- "80:80"
#- "443:443"
##networks:
##frontend:
##ipv4_address: 172.20.0.2
mongo: #rabbit:
image: mongo:4 #image: rabbitmq:3.8-management
ports: #ports:
- "27017:27017" #- "5671-5672:5671-5672"
#- "15672:15672"
#- "4369:4369"
#- "15671:15671"
##networks:
##frontend:
##ipv4_address: 172.20.0.3
mysql: mysql:
image: mysql:5.6 image: mysql:5.7 #works with 5.6 abd emaphore:2.4.1
environment: environment:
MYSQL_RANDOM_ROOT_PASSWORD: 'yes' MYSQL_RANDOM_ROOT_PASSWORD: 'yes'
MYSQL_DATABASE: semaphore MYSQL_DATABASE: semaphore
MYSQL_USER: semaphore MYSQL_USER: semaphore
MYSQL_PASSWORD: semaphore MYSQL_PASSWORD: semaphore
ports: #ports:
- "3306:3306" #- "3306:3306"
#networks:
#frontend:
#ipv4_address: 172.20.0.4
semaphore: semaphore:
image: qcdis/docker_ansible_semaphore image: ss
environment: environment:
SEMAPHORE_DB_USER: semaphore SEMAPHORE_DB_USER: semaphore
SEMAPHORE_DB_PASS: semaphore SEMAPHORE_DB_PASS: semaphore
...@@ -37,13 +52,57 @@ services: ...@@ -37,13 +52,57 @@ services:
SEMAPHORE_ADMIN_NAME: "Developer" SEMAPHORE_ADMIN_NAME: "Developer"
SEMAPHORE_ADMIN_EMAIL: admin@localhost SEMAPHORE_ADMIN_EMAIL: admin@localhost
SEMAPHORE_ADMIN: admin SEMAPHORE_ADMIN: admin
SEMAPHORE_WEB_ROOT: http://0.0.0.0:3000/semaphore SEMAPHORE_WEB_ROOT: http://0.0.0.0:3000
ports: ports:
- "3000:3000" - "3000:3000"
depends_on: depends_on:
- mysql - mysql
#networks:
#frontend:
#ipv4_address: 172.20.0.5
#mongo:
#image: mongo:4
#ports:
#- "27017:27017"
##networks:
##frontend:
##ipv4_address: 172.20.0.6
#sure-tosca:
#image: qcdis/sure-tosca
#ports:
#- "8081:8081"
##networks:
##frontend:
##ipv4_address: 172.20.0.7
#compute:
#image: ubuntu:18.04
#volumes:
#- "./run.sh:/tmp/run.sh"
#command: "/tmp/run.sh"
##networks:
##frontend:
##ipv4_address: 172.20.0.8
##compute_1:
##image: ubuntu:18.04
##command: "apt update && apt install openssh-server && tail -f /dev/null"
##networks:
##frontend:
##ipv4_address: 172.20.0.9
##networks:
##frontend:
##ipam:
##config:
##- subnet: 172.20.0.0/24
sure-tosca:
image: qcdis/sure-tosca:3.0.0
ports:
- "8081:8081"
...@@ -21,7 +21,9 @@ services: ...@@ -21,7 +21,9 @@ services:
- "15671:15671" - "15671:15671"
mysql: mysql:
image: mysql:5.6 image: mysql:5.7
volumes:
- ./mysql.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf
environment: environment:
MYSQL_RANDOM_ROOT_PASSWORD: 'yes' MYSQL_RANDOM_ROOT_PASSWORD: 'yes'
MYSQL_DATABASE: semaphore MYSQL_DATABASE: semaphore
...@@ -54,18 +56,43 @@ services: ...@@ -54,18 +56,43 @@ services:
ports: ports:
- "27017:27017" - "27017:27017"
mongo-express:
image: mongo-express
environment:
- ME_CONFIG_MONGODB_SERVER=mongo
- ME_CONFIG_MONGODB_PORT=27017
- ME_CONFIG_BASICAUTH_USERNAME=user
- ME_CONFIG_BASICAUTH_PASSWORD=pass
- ME_CONFIG_SITE_BASEURL=/mongo-express
- VCAP_APP_PORT=8082
depends_on:
- mongo
ports:
- "8082:8082"
manager: #mongoclient:
#image: mongoclient/mongoclient
#environment:
#- MONGO_URL=mongodb://mongo:27017
#- ROOT_URL=http://mongoclient/mongoclient
#depends_on:
#- mongo
#ports:
#- "3001:3000"
sdia-orchestrator:
depends_on: depends_on:
- rabbit - rabbit
- mongo - mongo
- sure-tosca - sure-tosca
image: qcdis/manager image: qcdis/sdia-orchestrator
environment: environment:
RABBITMQ_HOST: rabbit RABBITMQ_HOST: rabbit
MONGO_HOST: mongo MONGO_HOST: mongo
SURE_TOSCA_BASE_PATH: http://sure-tosca:8081/tosca-sure/1.0.0 SURE_TOSCA_BASE_PATH: http://sure-tosca:8081/tosca-sure/1.0.0
CREDENTIAL_SECRET: 123 CREDENTIAL_SECRET: top_secret
ports: ports:
- "8080:8080" - "8080:8080"
...@@ -91,7 +118,7 @@ services: ...@@ -91,7 +118,7 @@ services:
RABBITMQ_HOST: rabbit RABBITMQ_HOST: rabbit
SURE_TOSCA_BASE_PATH: http://sure-tosca:8081/tosca-sure/1.0.0 SURE_TOSCA_BASE_PATH: http://sure-tosca:8081/tosca-sure/1.0.0
CLOUD_STORM_SECRET: 456 CLOUD_STORM_SECRET: 456
CREDENTIAL_SECRET: 123 CREDENTIAL_SECRET: top_secret
deployer: deployer:
depends_on: depends_on:
...@@ -103,7 +130,14 @@ services: ...@@ -103,7 +130,14 @@ services:
SURE_TOSCA_BASE_PATH: http://sure-tosca:8081/tosca-sure/1.0.0 SURE_TOSCA_BASE_PATH: http://sure-tosca:8081/tosca-sure/1.0.0
SEMAPHORE_BASE_PATH: http://semaphore:3000/api SEMAPHORE_BASE_PATH: http://semaphore:3000/api
#cadvisor:
#image: gcr.io/google-containers/cadvisor:latest
#ports:
#- 8083:8080
#volumes:
#- /:/rootfs:ro
#- /var/run:/var/run:rw
#- /sys:/sys:ro
#- /var/lib/docker/:/var/lib/docker:ro
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
#log-error = /var/log/mysql/error.log
# By default we only accept connections from localhost
#bind-address = 127.0.0.1
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
max_connections = 2048
...@@ -62,6 +62,7 @@ http { ...@@ -62,6 +62,7 @@ http {
location /manager { location /manager {
add_header 'Access-Control-Allow-Origin' *;
proxy_pass http://manager:8080/manager; proxy_pass http://manager:8080/manager;
proxy_set_header Host $http_host; proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
...@@ -96,5 +97,11 @@ http { ...@@ -96,5 +97,11 @@ http {
proxy_buffering off; proxy_buffering off;
proxy_request_buffering off; proxy_request_buffering off;
} }
location /mongo-express {
proxy_pass http://mongo-express:8082/mongo-express;
proxy_set_header Host $host;
proxy_set_header X-Real_IP $remote_addr;
}
} }
} }
-----BEGIN PRIVATE KEY-----
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
eZ3DUvayu1QuVkGz3Y52NM1CbZmz9g==
-----END PRIVATE KEY-----
#!/bin/bash
apt update -y
apt install openssh-server -y
service ssh start
getent passwd vm_user > /dev/null 2&>1
if [ $? -eq 0 ]; then
echo "user exists"
else
useradd vm_user -s /bin/bash -m
fi
mkdir -p /home/vm_user/.ssh && touch /home/vm_user/.ssh/authorized_keys
echo 'c3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFBZ1FDSUJpNHRYeFZtaXdNL01YWWE5VEZRS1FRMjFIWjg0SnpReFRrai9PcXVoTkwwdVZmeWVHUFN6RUFVRnV5bWMrWk43cUJWRkhtOCtlSkpYd1pGRENoeENuWjBWZHFNS1ZzQkZWK2QxK3ZESXllZ0k4djBSVm42alFXOEV5UnlzTEprckRCdkdLa1UxcDNzNkVQMTEyVExZU3J2UXRYZHVMVHhONTNZMGY3QmV3PT0gZ2VuZXJhdGVkIHVzZXIgYWNjZWVzIGtleXMK' | base64 -d >> /home/vm_user/.ssh/authorized_keys
cat /home/vm_user/.ssh/authorized_keys
tail -f /dev/null
...@@ -198,19 +198,19 @@ ...@@ -198,19 +198,19 @@
"description": "TOSCA example", "description": "TOSCA example",
"imports": [ "imports": [
{ {
"nodes": "https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/types/nodes.yaml" "nodes": "https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/nodes.yaml"
}, },
{ {
"data": "https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/types/data.yml" "data": "https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/data.yml"
}, },
{ {
"capabilities": "https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/types/capabilities.yaml" "capabilities": "https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/capabilities.yaml"
}, },
{ {
"policies": "https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/types/policies.yaml" "policies": "https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/policies.yaml"
}, },
{ {
"interfaces": "https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/types/interfaces.yml" "interfaces": "https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/interfaces.yml"
} }
], ],
"dsl_definitions": null, "dsl_definitions": null,
......
...@@ -4,34 +4,81 @@ ...@@ -4,34 +4,81 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"Upload ExoGeni Credentials from ~/.ssl/user.jks\n" "## Install Prerequisites"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import subprocess\n",
"import sys\n",
"import base64\n",
"import getpass\n",
"import requests\n",
"subprocess.check_call([sys.executable, \"-m\", \"pip\", \"install\", \"pyyaml\"])\n",
"subprocess.check_call([sys.executable, \"-m\", \"pip\", \"install\", \"networkx\"])\n",
"subprocess.check_call([sys.executable, \"-m\", \"pip\", \"install\", \"matplotlib\"])\n",
"subprocess.check_call([sys.executable, \"-m\", \"pip\", \"install\", \"plotly\"])\n",
"import yaml\n",
"import matplotlib\n",
"import plotly.graph_objects as go\n",
"import networkx as nx\n",
"import webbrowser"
] ]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"## Create ExoGeni Credentials " "## Create ExoGeni Credentials \n",
"Upload ExoGeni Credentials from ~/.ssl/user.jks"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 2,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"ename": "FileNotFoundError",
"evalue": "[Errno 2] No such file or directory: 'user.jks'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mFileNotFoundError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-2-a7453877d0f6>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mbase64\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32mwith\u001b[0m \u001b[0mopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"user.jks\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"rb\"\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mimage_file\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0mexoGENI_keystore_as_base64\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mbase64\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mb64encode\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimage_file\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdecode\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"utf-8\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: 'user.jks'"
]
}
],
"source": [ "source": [
"import base64\n",
"with open(\"user.jks\", \"rb\") as image_file:\n", "with open(\"user.jks\", \"rb\") as image_file:\n",
" exoGENI_keystore_as_base64 = base64.b64encode(image_file.read()).decode(\"utf-8\") \n" " exoGENI_keystore_as_base64 = base64.b64encode(image_file.read()).decode(\"utf-8\") \n"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 3,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"ename": "KeyboardInterrupt",
"evalue": "Interrupted by user",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-3-3cdeee16635b>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mgetpass\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mexoGENI_credential_user\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgetpass\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgetpass\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Enter your ExoGENI_credential_user'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m/opt/conda/lib/python3.7/site-packages/ipykernel/kernelbase.py\u001b[0m in \u001b[0;36mgetpass\u001b[0;34m(self, prompt, stream)\u001b[0m\n\u001b[1;32m 844\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_parent_ident\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 845\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_parent_header\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 846\u001b[0;31m \u001b[0mpassword\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 847\u001b[0m )\n\u001b[1;32m 848\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/opt/conda/lib/python3.7/site-packages/ipykernel/kernelbase.py\u001b[0m in \u001b[0;36m_input_request\u001b[0;34m(self, prompt, ident, parent, password)\u001b[0m\n\u001b[1;32m 902\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyboardInterrupt\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 903\u001b[0m \u001b[0;31m# re-raise KeyboardInterrupt, to truncate traceback\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 904\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mKeyboardInterrupt\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Interrupted by user\"\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 905\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mException\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 906\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlog\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwarning\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Invalid Message:\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mexc_info\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mKeyboardInterrupt\u001b[0m: Interrupted by user"
]
}
],
"source": [ "source": [
"import getpass\n",
"exoGENI_credential_user = getpass.getpass('Enter your ExoGENI_credential_user')" "exoGENI_credential_user = getpass.getpass('Enter your ExoGENI_credential_user')"
] ]
}, },
...@@ -53,22 +100,72 @@ ...@@ -53,22 +100,72 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 6,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Enter your aws_access_key_id········\n"
]
}
],
"source": [ "source": [
"aws_access_key_id = getpass.getpass('Enter your aws_access_key_id')" "aws_access_key_id = getpass.getpass('Enter your aws_access_key_id')"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 7,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Enter your aws_secret_access_key········\n"
]
}
],
"source": [ "source": [
"aws_secret_access_key = getpass.getpass('Enter your aws_secret_access_key')" "aws_secret_access_key = getpass.getpass('Enter your aws_secret_access_key')"
] ]
}, },
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Enter your username········\n"
]
}
],
"source": [
"username = getpass.getpass('Enter your username')"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Enter your password········\n"
]
}
],
"source": [
"password = getpass.getpass('Enter your password')"
]
},
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
...@@ -78,13 +175,22 @@ ...@@ -78,13 +175,22 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 19,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"https://lifewatch.lab.uvalight.net:30001/manager\n"
]
}
],
"source": [ "source": [
"base_url = input(\"Enter host base_url \" )\n", "# base_url = input(\"Enter host base_url \" )\n",
"# http://manager:8080\n", "# http://manager:8080\n",
"# http://localhost:30000\n", "# http://localhost:30000\n",
"base_url = 'https://lifewatch.lab.uvalight.net:30001/manager'\n",
"print(base_url)" "print(base_url)"
] ]
}, },
...@@ -97,11 +203,22 @@ ...@@ -97,11 +203,22 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 14,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"ename": "NameError",
"evalue": "name 'exoGENI_keystore_as_base64' is not defined",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-14-97b4be67a8de>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mrequests\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mpath\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"/credential\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mpayload\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'{\"cloud_provider_name\": \"ExoGENI\",\"keys\": {\"keystore\": \"'\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0mexoGENI_keystore_as_base64\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;34m'\"}, \"token\": \"'\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0mexoGENI_credential_token\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;34m'\", \"token_type\": \"password\", \"user\": \"'\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0mexoGENI_credential_user\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;34m'\"}'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m headers = {\n\u001b[1;32m 5\u001b[0m \u001b[0;34m'Content-Type'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m'application/json'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mNameError\u001b[0m: name 'exoGENI_keystore_as_base64' is not defined"
]
}
],
"source": [ "source": [
"import requests\n",
"path = \"/credential\"\n", "path = \"/credential\"\n",
"payload = '{\"cloud_provider_name\": \"ExoGENI\",\"keys\": {\"keystore\": \"'+exoGENI_keystore_as_base64+'\"}, \"token\": \"'+exoGENI_credential_token+'\", \"token_type\": \"password\", \"user\": \"'+exoGENI_credential_user+'\"}'\n", "payload = '{\"cloud_provider_name\": \"ExoGENI\",\"keys\": {\"keystore\": \"'+exoGENI_keystore_as_base64+'\"}, \"token\": \"'+exoGENI_credential_token+'\", \"token_type\": \"password\", \"user\": \"'+exoGENI_credential_user+'\"}'\n",
"headers = {\n", "headers = {\n",
...@@ -115,9 +232,25 @@ ...@@ -115,9 +232,25 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 21,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"5efb35329c8dc53728a46cfc\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/opt/conda/lib/python3.7/site-packages/urllib3/connectionpool.py:986: InsecureRequestWarning: Unverified HTTPS request is being made to host 'lifewatch.lab.uvalight.net'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings\n",
" InsecureRequestWarning,\n"
]
}
],
"source": [ "source": [
"path = \"/credential\"\n", "path = \"/credential\"\n",
"payload = '{ \"cloud_provider_name\": \"EC2\",\"keys\": {\"aws_access_key_id\": \"'+aws_access_key_id+'\"}, \"token_type\": \"access_key\", \"token\": \"'+aws_secret_access_key+'\"}' \n", "payload = '{ \"cloud_provider_name\": \"EC2\",\"keys\": {\"aws_access_key_id\": \"'+aws_access_key_id+'\"}, \"token_type\": \"access_key\", \"token\": \"'+aws_secret_access_key+'\"}' \n",
...@@ -125,7 +258,9 @@ ...@@ -125,7 +258,9 @@
" 'Content-Type': 'application/json',\n", " 'Content-Type': 'application/json',\n",
" 'accept': 'application/json'\n", " 'accept': 'application/json'\n",
"}\n", "}\n",
"response = requests.post(base_url+path, data=payload,headers=headers)\n", "\n",
"\n",
"response = requests.post(base_url+path, data=payload,headers=headers,verify=False, auth=(username, password))\n",
"credential_id = response.text\n", "credential_id = response.text\n",
"print(credential_id)" "print(credential_id)"
] ]
...@@ -139,9 +274,18 @@ ...@@ -139,9 +274,18 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 24,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/opt/conda/lib/python3.7/site-packages/urllib3/connectionpool.py:986: InsecureRequestWarning: Unverified HTTPS request is being made to host 'lifewatch.lab.uvalight.net'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings\n",
" InsecureRequestWarning,\n"
]
}
],
"source": [ "source": [
"path = \"/tosca_template\"\n", "path = \"/tosca_template\"\n",
"payload = {}\n", "payload = {}\n",
...@@ -151,7 +295,7 @@ ...@@ -151,7 +295,7 @@
"\n", "\n",
"headers = {}\n", "headers = {}\n",
"\n", "\n",
"response = requests.request(\"POST\", base_url+path, headers=headers, files = files)\n", "response = requests.request(\"POST\", base_url+path, headers=headers, files = files,verify=False, auth=(username, password))\n",
"tosca_id = response.text\n", "tosca_id = response.text\n",
" " " "
] ]
...@@ -165,19 +309,84 @@ ...@@ -165,19 +309,84 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 29,
"metadata": { "metadata": {
"scrolled": true "scrolled": true
}, },
"outputs": [], "outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tosca_definitions_version: \"tosca_simple_yaml_1_0\"\n",
"topology_template:\n",
" node_templates:\n",
" ws-pema:\n",
" properties:\n",
" ports:\n",
" - \"30001:8080\"\n",
" interfaces:\n",
" Kubernetes:\n",
" delete:\n",
" inputs:\n",
" repository: \"https://github.com/QCAPI-DRIP/playbooks.git\"\n",
" resources:\n",
" - \"k8s/delete_service.yml\"\n",
" create:\n",
" inputs:\n",
" repository: \"https://github.com/QCAPI-DRIP/playbooks.git\"\n",
" resources:\n",
" - \"k8s/create_service.yml\"\n",
" scale:\n",
" inputs:\n",
" repository: \"https://github.com/QCAPI-DRIP/playbooks.git\"\n",
" resources:\n",
" - \"k8s/scale_service.yml\"\n",
" replicas: 1\n",
" autoscale:\n",
" inputs:\n",
" repository: \"https://github.com/QCAPI-DRIP/playbooks.git\"\n",
" resources:\n",
" - \"k8s/autoscale_service.yml\"\n",
" horizontal_pod_autoscaler: \"horizontal_pod_autoscaler.yml\"\n",
" info:\n",
" inputs:\n",
" repository: \"https://github.com/QCAPI-DRIP/playbooks.git\"\n",
" resources:\n",
" - \"k8s/get_info_service.yml\"\n",
" type: \"tosca.nodes.QC.Container.Application.Docker\"\n",
" artifacts:\n",
" image:\n",
" type: \"tosca.artifacts.Deployment.Image.Container.Docker\"\n",
" file: \"alogo53/ws-pema-lifewatch\"\n",
" repository: \"docker_hub\"\n",
"description: \"TOSCA example\\n\"\n",
"imports:\n",
"- nodes: \"https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/nodes.yaml\"\n",
"- data: \"https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/data.yml\"\n",
"- capabilities: \"https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/capabilities.yaml\"\n",
"- policies: \"https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/policies.yaml\"\n",
"- interfaces: \"https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/types/interfaces.yml\"\n",
"repositories:\n",
" docker_hub: \"https://hub.docker.com/\"\n",
"\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/opt/conda/lib/python3.7/site-packages/urllib3/connectionpool.py:986: InsecureRequestWarning: Unverified HTTPS request is being made to host 'lifewatch.lab.uvalight.net'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings\n",
" InsecureRequestWarning,\n"
]
}
],
"source": [ "source": [
"import yaml\n",
"\n",
"path = \"/tosca_template/\"+tosca_id\n", "path = \"/tosca_template/\"+tosca_id\n",
"payload = {}\n", "payload = {}\n",
"headers= {'accept':'text/plain'}\n", "headers= {'accept':'text/plain'}\n",
"\n", "\n",
"response = requests.request(\"GET\", base_url+path, headers=headers, data = payload)\n", "response = requests.request(\"GET\", base_url+path, headers=headers, data = payload,verify=False, auth=(username, password))\n",
"tosca = response.text\n", "tosca = response.text\n",
"print(tosca)" "print(tosca)"
] ]
...@@ -191,13 +400,30 @@ ...@@ -191,13 +400,30 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 38,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/opt/conda/lib/python3.7/site-packages/urllib3/connectionpool.py:986: InsecureRequestWarning: Unverified HTTPS request is being made to host 'lifewatch.lab.uvalight.net'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings\n",
" InsecureRequestWarning,\n"
]
},
{
"data": {
"image/png": "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dlv279+fF198MUNDQ7nvvvuybNmyjI6OZnR0NBse+dHMeNPjo5k+NT6zPTnydtq6FqT1Cz1paZ+Txb/zYJZt+uuf/mzPsm89PvPc1paPP+9bbrklK1euzMsvv5yRkZFs2bIlLtOF/0z44CMajUZ2796dsbGxLFmyJGvXrs3OnTtz9OjRXHHFFXn66afz5JNPZmJiIueee246OzvT2nr6W2nll3syp/1nvzv+93+R5tRExg+9kLF/fSrnrvzVtLS0puvyX8+7u/4kU+99cOnC5InhjL2yP0lyTltr2ts+fvlOnDiRnp6edHV1ZXBwMA899NCnsBrw+SN88BErVqxIV1dX1q5dmyTp6enJ8uXLc9VVV6WtrS0jIyPp6+vL/Pnzc8EFF2ThwoW58847Txvj66uXzDxu65qf1s6uHH7gmxn+/rezYN2GdCxcmiSZ/9Wb0j6/N2/82bfyb3+wPm/+1e9n4p0jSZJmkrkdH//biK1bt+axxx5Ld3d3+vr6cv311/8fVwI+n/zLMpglv/vnz+Rvdv4gw9//dpZseOQTvbalJVm36rz80Y2/NEuzg7oc8cEs2XD1RTnnpyemfFKd7W259eqLPuUZAYnwway5fOm8fGPNsnyC81OSJHM7WrP5ayvzC0vcpQFmg486YZa5OwP8/yJ8cAY8f/hYtu05mN3/8nZakoz/F/fj++pXvpRbr77IkR7MMuGDM+jo6Mk8/k+HM/iTExkZn0hPZ0dW9nbn67/oDuxwpggfAKU4uQWAUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFKED4BShA+AUoQPgFL+HWZOPF1Nbc9sAAAAAElFTkSuQmCC\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [ "source": [
"import networkx as nx\n", "\n",
"import matplotlib\n",
"import plotly.graph_objects as go\n",
"\n", "\n",
"\n", "\n",
"def build_graph(node_templates):\n", "def build_graph(node_templates):\n",
...@@ -226,7 +452,7 @@ ...@@ -226,7 +452,7 @@
" path = \"/tosca_template/\"+tosca_id\n", " path = \"/tosca_template/\"+tosca_id\n",
" payload = {}\n", " payload = {}\n",
" headers= {'accept':'text/plain'}\n", " headers= {'accept':'text/plain'}\n",
" response = requests.request(\"GET\", base_url+path, headers=headers, data = payload)\n", " response = requests.request(\"GET\", base_url+path, headers=headers, data = payload,verify=False, auth=(username, password))\n",
" return response.text\n", " return response.text\n",
"\n", "\n",
"tosca = get_tosca(tosca_id)\n", "tosca = get_tosca(tosca_id)\n",
...@@ -244,23 +470,65 @@ ...@@ -244,23 +470,65 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 39,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/opt/conda/lib/python3.7/site-packages/urllib3/connectionpool.py:986: InsecureRequestWarning: Unverified HTTPS request is being made to host 'lifewatch.lab.uvalight.net'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings\n",
" InsecureRequestWarning,\n"
]
}
],
"source": [ "source": [
"path = \"/planner/plan/\"+tosca_id\n", "path = \"/planner/plan/\"+tosca_id\n",
"payload = {}\n", "payload = {}\n",
"headers= {'accept':'text/plain'}\n", "headers= {'accept':'text/plain'}\n",
"\n", "\n",
"response = requests.request(\"GET\", base_url+path, headers=headers, data = payload)\n", "response = requests.request(\"GET\", base_url+path, headers=headers, data = payload,verify=False, auth=(username, password))\n",
"planed_tosca_id = response.text" "planed_tosca_id = response.text"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 40,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/opt/conda/lib/python3.7/site-packages/urllib3/connectionpool.py:986: InsecureRequestWarning: Unverified HTTPS request is being made to host 'lifewatch.lab.uvalight.net'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings\n",
" InsecureRequestWarning,\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"compute: {'disk_size': '20000 MB', 'mem_size': '1000 MB', 'num_cores': 1, 'os': 'Ubuntu 18.04', 'user_name': 'vm_user'}\n",
"---------------------------------------------------------------------------------------------------------------------\n",
"compute_1: {'disk_size': '20000 MB', 'mem_size': '1000 MB', 'num_cores': 1, 'os': 'Ubuntu 18.04', 'user_name': 'vm_user'}\n",
"---------------------------------------------------------------------------------------------------------------------\n",
"topology: {'domain': 'Frankfurt', 'provider': 'EC2'}\n",
"---------------------------------------------------------------------------------------------------------------------\n",
"ws-pema: {'ports': ['30001:8080']}\n",
"---------------------------------------------------------------------------------------------------------------------\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAb4AAAEuCAYAAADx63eqAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nO3deXxM9/7H8ddkkaQiEooKEVQVoUJU7UERtXRzlajlaiuUlKq2Wurqr6V6VXWxlha1xdaWuk2k1qD2iCAVqpYslgoimcg2yfz+cDvkUkIxk8z7+Xjk8ZjlnDOfOY/qez7f71kMZrPZjIiIiJ1wsHYBIiIi95OCT0RE7IqCT0RE7IqCT0RE7IqCT0RE7IqCT0RE7IqCT0RE7IqCT0RE7IqCT0RE7IqCT0RE7IqCT0RE7IqCT0RE7IqCT0RE7IqCT0RE7IqCT0RE7IqCT0RE7IqCT0RE7IqCT0RE7IqCT0RE7IqCT0RE7IqCT0RE7IqCT0RE7IqTtQsQEZGiJ8WYzYroJOLPpJGWZcLD1YlaD3nQPaAyZd1drF3eTRnMZrPZ2kWIiEjREJuYyrRNR4k6cg6AbFO+5T1XJwfMQOtHyzE4sAb1fTytVOXNKfhERKRQFu44wfjweLJMedwsOQwGcHVyZHSnWvRuUvW+1VdYGuoUEZFbuhJ6h8jMzb/lsmYzZObmMT78EIDNhZ8ObhERkZuKTUxlfHh8oULvWpm5+YwPj2d/UuoN3z9x4gQGgwGTyXQ3yiw0BZ+IiNzUtE1HyTLl3dG6WaY8pm86epcr+nsUfCIixVhiYiLPP/885cqVo2zZsoSGhpKfn8+4cePw9fWlfPny9O3bl0uXLgFXu7C5c+fi4+ODp5cXq8LmkXXqCKe+CSXhsx5c+HmGZfvG/es4s+AtLvw8g4TPXiB51iAyT+y7+vnTXuI/ET9z3pgNwPvvv0/v3r0BaNWqFQCenp64u7uzfft2AObMmUPt2rXx8vIiKCiIkydP3tV9ouATESmm8vLy6NKlC76+vpw4cYLk5GR69uzJvHnzmDdvHhs3buTYsWMYjUZCQ0MLrLtz505+++03+o7+jHM/z+LStmVU6DkO71emkRG/layEA5Zls08dxsmzIj5DF+PZshfnfviIvMx0y/sGYMXepOvq27x5MwCpqakYjUaaNm3KqlWr+Oijj/j+++85d+4cLVu2JDg4+K7uFwWfiEgxtWvXLk6dOsUnn3xCyZIlcXV1pUWLFixatIg33niD6tWr4+7uzoQJE1iyZEmBubYxY8bg6uqKg099DM6ulKzTCseSnjiVehDXyn7knD1mWdaxpCelHn8Gg6MTJWu3wrlMJTJ/3215PyffTPzpdApj5syZvPvuu9SuXRsnJydGjRrFvn377mrXp+ATESmmEhMT8fX1xcmp4AH8p06dwtfX1/Lc19cXk8nE2bNnLa9VqFABgLQsEwbnEjg+cPWcPINzCfJzMi3PHd3LYjAYLM+dPMqTZ7xQ4DPTsnILVfPJkycZNmwYnp6eeHp6UqZMGcxmM8nJyYVavzAUfCIixZSPjw8JCQnXHTXp7e1doINKSEjAycnJEnbX8nC99VlvecbzXHtKuCntHI7uZQBwKOGKOTcbD1dnAM6cOWNZ7tqwvLbmr776itTUVMtfZmYmzZo1u2UdhaXgExEppho3bkzFihV55513yMjIICsri19++YXg4GA+++wzjh8/jtFoZNSoUfTo0eO6zhCg1kMeXB9PBeVlpJK+50fMeSYy4reSez4Rt4cbAeBcvhpZ8Zt5pJwre/bsYcWKFZb1ypUrh4ODA8eOXR02HTRoEBMmTCAuLg6AS5cusXz58r+/M66h4BMRKaYcHR1ZvXo1R48epUqVKlSuXJmlS5fy0ksv0adPH1q1akW1atVwdXVlypQpN9zGPwIq3/JzXLwfxXTxFIlf9iI1aj7lnnsXRzcPADxb9SH34mnefroRY8eOpVevXpb1HnjgAUaPHk3z5s3x9PRkx44dPPfcc4wcOZKePXvi4eFB3bp1iYiIuDs75L90yTIREflL+fn5DFq0l7WHzt7wMmXG/esw7v+Zh3pPvOH6BgME1anAzN6N7nGlhaeOT0READCZTMybN4/XXnuNli1b4uXlhaOjI4HlsnB1cryjbbo6OTK4dY27XOnfo2t1iogIAJcvXyY0NJSMjAzLazVr1qRXUHPMnicLfa3OP7k5OzC6Uy0eq2xbd2lwfP/999+3dhEiImJ9Li4ulChRgnXr1gHg5ubGDz/8gI+PD49V9sTTzZntxy6Qd82YZ4kK1XF/rH2B7RgM4ObsyOhOtW3uAtWgOT4REeHKXN6UKVMYN24c1atXJzo6mjZt2rB27doCy+1PSmX6pqNsPHwOA5B1g/vxtXm0HINb17C5Tu9PCj4RETt3+vRp+vfvT2pqKosWLaJ8+fI89dRTzJo1izp16txwnfPGbFbsTSL+dDppWbl4uDpTq2Ip/tFQd2AXEREb9uOPPzJw4EBCQkJ47733cHZ2tnZJ95wObhERsUOXL19mxIgRREZGsmLFCpo3b27tku4bnc4gImJn9u7dS0BAABkZGcTExNhV6IGCT0TEbuTn5/PJJ5/QsWNH/vWvfzF//nxKly5t7bLuOw11iojYgaSkJPr160dubi67d+8ucHcGe6OOT0SkmPvuu+8ICAjgySefZOPGjXYdeqCOT0Sk2DIajQwbNozNmzezevVqGjdubO2SbII6PhGRYmjnzp34+/tjMBiIiYlR6F1DHZ+ISDGSl5fHhAkTmDJlCtOnT6dbt27WLsnmKPhERIqJkydP0rt3b0qUKEF0dDSVK9/6Xnr2SEOdIiLFQFhYGI8//jjPPPMMa9euVejdhDo+EZEi7NKlSwwZMoTo6GgiIyNp0KCBtUuyeer4RESKqK1bt+Lv74+HhwfR0dEKvUJSxyciUsTk5uby4YcfMnv2bGbNmkXXrl2tXVKRouATESlCfv/9d1588UU8PT2JiYnhoYcesnZJRY6GOkVEigCz2cy8efNo0qQJvXr1Ijw8XKF3h9TxiYjYuAsXLjBo0CDi4+PZsGED9erVs3ZJRZo6PhERG7Zx40b8/f2pVKkSu3btUujdBer4RERsUE5ODv/6179YsGABc+bMISgoyNolFRsKPhERG3P48GF69epF5cqV2bdvH+XKlbN2ScWKhjpFRGyE2Wzmq6++okWLFoSEhLBy5UqF3j2gjk9ExAacO3eOV155hcTERLZs2UKtWrWsXVKxpY5PRMTKfv75Z/z9/alVqxY7duxQ6N1j6vhERKwkKyuLd999lxUrVrBgwQLatm1r7ZLsgoJPRMQKDh48SK9evahZsyaxsbGUKVPG2iXZDQ11iojcR2azmSlTptCmTRuGDx/O8uXLFXr3mTo+EZH75MyZM/Tv358LFy6wfft2atSoYe2S7JI6PhGR++A///kPDRo0oFGjRmzdulWhZ0Xq+ERE7qHLly/z1ltv8dNPP7Fs2TJatmxp7ZLsnjo+EZF7ZN++fTRq1IjU1FRiY2MVejZCwScicpfl5+czadIk2rdvz+jRo1m0aBGlS5e2dlnyXxrqFBG5i5KTk+nXrx9ZWVns2rWLatWqWbsk+R/q+ERE7pLvv/+ehg0bEhgYyKZNmxR6Nkodn4jI32Q0Gnn99dfZtGkTq1atokmTJtYuSW5CHZ+IyN+we/duGjZsSH5+PjExMQq9IkAdn4jIHcjLy+Pf//43X3zxBVOnTqV79+7WLkkKScEnInKbTp48SZ8+fXB0dGTPnj34+PhYuyS5DRrqFBG5DUuWLOHxxx+nS5curFu3TqFXBKnjExEphLS0NEJDQ9m5cycREREEBARYuyS5Q+r4RERuYdu2bfj7+/PAAw+wd+9ehV4Rp45PROQvmEwmxo0bx8yZM/nqq6945plnrF2S3AUKPhGRGzh27BgvvvgiHh4exMTEULFiRWuXJHeJhjpFRK5hNpuZP38+TzzxBD169CAiIkKhV8yo4xMR+a+LFy/y6quvcvDgQdavX89jjz1m7ZLkHlDHJyICREVF4e/vT/ny5dm9e7dCrxhTxycidi0nJ4exY8fy7bff8s033/DUU09ZuyS5xxR8ImK3Dh8+zIsvvkjFihXZt28f5cuXt3ZJch9oqFNE7I7ZbGb27Nm0aNGCl19+mR9//FGhZ0fU8YmIXUlJSWHAgAEcP36cqKgo6tSpY+2S5D5TxycidmPt2rX4+/vz8MMPs3PnToWenVLHJyLFXnZ2NqNGjWLp0qXMmzePdu3aWbsksSIFn4gUa3Fxcbz44otUr16d2NhYypYta+2SxMo01CkixZLZbGbatGm0bt2a0NBQvvvuO4WeAOr4RKQYOnv2LC+99BJ//PEHv/zyCzVr1rR2SWJD1PGJSLESHh5OgwYN8Pf3Z9u2bQo9uY46PhEpFjIzM3nrrbdYvXo1YWFhBAYGWrsksVHq+ESkyIuNjaVRo0akpKQQGxur0JObUvCJSJGVn5/P5MmTadeuHe+88w5hYWF4enpauyyxcRrqFJEi6dSpU/zzn//EaDSyc+dOqlevbu2SpIhQxyciRc7KlStp2LAhzZs3Z/PmzQo9uS3q+ESkyMjIyGD48OGsX7+eH374gaZNm1q7JCmC1PGJSJGwZ88eGjZsSE5ODjExMQo9uWPq+ETEpuXl5fHJJ58wefJkpkyZQo8ePaxdkhRxCj4RsVmJiYn06dMHs9nMnj17qFKlirVLkmJAQ50iYpOWLVtGQEAAHTt2ZMOGDQo9uWvU8YmITUlLS2Po0KFs27aN8PBwGjVqZO2SpJhRxyciNmP79u00aNCAEiVKsHfvXoWe3BPq+ETE6kwmEx999BHTpk1j5syZPPfcc9YuSYoxBZ+IWNXx48fp3bs3DzzwADExMXh7e1u7JCnmNNQpIlZhNptZuHAhjRs3plu3bkRGRir05L5Qxyci911qaiqvvvoqsbGxrF27Fn9/f2uXJHZEHZ+I3FebN2+mfv36lC1blj179ij05L5Txyci90Vubi7vv/8+c+bM4euvv6Zz587WLknslIJPRO653377jRdffJEHH3yQffv2UaFCBWuXJHZMQ50ics+YzWa++eYbmjVrRt++ffnpp58UemJ16vhE5J44f/48ISEhHD16lE2bNuHn52ftkkQAdXwicg+sX78ef39/fH192blzp0JPbIo6PhG5a7Kzs3nvvfcICwtj7ty5tG/f3toliVxHwScid8WhQ4fo1asXvr6+7Nu3jwcffNDaJYnckIY6ReRvMZvNzJgxg1atWjF48GB++OEHhZ7YNHV8InLH/vjjD15++WVOnz7N1q1befTRR61dksgtqeMTkTsSERGBv78/devWZdu2bQo9KTLU8YnIbcnMzGTkyJGsXLmSxYsX07p1a2uXJHJb1PGJSKEdOHCAxo0bc+bMGWJjYxV6UiQp+ETklvLz8/niiy9o27Ytb775JkuXLsXLy8vaZYncEQ11ishNnT59mv79+5OamsqOHTt4+OGHrV2SyN+ijk9E/tKqVato0KABTzzxBFu2bFHoSbGgjk9ErpORkcGIESOIjIzku+++o3nz5tYuSeSuUccnIgXs3buXgIAALl++zL59+xR6Uuwo+EQEuHIAy8SJE+nYsSNjx45l/vz5lC5d2tplidx1GuoUEZKSkujbty8mk4ndu3fj6+tr7ZJE7hl1fCJ2bvny5QQEBPDkk0+yceNGhZ4Ue+r4ROxUeno6w4YNY8uWLaxevZrGjRtbuySR+0Idn4gd2rlzJw0aNMDBwYGYmBiFntgVdXwidiQvL48JEyYwZcoUpk+fTrdu3axdksh9p+ArhBRjNiuik4g/k0ZalgkPVydqPeRB94DKlHV3sXZ5IoVy4sQJ+vTpQ4kSJYiOjqZy5crWLknEKgxms9ls7SJsVWxiKtM2HSXqyDkAsk35lvdcnRwwA60fLcfgwBrU9/G0UpUit7Z48WJef/113n77bd544w0cHDTLIfZLwfcXFu44wfjweLJMedxsDxkM4OrkyOhOtejdpOp9q0+kMC5dusTgwYPZu3cvixcvpkGDBtYuScTq9LPvBq6E3iEyc28eegBmM2Tm5jE+/BALd5y4L/WJFMbWrVupX78+pUuXJjo6WqEn8l/q+P5HbGIqPWfvIDM377bXdXN2ZGlIEx6rrGFPuTvuZH45NzeXDz74gNmzZzN79my6du16n6sWsW0Kvv8RsmAPaw+dvWWndyMGAwTVqcDM3o3ufmFiV+50fvno0aO8+OKLeHl5MW/ePB566KH7XbqIzSsWQ51z584t8Kv2kUceoXv37pbnPj4+xMTEMHz4cMqXL4+Hhwf16tXj4MGDBbaTYswm6sg5Mk/sJ2laPy5tW0biF71Imv4SxriNluXMplwubviGpOn9SfyyN+fXTCU/NxuzGX6KXI93pcpMnDiR8uXLU7FiRVauXEl4eDg1a9akTJkyfPTRR5Zt7dq1i6ZNm+Lp6UnFihUJDQ0lJyfnHu4tsXULd5yg5+wdrD10lmxTfoHQA8j672s//3qWnrN3sHDHCcxmM3PnzqVp06a8+OKLhIeHK/RE/kKxCL7AwEC2bNlCfn4+p06dIicnh+3btwNw7NgxjEYjf/zxB5s3b+bIkSNcunSJZcuWUbZs2QLbWRGdZHmcZ7xIXuYlKg/5lge7DOfCmqnknr/y/sVN88i9kEzF/l9SaeAs8tLPc+mXMAAMwNmzZ8jKyiI5OZkPPviAAQMGsHDhQqKjo9myZQsffvghx48fB8DR0ZHPPvuMlJQUtm/fzvr165k+ffp92Gtii241v3zy4y7kXjwFXJ1fHvfTIVq/8h6fffYZGzZsYOjQoTpqU+QmisW/jurVq1OqVCn27dvH5s2bCQoKwtvbm/j4eKKiomjZsiXOzs6kp6cTHx+P2Wymdu3aVKxYscB24s+kFfh17dmyDwYnZ1yr1MPt4cfJiN+C2WzGGLsGrycH4OhWCgeXByjd7AUyDm0BICcvH4ODE6NHj8bZ2ZmePXuSkpLCsGHDKFWqFH5+ftSpU4fY2FgAAgICaNKkCU5OTlStWpWBAwcSFRV1/3ae3BVVq1Zl3bp1f2sbsYmpjA+PJzM3/9YLXyPLlE9SuSf4ZuU66tWr97dqELEHxeYE9sDAQDZt2sTRo0cJDAzE09OTqKgotm/fTmBgIG3btiU0NJQhQ4Zw8uRJnn/+eSZNmkRqaip16tQBrsyjVBq+HAAHV3ccSrhatu/kUZ484wXyL1/CnJvN6XmvX/PpZsi/+j8rF/fSODo6AuDm5gZAhQoVLO+7ublhNBoBOHLkCG+88QZ79uzh8uXLmEwmAgIC7sk+Ets2bdNRsky3f1AVQL6DI99sS+Dx6uXvclUixU+x6PjgavBt2bKFwMBAAgMDiYqKIioqisDAQACGDh1KdHQ0v/76K0eOHOGTTz6hSpUqGI1GjEYjQ779xbK9/Cwj+TlZluemtHM4upfB4QEPDE4ueL8yjSrDl/73bxlVRqywLGvOzyMr6+q6N/Pqq69Sq1YtfvvtN9LS0vjoo4/Q8UZFS58+fUhISKBr1664u7szceJEfvzxR/z8/PD09KR169YcOnTIsnzVqlWZMGECderUwcvLi/79+5OUcomoI+cwmyF93xqSZw4g8fOe/LHiA0zp52/4uflZGaSs/pTEL3qROK0/K77+knNpmcCVS5ONGDGCBx98kGrVqjF16lQMBgMmk8lyN4ZrTZ48mWeeeebe7SQRG1Ksgm/jxo1kZmZSuXJlWrZsyZo1azh//jwNGjRg9+7d7Ny5k9zcXEqWLImrq+t18yC1HvLAxenqa5e2LsKcl0tW4kEyf99FyVotMBgccK/fgYvrvyYvIxUAU3oKmceiAXDATG5ONuXKlaNTp05MmTIF4C/DLD09HQ8PD9zd3YmPj2fGjBn3YvfIPbRgwQKqVKnC6tWrMRqNPPvsswQHB/P5559z7tw5OnXqRNeuXQsctLRo0SIiIyP5/fffOXLkCAOGjwIg80QsqVHzefDZkVQOXYCTR3lSVk284edeWDuT/OzLVBr0NQ/1+pi0A+sZMf5zAGbPnk1ERAT79u1j7969rFy50rLe008/zfHjxwuE8YIFC+jbt++92D0iNqfYBF/NmjVxd3enZcuWAHh4eFC9enWaN2+Oo6MjaWlpDBgwAC8vL3x9fSlbtixvvfVWgW38I+DqtQsd3b1wcHUnaWo/UlZ/SpmgITiX9QHAq01/nLwqcmb+CBImd+fskvfIvZB8ZT1HR8p5lSYhIYH+/fuzf/9+AFq1asWrr77KqlWryMu7Opw1adIkFi9eTKlSpRgwYAA9evS4p/tJ7r2lS5fSuXNn2rdvj7OzM2+++SaZmZls27bNskxoaCg+Pj6UKVOG0aNHs/3nH8k25ZPx6ybcH2uHy0M1MDg549m6H9mn4jGlni3wGeb8PDIObcGzdT8cXB7AybMCpR5/jg2rvwNg2bJlDBs2jMqVK+Pl5cU777xjWdfFxYUePXqwcOFCAOLi4jhx4gRdunS5D3tHxPqKzRwfwOnTpws837Nnj+Xxk08+aQmhv/KguwuBNcvx47Erz0s360HpZtcHkcGpBF6B/fAK7FfwdQN0DnqSmQtGAtC9e3e6d+/OnDlziIuLY82aNUyZMoWDBw/yzTffkJycTFBQEIcOHcJgMFi288EHH9zW9xbbcurUqQI3c3VwcMDHx4fk5GTLaz4+PpbHvr6+GC+ewxPIM17ApcLDV9ct4YaDWylMxvM4eV6dJ87PTIN8E04eV+f0nEqXJ/3CH5Yarv2Max8D9OvXj+DgYMaNG8eCBQt44YUXcHHRBdfFPhSbju9uGdK6BiX+e2DK7XJ1cmRw6xrXvW4wGKhbty5vvvkm69at48yZM7z55pskJSXRvXt3vL29+ec//8mSJUs4f/7G8zli26794eLt7c3Jkyctz81mM4mJiVSqVMnyWmJiouVxQkIC7l7lAHB0L4Mp7Q/Le/k5WeRnpuPkXvDUGwc3D3BwKrCsKe0cpcpcCcKKFSuSlHT19JxrPw+gSZMmlChRgi1btrB48WL69OlzR99bpChS8P2P+j6e9GlSBcOtFy3AzdmB0Z1qFepyZSVLlqRz585MmTKF3377ja1bt9K4cWMWL15MtWrVeOKJJxg7dizbt2/HZDLd2ReR+6pChQocO3ZlqOCFF17gp59+Yv369eTm5vLpp5/i4uJCs2bNuHDhguUgpvDwcH7//XfGjx9Pk/ZdcHFyoGSdQIz715Fz9hhmUy6pUd/i4v1ogW4PwODgSMnaLUiNmk9+9mVMl/7AuHslbbo8b6nhiy++IDk5mdTUVP79739fV3Pfvn0JDQ3F2dmZFi1a3PudJGIjdMmyv2CtuzNkZ2fzyy+/sGbNGiIjI0lMTKRdu3Z07NiRoKCgAl2D2I5Vq1bx2muvkZaWxnvvvcfDDz/M6NGjSU5Oxt/fn+nTp+Pn58eRI0d49NFHKVGiBLm5uZjNZgwGAzGHfuOFhUfINuWTHhNO2s7vyc8y4lKpNmWChuDk8SBw5QR274GzcPbyJi/LyMW1M8k8theDUwk8G3Tk0OpZlPNww2Qy8dZbbzF//nw8PDwYOnQob7/9Njk5OZbuNCEhgapVqzJmzBj+7//+z5q7T+S+UvDdxP6kVKZvOsrGw+cwcOVE4T/9eb3ENo+WY3DrGvfswtTJycn8/PPPrFmzhnXr1lGpUiWCgoLo2LEjLVq00LxMEXP48GHq1KlD/n/P+3R2dmbIkCGMHTuWDh+u4KxTBQx3cNWVW10nNiIigkGDBhUYgs3MzKR8+fLs3buXRx555M6+kEgRpOArhPPGbFbsTSL+dDppWbl4uDpTq2Ip/tHw/t6BPS8vj927d7NmzRrWrFnDr7/+SmBgoCUIa9S4fn5RrC8xMZGlS5cSFhbG6dOnuXDhAiaTCRcXF958803q1KnD8OHDCXy+LzFegQV+YBXW/94ZJDMzk40bN9KhQwfOnj1Lt27daNKkCZ9//rllncmTJ/Of//yHDRs23LXvKlIUKPiKsPPnz7Nu3TpLEJYsWdIyJNqmTRvc3d2tXaLdSklJYcWKFSxevJi4uDief/55goODCQwMpGrVqiQlJVk6sISEBGbNmkWzZs2uuVZn4cPvyvxy7QJD7ZcvXyYwMJD4+Hjc3Nzo3LkzX3zxBR4eHsCVk+jNZjMrV67UffrE7ij4igmz2cyBAwcsIbh7924aN25Mx44d6dixI3Xr1i1w5KHcfenp6axcuZKwsDC2bdvGU089RXBwMEFBQQWGpE0mE6NGjWLOnDmMGDGCESNGUKJECcv71ppfFrEXCr5iKj09nY0bNxIZGUlERATZ2dmWIdF27dpRpkwZa5dYLGRlZREREUFYWBiRkZG0atWKXr16WS5f9r927dpFSEgI5cqVY8aMGX85PG0L88sixZWCzw6YzWaOHj1qOVJ08+bN+Pn5WbrBRo0aWS6qLbdmMpnYuHEjixcvZtWqVdSvX59evXrRrVu3v/xB8efRnsuXL2fSpEn06tWrUB24rcwvixQnCj47lJWVxdatWy3DomfOnKF9+/YEBQURFBR03e2a5MqPh+3btxMWFsby5cupUqUKwcHBvPDCC7c8xWTlypW89tprdOjQgYkTJ153H0gRub8UfEJSUhKRkZGWUyZ8fX0tB8k0b968wPyTPflz3jQsLIwlS5bg6upKr1696NmzZ6EO/09KSiI0NJT4+Hi++uory11CRMS6FHxSgMlkYteuXZZu8PDhw7Ru3doShNWrV7d2iffcsWPHCAsLIywsjPT0dHr27ElwcDD169cv1PBkXl4e06ZN48MPPyQ0NJR33nlH51uK2BAFn9zUuXPnWLt2LZGRkURGRuLh4WGZGwwMDKRkyZL3vIYUYzYropOIP5NGWpYJD1cnaj3kQfeAuzfPdfr0acu5dsePH6d79+4EBwfTrFmz625fdTMxMTGEhIRQsmRJZs6cSa1ate5KfSJy9yj4pNDy8/OJjY21DItGR0fTpEkTSxDWqVPnrp4yEZuYyrRNR4k6cg6A7Bsc2dj60XIMDqxBfZ/bP7Lx4sWLfEscCOYAABbiSURBVPfdd4SFhbF3716eeeYZgoODefLJJ3Fyur0bl2RkZDB27Fjmz5/Pxx9/TP/+/XX6iIiNUvDJHUtLS2PDhg2WYdG8vLwCp0x4et75Yfb36ly2jIwMVq9ezeLFi4mKiqJ9+/YEBwfTqVMn3Nzc7qjW8PBwBg8eTIsWLZg8eTLly5e/9UoiYjUKPim0qlWr8vXXX9OuXbvr3jObzRw5csQSglu3bqV+/fpkZGTQoEEDvv766wJDhvPnzycnJ4dXXnnlum3drauX/CknJ4fIyEjCwsIIDw+nSZMmBAcH8+yzz1K6dOlCf8b/On36NMOGDWPv3r3MmDGD9u3b3/G2ROT+UfBJod0s+P5XZmYmW7ZsYfjw4Zw9exaDwUCHDh3o2LEjHTp0oGXLlpw4cYK3336bDz/80DIsGJuYSs/ZO8jMzbvFJ1zv2utV5uXlsXnzZsLCwvj++++pVasWhw4dYubMmXTv3v22t32t/Px8Zs2axZgxYwgJCeG99967425RRO6/YnUHdrEdbm5udOjQgccff5zKlSsTEhJCZGQkK1euZMiQIRiNRsxmM59++inJycl8/fXXODo6Mm3TUbJMNw49c34eBoe/PtE+y5TH+B92U+l4BEuXLqV8+fIEBwcTHR2Nr68vVatWxcvL6299r4MHDzJw4EDMZjMbN26kbt26f2t7InL/6Ua0ckcOHTpEtWrVmDBhwnU3MTUYDBw9etTyPCUlhZdffpk33niDlJQUxo4dazm8Pysri3nz5uHq6kqNR2ryn5XfWeb0Uv7zGecjp3F22VgSPu1GVsIBkqa/xKWd33Pqm1ASPnuBcyv/jdmUA4DZDBs3bWLh4iunIbi5udGxY0d8fX3p06cPCQkJlkuJTZw4EYAdO3bQrFkzPD09qV+/Pps2bbLUPW/ePKpXr06pUqWoWrUqTz/9NG3atKFPnz5s3bpVoSdSRCn45Lbt3buXoKAgpkyZUqirvCxatIgxY8aQkpKCv78/kyZNIjc3l2rVquHm5ka3bt2IjIykx8hJnI2YTk5KgmXdjF+jKN2sBz5vLMe1ch0ALsdvofwL/0elQd+Qc+44xgPrAMg58zsX1kzjpfencvHiRQYOHMjTTz9NdnY2CxYsoEqVKqxevRqj0cjbb79NcnIynTt35r333uPChQtMmjSJbt26ce7cOTIyMhg6dCgRERH88MMPV7afk8P+/fsZNGjQbZ3iICK2Rf965bZs2bKFp59+mvnz59OlS5dCrdO5c2datWqFi4sL48eP548//uDw4cNMmDCBgIAAVqxYQdu2bcko5cMDjzbjcvxWy7oP1HgC18p1MBgcMDhduYJMqYCncSpVFke3UjxQozE5Z48BkB67Bnf/jmR7PYyjoyP9+vXDxcWFHTt23LCuhQsX0qlTJzp16oSDgwPt27enUaNGhIeHA1c615CQEF566SWmT5/OmjVrdDk3kWJAc3xyW2bOnElgYCCtW7cu9Do+Pj6Wx+7u7pQpU4aUlBROnjzJzp07Lac9ZObkkWsyUbJuG8vyjh7lrtueo/vVeTqDkwtm4wUATJf+IOPABqb3/4m5A6/MBebk5HDq1Kkb1nXy5EmWL1/O6tWrLa/l5ubSunVrli5disFg4MSJE6SlpTFt2jSqV6+uE9JFigF1fHJbZs6cSUJCAsOHDwegZMmSXL582fL+mTNnrlsnMTHR8thoNHLhwgW8vb3x8fEhMDCQ1NRUUlNTeXXuZqqMWEHZoCFXV76Nk8CdPMpRutkLDJ67xbLNy5cvExwc/N9NFdyWj48Pffr0sSybmprK3r17iYyMZMaMGWzcuJGTJ09y+vRpatWqxYABAwpdi4jYLgWf3JZSpUqxZs0aNm/ezDvvvEP9+vWJi4tj3759ZGVl8f7771+3Tnh4OFu3biUnJ4cxY8bQpEkTfHx86NKlC0eOHGHBggXk5ubyyINumP84Sm5K4vUfXAju9YMwxkTgcvF3zGYzGRkZ/PTTT6SnpwNQoUIFjh07Zlm+d+/erF69msjISC5fvsx7771H48aNadu2LatWrSIhIYGMjAxcXFxwd3fXvJ5IMaF/yXLbPD09Wbt2LRERESxYsIB//etftGvXjkceeeS6IzwBevXqxf/93/9RpkwZoqOjWbhwIXAlRH/++WeWLFmCt7c3Y7o359z6OZjzcu+oLpeKj1Chy1AiZ0/Ay8uLGjVqMG/ePMv77777LuPGjcPT05NJkybh4+PDqlWrGDlyJKVKleKTTz6hUaNG/POf/8RgMDB58mS8vb0pU6YMUVFRzJgx447qEhHbohPYxaaELNjD2kNnb3qZsr9iMEBQnQrM7N2oUMtfuHCBt956i59//pkpU6bw7LPP3v6HikiRo45PbMqQ1jVwdbqzu8G7OjkyuHWNWy5nNptZuHAhderUoWTJksTFxSn0ROyIjuoUm1Lfx5PRnWrd4bU6a/FY5ZtfGPv333/n1Vdf5Y8//uDHH3+kcePGf7dkESli1PGJzendpCqjO9XGzdnxlgd1GgxXrtH5Vxeo/lNOTg4TJkzgiSeeoEOHDuzZs0ehJ2KnNMcnNmt/UirTNx1l4+FzGICsG9yPr82j5RjcusZNO71t27YxcOBAfHx8mD59OlWrVr3ntYuI7VLwic07b8xmxd4k4k+nk5aVi4erM7UqluIfDW9+B/bU1FTeffddVq1axeeff0737t11c1gRUfBJ8WM2m1m+fDnDhw+na9eufPzxx3/rprgiUrzo4BYpVk6cOMGQIUM4ceIEy5Yto3nz5tYuSURsjA5ukWLBZDLx6aef0qhRI5o3b05MTIxCT0RuSB2fFHm7d+8mJCSEsmXLsmPHDmrUuPW5fCJiv9TxSZGVnp7OsGHD6Nq1K2+88QZr165V6InILSn4pEhatWoVfn5+pKenExcXR58+fXTEpogUioY6pUhJSkritdde49dff2X+/Pm3dV9AERFQxydFRF5eHlOmTKFBgwbUr1+f2NhYhZ6I3BF1fGLz9u3bx8CBA3F1dWXLli26C7qI/C3q+MRmZWRk8NZbb9GhQwdCQkLYuHGjQk9E/jYFn9ikiIgI6taty+nTpzl48CAvv/yy7oAuIneFhjrFppw5c4bXX3+d3bt389VXX9GhQwdrlyQixYx+QotNyM/P56uvvqJevXpUq1aNAwcOKPRE5J5QxydWFxcXR0hICGazmQ0bNlCvXj1rlyQixZg6PrGazMxMRo8eTevWrenduzdbt25V6InIPaeOT6xi/fr1DBo0iAYNGhAbG4u3t7e1SxIRO6Hgk/vq3LlzjBgxgs2bNzN16lS6dOli7ZJExM5oqFPuC7PZzNy5c6lbty7lypXj4MGDCj0RsQp1fHLPHT58mEGDBpGenk5ERAQNGza0dkkiYsfU8ck9k52dzQcffEDz5s159tln2blzp0JPRKxOHZ/cE5s3b2bgwIHUrFmTmJgYfHx8rF2SiAig4JO77MKFC7z99ttERkby5Zdf8uyzz+o+eSJiUzTUKXeF2Wxm0aJF+Pn54ebmRlxcHM8995xCT0Rsjjo++dt+//13Bg8ezJkzZ1i5ciVPPPGEtUsSEflL6vjkjuXm5vLxxx/zxBNP0K5dO/bs2aPQExGbp45P7sj27dsJCQmhcuXK7N69m2rVqlm7JBGRQlHwyW1JTU1l1KhRrFy5ksmTJ9OjRw/N44lIkaKhTikUs9nM8uXL8fPzIy8vj7i4OHr27KnQE5EiRx2f3NLJkycZMmQIx48fZ+nSpbRo0cLaJYmI3DF1fPKXTCYTkydPJiAggKZNmxITE6PQE5EiTx2f3FB0dDQhISF4enqyfft2HnnkEWuXJCJyV6jjkwLS09N5/fXX6dy5M8OGDWPdunUKPREpVhR8YvHjjz/i5+fHpUuXOHjwIH379tXBKyJS7GioU0hOTmbo0KEcOHCAb7/9ljZt2li7JBGRe0Ydnx3Ly8tj6tSp+Pv74+fnx/79+xV6IlLsqeOzU7GxsYSEhODi4sLmzZupXbu2tUsSEbkv1PHZmYyMDN5++23at2/PgAED2LRpk0JPROyKgs+OrFmzhnr16pGcnMyBAwd45ZVXcHDQfwIiYl801GkHzpw5w+uvv87u3buZMWMGQUFB1i5JRMRq9HO/GMvPz2fWrFk89thjVK1alQMHDij0RMTuqeMrpn799VdCQkIwmUysW7eOxx57zNoliYjYBHV8xUxWVhZjxowhMDCQXr168csvvyj0RESuoY6vGFm/fj2DBg2ifv36xMbG4u3tbe2SRERsjoKvGEhJSWHEiBFs2rSJqVOn0rVrV2uXJCJiszTUWYSZzWbmzZuHn58fZcuWJS4uTqEnInIL6viKqCNHjjBo0CAuXbpEeHg4AQEB1i5JRKRIUMdXxGRnZ/PBBx/QrFkznn76aXbu3KnQExG5Der4ipAtW7YwcOBAatSowd69e6lSpYq1SxIRKXIUfEXAhQsXGDlyJBEREXzxxRc8//zzuk+eiMgd0lCnDTObzSxevBg/Pz9cXFyIi4ujW7duCj0Rkb9BHZ+NOnbsGIMHD+bUqVP88MMPNGnSxNoliYgUC+r4bExubi7//ve/ady4MW3btiU6OlqhJyJyF6njsyE7duwgJCQEb29vdu3aRfXq1a1dkohIsaPgswGXLl1i1KhRfP/990yePJmePXtqHk9E5B7RUKcVmc1mvvvuO/z8/MjNzSUuLo7g4GCFnojIPaSOz0oSEhIIDQ3l6NGjhIWF0bJlS2uXJCJiF9Tx3Wcmk4nPPvuMhg0b8vjjjxMTE6PQExG5j9Tx3UfR0dGEhIRQunRptm3bRs2aNa1dkoiI3VHHdx8YjUaGDx9Op06dGDp0KOvXr1foiYhYiYLvHlu9ejV+fn5cvHiRuLg4+vXrp4NXRESsSEOd90hycjJDhw7lwIEDzJ07l7Zt21q7JBERQR3fXZeXl8e0adPw9/enTp067N+/X6EnImJD1PHdRfv37yckJAQnJyeioqKoU6eOtUsSEZH/oY7vLrh8+TIjR46kXbt2vPzyy2zevFmhJyJioxR8f1NkZCR169YlISGB/fv3M2DAABwctFtFRGyVhjrv0NmzZxk+fDg7duxg+vTpdOzY0doliYhIIag1uU35+fnMnj2bevXq4ePjw8GDBxV6IiJFiDq+2/Drr78ycOBAcnJyWLt2LfXr17d2SSIicpvU8RVCVlYWY8aMITAwkJ49e7Jt2zaFnohIEaWO7xY2bNjAoEGDqFevHvv27aNSpUrWLklERP4GBd9fSElJ4c0332TDhg1MnTqVp59+2toliYjIXaChzv9hNpv59ttv8fPzw8vLi7i4OIWeiEgxoo7vGr/99huDBg3i4sWLhIeHExAQYO2SRETkLlPHB+Tk5DBu3DiaNm1Kly5d2LVrl0JPRKSYsvuOb+vWrYSEhPDwww8THR2Nr6+vtUsSEZF7yG6D7+LFi4wcOZKffvqJL774gm7duuk+eSIidsDuhjrNZjNLlizBz88PZ2dnfv31V/7xj38o9ERE7IRddXzHjx9n8ODBJCcn891339G0aVNrlyQiIvdZse34jh49yrvvvovZbCY3N5eJEyfy+OOP07p1a6KjoxV6IiJ2qsh0fCnGbFZEJxF/Jo20LBMerk7UesiD7gGVKevuUmBZs9lM37592blzJ6VKlWLp0qU89NBD7Nq1i+rVq1vpG4iIiC0wmM1ms7WLuJnYxFSmbTpK1JFzAGSb8i3vuTo5YAZaP1qOwYE1qO/jCcCSJUt4+eWXuXz5MgaDgVmzZvHyyy9rHk9ERGw7+BbuOMH48HiyTHncrEqDAVydHBndqRZda3tRqVIlMjIyAHBycqJPnz7MmTPnPlUtIiK2zGaHOq+E3iEyc/NvuazZDJm5eYwPP8S33+4iIyMDJycnypQpQ7ly5XB3d78PFYuISFFgkwe3xCamMj48vlChd63M3HyOOV85Af3y5cucPXuWgwcP8uWXX95RHWPGjKFevXo4OTnx/vvv39E2RETEtthk8E3bdJQsU94drfvnHODdmM+rUaMGEydOpHPnzn97WyIiYhvuKPgSExN5/vnnKVeuHGXLliU0NJT8/HzGjRuHr68v5cuXp2/fvly6dAmAEydOYDAYmDt3Lj4+Pnh5eTFz5kx2797NY489hqenJ6GhocCVozd/XL6Y0/Pf4sLPM0j47AWSZw0i88Q+y+cnTX+pwPPULYtIWT0JgDOL3gHA09MTd3d3tm/fDsCcOXOoXbs2Xl5eBAUFcfLkyVt+z379+vHUU09RqlSpO9lNIiJig247+PLy8ujSpQu+vr6cOHGC5ORkevbsybx585g3bx4bN27k2LFjGI1GS5j9aefOnfz2228sXbqU119/nfHjx7Nu3Tri4uJYtmwZUVFRrIhOAiD71GGcPCviM3Qxni17ce6Hj8jLTL9lfQ/1+hiAiT9GYzQaadq0KatWreKjjz7i+++/59y5c7Rs2ZLg4ODb/eoiIlIM3Hbw7dq1i1OnTvHJJ59QsmRJXF1dadGiBYsWLeKNN96gevXquLu7M2HCBJYsWYLJZLKsO2bMGFxdXenQoQMlS5YkODiY8uXLU6lSJVq2bElMTAzxZ9Iw5ZlxLOlJqcefweDoRMnarXAuU4nM33cXus7DZ66G5MyZM3n33XepXbs2Tk5OjBo1in379hWq6xMRkeLltoMvMTERX19fnJwKHhB66tSpAnc28PX1xWQycfbsWctrFSpUsDx2c3O77rnRaCQt60pQOrqXLTBP5+RRnjzjhULXmZaVa3l88uRJhg0bhqenJ56enpQpUwaz2UxycnKhtyciIsXDbQefj48PCQkJBTo5AG9v7wIdVEJCAk5OTgXCrTA8XK8Eap7xPNeeYmhKO4eje5krRZdwxZybbXkvL+Pi1Q38Nyw9XJ0L1PzVV1+Rmppq+cvMzKRZs2a3VZuIiBR9tx18jRs3pmLFirzzzjtkZGSQlZXFL7/8QnBwMJ999hnHjx/HaDQyatQoevTocV1neCu1HvLAydFAXkYq6Xt+xJxnIiN+K7nnE3F7uBEAzuWrkXFoM+Y8E9mnf+Py4W1Xv9ADHmBwoKw51fLaoEGDmDBhAnFxcQBcunSJ5cuX37KW3NxcsrKyyM/Px2QykZWVRV7enR1tKiIituG2g8/R0ZHVq1dz9OhRqlSpQuXKlVm6dCkvvfQSffr0oVWrVlSrVg1XV1emTJly2wX9I6AyAC7ej2K6eIrEL3uRGjWfcs+9i6ObBwCerfpguniaxM97cmnrIkrWCbz6hZxdKdO8B18OC8bT05MdO3bw3HPPMXLkSHr27ImHhwd169YlIiLilrUMGDAANzc3wsLCGD9+PG5ubixYsOC2v5OIiNgOm7xkWeuQseyIWMFDvSfe9roGAwTVqcDM3o3uQWUiIlLU2eQJ7G1rVcDhDs8/d3VyZHDrGne3IBERKTZsMviqlHkAH68HcHO+vfLcnB0Y3akWj1X2LNTyW7Zswd3d/YZ/IiJSPNnkUOef7uTuDL2bVL1v9YmISNFj08EHsD8plembjrLx8DkMQNYN7sfX5tFyDG5do9CdnoiI2C+bD74/nTdms2JvEvGn00nLysXD1ZlaFUvxj4bX34FdRETkrxSZ4BMREbkbbPLgFhERkXtFwSciInZFwSciInZFwSciInZFwSciInZFwSciInZFwSciInZFwSciInZFwSciInZFwSciInZFwSciInZFwSciInZFwSciInZFwSciInZFwSciInZFwSciInZFwSciInZFwSciInZFwSciInZFwSciInZFwSciInbl/wGyQCXpRk2+HQAAAABJRU5ErkJggg==\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [ "source": [
"tosca = get_tosca(planed_tosca_id)\n", "tosca = get_tosca(planed_tosca_id)\n",
"\n", "\n",
...@@ -285,23 +553,59 @@ ...@@ -285,23 +553,59 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 41,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/opt/conda/lib/python3.7/site-packages/urllib3/connectionpool.py:986: InsecureRequestWarning: Unverified HTTPS request is being made to host 'lifewatch.lab.uvalight.net'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings\n",
" InsecureRequestWarning,\n"
]
}
],
"source": [ "source": [
"path = \"/provisioner/provision/\"+planed_tosca_id\n", "path = \"/provisioner/provision/\"+planed_tosca_id\n",
"payload = {}\n", "payload = {}\n",
"headers= {'accept':'text/plain'}\n", "headers= {'accept':'text/plain'}\n",
"\n", "\n",
"response = requests.request(\"GET\", base_url+path, headers=headers, data = payload)\n", "response = requests.request(\"GET\", base_url+path, headers=headers, data = payload,verify=False, auth=(username, password))\n",
"provisioned_tosca_id = response.text" "provisioned_tosca_id = response.text"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 42,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/opt/conda/lib/python3.7/site-packages/urllib3/connectionpool.py:986: InsecureRequestWarning: Unverified HTTPS request is being made to host 'lifewatch.lab.uvalight.net'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings\n",
" InsecureRequestWarning,\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"compute: 3.120.209.252\n",
"compute_1: 3.126.139.56\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAb4AAAEuCAYAAADx63eqAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nO3deVSUhf7H8fcMICBII+4KooZrbqmZWgqu3NT06s891HIp11xKW8zAvdSyum6VoTeX61apXJdMc8vUTFPRJEVld8EFBWQbZn5/eKMoyw0cYD6vczyHYZ7nmc/M0fn4nXkWg9VqtSIiImInjLYOICIi8jCp+ERExK6o+ERExK6o+ERExK6o+ERExK6o+ERExK6o+ERExK6o+ERExK6o+ERExK6o+ERExK6o+ERExK6o+ERExK6o+ERExK6o+ERExK6o+ERExK6o+ERExK6o+ERExK6o+ERExK6o+ERExK6o+ERExK6o+ERExK6o+ERExK442jqASGF2OTmdtYdiCb9wgxtpZjxcHKlR1oPuDb0o4e5s63gidslgtVqttg4hUtgcjUlk3s4Idp1KACDdbMm+z8XRiBXwr16KYX6+1PM22SiliH1S8YnksmX7I5m2KZw0cxZ/96/LYAAXRwcmtK9BYJNKDy2fiL3TR50iuehW6Z0kNdNyx2WtVkjNzGLappMAKj+Rh0Q7t4jkkqMxiUzbFH5Xpfd7qZkWpm0K51hsYh4lE5HfU/GJ5JJ5OyNIM2fd17pp5izm74zI5UQicjsqPrFrixcv5tlnn82+XbVqVbp3755929vbm59++okxY8ZQunRpPDw8qFOnDsePH8+xncvJ6ew6lUBq5DFi5/Xn+verifmwD7HzB5B8Ykf2clZzJte+/YzY+S8Q81EgV7bMxZKZjtUKG7/eTvkKXsycOZPSpUtTrlw51q1bx6ZNm6hWrRqenp5Mnz49e1s//PADTZs2xWQyUa5cOUaMGEFGRkYevloihYOKT+yan58fe/bswWKxEB8fT0ZGBvv27QPg7NmzJCcnc+nSJXbv3s2pU6e4fv06q1evpkSJEjm2s/ZQbPbPWcnXyEq9jtfwf1Oy4xiubplL5pVb91/buYTMq3GUe+EjKrz0CVlJV7i+9z8AGICLFy+QlpZGXFwckydPZvDgwSxbtoxDhw6xZ88epkyZwrlz5wBwcHBgzpw5XL58mX379rF9+3bmz5//EF41kYJNxSd2rUqVKhQrVowjR46we/duAgICKF++POHh4ezatYvmzZvj5OREUlIS4eHhWK1WatasSbly5XJsJ/zCjRyHLJia98Xg6IRLxTq4PvoEKeF7sFqtJB/dQvHWg3FwLYbRuSiPNOtBysk9AGRkWTAYHZkwYQJOTk706tWLy5cvM2rUKIoVK8Zjjz1GrVq1OHr0KAANGzakSZMmODo6UqlSJV566SV27dr18F48kQJKe3WK3fPz82Pnzp1ERETg5+eHyWRi165d7Nu3Dz8/P1q1asWIESMYPnw4UVFRdO3aldmzZ5OYmEitWrWAW8fpVRizBgCjizvGIi7Z23f0KE1W8lUsN69jzUzn/JLRv3t0K1h+K0xn90dwcHAAwNXVFYAyZcpk3+/q6kpycjIAp06dYuzYsfz444/cvHkTs9lMw4YN8+Q1EilMNPGJ3fu1+Pbs2YOfnx9+fn7s2rWLXbt24efnB8DLL7/MoUOH+Pnnnzl16hSzZs2iYsWKJCcnk5yczPB/783eniUtGUtGWvZt840EHNw9MRb1wODoTPlB86g4ZtX//qym4itrs5c1Gu4+99ChQ6lRowanT5/mxo0bTJ8+HR2WK3JnKj6xe35+fuzYsYPU1FS8vLxo3rw5W7Zs4cqVKzz++OMcPHiQAwcOkJmZiZubGy4uLhiNOf/p1CjrgbPjb7+7/t1yrFmZpMUcJ/XMD7jVeBqDwYh7vXZc276IrJRbhy6Yky6TevYQAEUcjDg63H3zJSUl4eHhgbu7O+Hh4SxYsCAXXg2Rwk/FJ3avWrVquLu707x5cwA8PDyoUqUKTz31FA4ODty4cYPBgwdTvHhxfHx8KFGiBOPGjcuxjW4NvbJ/dnAvjtHFndi5/bkc+h6eAcNxKuENQPGWL+BYvBwXPn+F6Pe7c3HlW2RejQPACrg63f23D7Nnz2bFihUUK1aMwYMH07Nnzwd8JUTsg05ZJpJLXlz6Ixu2fMPl0PfwGv7ve1rXYICAWmVYGNgoj9KJyK808YnkkuH+vhT5344p98rF0YFh/r65nEhEbkfFJ5JL6nmb6NukIvewfwoArk5GJrSvQV0vXaVB5GHQR50iueyur84AuDjp6gwiD5uKTyQPHItNZP7OCHb8koABSPvD9fgyMjOp6JjER0M6aNITechUfCJ56EpyOmsPxxJ+PokbaZl4uDhRo1wx6ril0LVDOyIjI3FxcbnzhkQk16j4RGykQ4cOdO7cmRdffNHWUUTsiopPxEZ27tzJSy+9xMmTJ/90QLyI5B39axOxET8/Pzw8PNiwYYOto4jYFRWfiI0YDAbGjx/PrFmzbB1FxK6o+ERsqGvXrly4cIG9e/feeWERyRUqPhEbcnBwYOzYsZr6RB4i7dwiYmM3b96kUqVK7Nmzh+rVq9s6jkihp4lPxMaKFi3K0KFDee+992wdRcQuaOITyQcSEhKoVq0a4eHhOa64LiK5TxOfSD5QqlQpevXqxb/+9S9bRxEp9DTxieQTERERNG3alHPnzuHu7m7rOCKFliY+kXzC19cXPz8/QkJCbB1FpFDTxCeSjxw4cICePXsSERGBo6OjreOI/KXLyemsPRRL+IUb3Egz4+HiSI2yHnRv6EUJd2dbx/tbKj6RfKZFixYMHTqU3r172zqKyJ8cjUlk3s4Idp1KACD9D5fcsgL+1UsxzM+Xet7585JbKj6RfCY0NJSgoCAOHTqEwXCv13MXyTt3fZFlA7g45t+LLOs7PpF8pkOHDqSmpvLtt9/aOopItluld5LUzL8vPQCrFVIzs5i26STL9kc+lHz3QsUnks8YjUZeffVVncZM8o2jMYlM2xROaqblzgv/TmqmhaAVuzAYDJjN5gfOMXHiROrUqYOjoyPBwcH3vR0Vn0g+FBgYyLFjxzh27Jito4gwb2cEaeas+1o3/T7Xux1fX19mzpxJhw4dHmg7Kj6RfMjZ2ZmXX36Z2bNn2zqKFAAxMTF07dqVUqVKUaJECUaMGIHFYmHq1Kn4+PhQunRp+vXrx/Xr1wGIjIzEYDCwePFivL29KV68OAsXLuTgwYPUrVsXk8nEiBEjgFt7b25Ys4Lzn4/j6tYFRM/pQdwnQ0iNPJL9+LHzB+S4nbhnOZdDb/3dvbD8dQBMJhPu7u7s27cPgJCQEGrWrEnx4sUJCAggKirqjs+zf//+PPPMMxQrVuyBXi8Vn0g+NWTIEP773/8SExNj6yiSj2VlZdGxY0d8fHyIjIwkLi6OXr16sWTJEpYsWcKOHTs4e/YsycnJ2WX2qwMHDnD69GlWrVrF6NGjmTZtGtu2bePEiROsXr2aXbt2sfZQLADp8b/gaCqH98srMDXvQ8JX08lKTbpjvrJ93gFg5oZDJCcn07RpU9avX8/06dP58ssvSUhIoHnz5g91L2YVn0g+ZTKZeP755/nggw9sHUXysR9++IH4+HhmzZqFm5sbLi4uPP300yxfvpyxY8dSpUoV3N3dmTFjBitXrszxXdvEiRNxcXGhXbt2uLm50bt3b0qXLk2FChVo3rw5P/30E+EXbmDOsuLgZqLYE50xODjiVrMFTp4VSD1z8K5z/nLht5JcuHAhb7zxBjVr1sTR0ZE333yTI0eO3NXUlxtUfCL52OjRo1m8eDGJiYm2jiL5VExMDD4+Pn864UF8fDw+Pj7Zt318fDCbzVy8eDH7d78/Ibqrq+ufbicnJ3Mj7VZROriXyHF4jaNHabKSr951zhtpmdk/R0VFMWrUKEwmEyaTCU9PT6xWK3FxcXe9vQeh4hPJxypWrEj79u35+OOPbR1F8ilvb2+io6P/tNdk+fLlc0xQ0dHRODo63vPVPzxcbhVqVvIVfn/Yt/lGAg7ungAYi7hgzUzPvi8r5dpvG/hfWXq4OOXI/PHHH5OYmJj9JzU1lWbNmt1Ttvul4hPJ58aNG8dHH31Eenr6nRcWu9O4cWPKlSvH66+/TkpKCmlpaezdu5fevXszZ84czp07R3JyMm+++SY9e/a851Ph1SjrgaODgayURJJ+3IA1y0xK+HdkXonB9dFGADiVrkzKyd1Ys8yknz/NzV++z17fWNQDDEZKWH/71GLIkCHMmDGDEydOAHD9+nXWrFlzxyyZmZmkpaVhsVgwm82kpaWRlXXve42q+ETyuXr16lG7dm1WrFhh6yiSDzk4OBAaGkpERAQVK1bEy8uLVatWMWDAAPr27UuLFi2oXLkyLi4u93XZq24NvQBwLl8d87V4Yj7qQ+KuzynV5Q0cXD0AMLXoi/naeWI+6MX175bjVssve32jkwueT/Xko1G9MZlM7N+/ny5duvDaa6/Rq1cvPDw8qF27Nps3b75jlsGDB+Pq6sp//vMfpk2bhqurK0uXLr3n56RTlokUANu2bWPUqFGEhYVhNOr/q5J3bt68SUxMDDExMZw6dYoffviByCI+7N+8lrKBM+95ewYDBNQqw8LARnmQ9v7o9O8iBUDr1q0pUqQImzdvfuCDd0X+ytatWwkICMDd3R2r1UpKSgqPPPIIY9+exg9b7m+bLo4ODPP3zd2gD0j/dRQpAAwGA+PGjWPmzHv/H7fI3WrRogUVKlQgOTmZlJQUnJ2dCQ0NpaKnG97Fi+LqdG+V4epkZEL7GtT1ururNOzZswd3d/fb/slN+qhTpIDIzMzE19eXNWvW0LhxY1vHkUJo/fr1DBo0iMTERKxWKx06dGD9+vXZ9xeWqzM4BD/ImT5F5KFxcHDAYDCwcuVKevToYes4UogkJCQwaNAglixZwrJlyyhSpAhHjhzh66+/5pFHHslerq6XiRZVS3ItJYOYa6k4GQ2YLb81oIujEQejgTY1SzPz/+rStlZZWzydO9LEJ1KAJCcnU7lyZfbv38+jjz5q6zhSwFmt1uzTlQUGBjJ58mSKFi1KWloaJ0+e5PHHH//Lda8kp7P2cCzh55O4kZaJh4sTNcoVo1sDXYFdRHLZhAkTSExMZN68ebaOIgVYfHw8w4YN4/Tp04SEhPDkk0/aOtJDo51bRAqYkSNH8p///IfLly/bOooUQFarlcWLF1O/fn3q1KnD4cOH7ar0QBOfSIE0ePBgvLy8CAoKsnUUKUCioqJ48cUXSUhIICQkhPr169s6kk1o4hMpgF555RXmzZvHzZs3bR1FCgCLxcL8+fNp2LAh/v7+HDhwwG5LDzTxiRRYnTt3JiAggGHDhtk6iuRjp0+fZtCgQWRkZGRf/NXeaeITKaDGjRvH+++/f18n6ZXCLysri/fee4+mTZvSpUsXvvvuO5Xe/+iUZSIF1FNPPUXp0qX56quv6Natm63jSD5y4sQJBgwYQNGiRTlw4IAOffkDTXwiBdSvpzGbNWsW+sZC4NbZfaZOnYq/vz8DBgxg+/btKr3bUPGJFGCdOnXi2rVr7Nmzx9ZRxMYOHz7ME088wffff8/hw4d56aWXdCWPv6BXRaQAc3Bw4JVXXmHWrFm2jiI2kpaWxptvvsk//vEPxo4dy8aNG/H29rZ1rHxNxSdSwPXr14+DBw/y888/2zqKPGT79u3j8ccfJzw8nGPHjtGvXz8MBoOtY+V7Kj6RAs7V1ZXhw4cze/ZsW0eRhyQlJYUxY8bQtWtXJk+ezBdffEHZsvnzhND5kYpPpBAYNmwYX331FfHx8baOInlsx44d1K1bl4SEBMLCwujevbumvHukA9hFComXX36ZokWL8s4779g6iuSBGzduMH78eDZu3MiCBQvo2LGjrSMVWJr4RAqJMWPGsGjRIpKSkmwdRXLZ5s2bqV27NllZWYSFhan0HpAmPpFCpFevXjRu3JixY8faOorkgqtXrzJmzBh2797Np59+Sps2bWwdqVDQxCdSiIwbN44PPviAzMxMW0eRB/Tll19Su3ZtTCYTYWFhKr1cpFOWiRQiDRs2xNfXl1WrVhEYGGjrOHIfLl68yMiRIzl69Chr1qzhqaeesnWkQkcTn0ghM27cOGbOnKnTmBUwVquV5cuXU7duXapUqcKRI0dUenlE3/GJFDJWq5W6desye/ZsAgICbB1H7kJcXBxDhgwhKiqKkJAQGjVqZOtIhZomPpFCxmAw8Oqrr+o0ZgWA1Wpl0aJF1K9fn0aNGvHjjz+q9B4CTXwihVBGRgZVqlRhw4YNNGjQwNZx5DbOnTvH4MGDuX79OiEhIdSpU8fWkeyGJj6RQqhIkSKMHj1apzHLhywWCx999BFPPPEE7dq1Y9++fSq9h0wTn0ghdePGDSpXrszhw4fx8fGxdRwBfvnlFwYOHAjAZ599RvXq1W2cyD5p4hMppDw8PBg4cCBz5syxdRS7Zzabeffdd3nqqafo1asXu3fvVunZkCY+kUIsLi6OOnXqEBERgaenp63j2KVjx44xYMAATCYTn376KZUrV7Z1JLuniU+kEKtQoQKdOnViwYIFto5idzIyMggODqZ169YMHTqUb775RqWXT2jiEynkjh8/Ttu2bTl37hwuLi62jmMXDh48yIABA6hUqRILFy6kQoUKto4kv6OJT6SQq127Ng0aNGDp0qW2jlLopaamMn78eDp27Mgbb7zBhg0bVHr5kIpPxA6MGzeO9957D4vFYusohdZ3331HvXr1iIqKIiwsjD59+ugCsfmUik/EDvj5+VGsWDFCQ0NtHaXQSU5OZuTIkfTs2ZN3332XVatWUbp0aVvHkr+h4hOxAwaDgXHjxuk0Zrls27Zt1KlTh6SkJMLCwujSpYutI8ld0M4tInbCbDZTrVo1li1bRrNmzWwdp0BLTEzk1Vdf5ZtvvmHhwoU888wzto4k90ATn4idcHR0ZOzYsZr6HlBoaCi1a9fGycmJsLAwlV4BpIlPxI6kpKRQuXJlvvvuO6pVq2brOAXK5cuXGTVqFAcOHGDRokX4+/vbOpLcJ018InbEzc2NIUOG8N5779k6SoFhtVpZvXo1derUoUyZMhw9elSlV8Bp4hOxM5cuXaJ69eqEh4dTpkwZW8fJ186fP8/w4cMJDw8nJCSEJk2a2DqS5AJNfCJ2pnTp0vTq1Yu5c+faOkq+ZbVa+fe//029evWoVasWP/30k0qvENHEJ2KHTp8+TbNmzYiMjMTNzc3WcfKV6OhoXnrpJS5cuEBISAiPP/64rSNJLtPEJ2KHqlatSosWLQgJCbF1lHzDYrGwcOFCGjZsyNNPP80PP/yg0iukNPGJ2Kn9+/fTu3dvTp8+jaOjo63j2FRERASDBg0iLS2NkJAQatWqZetIkoc08YnYqSZNmuDl5cXatWttHcVmsrKymDNnDk2aNKFTp07s3btXpWcHNPGJ2LENGzYwadIkfvzxR7s7ofLPP//MwIEDcXZ2ZtGiRfj6+to6kjwkmvhE7FjHjh25efMmO3bssHWUhyYzM5Pp06fj5+dH//79+fbbb1V6dsa+P9gXsXNGo5FXX32VWbNm0apVK1vHyXNHjhzhhRdeoEyZMhw6dIiKFSvaOpLYgCY+ETsXGBjI0aNHCQsLs3WUPJOens5bb71Fu3btGD16NJs3b1bp2TEVn4idc3Z2ZuTIkcyePdvWUfLEgQMHaNCgASdOnODo0aP079/f7r7PlJy0c4uIcO3aNR599FGOHTuGl5eXrePkips3bzJx4kRWrFjBhx9+SPfu3VV4AmjiExGgePHi9O/fnw8++MDWUXLFrl27qFu3LhcuXCAsLIwePXqo9CSbJj4RASAqKoq6devSuXNnvvzyS86ePUvp0qVtHeueJCUl8dprr7Fhwwbmz59Pp06dbB1J8iFNfCJCZGQkw4cPJyUlheXLl5OZmUlWVpatY92Tr7/+mtq1a5ORkcHx48dVevKXdDiDiHD27Fm+/vrrHGXn6upqw0R379q1a4wdO5YdO3awaNEi2rZta+tIks9p4hMRWrVqxb59+yhRogRw6yDvglB869ato3bt2ri7u3P8+HGVntwVfccnItkuXrzIU089xZkzZ7BYLPl2h5CEhARGjhzJ4cOH+eyzz2jevLmtI0kBoo86RSRbmTJlOHHiBHPmzMFgMHA5OZ21h2IJv3CDG2lmPFwcqVHWg+4NvSjh7vzQ81mtVlauXMmYMWPo168fixcvLhCTqeQvmvhE5E+OxiQyb2cEu04lAJButmTf5+JoxAr4Vy/FMD9f6nmbHkqm+Ph4hg4dytmzZwkJCeGJJ554KI8rhY++4xORHJbtj6TXp/v55uRF0s2WHKUHkPa/3239+SK9Pt3Psv2ReZrHarXy2WefUb9+fR5//HEOHTqk0pMHoo86RQqASpUqsWjRItq0aXPX6zz//PN4eXkxderUu15n2f5Ipm06SWqm5Y7LWq2QmpnFtE0nAQhsUumuH+duRUZGMnjwYK5du8a2bduoW7durj+G2B9NfCIC3Pp4c9qm8Lsqvd9LzbQwbVM4x2IT/3KZSpUqsW3btrvepsViYe7cuTRq1Ig2bdqwf/9+lZ7kGk18IgLAvJ0RpJlvf9C61ZKFwejwl+ummbOYvzOChYGNHjjHqVOnGDhwIBaLhb1791K9evUH3qbI72niEylgTp48SeXKlZkxYwZPP/10jvsMBgMRERHZty9fvkzbtm0pVqwYfn5+REVFZd8XHh5O27Zt8fT0xLdqNf677gt+3dXt8n/ncOXreVxcHUT0e/9HWnQYsfMHcP3Al8R/NoLoOT1IWPcuVnMGcOtjz9D//pc6dethMplo1qwZx44dA6Bv375ER0fz7LPP4u7uzsyZMwHYv38/zZo1w2QyUa9ePbZv386sWbNo1qwZFStW5Pz58zRq1IjKlSuzfPnyvHxJxc6o+EQKkMOHDxMQEMC//vUvypUrd8flly9fzsSJE7l8+TL169fnueeeAyAlJYW2bdvSp08fLl26RM/XZnNx83wyLkdnr5vy8y4eadYT77FrcPGqBcDN8D2U7jGJCkM+IyPhHMlhtz6+zLhwhouhH9Bh2NtcuXKFl156iU6dOpGens7SpUupWLEioaGhJCcnM378eOLi4ujQoQNvvfUWV69eZfjw4QQEBLBhwwZ27txJaGgomzdvJikpie+//5769evnwasp9krFJ1JA7Nmzh06dOvH555/TsWPHu1qnQ4cOtGjRAmdnZ6ZNm8a+ffuIiYnhv//9L5UqVeKFF17A0dGRlGLeFK3ejJvh32WvW9T3SVy8amEwGDE4FgGgWMNOOBYrgYNrMYr6Nibj4lkAko5uwb3+P0gv/igODg70798fZ2dn9u/ff9tcy5Yto3379rRp04apU6cyYcIEqlevzsCBA6lcuTJGo5Hjx4+TmppKuXLleOyxxx7w1RP5jYpPpIBYuHAhzZo1w9/f/67X8fb2zv7Z3d0dT09P4uPjiYqK4sCBA5hMJkwmEwteaEHKiZ1kpVzLXt7Bo9SftufgXjz7Z4OjM9bMNADM1y9x44d1zH+hefY2Y2JiiI+Pv22uqKgoVq9ejaurK1OmTCEjI4PIyEguXLiAm5sbq1atYuHChZQrV44OHToQHh5+189Z5E5UfCIFxMKFC4mOjmbMmDEAuLm5cfPmzez7L1y48Kd1YmJisn9OTk7m6tWrlC9fHm9vb/z8/EhMTCQxMZGhi3dT8ZW1lAgY/tvK93C6MkePUjzSrAfDFu/J3ubNmzfp3bv3/zb127bS0tI4ceIERqORzz//nIyMDK5fv05KSgqvv/46AAEBAXzzzTecP3+eGjVqMHjw4LvOInInKj6RAqJYsWJs2bKF3bt38/rrr1OvXj1OnDjBkSNHSEtLIzg4+E/rbNq0ie+++46MjAwmTpxIkyZN8Pb2pmPHjpw6dYqlS5eSmZlJ1ZKuWC9FkHk55s8PfBfc6wWQ/NNmnK+dwWq1kpKSwsaNG0lKSgJunQrt7Nmz7N27l/r16+Pu7k6xYsUoWbIkFouFtLQ0du7cSWxsLBcvXmT9+vWkpKTg7OyMu7s7RqPeqiT36G+TSAFiMpn45ptv2Lx5M0uXLuXtt9+mTZs2VK1a9U97eAL06dOHSZMm4enpyaFDh1i2bBlwq0S3bt3KypUrKV++PBO7P0XC9hCsWZn3lcu5XFXKdHyZrz+dQfHixfH19WXJkiXZ948ZM4ZXXnmF5s2b07hxYzZu3EhoaCjTp0+nVKlSeHt7M2vWLCwWCxaLhffff5/y5cvj6enJrl27WLBgwX3lErkdnatTRAB4cemPfPPzRe7nDcFggIBaZW57HN/27dsZPHgwzZs3Z86cOXh6ej54WJEHoAPYRQSAvg1KszUsBhyK3PO6Lo4ODPP3zfG769evM27cOLZs2cLChQtp3759bkUVeSD6qFNEuHr1KqP6/pMGhkhcne7tbcHVyciE9jWo6/XbVRo2btxI7dq1sw9LUOlJfqKJT8TOXblyhTZt2tCuXTveeWc0yw9EMW1TOGnmLP7uixCD4dakN6F9jewTVF+5coXRo0fz/fff8/nnn9OyZcuH8yRE7oEmPhE79mvpBQQE8M4772AwGAhsUolVLzYhoFYZnB2NuDjmfJtwcTTi7GgkoFYZVr3YJLv01q5dS506dShZsiTHjh1T6Um+pZ1bROzU5cuXadOmDc888wzTp0/Pcazdr64kp7P2cCzh55O4kZaJh4sTNcoVo1uD367AfuHCBYYPH87PP/9MSEgITZs2fdhPReSeqPhE7NDly5dp3bo1HTp0YNq0abctvTuxWq0sXbqUcePGMWjQICZOnIiLi0sepBXJXfqOT8TOJCQk0Lp1a5599lmmTp16X6UXExPDSy+9RHx8PJs3b6ZBgwZ5kFQkb+g7PhE78mvpderU6b5Kz2Kx8PHHH9OgQQOaNWvGwYMHVXpS4GjiE7ETly5donXr1vzzn/9k8uTJ91x6Z86cYfDgwaSkpLBz505dMUEKLE18Inbg0qVLtGrVii5dutxz6a8R+70AABkhSURBVGVlZfHBBx/w5JNP0qFDB77//nuVnhRomvhECrmLFy/SqlUrunXrRnBw8D2V3smTJxk4cCBOTk7s27ePqlWr5mFSkYdDE59IIfZr6XXv3p1JkybddellZmYyY8YMWrRoQWBgIDt27FDpSaGhiU+kkLpw4QKtWrWiR48et71k0V85cuQIAwYMoFSpUvz444/4+PjkXUgRG9DEJ1II/Vp6PXv2vOvSS09P5+2336Zdu3aMHDmSLVu2qPSkUNLEJ1LInD9/nlatWtG7d2/efvvtu1rnwIEDDBgwgKpVq3LkyBHKly+fxylFbEfFJ1KInD9/npYtW/Lcc88xceLEOy5/8+ZNgoKCWLp0KR9++CE9evS4rwPaRQoSfdQpUkj8WnqBgYF3VXq7d++mXr16xMbGEhYWRs+ePVV6Yhc08YkUAvHx8bRs2ZL+/fvz5ptv/u2ySUlJvP7666xbt4758+fTuXPnh5RSJH/QxCdSwMXFxeHv78/zzz9/x9LbunUrderUIS0tjePHj6v0xC5p4hMpwOLi4mjZsiUDBgzg9ddf/8vlrl27xiuvvMK3337LJ598Qrt27R5iSpH8RROfSAEVGxuLv78/AwcO/NvSW79+PXXq1KFo0aKEhYWp9MTuaeITKYBiY2Np2bIlgwcPZvz48bddJiEhgZEjR3L48GFWrFhBixYtHnJKkfxJE59IARMTE4O/vz8vvvjibUvParWycuVK6tSpQ8WKFTl69KhKT+R3NPGJFCAxMTG0bNmSIUOG8Oqrr/7p/vj4eIYOHcqZM2fYsGEDjRs3tkFKkfxNE59IAREdHY2/vz9Dhw79U+lZrVZCQkKoX78+9evX59ChQyo9kb+giU+kAIiOjqZly5aMGDGCMWPG5LgvKiqKwYMHc+XKFb755hvq1atno5QiBYMmPpF8LioqCn9//z+VnsViYd68eTRq1IhWrVpx4MABlZ7IXdDEJ5LPmM1mjEYjRqORyMhIWrZsyahRoxg9enT2MqdPn2bgwIGYzWb27NlDjRo1bJhYpGDRxCeSz4wcOZInn3ySn3/+mZYtWzJ69Ojs0svKymL27Nk0bdqU//u//1PpidwHg9Vqtdo6hIjckpWVhaenJ6mpqRgMBqZOncq4ceMAOHHiBAMGDMDNzY1FixZRpUoVG6cVKZg08YnkI3v27CErK4vMzEwsFgtr1qzh+vXrTJkyJfssLdu3b1fpiTwAfccn8pBcTk5n7aFYwi/c4EaaGQ8XR2qU9aB7Qy9KuDsDMHfuXFJSUjAajTg7O3Pu3DmaNm1K5cqVOXz4MN7e3jZ+FiIFnz7qFMljR2MSmbczgl2nEgBIN1uy73NxNGIF/KuXYpifL09WLYuzszMDBgzg+vXrbNy4kdmzZxMYGKhr5YnkEhWfSB5atj+SaZvCSTNn8cd/aVHvdKT8S5/gVLw8BgO4ODrwcgsv6rpeZ9CgQTz22GPMnTuXsmXL2ia8SCGl7/hE/qBSpUps27btgbdzq/ROkpr559L7I6sVUjOzmL3tLD0nzGXKlCmsXbtWpSeSB/Qdn0geOBqTyLRN4aRmWu688O9kGRxwb96Pak2a5lEyEdHEJ/I7ffv2JTo6mmeffRZ3d3dmzpzJhg0beOyxxzCZTPj7+3Py5Mns5StVqsSMGTOoVasWxYsX54UXXiAtLY15OyNIM2eRdGQLcQsHE/NBLy6tnYw56cptH9eSlsLl0PeI+bAPER/1Z9DoN7BYbpVmVlYWr7zyCiVLlqRy5crMnTsXg8GA2WxmzZo1NGzYMMe23n//fV1ZXeRvqPhEfmfp0qVUrFiR0NBQkpOT+ec//0nv3r354IMPSEhIoH379jz77LNkZGRkr7N8+XK+/vprzpw5w6lTp3jz7WB2nUrg5rmjJO76nJL/fA2vEUtx9CjN5fUzb/u4V79ZiCX9JhWGLKJsn3c4smMD/1rwCQCffvopmzdv5siRIxw+fJh169Zlr9epUyfOnTuXo4yXLl1Kv3798ugVEin4VHwif2PVqlV06NCBtm3b4uTkxKuvvkpqairff/999jIjRozA29sbT09PJkyYwNLlKwBI+Xkn7nXb4FzWF4OjEyb//qTHh2NOvJjjMayWLFJO7sHk3x+jc1EcTWXwfLIr8xYtBmD16tWMGjUKLy8vihcvnuNq687OzvTs2ZNly5YBtw5yj4yMpGPHjnn90ogUWCo+kb8RHx+Pj49P9m2j0Yi3tzdxcXHZv/v9sXU+Pj5cS7hEutlCVvJVHD1K/7ZuEVeMrsUwJ+f8uNOSegMs5hzLWouVIuHC+ewMv3+MPx7L179/f1asWIHVamXp0qX06NEDZ2fnB3zmIoWXik/kD35/vFz58uWJiorKvm21WomJiaFChQrZv4uJicn+OTo6mqKmkgA4uHtivnEp+z5LRhqW1CQc3UvkeDyjqwcYHXMsa76RgMsjpQAoV64csbGxt308gCZNmlCkSBH27NnDihUr6Nu37309bxF7oeIT+YMyZcpw9uxZAHr06MHGjRvZvn07mZmZvPfeezg7O9OsWbPs5efNm0dsbCxXr15l2rRpVG/WDgC3Wn4kH9tGxsWzWM2ZJO76N87lq+NoKpPj8QxGB9xqPk3irs+xpN/EfP0SN35YR22/DtkZPvzwQ+Li4khMTOTdd9/9U+Z+/foxYsQInJycePrpp/PqpREpFFR8In/wxhtvMHXqVEwmE6GhoSxbtoyRI0dSsmRJQkNDCQ0NpUiRItnL9+nTh3bt2lGlShUeffRReg9+GQcsuFaqj6lFIAlfTSd2bl/MiRco2Wn8bR+zeNshGIu4ELdwEBeWjeeR2v507X1rchs8eDDt2rWjbt26PP7447Rv3x5HR0ccHByy1+/bty/Hjx8nMDAwb18ckUJAZ24ReQCVKlVi0aJFtGnThvT0dBYtWsSMOXNx+r93sBrv/zBZZ0cj37/WKvscnr+3efNmhgwZkuMj2NTUVEqXLs3hw4epWrXqfT+uiD3QxCfygDIyMliwYAG+vr5s3ryZdSuX0rZ2Be731JoGA7SsXiq79FJTU9m0aRNms5m4uDgmTZpEly5dcqyzYMECnnjiCZWeyF3QmVtE7lNGRgZJSUm88MILNGjQgC+++ILGjRsD4FQmkT2nL5OamXXP23VxdGCYv2/2bavVSlBQED179sTV1ZUOHTowefLk7PsrVaqE1WrNcXyfiPw1fdQpco8yMzP597//zdSpU6levTrBwcE0bfrnU4z9dq7Ouz9tmauTkQntaxLYpFIuJhaR39PEJ3KXMjMzWbp0KVOnTuXRRx9lxYoVOfbu/KNfy+uvrs7we79enWFC+xoqPZE8polP5A7MZjPLli1jypQp+Pj4MGnSJJo3b37X6x+LTWT+zgh2/JKAAUi7zfX4WlYvxTB/X+p6mXL/CYhIDio+kb9gNptZsWIFU6ZMoUKFCkyaNAk/P7/73t6V5HTWHo4l/HwSN9Iy8XBxoka5YnRr4HXbvTdFJG+o+ET+ICsri5UrVzJ58mTKlCnDpEmTaNmypa1jiUgu0Xd8Iv+TlZXF6tWrmTx5Mp6ensybN4/WrVvnOIWZiBR8Kj6xexaLhTVr1jBp0iQeeeQRPvzwQ9q2bavCEymkVHxitywWC1988QWTJk3Czc2N999/n4CAABWeSCGn4hO7Y7FYWLduHcHBwTg7OzNz5kyeeeYZFZ6InVDxid2wWq2sX7+e4OBgjEYj06ZNo2PHjio8ETuj4pNCz2q1EhoaSnBwMFarlUmTJtGpUycVnoidUvFJoWW1Wtm0aRPBwcFkZGQQHBxM586dMRp1bnYRe6bik0LHarWyZcsWgoODuXnzJkFBQXTt2lWFJyKAik8KEavVytatWwkKCiIpKYmgoCC6deumwhORHFR8UuBZrVa2bdtGcHAwV69eJSgoiO7du+e4QrmIyK9UfFJgWa1WduzYQVBQEJcuXcq+Zp0KT0T+jopPCqSdO3cSFBREfHw8b7/9Nr1798bRUX+dReTO9E4hBcru3bsJCgoiJiaGiRMn8txzz6nwROSe6B1DCoS9e/cSFBTE2bNnmThxIoGBgTg5Odk6logUQCo+ydf27dtHUFAQp06d4q233qJ///4qPBF5INrPW/KlAwcO8I9//INevXrRrVs3Tp06xaBBg1R6IvLANPFJvnLw4EGCg4MJCwvjzTffZP369Tg76+rkIpJ7NPFJvnDo0CGeffZZunTpQocOHTh9+jRDhgxR6YlIrlPxiU399NNPdO7cmU6dOtGuXTsiIiIYNmyYCk9E8oyKT2zi6NGj2dNdq1atiIiIYOTIkbi4uNg6mogUcio+eajCwsLo1q0b//jHP2jRogURERGMGjUKV1dXW0cTETuh4pOH4sSJE/To0YO2bdvStGlTzpw5w5gxYyhatKito4mInVHxSZ46efIkvXv3plWrVjRq1IgzZ87wyiuvqPBExGZUfJInfvnlF5577jn8/PyoV68eZ86cYfz48bi5udk6mojYORWf5KrTp0/Tt29fnn76aWrVqkVERASvv/467u7uto4mIgKo+CSXRERE0L9/f5o1a0a1atWIiIhgwoQJeHh42DqaiEgOOnOLPJCzZ88ydepUNmzYwMiRIzl9+jQmk8nWsURE/pImPrkvkZGRDBo0iCeeeAIvLy9Onz5NUFCQSk9E8j0Vn9yTqKgoXnzxRRo2bEjZsmU5ffo0kydPpnjx4raOJiJyV1R8cldiYmIYOnQoDRo0oGTJkpw6dYqpU6fi6elp62giIvdExSd/KzY2luHDh1O/fn0eeeQRfvnlF6ZPn06JEiVsHU1E5L6o+OS24uPjGTlyJHXr1qVo0aKcPHmSd955h5IlS9o6mojIA1HxSQ7nz59n1KhR1K5dmyJFinDy5ElmzZpF6dKlbR1NRCRXqPgEgIsXLzJ27Fgee+wxjEYjP//8M++99x5lypSxdTQRkVyl4rNzly5d4tVXX6VmzZqYzWaOHz/OnDlzKFu2rK2jiYjkCRWfnUpISGD8+PHUqFGDtLQ0wsLC+Oijjyhfvryto4mI5CkVn525cuUKb7zxBjVq1CA5OZmjR48yd+5cKlSoYOtoIiIPhYrPTly9epUJEyZQrVo1rl69yuHDh5k/fz7e3t62jiYi8lCp+Aq5a9euMXHiRKpWrcqlS5c4dOgQH3/8MT4+PraOJiJiEyq+QioxMZHg4GCqVq1KfHw8Bw8e5NNPP6VSpUq2jiYiYlMqvkLm+vXrTJ48GV9fX6Kiojhw4ACfffYZVapUsXU0EZF8QcVXSNy4cYOpU6fi6+tLREQE+/btY/HixTz66KO2jiYikq+o+Aq4pKQkZsyYga+vL+Hh4Xz33Xd8/vnnVK1a1dbRRETyJV2ItoBKTk5m3rx5vP/++7Ru3Zrdu3dTo0YNW8cSEcn3VHwFTEpKCvPnz2f27Nn4+/vz7bff8thjj9k6lohIgaHiKyBu3rzJwoULmTlzJs2bN2f79u3Url3b1rFERAocFV8+l5qayscff8zMmTNp2rQpW7dupW7duraOJSJSYKn48qm0tDQ++eQT3n33XZ544gk2bdpE/fr1bR1LRKTAU/HlM+np6SxatIgZM2bQoEEDQkNDadCgga1jiYgUGiq+fCI9PZ2QkBCmT59OvXr1WLduHY0aNbJ1LBGRQkfFZ2MZGRksXryY6dOnU6tWLb744gsaN25s61giIoWWis9GMjMzWbJkCdOmTaN69eqsXLmSpk2b2jqWiEihp+J7yDIzM1m6dClTpkzB19eXFStW0KxZM1vHEhGxGyq+h8RsNrNs2TKmTJlCpUqV+Pzzz2nevLmtY4mI2B0VXx4zm82sWLGCKVOmUKFCBUJCQvDz87N1LBERu6XiyyNZWVmsXLmSyZMnU6ZMGT755BNatmxp61giInZPxZfLsrKyWL16NZMnT8bT05N58+bRunVrDAaDraOJiAgqvlxjsVhYs2YNkyZN4pFHHuHDDz+kbdu2KjwRkXxGxfeALBYLX375JZMmTaJo0aK8//77BAQEqPBERPIpFd99slgsrFu3jkmTJlGkSBHeffddnnnmGRWeiEg+p+K7R1arlfXr1xMcHIzRaGTq1Kl07NhRhSciUkCo+O6S1WolNDSU4OBgrFYrkyZNolOnTio8EZECRsV3B1arlU2bNhEcHExGRgbBwcF07twZo9Fo62giInIfVHx/wWq1smXLFoKDg7l58yZBQUF07dpVhSciUsCp+P7AarWydetWgoKCSEpKIigoiG7duqnwREQKCRXf/1itVrZv305QUBBXr14lKCiI7t274+DgYOtoIiKSi+y++KxWKzt27CAoKIhLly4RFBREz549VXgiIoWUXRffrl27ePvtt4mPj+ftt9+md+/eODra9UsiIlLo2eW7/J49ewgKCiI6OpqJEyfy3HPPqfBEROxEgXm3v5ycztpDsYRfuMGNNDMeLo7UKOtB94ZelHB3vu0627Zt4/z58/Tt2xeAvXv3EhQUxNmzZ5k4cSKBgYE4OTk9zKchIiI2ZrBarVZbh/g7R2MSmbczgl2nEgBIN1uy73NxNGIF/KuXYpifL/W8Tdn3RUVFUadOHSwWC1999RWzZs3i1KlTvPXWW/Tv31+FJyJip/J18S3bH8m0TeGkmbP4u5QGA7g4OjChfQ0Cm1QiMzOThg0bcuLECQDc3d2ZNWsWzz//PEWKFHlI6UVEJD/Kt8V3q/ROkpppufPC/+PqZGRC+5ps/PANVq9ejcVya11XV1fi4+MxmUx32IKIiBR2+fI7vqMxiUzbFH5PpQeQmmlh6qaTxH5/jCJFilCkSBGMRiMODg4cP34cLy8vKleuTGZmpnZmERGxU/ny3X/ezgjSzFn3tW662ULgtH+zMLDRn+6LjIx8wGQiIlLQ5fp5uGJiYujatSulSpWiRIkSjBgxAovFwtSpU/Hx8aF06dL069eP69evA7fKyGAwsHjxYry9vTEVL876/ywhLf4U8Z+NIHpOT65uXZC9/eRj27iwdBxXty4gek4P4j4ZQmrkkd8ef94A/rt5K1eS0wEIDg4mMDAQgBYtWgBgMplwd3dn3759AISEhFCzZk2KFy9OQEAAUVFRuf2yiIhIPpGrxZeVlUXHjh3x8fEhMjKSuLg4evXqxZIlS1iyZAk7duzg7NmzJCcnM2LEiBzrHjhwgNOnT9NvwhwStn7C9e9XU6bXVMoPmkdK+HekRYdlL5se/wuOpnJ4v7wCU/M+JHw1nazUpOz7DcDaw7F/yrd7924AEhMTSU5OpmnTpqxfv57p06fz5ZdfkpCQQPPmzendu3duviwiIpKP5Grx/fDDD8THxzNr1izc3NxwcXHh6aefZvny5YwdO5YqVarg7u7OjBkzWLlyJWazOXvdiRMn4uLigtG7HgYnF9xqtcDBzYRjsZK4eD1GxsWz2cs6uJko9kRnDA6OuNVsgZNnBVLPHMy+P8NiJfx8Endj4cKFvPHGG9SsWRNHR0fefPNNjhw5oqlPRKSQytXii4mJwcfH5087jsTHx+Pj45N928fHB7PZzMWLF7N/V6ZMGQBupJkxOBXBoehve2AanIpgyUjNvu3gXiLHBWAdPUqTlXw1x2PeSMu8q8xRUVGMGjUKk8mEyWTC09MTq9VKXFzcXa0vIiIFS64Wn7e3N9HR0TkmOYDy5cvnmKCio6NxdHTMLrvf83C58/42WclX+P1RGOYbCTi4ewJgLOKCNTMdD5dbB6hfuHAhe7nbXS3d29ubjz/+mMTExOw/qampNGvW7I45RESk4MnV4mvcuDHlypXj9ddfJyUlhbS0NPbu3Uvv3r2ZM2cO586dIzk5mTfffJOePXve9pCCGmU9+HM95ZSVkkjSjxuwZplJCf+OzCsxuD56ay9Op9KVSQvfTdVSLvz444+sXbs2e71SpUphNBo5e/a3j02HDBnCjBkzsg92v379OmvWrHnwF0NERPKlXC0+BwcHQkNDiYiIoGLFinh5ebFq1SoGDBhA3759adGiBZUrV8bFxYV//etft91Gt4Zed3wc5/LVMV+LJ+ajPiTu+pxSXd7AwdUDAFOLvmReO8/4To0ICgqiT58+2esVLVqUCRMm8NRTT2Eymdi/fz9dunThtddeo1evXnh4eFC7dm02b96cOy+IiIjkO/nyzC0vLv2Rb05evO1pypKPbSP52FbKBs687boGAwTUKnPb4/hERERy/Ti+3DDc3xcXx/u7EKyLowPD/H1zOZGIiBQW+bL46nmbmNC+Bq5O9xbv1rk6a1DXS+fkFBGR28uXH3X+6n6vziAiIvJX8nXxARyLTWT+zgh2/JKAAUi7zfX4WlYvxTB/X016IiJyR/m++H51JTmdtYdjCT+fxI20TDxcnKhRrhjdGvz1FdhFRET+qMAUn4iISG7Ilzu3iIiI5BUVn4iI2BUVn4iI2BUVn4iI2BUVn4iI2BUVn4iI2BUVn4iI2BUVn4iI2BUVn4iI2BUVn4iI2BUVn4iI2BUVn4iI2BUVn4iI2BUVn4iI2BUVn4iI2BUVn4iI2BUVn4iI2BUVn4iI2BUVn4iI2BUVn4iI2BUVn4iI2JX/B10idCArPXtjAAAAAElFTkSuQmCC\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [ "source": [
"tosca = get_tosca(provisioned_tosca_id)\n", "tosca = get_tosca(provisioned_tosca_id)\n",
"\n", "\n",
...@@ -326,13 +630,22 @@ ...@@ -326,13 +630,22 @@
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/opt/conda/lib/python3.7/site-packages/urllib3/connectionpool.py:986: InsecureRequestWarning: Unverified HTTPS request is being made to host 'lifewatch.lab.uvalight.net'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings\n",
" InsecureRequestWarning,\n"
]
}
],
"source": [ "source": [
"path = \"/deployer/deploy/\"+provisioned_tosca_id\n", "path = \"/deployer/deploy/\"+provisioned_tosca_id\n",
"payload = {}\n", "payload = {}\n",
"headers= {'accept':'text/plain'}\n", "headers= {'accept':'text/plain'}\n",
"\n", "\n",
"response = requests.request(\"GET\", base_url+path, headers=headers, data = payload)\n", "response = requests.request(\"GET\", base_url+path, headers=headers, data = payload, verify=False, auth=(username, password))\n",
"deployed_tosca_id = response.text" "deployed_tosca_id = response.text"
] ]
}, },
...@@ -383,7 +696,7 @@ ...@@ -383,7 +696,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.6.9" "version": "3.7.6"
} }
}, },
"nbformat": 4, "nbformat": 4,
......
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-config
namespace: conf
data:
htpasswd: |
alogo:$apr1$pbMniSeq$m4PZevv7VLULQLhiD2V2R0
conf_user:$apr1$sDBv9ugd$AV7m5Jeg0463jXaBxiZDs.
articonf_ui:$apr1$qFaau5L2$xgO53tciXFlrL/Z61nrzP.
mysqld.cnf: |
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
#log-error = /var/log/mysql/error.log
# By default we only accept connections from localhost
#bind-address = 127.0.0.1
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
max_connections = 2048
...@@ -37,9 +37,24 @@ spec: ...@@ -37,9 +37,24 @@ spec:
value: "yes" value: "yes"
- name: MYSQL_USER - name: MYSQL_USER
value: semaphore value: semaphore
image: mysql:5.6 image: mysql:5.7
name: mysql name: mysql
imagePullPolicy: Always imagePullPolicy: Always
resources: {} resources: {}
volumeMounts:
- name: config-volume
mountPath: /etc/mysql/mysql.conf.d/
volumes:
- name: config-volume
configMap:
name: mysql-config
items:
- key: mysqld.cnf
path: mysqld.cnf
restartPolicy: Always restartPolicy: Always
status: {} status: {}
...@@ -36,8 +36,8 @@ spec: ...@@ -36,8 +36,8 @@ spec:
- name: SURE_TOSCA_BASE_PATH - name: SURE_TOSCA_BASE_PATH
value: http://sure-tosca:8081/tosca-sure/1.0.0 value: http://sure-tosca:8081/tosca-sure/1.0.0
- name: CREDENTIAL_SECRET - name: CREDENTIAL_SECRET
value: top_secret value: MGY0MGQ1MDFkYzg5ZGIxYjY4MjQ4MzQz
image: qcdis/manager:3.0.0 image: qcdis/manager
name: manager name: manager
imagePullPolicy: Always imagePullPolicy: Always
ports: ports:
......
...@@ -10,10 +10,16 @@ metadata: ...@@ -10,10 +10,16 @@ metadata:
io.kompose.service: manager io.kompose.service: manager
name: manager name: manager
spec: spec:
type: NodePort
ports: ports:
- name: "8080" - port: 8080
port: 8080 nodePort: 30000
targetPort: 8080 protocol: TCP
name: http
#ports:
#- name: "8080"
#port: 8080
#targetPort: 8080
selector: selector:
io.kompose.service: manager io.kompose.service: manager
status: status:
......
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: conf
annotations:
kompose.cmd: kompose convert
kompose.version: 1.16.0 (0c01309)
creationTimestamp: null
labels:
io.kompose.service: mongo-express
name: mongo-express
spec:
selector:
matchLabels:
io.kompose.service: mongo-express
replicas: 1
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
io.kompose.service: mongo-express
spec:
containers:
- env:
#- name: ME_CONFIG_BASICAUTH_PASSWORD
#value: ZjEwMjhiNmRiNDQ0N2UzMTU5OWFhNjkz
#- name: ME_CONFIG_BASICAUTH_USERNAME
#value: NGU4NWIwMDM0Njg1ZGRhYjhkMzgyNGQ3
- name: ME_CONFIG_MONGODB_PORT
value: "27017"
- name: ME_CONFIG_MONGODB_SERVER
value: mongo
- name: ME_CONFIG_SITE_BASEURL
value: /mongo-express
- name: VCAP_APP_PORT
value: "8082"
image: mongo-express
name: mongo-express
ports:
- containerPort: 8082
resources: {}
restartPolicy: Always
status: {}
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: conf
annotations:
kompose.cmd: kompose convert
kompose.version: 1.16.0 (0c01309)
creationTimestamp: null
labels:
io.kompose.service: mongo-express
name: mongo-express
spec:
selector:
matchLabels:
io.kompose.service: mongo-express
replicas: 1
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
io.kompose.service: mongo-express
spec:
containers:
- env:
- name: ME_CONFIG_BASICAUTH_PASSWORD
value: pass
- name: ME_CONFIG_BASICAUTH_USERNAME
value: user
- name: ME_CONFIG_MONGODB_PORT
value: "27017"
- name: ME_CONFIG_MONGODB_SERVER
value: mongo
- name: ME_CONFIG_SITE_BASEURL
value: /mongo-express
- name: VCAP_APP_PORT
value: "8082"
image: mongo-express
name: mongo-express
ports:
- containerPort: 8082
resources: {}
restartPolicy: Always
status: {}
apiVersion: v1
kind: Service
metadata:
namespace: conf
annotations:
kompose.cmd: kompose convert
kompose.version: 1.16.0 (0c01309)
creationTimestamp: null
labels:
io.kompose.service: mongo-express
name: mongo-express
spec:
ports:
- name: "8082"
port: 8082
targetPort: 8082
selector:
io.kompose.service: mongo-express
status:
loadBalancer: {}
apiVersion: v1 apiVersion: v1
kind: ConfigMap kind: ConfigMap
metadata: metadata:
name: nginx-conf name: nginx-config
namespace: conf
data: data:
htpasswd: |
alogo:$apr1$pbMniSeq$m4PZevv7VLULQLhiD2V2R0
conf_user:$apr1$sDBv9ugd$AV7m5Jeg0463jXaBxiZDs.
articonf_ui:$apr1$qFaau5L2$xgO53tciXFlrL/Z61nrzP.
deploy_tester:$apr1$k/SfT3BS$PtccoOeG87XErtNGtyM7r/
nginx.conf: | nginx.conf: |
worker_processes auto; worker_processes auto;
...@@ -13,18 +21,19 @@ data: ...@@ -13,18 +21,19 @@ data:
} }
http { http {
proxy_connect_timeout 1200;
proxy_send_timeout 1200;
proxy_read_timeout 1200;
send_timeout 1200;
tcp_nodelay on; tcp_nodelay on;
# this is necessary for us to be able to disable request buffering in all cases
proxy_http_version 1.1; proxy_http_version 1.1;
upstream semaphore { upstream semaphore {
server semaphore:3000; server semaphore:3000;
} }
# upstream sure-tosca {
# server sure-tosca:8081;
# }
server { server {
listen [::]:80 default_server; listen [::]:80 default_server;
...@@ -39,26 +48,27 @@ data: ...@@ -39,26 +48,27 @@ data:
listen 443 ssl; listen 443 ssl;
server_name _; server_name _;
# add Strict-Transport-Security to prevent man in the middle attacks
add_header Strict-Transport-Security "max-age=31536000" always; add_header Strict-Transport-Security "max-age=31536000" always;
# SSL # SSL
ssl_certificate /etc/nginx/cert/cert.pem; ssl_certificate /etc/nginx/cert.pem;
ssl_certificate_key /etc/nginx/cert/privkey.pem; ssl_certificate_key /etc/nginx/privkey.pem;
# Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1.1 TLSv1.2; ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
ssl_prefer_server_ciphers on; ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m; ssl_session_cache shared:SSL:10m;
# disable any limits to avoid HTTP 413 for large image uploads
client_max_body_size 0; client_max_body_size 0;
# required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)
chunked_transfer_encoding on; chunked_transfer_encoding on;
location / { location / {
add_header 'Access-Control-Allow-Origin' *;
proxy_pass http://semaphore/; proxy_pass http://semaphore/;
proxy_set_header Host $http_host; proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
...@@ -71,6 +81,7 @@ data: ...@@ -71,6 +81,7 @@ data:
} }
location /api/ws { location /api/ws {
add_header 'Access-Control-Allow-Origin' *;
proxy_pass http://semaphore/api/ws; proxy_pass http://semaphore/api/ws;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
...@@ -79,8 +90,22 @@ data: ...@@ -79,8 +90,22 @@ data:
} }
location /tosca-sure/1.0.0/ { location /tosca-sure/1.0.0 {
proxy_pass http://sure-tosca:8081/tosca-sure/1.0.0/; add_header 'Access-Control-Allow-Origin' *;
proxy_pass http://sure-tosca:8081/tosca-sure/1.0.0;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_request_buffering off;
}
location /manager {
add_header 'Access-Control-Allow-Origin' *;
proxy_pass http://manager:8080/manager;
proxy_set_header Host $http_host; proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
...@@ -91,8 +116,9 @@ data: ...@@ -91,8 +116,9 @@ data:
proxy_request_buffering off; proxy_request_buffering off;
} }
location /manager/ { location /swagger-ui.html {
proxy_pass http:///manager:8080/manager; add_header 'Access-Control-Allow-Origin' *;
proxy_pass http://manager:8080/swagger-ui.html;
proxy_set_header Host $http_host; proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
...@@ -102,17 +128,110 @@ data: ...@@ -102,17 +128,110 @@ data:
proxy_buffering off; proxy_buffering off;
proxy_request_buffering off; proxy_request_buffering off;
} }
location /mongo-express {
proxy_pass http://mongo-express:8082/mongo-express;
proxy_set_header Host $host;
proxy_set_header X-Real_IP $remote_addr;
} }
location /rabbit {
proxy_pass http://rabbit:15672/#/queues;
proxy_set_header Host $host;
proxy_set_header X-Real_IP $remote_addr;
}
}
} }
cert.pem: | cert.pem: |
second file -----BEGIN CERTIFICATE-----
contents MIIFezCCA2OgAwIBAgIUROYyFnRFb0q04tViEuDvyQnmR34wDQYJKoZIhvcNAQEL
BQAwTTEOMAwGA1UECgwFcWNkaXMxDjAMBgNVBAsMBXFjZGlzMSswKQYDVQQDDCJ1
bmEubmwvYW5zaWJsZS1zZW1hcGhvcmUvc2VtYXBob3JlMB4XDTIwMDUwOTExMzkx
NFoXDTIwMDYwODExMzkxNFowTTEOMAwGA1UECgwFcWNkaXMxDjAMBgNVBAsMBXFj
ZGlzMSswKQYDVQQDDCJ1bmEubmwvYW5zaWJsZS1zZW1hcGhvcmUvc2VtYXBob3Jl
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEApYMrTifbMSXSb8nQycX8
LYfYbYZW4Pm1b/lw1RwC5WI3G4o0NxEJPvLiHuceva/70FwohT1l+qs26moeISzN
30TFkNMvVhWCDC3E8+K1Ik2/oGLVSJcB4v+9DkXH3Z7BeEjZaR58sl8SlUtYoCB9
feLIagYyiLv/IthxR4MEeARjhvZfOST7Y5AQaQ0/wR7KNmKyiWzfNgsL9LmXkWMr
qrd1ldrW9+JnFqhzCeuaoJ3GIWA75sKgWSMt0zeVDOQHoRVs9MhJ2zvqvksrchOP
E3JdNvadcx97BP/vxLOXH4hW/kuHq4ouOGWmJ3TC46XUHnR/KMVnOa8TagDrpbK0
Xiw3eGYm2oBScKB9CPfhxJuo0AH4Z5yvPQkQCnrhGzF71APho2FpLdciiRm03NaT
wP1Yw0SiJR1mObVuUzQQcPGkk9IolW6seasTTA+P0QfRx2N+Ka4nHcjodLxp7tMV
iPwXeQc2SZdMaH7vJKzB21rloZ4eum8CjH38s09mol5iXEWeSLPCohU0FkST4LQk
WqFPDffzNSbQOsz5MnsxhIYs4Hg8IK+LAC/r585Xe6lMSQszoufG6njUfLJppTXD
cj7Wsu1cn2aLgbkv7v4Bvb31e8TISS9HwEVksxFSW4kp1ZIr7G9EZfR4gKqElyB3
098e44Odqh9DSittqKYK8mECAwEAAaNTMFEwHQYDVR0OBBYEFNSU+k9Saizw0s4Y
ukdu0xgGlOoQMB8GA1UdIwQYMBaAFNSU+k9Saizw0s4Yukdu0xgGlOoQMA8GA1Ud
EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBABheqNkWhg2JYqR3/8Yq+Jql
z++plJ5Tuh5C2cW4NnMwSq1dREsNp8RCLPf0FsinD5g9+SOFXc89Xluhgakr9RLF
uJTdWDElVzsyrzy+c/Khjh1zTyHlk8Vvtj/zB+Dw0+n9j5hWmZmhxl/R2k1Nhh55
vN8HBwHTmPfdjiruvbml+wG4TjqBBhvo6/RgQYFzgWY5K83cd/PsdlPbmf75S8CC
l5r3FLMsbpPmIdrfrEnAzyx+MspPnxW67P31arrFrGqR65Gem8HMBkkhWcET15Rz
ujtDzje25KJCXT1Ee1zBOe93De80x9VuXCxEZY7Lcl2ZaK8D37WdX7DGHhM+oV61
AnH5UurS3PEqE63l1RAuGLsfotFrxOWM6YI2mS0k2aappXgxUSbPcWtrK2a4o7sW
k4JWJirYANbKJmS6QuxQ6tsYOywoMpqoojNSQKRl/nLlqfg2IvzRKGS0zJ3+lFoZ
SZpisk+RRLuF3vi2X+7wtFm4G66N6FbTeQcRmybAh0U1RJriso9aO7TPO87WddOB
tHDpzueBlqytnZKsoBOylFc8Ci5KMRMRtiZRM65FcrO8RWJsSce1RwymM2r0UNZa
yinfAEVPqRXgOeGERcTBJHGMlnfWiPbkVJlKYI+X2FJxOueo7l02wF/OOA4K7HTQ
Ym991UvfEl+ffXQlrgSz
-----END CERTIFICATE-----
privkey.pem: | privkey.pem: |
second file -----BEGIN PRIVATE KEY-----
contents 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
IcMOOL2BxVOnf/0kzIRiuo8SUzbK+g==
-----END PRIVATE KEY-----
...@@ -12,6 +12,9 @@ spec: ...@@ -12,6 +12,9 @@ spec:
nodePort: 30001 nodePort: 30001
protocol: TCP protocol: TCP
name: https name: https
- port: 80
protocol: TCP
name: http
selector: selector:
io.kompose.service: nginx io.kompose.service: nginx
status: status:
......
...@@ -33,7 +33,11 @@ spec: ...@@ -33,7 +33,11 @@ spec:
value: rabbit value: rabbit
- name: SURE_TOSCA_BASE_PATH - name: SURE_TOSCA_BASE_PATH
value: http://sure-tosca:8081/tosca-sure/1.0.0 value: http://sure-tosca:8081/tosca-sure/1.0.0
image: qcdis/provisioner:3.0.0 - name: CLOUD_STORM_SECRET
value: ODlkYjgxM2RhNTAzMjExZTdiYWNhYWQ0
- name: CREDENTIAL_SECRET
value: MGY0MGQ1MDFkYzg5ZGIxYjY4MjQ4MzQz
image: qcdis/provisioner
name: provisioner name: provisioner
imagePullPolicy: Always imagePullPolicy: Always
resources: {} resources: {}
......
...@@ -51,7 +51,7 @@ spec: ...@@ -51,7 +51,7 @@ spec:
value: /etc/semaphore value: /etc/semaphore
- name: SEMAPHORE_WEB_ROOT - name: SEMAPHORE_WEB_ROOT
value: http://0.0.0.0:3000 value: http://0.0.0.0:3000
image: qcdis/docker_ansible_semaphore image: qcdis/docker_ansible_semaphore:v2.5.1-2.9.9
name: semaphore name: semaphore
imagePullPolicy: Always imagePullPolicy: Always
ports: ports:
......
...@@ -15,15 +15,16 @@ import org.springframework.web.bind.annotation.RequestBody; ...@@ -15,15 +15,16 @@ import org.springframework.web.bind.annotation.RequestBody;
import javax.validation.Valid; import javax.validation.Valid;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.List; import java.util.List;
import java.util.logging.Level;
import javax.crypto.BadPaddingException; import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException; import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException; import javax.crypto.NoSuchPaddingException;
import nl.uva.sne.drip.service.CredentialService; import nl.uva.sne.drip.service.CredentialService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
@javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2019-10-10T17:15:46.465Z") @javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2019-10-10T17:15:46.465Z")
@CrossOrigin(origins = "*")
@Controller @Controller
public class CredentialApiController implements CredentialApi { public class CredentialApiController implements CredentialApi {
...@@ -46,27 +47,27 @@ public class CredentialApiController implements CredentialApi { ...@@ -46,27 +47,27 @@ public class CredentialApiController implements CredentialApi {
public ResponseEntity<String> createCredentials(@ApiParam( public ResponseEntity<String> createCredentials(@ApiParam(
value = "Created user object", required = true) value = "Created user object", required = true)
@Valid @RequestBody Credential body) { @Valid @RequestBody Credential body) {
String accept = request.getHeader("Accept"); // String accept = request.getHeader("Accept");
if (accept != null && accept.contains("application/json")) { // if (accept != null && accept.contains("application/json")) {
try { try {
String id = credentialService.save(body); String id = credentialService.save(body);
return new ResponseEntity<>(id, HttpStatus.OK); return new ResponseEntity<>(id, HttpStatus.OK);
} catch (UnsupportedEncodingException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException ex) { } catch (UnsupportedEncodingException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException ex) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
} }
} else { // } else {
return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE); // return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE);
} // }
} }
@Override @Override
public ResponseEntity<List<String>> getCredentialIDs() { public ResponseEntity<List<String>> getCredentialIDs() {
String accept = request.getHeader("Accept"); // String accept = request.getHeader("Accept");
if (accept != null && accept.contains("application/json")) { // if (accept != null && accept.contains("application/json")) {
List<String> ids = credentialService.getAllIds(); List<String> ids = credentialService.getAllIds();
return new ResponseEntity<>(ids, HttpStatus.OK); return new ResponseEntity<>(ids, HttpStatus.OK);
} // }
return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); // return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
} }
} }
...@@ -12,10 +12,12 @@ import org.springframework.web.bind.annotation.PathVariable; ...@@ -12,10 +12,12 @@ import org.springframework.web.bind.annotation.PathVariable;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import nl.uva.sne.drip.service.DRIPService; import nl.uva.sne.drip.service.DRIPService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
@javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2019-10-10T17:15:46.465Z") @javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2019-10-10T17:15:46.465Z")
@Controller @Controller
@CrossOrigin(origins = "*")
public class DeployerApiController implements DeployerApi { public class DeployerApiController implements DeployerApi {
private static final Logger log = LoggerFactory.getLogger(DeployerApiController.class); private static final Logger log = LoggerFactory.getLogger(DeployerApiController.class);
...@@ -38,8 +40,8 @@ public class DeployerApiController implements DeployerApi { ...@@ -38,8 +40,8 @@ public class DeployerApiController implements DeployerApi {
@ApiParam(value = "ID of topolog template to deploy", required = true) @ApiParam(value = "ID of topolog template to deploy", required = true)
@PathVariable("id") String id) { @PathVariable("id") String id) {
String accept = request.getHeader("Accept"); // String accept = request.getHeader("Accept");
if (accept != null && accept.contains("")) { // if (accept != null && accept.contains("")) {
try { try {
String planedYemplateId = dripService.deploy(id, null); String planedYemplateId = dripService.deploy(id, null);
return new ResponseEntity<>(planedYemplateId, HttpStatus.OK); return new ResponseEntity<>(planedYemplateId, HttpStatus.OK);
...@@ -49,9 +51,9 @@ public class DeployerApiController implements DeployerApi { ...@@ -49,9 +51,9 @@ public class DeployerApiController implements DeployerApi {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
} }
} else { // } else {
return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE); // return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE);
} // }
} }
} }
...@@ -15,8 +15,10 @@ import javax.servlet.http.HttpServletRequest; ...@@ -15,8 +15,10 @@ import javax.servlet.http.HttpServletRequest;
import nl.uva.sne.drip.service.DRIPService; import nl.uva.sne.drip.service.DRIPService;
import nl.uva.sne.drip.sure.tosca.client.ApiException; import nl.uva.sne.drip.sure.tosca.client.ApiException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
@Controller @Controller
@CrossOrigin(origins = "*")
public class PlannerApiController implements PlannerApi { public class PlannerApiController implements PlannerApi {
private static final Logger log = LoggerFactory.getLogger(PlannerApiController.class); private static final Logger log = LoggerFactory.getLogger(PlannerApiController.class);
...@@ -38,21 +40,26 @@ public class PlannerApiController implements PlannerApi { ...@@ -38,21 +40,26 @@ public class PlannerApiController implements PlannerApi {
public ResponseEntity<String> planToscaTemplateByID(@ApiParam( public ResponseEntity<String> planToscaTemplateByID(@ApiParam(
value = "ID of topolog template to plan", required = true) value = "ID of topolog template to plan", required = true)
@PathVariable("id") String id) { @PathVariable("id") String id) {
String accept = request.getHeader("Accept"); // String accept = request.getHeader("Accept");
if (accept != null && accept.contains("text/plain")) { // if (accept != null && accept.contains("text/plain")) {
try { try {
String planedYemplateId = dripService.plan(id); String planedYemplateId = dripService.plan(id);
return new ResponseEntity<>(planedYemplateId, HttpStatus.OK); return new ResponseEntity<>(planedYemplateId, HttpStatus.OK);
} catch (ApiException | NotFoundException | IOException | TimeoutException | InterruptedException ex) { } catch (NotFoundException | java.util.NoSuchElementException ex) {
java.util.logging.Logger.getLogger(ToscaTemplateApiController.class.getName()).log(Level.WARNING, null, ex);
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
} catch (TimeoutException ex) {
java.util.logging.Logger.getLogger(PlannerApiController.class.getName()).log(Level.SEVERE, null, ex);
return new ResponseEntity<>(HttpStatus.GATEWAY_TIMEOUT);
} catch (ApiException | IOException | InterruptedException ex) {
java.util.logging.Logger.getLogger(PlannerApiController.class.getName()).log(Level.SEVERE, null, ex); java.util.logging.Logger.getLogger(PlannerApiController.class.getName()).log(Level.SEVERE, null, ex);
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
} }
} else { // } else {
return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE); // return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE);
} // }
} }
} }
...@@ -18,10 +18,12 @@ import nl.uva.sne.drip.model.Exceptions.TypeExeption; ...@@ -18,10 +18,12 @@ import nl.uva.sne.drip.model.Exceptions.TypeExeption;
import nl.uva.sne.drip.service.DRIPService; import nl.uva.sne.drip.service.DRIPService;
import nl.uva.sne.drip.sure.tosca.client.ApiException; import nl.uva.sne.drip.sure.tosca.client.ApiException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
@javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2019-10-10T17:15:46.465Z") @javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2019-10-10T17:15:46.465Z")
@Controller @Controller
@CrossOrigin(origins = "*")
public class ProvisionerApiController implements ProvisionerApi { public class ProvisionerApiController implements ProvisionerApi {
private static final Logger log = LoggerFactory.getLogger(ProvisionerApiController.class); private static final Logger log = LoggerFactory.getLogger(ProvisionerApiController.class);
...@@ -43,8 +45,8 @@ public class ProvisionerApiController implements ProvisionerApi { ...@@ -43,8 +45,8 @@ public class ProvisionerApiController implements ProvisionerApi {
public ResponseEntity<String> provisionPlanToscaTemplateByID( public ResponseEntity<String> provisionPlanToscaTemplateByID(
@ApiParam(value = "ID of topolog template to provision", required = true) @ApiParam(value = "ID of topolog template to provision", required = true)
@PathVariable("id") String id) { @PathVariable("id") String id) {
String accept = request.getHeader("Accept"); // String accept = request.getHeader("Accept");
if (accept != null && accept.contains("text/plain")) { // if (accept != null && accept.contains("text/plain")) {
try { try {
String planedYemplateId = dripService.provision(id); String planedYemplateId = dripService.provision(id);
return new ResponseEntity<>(planedYemplateId, HttpStatus.OK); return new ResponseEntity<>(planedYemplateId, HttpStatus.OK);
...@@ -55,9 +57,9 @@ public class ProvisionerApiController implements ProvisionerApi { ...@@ -55,9 +57,9 @@ public class ProvisionerApiController implements ProvisionerApi {
java.util.logging.Logger.getLogger(ProvisionerApiController.class.getName()).log(Level.SEVERE, null, ex); java.util.logging.Logger.getLogger(ProvisionerApiController.class.getName()).log(Level.SEVERE, null, ex);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ex.getMessage()); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ex.getMessage());
} }
} else { // } else {
return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE); // return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE);
} // }
} }
} }
...@@ -14,12 +14,14 @@ import nl.uva.sne.drip.service.ToscaTemplateService; ...@@ -14,12 +14,14 @@ import nl.uva.sne.drip.service.ToscaTemplateService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
@javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2019-10-10T17:15:46.465Z") @javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2019-10-10T17:15:46.465Z")
@Controller @Controller
@CrossOrigin(origins = "*")
public class ScalerApiController implements ScalerApi { public class ScalerApiController implements ScalerApi {
private static final Logger log = LoggerFactory.getLogger(ScalerApiController.class); private static final Logger log = LoggerFactory.getLogger(ScalerApiController.class);
......
...@@ -39,6 +39,24 @@ public interface ToscaTemplateApi { ...@@ -39,6 +39,24 @@ public interface ToscaTemplateApi {
method = RequestMethod.DELETE) method = RequestMethod.DELETE)
ResponseEntity<String> deleteToscaTemplateByID(@ApiParam(value = "ID of topology template to return", required = true) @PathVariable("id") String id, @ApiParam(value = "The node(s) to delete") @Valid @RequestParam(value = "node_name", required = false) List<String> nodeName); ResponseEntity<String> deleteToscaTemplateByID(@ApiParam(value = "ID of topology template to return", required = true) @PathVariable("id") String id, @ApiParam(value = "The node(s) to delete") @Valid @RequestParam(value = "node_name", required = false) List<String> nodeName);
@ApiOperation(value = "Deletes all tosca topology templates", nickname = "deleteAllToscaTemplates",
notes = "If the topology is provisoned it will delete the provison (Infrastructure). If it is deployed it will delete the deploymet too (Application)", response = String.class, authorizations = {
@Authorization(value = "auth", scopes = {
@AuthorizationScope(scope = "read:ToscaTemplate", description = "read your topolog template")
,
@AuthorizationScope(scope = "write:ToscaTemplate", description = "modify topolog template in your account")
})
}, tags = {})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = String.class)
,
@ApiResponse(code = 404, message = "ToscaTemplate not found")})
@RequestMapping(value = "/manager/tosca_template/all",
method = RequestMethod.DELETE)
ResponseEntity<String> deleteAllToscaTemplates();
@ApiOperation(value = "Find topolog template by ID", nickname = "getToscaTemplateByID", notes = "Returns a single topolog template", response = String.class, authorizations = { @ApiOperation(value = "Find topolog template by ID", nickname = "getToscaTemplateByID", notes = "Returns a single topolog template", response = String.class, authorizations = {
@Authorization(value = "auth", scopes = { @Authorization(value = "auth", scopes = {
@AuthorizationScope(scope = "read:ToscaTemplate", description = "read your topolog template") @AuthorizationScope(scope = "read:ToscaTemplate", description = "read your topolog template")
......
...@@ -23,11 +23,13 @@ import nl.uva.sne.drip.service.DRIPService; ...@@ -23,11 +23,13 @@ import nl.uva.sne.drip.service.DRIPService;
import nl.uva.sne.drip.service.ToscaTemplateService; import nl.uva.sne.drip.service.ToscaTemplateService;
import nl.uva.sne.drip.sure.tosca.client.ApiException; import nl.uva.sne.drip.sure.tosca.client.ApiException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
@javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2019-10-10T17:15:46.465Z") @javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2019-10-10T17:15:46.465Z")
@Controller @Controller
@CrossOrigin(origins = "*")
public class ToscaTemplateApiController implements ToscaTemplateApi { public class ToscaTemplateApiController implements ToscaTemplateApi {
private static final Logger log = LoggerFactory.getLogger(ToscaTemplateApiController.class); private static final Logger log = LoggerFactory.getLogger(ToscaTemplateApiController.class);
...@@ -50,8 +52,8 @@ public class ToscaTemplateApiController implements ToscaTemplateApi { ...@@ -50,8 +52,8 @@ public class ToscaTemplateApiController implements ToscaTemplateApi {
@ApiParam(value = "ID of topology template to return", required = true) @ApiParam(value = "ID of topology template to return", required = true)
@PathVariable("id") String id, @ApiParam(value = "The node(s) to delete") @PathVariable("id") String id, @ApiParam(value = "The node(s) to delete")
@Valid @RequestParam(value = "node_names", required = false) List<String> nodeName) { @Valid @RequestParam(value = "node_names", required = false) List<String> nodeName) {
String accept = request.getHeader("Accept"); // String accept = request.getHeader("Accept");
if (accept != null && accept.contains("text/plain")) { // if (accept != null && accept.contains("text/plain")) {
try { try {
dripService.delete(id, nodeName); dripService.delete(id, nodeName);
return new ResponseEntity<>(id, HttpStatus.OK); return new ResponseEntity<>(id, HttpStatus.OK);
...@@ -61,28 +63,47 @@ public class ToscaTemplateApiController implements ToscaTemplateApi { ...@@ -61,28 +63,47 @@ public class ToscaTemplateApiController implements ToscaTemplateApi {
} catch (NotFoundException ex) { } catch (NotFoundException ex) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND); return new ResponseEntity<>(HttpStatus.NOT_FOUND);
} }
} else { // } else {
return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE); // return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE);
} // }
} }
@Override @Override
public ResponseEntity<String> getToscaTemplateByID(@ApiParam(value = "ID of topolog template to return", required = true) @PathVariable("id") String id) { public ResponseEntity<String> deleteAllToscaTemplates() {
String accept = request.getHeader("Accept"); List<String> ids = toscaTemplateService.getAllIds();
if (accept != null && accept.contains("text/plain")) { try {
for (String id : ids) {
dripService.delete(id, null);
}
return new ResponseEntity<>(HttpStatus.OK);
} catch (IOException | ApiException | TypeExeption | TimeoutException | InterruptedException ex) {
java.util.logging.Logger.getLogger(ToscaTemplateApiController.class.getName()).log(Level.SEVERE, null, ex);
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
} catch (NotFoundException ex) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
@Override
public ResponseEntity<String> getToscaTemplateByID(@ApiParam(value = "ID of topolog template to return", required = true)
@PathVariable("id") String id) {
// String accept = request.getHeader("Accept");
// if (accept != null && accept.contains("text/plain")) {
try { try {
java.util.logging.Logger.getLogger(ToscaTemplateApiController.class.getName()).log(Level.INFO, "Requestsed ID: {0}", id);
String ymlStr = toscaTemplateService.findByID(id); String ymlStr = toscaTemplateService.findByID(id);
return new ResponseEntity<>(ymlStr, HttpStatus.OK); return new ResponseEntity<>(ymlStr, HttpStatus.OK);
} catch (JsonProcessingException | NotFoundException ex) { } catch (NotFoundException | java.util.NoSuchElementException ex) {
java.util.logging.Logger.getLogger(ToscaTemplateApiController.class.getName()).log(Level.WARNING, null, ex);
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
} catch (JsonProcessingException ex) {
java.util.logging.Logger.getLogger(ToscaTemplateApiController.class.getName()).log(Level.SEVERE, null, ex); java.util.logging.Logger.getLogger(ToscaTemplateApiController.class.getName()).log(Level.SEVERE, null, ex);
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
} }
} else { // } else {
return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE); // return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE);
} // }
} }
@Override @Override
...@@ -90,8 +111,8 @@ public class ToscaTemplateApiController implements ToscaTemplateApi { ...@@ -90,8 +111,8 @@ public class ToscaTemplateApiController implements ToscaTemplateApi {
value = "ID of topolog template to return", required = true) value = "ID of topolog template to return", required = true)
@PathVariable("id") String id, @ApiParam(value = "file detail") @PathVariable("id") String id, @ApiParam(value = "file detail")
@Valid @RequestPart("file") MultipartFile file) { @Valid @RequestPart("file") MultipartFile file) {
String accept = request.getHeader("Accept"); // String accept = request.getHeader("Accept");
if (accept != null && accept.contains("text/plain")) { // if (accept != null && accept.contains("text/plain")) {
try { try {
id = toscaTemplateService.updateToscaTemplateByID(id, file); id = toscaTemplateService.updateToscaTemplateByID(id, file);
return new ResponseEntity<>(id, HttpStatus.OK); return new ResponseEntity<>(id, HttpStatus.OK);
...@@ -100,15 +121,15 @@ public class ToscaTemplateApiController implements ToscaTemplateApi { ...@@ -100,15 +121,15 @@ public class ToscaTemplateApiController implements ToscaTemplateApi {
java.util.logging.Logger.getLogger(ToscaTemplateApiController.class.getName()).log(Level.SEVERE, null, e); java.util.logging.Logger.getLogger(ToscaTemplateApiController.class.getName()).log(Level.SEVERE, null, e);
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
} }
} else { // } else {
return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE); // return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE);
} // }
} }
@Override @Override
public ResponseEntity<String> uploadToscaTemplate(@ApiParam(value = "file detail") @Valid @RequestPart("file") MultipartFile file) { public ResponseEntity<String> uploadToscaTemplate(@ApiParam(value = "file detail") @Valid @RequestPart("file") MultipartFile file) {
String accept = request.getHeader("Accept"); // String accept = request.getHeader("Accept");
if (accept != null && accept.contains("*/*")) { // if (accept != null && accept.contains("*/*")) {
try { try {
String id = toscaTemplateService.saveFile(file); String id = toscaTemplateService.saveFile(file);
return new ResponseEntity<>(id, HttpStatus.OK); return new ResponseEntity<>(id, HttpStatus.OK);
...@@ -117,21 +138,21 @@ public class ToscaTemplateApiController implements ToscaTemplateApi { ...@@ -117,21 +138,21 @@ public class ToscaTemplateApiController implements ToscaTemplateApi {
log.error("Couldn't serialize response for content type application/json", e); log.error("Couldn't serialize response for content type application/json", e);
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
} }
} else { // } else {
return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE); // return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE);
} // }
} }
@Override @Override
public ResponseEntity<List<String>> getToscaTemplateIDs() { public ResponseEntity<List<String>> getToscaTemplateIDs() {
String accept = request.getHeader("Accept"); // String accept = request.getHeader("Accept");
if (accept != null && accept.contains("application/json")) { // if (accept != null && accept.contains("application/json")) {
List<String> ids = toscaTemplateService.getAllIds(); List<String> ids = toscaTemplateService.getAllIds();
return new ResponseEntity<>(ids, HttpStatus.NOT_IMPLEMENTED); return new ResponseEntity<>(ids, HttpStatus.OK);
} else { // } else {
return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE); // return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE);
} // }
} }
......
...@@ -17,10 +17,12 @@ import javax.validation.Valid; ...@@ -17,10 +17,12 @@ import javax.validation.Valid;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.io.IOException; import java.io.IOException;
import java.util.logging.Level; import java.util.logging.Level;
import org.springframework.web.bind.annotation.CrossOrigin;
@javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2019-10-10T17:15:46.465Z") @javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2019-10-10T17:15:46.465Z")
@Controller @Controller
@CrossOrigin(origins = "*")
public class UserApiController implements UserApi { public class UserApiController implements UserApi {
private static final Logger log = LoggerFactory.getLogger(UserApiController.class); private static final Logger log = LoggerFactory.getLogger(UserApiController.class);
......
...@@ -15,8 +15,12 @@ public class SwaggerDocumentationConfig { ...@@ -15,8 +15,12 @@ public class SwaggerDocumentationConfig {
ApiInfo apiInfo() { ApiInfo apiInfo() {
return new ApiInfoBuilder() return new ApiInfoBuilder()
.title("DRIP") .title("CONF")
.description("The Dynamic Real-time infrastructure planner (DRIP) allows application developers to seamlessly plan a customized virtual infrastructure based on application level constraints on QoS and resource budgets, provisioning the virtual infrastructure, deploy application components onto the virtual infrastructure, and start execution on demand using TOSCA.") .description("Allows application developers to seamlessly plan a customized "
+ "virtual infrastructure based on application level constraints "
+ "on QoS and resource budgets, provisioning the virtual infrastructure, "
+ "deploy application components onto the virtual infrastructure, "
+ "and start execution on demand using TOSCA.")
.license("Apache 2.0") .license("Apache 2.0")
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html") .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")
.termsOfServiceUrl("") .termsOfServiceUrl("")
......
...@@ -9,9 +9,12 @@ import com.rabbitmq.client.ConnectionFactory; ...@@ -9,9 +9,12 @@ import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DefaultConsumer; import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope; import com.rabbitmq.client.Envelope;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
...@@ -40,9 +43,9 @@ import org.springframework.stereotype.Service; ...@@ -40,9 +43,9 @@ import org.springframework.stereotype.Service;
@Service @Service
public class DRIPCaller implements AutoCloseable { public class DRIPCaller implements AutoCloseable {
private Connection connection; // private Connection connection;
private Channel channel; // private Channel channel;
private String replyQueueName; // private String replyQueueName;
private String requestQeueName; private String requestQeueName;
private final ObjectMapper mapper; private final ObjectMapper mapper;
private final ConnectionFactory factory; private final ConnectionFactory factory;
...@@ -60,61 +63,70 @@ public class DRIPCaller implements AutoCloseable { ...@@ -60,61 +63,70 @@ public class DRIPCaller implements AutoCloseable {
} }
public void init() throws IOException, TimeoutException { public void init() throws IOException, TimeoutException {
if (connection == null || !connection.isOpen()) { // if (connection == null || !connection.isOpen()) {
connection = factory.newConnection(); // connection = factory.newConnection();
channel = connection.createChannel(); // }
// create a single callback queue per client not per requests.
replyQueueName = channel.queueDeclare().getQueue();
}
} }
/** // /**
* @return the connection // * @return the connection
*/ // */
public Connection getConnection() { // public Connection getConnection() {
return connection; // return connection;
} // }
// /**
// * @return the channel
// */
// public Channel getChannel() {
// return channel;
// }
// /**
// * @return the replyQueueName
// */
// public String getReplyQueueName() {
// return replyQueueName;
// }
@Override
public void close() throws IOException, TimeoutException {
/** // if (connection != null && connection.isOpen()) {
* @return the channel // connection.close();
*/ // }
public Channel getChannel() {
return channel;
} }
/** public Message call(Message r) throws IOException, TimeoutException, InterruptedException {
* @return the replyQueueName Channel channel = null;
*/ Connection connection = null;
public String getReplyQueueName() { try {
return replyQueueName; String jsonInString = mapper.writeValueAsString(r);
}
@Override int timeOut = 25;
public void close() throws IOException, TimeoutException { if (getRequestQeueName().equals("planner")) {
if (channel != null && channel.isOpen()) { timeOut = 5;
channel.close();
}
if (connection != null && connection.isOpen()) {
connection.close();
} }
if (getRequestQeueName().equals("provisioner")) {
timeOut = 10;
} }
connection = factory.newConnection();
public Message call(Message r) throws IOException, TimeoutException, InterruptedException { channel = connection.createChannel();
Map<String, Object> args = new HashMap<>();
String jsonInString = mapper.writeValueAsString(r); String replyQueueName = channel.queueDeclare().getQueue();
//Build a correlation ID to distinguish responds //Build a correlation ID to distinguish responds
final String corrId = UUID.randomUUID().toString(); final String corrId = UUID.randomUUID().toString();
AMQP.BasicProperties props = new AMQP.BasicProperties.Builder() AMQP.BasicProperties props = new AMQP.BasicProperties.Builder()
.correlationId(corrId) .correlationId(corrId)
.replyTo(getReplyQueueName()) .expiration(String.valueOf(timeOut * 60000))
.replyTo(replyQueueName)
.build(); .build();
Logger.getLogger(DRIPCaller.class.getName()).log(Level.INFO, "Sending: {0} to queue: {1}", new Object[]{jsonInString, getRequestQeueName()}); Logger.getLogger(DRIPCaller.class.getName()).log(Level.INFO, "Sending: {0} to queue: {1}", new Object[]{jsonInString, getRequestQeueName()});
getChannel().basicPublish("", getRequestQeueName(), props, jsonInString.getBytes("UTF-8"));
channel.basicPublish("", getRequestQeueName(), props, jsonInString.getBytes("UTF-8"));
final BlockingQueue<String> response = new ArrayBlockingQueue(1); final BlockingQueue<String> response = new ArrayBlockingQueue(1);
getChannel().basicConsume(getReplyQueueName(), true, new DefaultConsumer(getChannel()) { channel.basicConsume(replyQueueName, true, new DefaultConsumer(channel) {
@Override @Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
if (properties.getCorrelationId().equals(corrId)) { if (properties.getCorrelationId().equals(corrId)) {
...@@ -122,10 +134,22 @@ public class DRIPCaller implements AutoCloseable { ...@@ -122,10 +134,22 @@ public class DRIPCaller implements AutoCloseable {
} }
} }
}); });
String resp = response.take(); // String resp = response.take();
Logger.getLogger(DRIPCaller.class.getName()).log(Level.INFO, "Got: {0}", resp);
String resp = response.poll(timeOut, TimeUnit.MINUTES);
Logger.getLogger(DRIPCaller.class.getName()).log(Level.INFO, "Got: {0}", resp);
if (resp == null) {
throw new TimeoutException("Timeout on qeue: " + getRequestQeueName());
}
return mapper.readValue(resp, Message.class); return mapper.readValue(resp, Message.class);
} finally {
if (channel != null && channel.isOpen()) {
channel.close();
}
if (connection != null && connection.isOpen()) {
connection.close();
}
}
} }
/** /**
......
...@@ -58,9 +58,10 @@ public class DRIPService { ...@@ -58,9 +58,10 @@ public class DRIPService {
@Value("${message.broker.queue.deployer}") @Value("${message.broker.queue.deployer}")
private String deployerQueueName; private String deployerQueueName;
private String execute(ToscaTemplate toscaTemplate, String requestQeueName) throws JsonProcessingException, ApiException, IOException, TimeoutException, InterruptedException { private String execute(ToscaTemplate toscaTemplate, String requestQeueName) throws IOException, TimeoutException, InterruptedException{
try {
caller.init(); caller.init();
Logger.getLogger(DRIPService.class.getName()).log(Level.INFO, "toscaTemplate:\n{0}", toscaTemplate); // Logger.getLogger(DRIPService.class.getName()).log(Level.INFO, "toscaTemplate:\n{0}", toscaTemplate);
Message message = new Message(); Message message = new Message();
message.setOwner("user"); message.setOwner("user");
message.setCreationDate(System.currentTimeMillis()); message.setCreationDate(System.currentTimeMillis());
...@@ -69,8 +70,16 @@ public class DRIPService { ...@@ -69,8 +70,16 @@ public class DRIPService {
caller.setRequestQeueName(requestQeueName); caller.setRequestQeueName(requestQeueName);
Message response = caller.call(message); Message response = caller.call(message);
ToscaTemplate updatedToscaTemplate = response.getToscaTemplate(); ToscaTemplate updatedToscaTemplate = response.getToscaTemplate();
caller.close();
return toscaTemplateService.save(updatedToscaTemplate); return toscaTemplateService.save(updatedToscaTemplate);
} catch (IOException | TimeoutException | InterruptedException ex) {
throw ex;
}finally{
try {
caller.close();
} catch (IOException | TimeoutException ex) {
Logger.getLogger(DRIPService.class.getName()).log(Level.SEVERE, null, ex);
}
}
} }
...@@ -162,13 +171,24 @@ public class DRIPService { ...@@ -162,13 +171,24 @@ public class DRIPService {
public String delete(String id, List<String> nodeNames) throws NotFoundException, IOException, JsonProcessingException, ApiException, TypeExeption, TimeoutException, InterruptedException { public String delete(String id, List<String> nodeNames) throws NotFoundException, IOException, JsonProcessingException, ApiException, TypeExeption, TimeoutException, InterruptedException {
ToscaTemplate toscaTemplate = initExecution(id); ToscaTemplate toscaTemplate = initExecution(id);
boolean nothingToDelete = true;
//If no nodes are specified delete all the infrastructure //If no nodes are specified delete all the infrastructure
if (nodeNames == null || nodeNames.isEmpty()) { if (nodeNames == null || nodeNames.isEmpty()) {
List<NodeTemplateMap> vmTopologies = helper.getVMTopologyTemplates(); List<NodeTemplateMap> vmTopologies = helper.getVMTopologyTemplates();
if (vmTopologies != null) {
for (NodeTemplateMap vmTopology : vmTopologies) { for (NodeTemplateMap vmTopology : vmTopologies) {
NODE_STATES currentState = helper.getNodeCurrentState(vmTopology);
if (currentState != null && currentState != NODE_STATES.DELETED) {
nothingToDelete = false;
toscaTemplate = setDesieredSate(toscaTemplate, vmTopology, NODE_STATES.DELETED); toscaTemplate = setDesieredSate(toscaTemplate, vmTopology, NODE_STATES.DELETED);
} }
}
if (!nothingToDelete) {
this.toscaTemplateService.deleteByID(id);
return execute(toscaTemplate, provisionerQueueName); return execute(toscaTemplate, provisionerQueueName);
}
}
return id;
} else { } else {
} }
......
...@@ -14,9 +14,7 @@ import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature; ...@@ -14,9 +14,7 @@ import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger;
import nl.uva.sne.drip.api.NotFoundException; import nl.uva.sne.drip.api.NotFoundException;
import nl.uva.sne.drip.dao.ToscaTemplateDAO; import nl.uva.sne.drip.dao.ToscaTemplateDAO;
import nl.uva.sne.drip.model.Exceptions.TypeExeption; import nl.uva.sne.drip.model.Exceptions.TypeExeption;
...@@ -76,6 +74,7 @@ public class ToscaTemplateService { ...@@ -76,6 +74,7 @@ public class ToscaTemplateService {
public String findByID(String id) throws JsonProcessingException, NotFoundException { public String findByID(String id) throws JsonProcessingException, NotFoundException {
ToscaTemplate tt = dao.findById(id).get(); ToscaTemplate tt = dao.findById(id).get();
if (tt == null) { if (tt == null) {
java.util.logging.Logger.getLogger(ToscaTemplateService.class.getName()).log(Level.SEVERE, "ToscaTemplate with id: " + id + " not found");
throw new NotFoundException(404, "ToscaTemplate with id: " + id + " not found"); throw new NotFoundException(404, "ToscaTemplate with id: " + id + " not found");
} }
String ymlStr = objectMapper.writeValueAsString(tt); String ymlStr = objectMapper.writeValueAsString(tt);
......
...@@ -108,7 +108,7 @@ def handle_delivery(message, sys=None): ...@@ -108,7 +108,7 @@ def handle_delivery(message, sys=None):
template_dict = tosca_helper.get_tosca_template_2_topology_template_dictionary(tosca_template) template_dict = tosca_helper.get_tosca_template_2_topology_template_dictionary(tosca_template)
Planner(yaml_dict_tpl=template_dict, spec_service=spec_service) Planner(yaml_dict_tpl=template_dict, spec_service=spec_service)
logger.info("template ----: \n" + yaml.dump(template_dict)) logger.debug("template ----: \n" + yaml.dump(template_dict))
response = {'toscaTemplate': template_dict} response = {'toscaTemplate': template_dict}
output_current_milli_time = int(round(time.time() * 1000)) output_current_milli_time = int(round(time.time() * 1000))
...@@ -130,14 +130,14 @@ if __name__ == "__main__": ...@@ -130,14 +130,14 @@ if __name__ == "__main__":
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
if sys.argv[1] == "test_local": if sys.argv[1] == "test_local":
tosca_path = "../TOSCA/" tosca_path = "../TOSCA/"
input_tosca_file_path = tosca_path + '/application_example_updated.yaml' input_tosca_file_path = tosca_path + '/generated_tosca_description_a8a061322c3b4b5593c289df841727af.yaml'
conf = {'url': "http://host"} conf = {'url': "http://host"}
spec_service = SpecService(conf) spec_service = SpecService(conf)
test_planner = Planner(input_tosca_file_path, spec_service) test_planner = Planner(input_tosca_file_path, spec_service)
test_tosca_template = test_planner.resolve_requirements() test_tosca_template = test_planner.resolve_requirements()
test_tosca_template = test_planner.set_node_templates_properties() test_tosca_template = test_planner.set_node_templates_properties()
template_dict = tosca_helper.get_tosca_template_2_topology_template_dictionary(test_tosca_template) template_dict = tosca_helper.get_tosca_template_2_topology_template_dictionary(test_tosca_template)
logger.info("template ----: \n" + yaml.dump(template_dict)) logger.debug("template ----: \n" + yaml.dump(template_dict))
ToscaTemplate(yaml_dict_tpl=copy.deepcopy(template_dict)) ToscaTemplate(yaml_dict_tpl=copy.deepcopy(template_dict))
......
import logging
import yaml
from toscaparser.nodetemplate import NodeTemplate
from toscaparser.tosca_template import ToscaTemplate
from toscaparser.topology_template import TopologyTemplate
import operator
from service.simple_spec_alayzer import SimpleAnalyzer
from util import tosca_helper
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
def add_requirements(node, missing_requirements, capable_node_name):
"""Add the requirements to the node """
for req in missing_requirements:
req[next(iter(req))]['node'] = capable_node_name
if isinstance(node, NodeTemplate):
contains_requirement = False
for node_requirement in node.requirements:
if node_requirement == req:
contains_requirement = True
break
if not contains_requirement:
node.requirements.append(req)
elif isinstance(node, dict):
type_name = next(iter(node))
if 'requirements' not in node[type_name]:
node[type_name]['requirements'] = []
node_requirements = node[type_name]['requirements']
contains_requirement = False
for node_requirement in node_requirements:
if node_requirement == req:
contains_requirement = True
break
if not contains_requirement:
node[type_name]['requirements'].append(req)
return node
def get_default_value(node_property):
if node_property and node_property.required and isinstance(node_property.value, dict) and 'required' in \
node_property.value and 'type' in node_property.value:
if node_property.default:
return {node_property.name: node_property.default}
if node_property.constraints:
for constraint in node_property.constraints:
print(constraint)
if node_property and node_property.required and node_property.value:
return {node_property.name: node_property.value}
return None
class Planner:
def __init__(self, tosca_path=None, yaml_dict_tpl=None, spec_service=None):
if tosca_path:
self.path = tosca_path
self.tosca_template = ToscaTemplate(tosca_path)
elif yaml_dict_tpl:
self.yaml_dict_tpl = yaml_dict_tpl
logger.info('yaml_dict_tpl:\n' + str(yaml.dump(yaml_dict_tpl)))
self.tosca_template = ToscaTemplate(yaml_dict_tpl=yaml_dict_tpl)
self.tosca_node_types = self.tosca_template.nodetemplates[0].type_definition.TOSCA_DEF
self.all_custom_def = self.tosca_template.nodetemplates[0].custom_def
self.all_node_types = {}
self.all_node_types.update(self.tosca_node_types.items())
self.all_node_types.update(self.all_custom_def.items())
self.required_nodes = []
self.spec_service = spec_service
def add_required_nodes_to_template(self, required_nodes):
for req_node in required_nodes:
node_template = tosca_helper.node_type_2_node_template(req_node, self.all_custom_def)
self.tosca_template.nodetemplates.append(node_template)
return self.tosca_template
def set_default_node_properties(self, node):
logger.info('Setting properties for: ' + str(node.type))
ancestors_properties = tosca_helper.get_all_ancestors_properties(node, self.all_node_types,
self.all_custom_def)
default_properties = {}
if ancestors_properties:
for ancestors_property in ancestors_properties:
for node_prop in node.get_properties_objects():
if ancestors_property.name == node_prop.name and isinstance(node_prop.value,dict) \
and 'required' in node_prop.value and 'type' in node_prop.value:
default_property = get_default_value(ancestors_property)
if default_property:
node_prop.value = default_property
default_properties[next(iter(default_property))] = default_property[
next(iter(default_property))]
if default_properties:
for default_property in default_properties:
for node_prop_obj in node.get_properties_objects():
if default_property == node_prop_obj.name and not node_prop_obj.value:
node.get_properties_objects().append(default_property)
node_name = next(iter(node.templates))
if 'properties' in node.templates[node_name]:
for prop_name in node.templates[node_name]['properties']:
if isinstance(node.templates[node_name]['properties'][prop_name], dict) or \
isinstance(node.templates[node_name]['properties'][prop_name], str):
if 'required' in node.templates[node_name]['properties'][prop_name] and \
node.templates[node_name]['properties'][prop_name]['required'] and \
'default' in node.templates[node_name]['properties'][prop_name] and \
prop_name not in default_properties:
default_properties[prop_name] = node.templates[node_name]['properties'][prop_name][
'default']
logger.info(
'Adding to : ' + str(node.templates[node_name]) + ' properties: ' + str(default_properties))
node.templates[node_name]['properties'] = default_properties
return node
def set_node_templates_properties(self):
for node_template in self.tosca_template.nodetemplates:
self.set_default_node_properties(node_template)
specification_analyzer = SimpleAnalyzer(self.tosca_template)
nodes_with_new_relationship_occurrences = specification_analyzer.set_relationship_occurrences()
added_node_names = []
for new_spec_occurrences in nodes_with_new_relationship_occurrences:
for index, node_in_temple in enumerate(self.tosca_template.nodetemplates):
if new_spec_occurrences.name == node_in_temple.name:
added_node_names.append(new_spec_occurrences.name)
self.tosca_template.nodetemplates[index] = new_spec_occurrences
break
for new_spec_occurrences in nodes_with_new_relationship_occurrences:
if new_spec_occurrences.name not in added_node_names:
self.tosca_template.nodetemplates.append(new_spec_occurrences)
return self.tosca_template
def get_node_template_property(self, prop_key, node_prop_dict):
prop_value = self.spec_service.get_property(prop_key)
if prop_value:
return {prop_key: node_prop_dict}
else:
if 'required' in node_prop_dict and 'default' in node_prop_dict:
return node_prop_dict['default']
if 'constraints' in node_prop_dict:
constraints = node_prop_dict['constraints']
for constraint in constraints:
if next(iter(constraint)) == 'greater_or_equal':
return constraint[next(iter(constraint))]
return None
def resolve_requirements(self):
""" Resolve requirements. Go over all nodes and recursively resolve requirements till node has no
requirements e.g. docker -> k8s -> cluster -> vm """
for node in self.tosca_template.nodetemplates:
self.add_interfaces(node)
self.add_required_nodes(node)
return self.add_required_nodes_to_template(self.required_nodes)
def add_required_nodes(self, node):
"""Adds the required nodes in self.required_nodes for an input node."""
if isinstance(node, NodeTemplate):
logger.info('Resolving requirements for: ' + node.name)
elif isinstance(node, dict):
logger.info('Resolving requirements for: ' + str(next(iter(node))))
# Get all requirements for node.
all_requirements = self.get_all_requirements(node)
if not all_requirements:
logger.debug('Node: ' + tosca_helper.get_node_type_name(node) + ' has no requirements')
return
matching_node = self.find_best_node_for_requirements(all_requirements)
# Only add node that is not in node_templates
matching_node_type_name = next(iter(matching_node))
matching_node_template = tosca_helper.node_type_2_node_template(matching_node, self.all_custom_def)
# Add the requirements to the node we analyzed. e.g. docker needed host now we added the type and name of host
node = add_requirements(node, all_requirements, matching_node_template.name)
if not tosca_helper.contains_node_type(self.required_nodes, matching_node_type_name) and \
not tosca_helper.contains_node_type(self.tosca_template.nodetemplates, matching_node_type_name):
logger.info(' Adding: ' + str(matching_node_template.name))
self.required_nodes.append(matching_node)
# Find matching nodes for the new node's requirements
self.add_required_nodes(matching_node)
def get_all_requirements(self, node):
"""Returns all requirements for an input node including all parents requirements"""
node_type_name = tosca_helper.get_node_type_name(node)
logger.info(' Looking for requirements for node: ' + node_type_name)
# Get the requirements for this node from its definition e.g. docker: hostedOn k8s
def_type = self.all_node_types[node_type_name]
all_requirements = []
if 'requirements' in def_type.keys():
all_requirements = def_type['requirements']
logger.info(' Found requirements: ' + str(all_requirements) + ' for node: ' + node_type_name)
# Get the requirements for this node from the template. e.g. wordpress: connectsTo mysql
# node_requirements = tosca_helper.get_node_requirements(node)
# if node_requirements:
# all_requirements += node_requirements
# Put them all together
parent_requirements = tosca_helper.get_ancestors_requirements(node, self.all_node_types, self.all_custom_def)
parent_type = tosca_helper.get_node_type_name(node)
if parent_type and parent_requirements:
logger.info(
' Adding to : ' + str(node_type_name) + ' parent requirements from: ' + str(parent_type))
if not all_requirements:
all_requirements += parent_requirements
else:
for all_requirement in all_requirements:
for parent_requirement in parent_requirements:
all_requirement_key = next(iter(all_requirement))
parent_requirement_key = next(iter(parent_requirement))
if all_requirement_key != parent_requirement_key and all_requirement[all_requirement_key][
'capability'] != parent_requirement[parent_requirement_key]['capability']:
all_requirements.append(parent_requirement)
logger.debug(' all_requirements: ' + str(all_requirements))
return all_requirements
def get_node_types_by_capability(self, cap):
"""Returns all nodes that have the capability: cap and have interfaces. This way we distinguish between
'abstract' and 'concrete' """
candidate_nodes = {}
for tosca_node_type in self.all_node_types:
if tosca_node_type.startswith('tosca.nodes') and 'capabilities' in self.all_node_types[tosca_node_type]:
logger.debug(' Node: ' + str(tosca_node_type))
for caps in self.all_node_types[tosca_node_type]['capabilities']:
logger.debug(' ' + str(
self.all_node_types[tosca_node_type]['capabilities'][caps]['type']) + ' == ' + cap)
if self.all_node_types[tosca_node_type]['capabilities'][caps]['type'] == cap:
candidate_nodes[tosca_node_type] = self.all_node_types[tosca_node_type]
logger.debug(' candidate_node: ' + str(tosca_node_type))
candidate_child_nodes = {}
for node in candidate_nodes:
candidate_child_nodes.update(self.get_child_nodes(node))
candidate_nodes.update(candidate_child_nodes)
capable_nodes = {}
# Only return the nodes that have interfaces. This means that they are not "abstract"
nodes_type_names_with_interface = tosca_helper.get_node_types_with_interface(candidate_nodes)
for type_name in nodes_type_names_with_interface:
capable_nodes[type_name] = candidate_nodes[type_name]
return capable_nodes
def find_best_node_for_requirements(self, all_requirements):
"""Returns the 'best' node for a set of requirements. Here we count the number of requiremets that the node
can cover and return the one which covers the most """
matching_nodes = {}
number_of_matching_requirement = {}
# Loop requirements to find nodes per requirement
for req in all_requirements:
key = next(iter(req))
if not req[key]:
raise Exception('Requirement: '+str(req)+ ' is not properly defined')
if 'capability' in req[key]:
capability = req[key]['capability']
# Find all nodes in the definitions that have the capability: capability
logger.info(' Looking for nodes in node types with capability: ' + capability)
capable_nodes = self.get_node_types_by_capability(capability)
if capable_nodes:
# Add number of matching capabilities for each node.
# Try to score matching_nodes to return one. The more requirements a node meets the better
for node_type in capable_nodes:
matching_requirement_count = 1
if node_type not in number_of_matching_requirement:
number_of_matching_requirement[node_type] = matching_requirement_count
else:
matching_requirement_count = number_of_matching_requirement[node_type]
matching_requirement_count += 1
number_of_matching_requirement[node_type] = matching_requirement_count
logger.info(' Found: ' + str(node_type))
matching_nodes.update(capable_nodes)
else:
logger.error('Did not find any node with required capability: ' + str(capability))
raise Exception('Did not find any node with required capability: ' + str(capability))
# if we only found 1 return it
if len(matching_nodes) == 1:
return matching_nodes
sorted_number_of_matching_requirement = sorted(number_of_matching_requirement.items(),
key=operator.itemgetter(1))
index = len(sorted_number_of_matching_requirement) - 1
winner_type = next(iter(sorted_number_of_matching_requirement[index]))
return {winner_type: matching_nodes[winner_type]}
def get_child_nodes(self, parent_node_type_name):
child_nodes = {}
for tosca_node_type in self.all_node_types:
if tosca_node_type.startswith('tosca.nodes') and 'derived_from' in self.all_node_types[tosca_node_type]:
if parent_node_type_name == self.all_node_types[tosca_node_type]['derived_from']:
child_nodes[tosca_node_type] = self.all_node_types[tosca_node_type]
return child_nodes
def add_interfaces(self, node):
# node_type_interfaces = tosca_helper.get_node_type_interfaces(node)
# node_template_interfaces = tosca_helper.get_node_template_interfaces(node)
# if not node_template_interfaces and node_type_interfaces:
# tosca_helper.add_interfaces(node,node_type_interfaces)
return node
import copy
from toscaparser.nodetemplate import NodeTemplate
from toscaparser.properties import Property
import networkx as nx
import logging
from service.specification_analyzer import SpecificationAnalyzer
from util import tosca_helper
def get_default_value(node_property):
if node_property and node_property.required and isinstance(node_property.value, dict) and 'required' in \
node_property.value and 'type' in node_property.value:
if node_property.default:
return {node_property.name: node_property.default}
if node_property.constraints:
for constraint in node_property.constraints:
print(constraint)
if node_property and node_property.required and node_property.value:
return {node_property.name: node_property.value}
return None
class SimpleAnalyzer(SpecificationAnalyzer):
def __init__(self, tosca_template):
super(SimpleAnalyzer, self).__init__(tosca_template)
def set_relationship_occurrences(self):
return_nodes = []
nodes_with_min_vms = tosca_helper.get_nodes_by_type('tosca.nodes.QC.docker.Orchestrator',
self.tosca_template.nodetemplates, self.all_node_types,
self.all_custom_def)
nodes_with_min_vms = nodes_with_min_vms + tosca_helper.get_nodes_by_type('tosca.nodes.QC.Application.GlusterFS',
self.tosca_template.nodetemplates,
self.all_node_types,
self.all_custom_def)
min_masters_num = 0
workers_num = 0
if nodes_with_min_vms:
for node_with_min_vms in nodes_with_min_vms:
if 'properties' in node_with_min_vms.entity_tpl:
if 'min_masters_num' in node_with_min_vms.entity_tpl['properties']:
min_masters_num = min_masters_num + node_with_min_vms.entity_tpl['properties'][
'min_masters_num']
if 'min_workers_num' in node_with_min_vms.entity_tpl['properties']:
workers_num = workers_num + node_with_min_vms.entity_tpl['properties']['min_workers_num']
else:
min_masters_num = min_masters_num + node_with_min_vms.get_property_value('min_masters_num')
workers_num = workers_num + node_with_min_vms.get_property_value('min_workers_num')
if min_masters_num < 0:
min_masters_num = 1
topology_nodes = tosca_helper.get_nodes_by_type('tosca.nodes.QC.VM.topology',
self.tosca_template.nodetemplates, self.all_node_types,
self.all_custom_def)
if topology_nodes:
vm_nodes = tosca_helper.get_nodes_by_type('tosca.nodes.QC.VM.Compute',
self.tosca_template.nodetemplates, self.all_node_types,
self.all_custom_def)
if vm_nodes:
for i in range(len(vm_nodes), min_masters_num):
old_vm_name = vm_nodes[0].name
new_vm = copy.deepcopy(vm_nodes[0])
new_vm_name = new_vm.name + '_' + str(i)
new_vm.name = new_vm_name
templates = new_vm.templates.pop(old_vm_name)
new_vm.templates[new_vm_name] = templates
return_nodes.append(new_vm)
for requirement in topology_nodes[0].requirements:
requirement_key = next(iter(requirement))
requirement_value = requirement[requirement_key]
if requirement_value['capability'] == 'tosca.capabilities.QC.VM':
new_requirement = copy.deepcopy(requirement)
new_requirement[requirement_key]['node'] = new_vm.name
topology_nodes[0].requirements.append(new_requirement)
return_nodes.append(topology_nodes[0])
break
for i in range(len(vm_nodes), workers_num + 1):
old_vm_name = vm_nodes[0].name
new_vm = copy.deepcopy(vm_nodes[0])
new_vm_name = new_vm.name + '_' + str(i)
new_vm.name = new_vm_name
templates = new_vm.templates.pop(old_vm_name)
new_vm.templates[new_vm_name] = templates
return_nodes.append(new_vm)
for requirement in topology_nodes[0].requirements:
requirement_key = next(iter(requirement))
requirement_value = requirement[requirement_key]
if requirement_value['capability'] == 'tosca.capabilities.QC.VM':
new_requirement = copy.deepcopy(requirement)
new_requirement[requirement_key]['node'] = new_vm.name
topology_nodes[0].requirements.append(new_requirement)
return_nodes.append(topology_nodes[0])
break
return return_nodes
def set_node_specifications(self):
nodes = []
for node_template in self.tosca_template.nodetemplates:
nodes.append(self.set_default_node_properties(node_template))
return nodes
# def set_default_node_properties(self, node):
# logging.info('Setting properties for: ' + str(node.type))
# ancestors_properties = tosca_helper.get_all_ancestors_properties(node, self.all_node_types,
# self.all_custom_def)
# default_properties = {}
# for ancestors_property in ancestors_properties:
# default_property = get_default_value(ancestors_property)
# if default_property:
# default_properties[next(iter(default_property))] = default_property[next(iter(default_property))]
#
# if default_properties:
# for default_property in default_properties:
# node.get_properties_objects().append(default_property)
# node_name = next(iter(node.templates))
# if 'properties' in node.templates[node_name]:
# for prop_name in node.templates[node_name]['properties']:
# if isinstance(node.templates[node_name]['properties'][prop_name], dict) or \
# isinstance(node.templates[node_name]['properties'][prop_name], str):
# if 'required' in node.templates[node_name]['properties'][prop_name] and \
# node.templates[node_name]['properties'][prop_name]['required'] and \
# 'default' in node.templates[node_name]['properties'][prop_name] and \
# prop_name not in default_properties:
# default_properties[prop_name] = node.templates[node_name]['properties'][prop_name][
# 'default']
#
# logging.info(
# 'Adding to : ' + str(node.templates[node_name]) + ' properties: ' + str(default_properties))
# node.templates[node_name]['properties'] = default_properties
# return node
class SpecService:
def __init__(self, conf):
self.configuration = conf
def get_property(self, prop_key):
return None
from abc import abstractmethod, ABCMeta
from toscaparser.tosca_template import ToscaTemplate
import networkx as nx
# import matplotlib.pyplot as plt
class SpecificationAnalyzer(metaclass=ABCMeta):
def __init__(self, tosca_template):
self.tosca_template = tosca_template
self.tosca_node_types = self.tosca_template.nodetemplates[0].type_definition.TOSCA_DEF
self.all_custom_def = self.tosca_template.nodetemplates[0].custom_def
self.all_node_types = {}
self.all_node_types.update(self.tosca_node_types.items())
self.all_node_types.update(self.all_custom_def.items())
self.required_nodes = []
self.g = self.build_graph(self.tosca_template.nodetemplates)
self.root_nodes = []
self.leaf_nodes = []
for node_name, degree in self.g.in_degree():
if degree == 0:
self.root_nodes.append(node_name)
for node_name, degree in self.g.out_degree():
if degree == 0:
self.leaf_nodes.append(node_name)
def build_graph(self, node_templates):
graph = nx.DiGraph()
for node in node_templates:
graph.add_node(node.name, attr_dict=node.entity_tpl)
for req in node.requirements:
req_name = next(iter(req))
req_node_name = req[req_name]['node']
if 'relationship' in req[req_name] and 'type' in req[req_name]['relationship']:
relationship_type = req[req_name]['relationship']['type']
else:
if 'relationship' not in req[req_name]:
relationship_type = 'tosca.relationships.DependsOn'
else:
relationship_type = req[req_name]['relationship']
graph.add_edge(node.name, req_node_name, relationship=relationship_type)
# nx.draw(graph, with_labels=True)
# plt.savefig("/tmp/graph.png")
# plt.show()
return graph
@abstractmethod
def set_node_specifications(self):
raise NotImplementedError('Must implement upload in subclasses')
@abstractmethod
def set_relationship_occurrences(self):
raise NotImplementedError('Must implement upload in subclasses')
import copy
import json
import logging
import os
import os.path
import tempfile
import time
import unittest
import requests
import yaml
from toscaparser.tosca_template import ToscaTemplate
from planner.planner import Planner
from service.spec_service import SpecService
from util import tosca_helper
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
class MyTestCase(unittest.TestCase):
# def test_tic_gluster_fs(self):
# url = 'https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/glusterFS.yaml'
# input_tosca_file_path = self.get_remote_tosca_file(url)
# self.run_test(input_tosca_file_path)
def test_tic(self):
url = 'https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/TIC.yaml'
input_tosca_file_path = self.get_remote_tosca_file(url)
self.run_test(input_tosca_file_path)
def test_docker(self):
url = 'https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/application_example_updated.yaml'
input_tosca_file_path = self.get_remote_tosca_file(url)
self.run_test(input_tosca_file_path)
url = 'https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/lifeWatch_vre1.yaml'
input_tosca_file_path = self.get_remote_tosca_file(url)
self.run_test(input_tosca_file_path)
def test_kubernetes(self):
url = 'https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/kubernetes.yaml'
input_tosca_file_path = self.get_remote_tosca_file(url)
self.run_test(input_tosca_file_path)
def test_topology(self):
url = 'https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/topology.yaml'
input_tosca_file_path = self.get_remote_tosca_file(url)
self.run_test(input_tosca_file_path)
def test_compute(self):
url = 'https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/compute.yaml'
input_tosca_file_path = self.get_remote_tosca_file(url)
self.run_test(input_tosca_file_path)
def test_lifeWatch(self):
url = 'https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/lifeWatch_vre1.yaml'
tic_tosca = requests.get(url)
input_tosca_file_path = os.path.join(tempfile.gettempdir(),'TIC.yaml')
open( input_tosca_file_path, 'wb').write(tic_tosca.content)
self.run_test(input_tosca_file_path)
def get_input_tosca_file_path(self, file_name):
tosca_path = "../../TOSCA/"
input_tosca_file_path = tosca_path + file_name
if not os.path.exists(input_tosca_file_path):
tosca_path = "../TOSCA/"
input_tosca_file_path = tosca_path + file_name
self.assertEqual(True, os.path.exists(input_tosca_file_path),
"Input TOSCA file: " + input_tosca_file_path + " not found")
return input_tosca_file_path
def run_test(self, input_tosca_file_path):
conf = {'url': "http://host"}
spec_service = SpecService(conf)
test_planner = Planner(input_tosca_file_path, spec_service)
test_tosca_template = test_planner.resolve_requirements()
template_dict = tosca_helper.get_tosca_template_2_topology_template_dictionary(test_tosca_template)
test_tosca_template = test_planner.set_node_templates_properties()
template_dict = tosca_helper.get_tosca_template_2_topology_template_dictionary(test_tosca_template)
logger.info("template ----: \n" + yaml.dump(template_dict))
print(yaml.dump(template_dict))
ToscaTemplate(yaml_dict_tpl=copy.deepcopy(template_dict))
test_response = {'toscaTemplate': template_dict}
response = {'toscaTemplate': template_dict}
output_current_milli_time = int(round(time.time() * 1000))
response["creationDate"] = output_current_milli_time
response["parameters"] = []
# print("Output message:" + json.dumps(response))
self.assertEqual(True, True)
def get_remote_tosca_file(self, url):
tosca = requests.get(url)
input_tosca_file_path = os.path.join(tempfile.gettempdir(),'test_tosca_file.yaml')
open( input_tosca_file_path, 'wb').write(tosca.content)
return input_tosca_file_path
import copy
from itertools import chain
from toscaparser import tosca_template
from toscaparser.elements.nodetype import NodeType
from toscaparser.nodetemplate import NodeTemplate
import yaml
import logging
# TOSCA template key names
SECTIONS = (DEFINITION_VERSION, DEFAULT_NAMESPACE, TEMPLATE_NAME,
TOPOLOGY_TEMPLATE, TEMPLATE_AUTHOR, TEMPLATE_VERSION,
DESCRIPTION, IMPORTS, DSL_DEFINITIONS, NODE_TYPES,
RELATIONSHIP_TYPES, RELATIONSHIP_TEMPLATES,
CAPABILITY_TYPES, ARTIFACT_TYPES, DATA_TYPES, INTERFACE_TYPES,
POLICY_TYPES, GROUP_TYPES, REPOSITORIES, INPUTS, NODE_TEMPLATES,
OUTPUTS, GROUPS, SUBSTITUION_MAPPINGS, POLICIES, TYPE, REQUIREMENTS,
ARTIFACTS, PROPERTIES, INTERFACES) = \
('tosca_definitions_version', 'tosca_default_namespace',
'template_name', 'tosca_template', 'template_author',
'template_version', 'description', 'imports', 'dsl_definitions',
'node_types', 'relationship_types', 'relationship_templates',
'capability_types', 'artifact_types', 'data_types',
'interface_types', 'policy_types', 'group_types', 'repositories',
'inputs', 'node_templates', 'outputs', 'groups', 'substitution_mappings',
'policies', 'type', 'requirements', 'artifacts', 'properties', 'interfaces')
node_type_key_names_to_remove = ['capabilities', 'derived_from']
def get_node_type_name(node):
"""Returns the node's type name as string"""
if isinstance(node, NodeTemplate):
if node.type:
if node.type and isinstance(node.type, str):
node_type = node.type
elif isinstance(node.type, NodeTemplate):
node_type = node.type.type
else:
node_type = None
elif isinstance(node, dict):
node_type = next(iter(node))
return node_type
def get_node_requirements(node):
if isinstance(node, NodeTemplate):
node_requirements = node.requirements
elif isinstance(node, dict):
node_type_name = get_node_type_name(node)
if 'requirements' not in node[node_type_name]:
node[node_type_name]['requirements'] = {}
node_requirements = node[node_type_name]['requirements']
return node_requirements
def get_parent_type(node):
if isinstance(node, NodeTemplate):
if node.parent_type:
parent_type = node.parent_type.type
else:
parent_type = None
elif isinstance(node, dict):
parent_type = node[next(iter(node))]['derived_from']
return parent_type
def get_node_type_requirements(type_name, all_nodes):
"""Returns the requirements for an input node as described in the template not in the node's definition """
def_type = all_nodes[type_name]
if 'requirements' in def_type.keys():
return def_type['requirements']
return None
def get_ancestors_requirements(node, all_nodes, all_custom_def, parent_requirements=None):
"""Recursively get all requirements all the way to the ROOT including the input node's"""
if not parent_requirements:
parent_requirements = []
if isinstance(node, NodeTemplate):
# If node has parent and parent has requirements add them
if node.parent_type and node.parent_type.requirements:
if isinstance(node.parent_type.requirements, dict):
parent_requirements.append(node.parent_type.requirements)
elif isinstance(node.parent_type.requirements, list):
parent_requirements.extend(node.parent_type.requirements)
# Make parent type to NodeTemplate to continue
if node.parent_type.type:
parent_template = node_type_2_node_template({'name': all_nodes[node.parent_type.type]}, all_custom_def)
if parent_template:
get_ancestors_requirements(parent_template, all_nodes, parent_requirements)
elif isinstance(node, dict):
node_type_name = get_node_type_name(node)
node_template = node_type_2_node_template({'name': all_nodes[node_type_name]}, all_custom_def)
return get_ancestors_requirements(node_template, all_nodes, all_custom_def, parent_requirements)
return parent_requirements
def get_node_types_with_interface(nodes):
node_types_with_interface = []
for node_name in nodes:
if 'interfaces' in nodes[node_name].keys() and 'tosca.nodes.Root' != node_name:
node_types_with_interface.append(node_name)
return node_types_with_interface
def node_type_2_node_template(node_type, all_custom_def):
node_template_dict = {}
type_name = next(iter(node_type))
node_type_array = type_name.split(".")
name = node_type_array[len(node_type_array) - 1].lower()
node_template_dict[name] = node_type[next(iter(node_type))].copy()
node_template_dict[name]['type'] = type_name
for name_to_remove in node_type_key_names_to_remove:
if name_to_remove in node_template_dict[name]:
node_template_dict[name].pop(name_to_remove)
if 'type' in node_type[next(iter(node_type))]:
node_type[next(iter(node_type))].pop('type')
node_template = NodeTemplate(name, node_template_dict, node_type)
# For some reason the tosca.capabilities.QC.docker.Orchestrator doesn't have all definitions so we need to add them
# manually. We get 'toscaparser.common.exception.InvalidTypeError: Type "tosca.capabilities.QC.docker.Orchestrator"
# is not a valid type.'
if len(node_template.custom_def) < len(all_custom_def):
for def_key in all_custom_def:
if isinstance(def_key, dict):
node_template.custom_def.update(def_key)
else:
node_template.custom_def[def_key] = all_custom_def[def_key]
return node_template
def get_tosca_template_2_topology_template_dictionary(template):
yaml_str = tosca_template2_yaml(template)
tosca_template_dict = yaml.load(yaml_str, Loader=yaml.FullLoader)
this_tosca_template = tosca_template_dict['tosca_template']
tosca_template_dict.pop('tosca_template')
tosca_template_dict['topology_template'] = this_tosca_template
if template.policies and 'policies' not in tosca_template_dict['topology_template']:
policies_list = []
for policy in template.policies:
policy_dict = {policy.name: policy.entity_tpl}
policies_list.append(policy_dict)
tosca_template_dict['topology_template']['policies'] = policies_list
return tosca_template_dict
def contains_node_type(node_types_list, node_type_name):
if not node_types_list:
return False
for node_type in node_types_list:
if isinstance(node_type, NodeTemplate):
type_name = node_type.type
elif isinstance(node_type, dict):
type_name = next(iter(node_type))
if type_name == node_type_name:
return True
return False
def get_node_properties(node):
node_type_name = get_node_type_name(node)
return node[node_type_name]['properties']
def set_node_properties(node, properties):
node_type_name = get_node_type_name(node)
node[node_type_name]['properties'] = properties
return node
def get_nodes_by_type(node_type, nodes, all_node_types, all_custom_def):
nodes_by_type = []
for node in nodes:
if node.type == node_type:
nodes_by_type.append(node)
break
elif node_type in get_all_ancestors_types(node, all_node_types, all_custom_def):
nodes_by_type.append(node)
return nodes_by_type
def get_all_ancestors_types(child_node, all_node_types, all_custom_def, ancestors_types=None):
if not ancestors_types:
ancestors_types = [get_node_type_name(child_node)]
parent_type = get_parent_type(child_node)
if parent_type:
ancestors_types.append(parent_type)
parent_type = node_type_2_node_template({'name': all_node_types[parent_type]}, all_custom_def)
get_all_ancestors_types(parent_type, all_node_types, all_custom_def, ancestors_types)
return ancestors_types
def get_all_ancestors_properties(node, all_nodes, all_custom_def, ancestors_properties=None, ancestors_types=None):
if not ancestors_properties:
ancestors_properties = []
ancestors_properties_names = []
node_prop_names = []
if node.get_properties_objects():
for node_prop in node.get_properties_objects():
node_prop_names.append(node_prop.name)
ancestors_properties.append(node_prop)
if not ancestors_types:
ancestors_types = get_all_ancestors_types(node, all_nodes, all_custom_def)
for ancestors_type in ancestors_types:
ancestor = node_type_2_node_template({'name': all_nodes[ancestors_type]}, all_custom_def)
if ancestor.get_properties_objects():
for ancestor_prop in ancestor.get_properties_objects():
if ancestor_prop.name not in ancestors_properties_names and ancestor_prop.name not in node_prop_names:
ancestors_properties_names.append(ancestor_prop.name)
ancestors_properties.append(ancestor_prop)
return ancestors_properties
def get_nodes_with_occurrences_in_requirements(topology_nodes):
nodes_with_occurrences_in_requirement = []
for node in topology_nodes:
for requirement in node.requirements:
requirement_dict = requirement[next(iter(requirement))]
if 'occurrences' in requirement_dict:
nodes_with_occurrences_in_requirement.append(node)
break
return nodes_with_occurrences_in_requirement
def tosca_template2_yaml(tosca_template):
topology_dict = {DEFINITION_VERSION: tosca_template.version, IMPORTS: tosca_template._tpl_imports(),
DESCRIPTION: tosca_template.description, TOPOLOGY_TEMPLATE: {}}
topology_dict[TOPOLOGY_TEMPLATE][NODE_TEMPLATES] = {}
node_templates = tosca_template.nodetemplates
for node_template in node_templates:
node_template_dict = get_node_template_dict(node_template)
topology_dict[TOPOLOGY_TEMPLATE][NODE_TEMPLATES][node_template.name] = node_template_dict
# If we don't add this then dump uses references for the same dictionary entries i.e. '&id001'
yaml.Dumper.ignore_aliases = lambda *args: True
return yaml.dump(topology_dict, default_flow_style=False)
def get_node_template_dict(node_template):
node_template_dict = {TYPE: node_template.type}
# node_template_dict[REQUIREMENTS] = {}
if node_template.requirements:
node_template_dict[REQUIREMENTS] = node_template.requirements
# if node_template.interfaces:
# interfaces = {}
# for interface in node_template.interfaces:
# interfaces[interface.type] = {}
# interfaces[interface.type][interface.name] = interface.implementation
# print( node_template.templates[node_template.name] )
if ARTIFACTS in node_template.templates[node_template.name].keys():
node_template_dict[ARTIFACTS] = node_template.templates[node_template.name][ARTIFACTS]
if PROPERTIES in node_template.templates[node_template.name].keys():
node_template_dict[PROPERTIES] = node_template.templates[node_template.name][PROPERTIES]
if INTERFACES in node_template.templates[node_template.name].keys():
interfaces = copy.deepcopy(node_template.templates[node_template.name][INTERFACES])
for interface_name in interfaces:
if 'type' in interfaces[interface_name]:
interfaces[interface_name].pop('type')
node_template_dict[INTERFACES] = interfaces
# print(dir(node_template))
# print(node_template.templates)
return node_template_dict
def get_node_type_interfaces(node):
node_type_interfaces = node.type_definition.interfaces
return node_type_interfaces
def get_node_template_interfaces(node):
node_template_interfaces = node.interfaces
return node_template_interfaces
def add_interfaces(node, node_type_interfaces):
# node.interfaces = node_type_interfaces
return node
Metadata-Version: 1.0
Name: drip-planner2
Version: 0.1
Summary: UNKNOWN
Home-page: UNKNOWN
Author: S. Koulouzis
Author-email: UNKNOWN
License: UNKNOWN
Description: Long description of the package
Platform: UNKNOWN
setup.py
drip_planner2.egg-info/PKG-INFO
drip_planner2.egg-info/SOURCES.txt
drip_planner2.egg-info/dependency_links.txt
drip_planner2.egg-info/requires.txt
drip_planner2.egg-info/top_level.txt
planner/__init__.py
planner/planner.py
service/__init__.py
service/simple_spec_alayzer.py
service/spec_service.py
service/specification_analyzer.py
test/__init__.py
test/test_planner.py
util/__init__.py
util/tosca_helper.py
\ No newline at end of file
matplotlib==3.1.1
matplotlib==3.1.1
names==0.3.0
networkx==2.4
pika==1.1.0
tosca-parser==1.6.0
...@@ -11,21 +11,21 @@ from service.simple_spec_alayzer import SimpleAnalyzer ...@@ -11,21 +11,21 @@ from service.simple_spec_alayzer import SimpleAnalyzer
from util import tosca_helper from util import tosca_helper
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG) logger.setLevel(logging.INFO)
def add_requirements(node, missing_requirements, capable_node_name): def add_requirement(node, missing_requirement, capable_node_name):
"""Add the requirements to the node """ """Add the requirement to the node """
for req in missing_requirements: first_key = next(iter(missing_requirement))
req[next(iter(req))]['node'] = capable_node_name missing_requirement[first_key]['node'] = capable_node_name
if isinstance(node, NodeTemplate): if isinstance(node, NodeTemplate):
contains_requirement = False contains_requirement = False
for node_requirement in node.requirements: for node_requirement in node.requirements:
if node_requirement == req: if node_requirement == missing_requirement:
contains_requirement = True contains_requirement = True
break break
if not contains_requirement: if not contains_requirement:
node.requirements.append(req) node.requirements.append(missing_requirement)
elif isinstance(node, dict): elif isinstance(node, dict):
type_name = next(iter(node)) type_name = next(iter(node))
if 'requirements' not in node[type_name]: if 'requirements' not in node[type_name]:
...@@ -33,11 +33,11 @@ def add_requirements(node, missing_requirements, capable_node_name): ...@@ -33,11 +33,11 @@ def add_requirements(node, missing_requirements, capable_node_name):
node_requirements = node[type_name]['requirements'] node_requirements = node[type_name]['requirements']
contains_requirement = False contains_requirement = False
for node_requirement in node_requirements: for node_requirement in node_requirements:
if node_requirement == req: if node_requirement == missing_requirement:
contains_requirement = True contains_requirement = True
break break
if not contains_requirement: if not contains_requirement:
node[type_name]['requirements'].append(req) node[type_name]['requirements'].append(missing_requirement)
return node return node
...@@ -62,7 +62,7 @@ class Planner: ...@@ -62,7 +62,7 @@ class Planner:
self.tosca_template = ToscaTemplate(tosca_path) self.tosca_template = ToscaTemplate(tosca_path)
elif yaml_dict_tpl: elif yaml_dict_tpl:
self.yaml_dict_tpl = yaml_dict_tpl self.yaml_dict_tpl = yaml_dict_tpl
logger.info('yaml_dict_tpl:\n' + str(yaml.dump(yaml_dict_tpl))) logger.debug('yaml_dict_tpl:\n' + str(yaml.dump(yaml_dict_tpl)))
self.tosca_template = ToscaTemplate(yaml_dict_tpl=yaml_dict_tpl) self.tosca_template = ToscaTemplate(yaml_dict_tpl=yaml_dict_tpl)
self.tosca_node_types = self.tosca_template.nodetemplates[0].type_definition.TOSCA_DEF self.tosca_node_types = self.tosca_template.nodetemplates[0].type_definition.TOSCA_DEF
...@@ -81,7 +81,7 @@ class Planner: ...@@ -81,7 +81,7 @@ class Planner:
return self.tosca_template return self.tosca_template
def set_default_node_properties(self, node): def set_default_node_properties(self, node):
logger.info('Setting properties for: ' + str(node.type)) logger.debug('Setting properties for: ' + str(node.type))
ancestors_properties = tosca_helper.get_all_ancestors_properties(node, self.all_node_types, ancestors_properties = tosca_helper.get_all_ancestors_properties(node, self.all_node_types,
self.all_custom_def) self.all_custom_def)
default_properties = {} default_properties = {}
...@@ -113,7 +113,7 @@ class Planner: ...@@ -113,7 +113,7 @@ class Planner:
default_properties[prop_name] = node.templates[node_name]['properties'][prop_name][ default_properties[prop_name] = node.templates[node_name]['properties'][prop_name][
'default'] 'default']
logger.info( logger.debug(
'Adding to : ' + str(node.templates[node_name]) + ' properties: ' + str(default_properties)) 'Adding to : ' + str(node.templates[node_name]) + ' properties: ' + str(default_properties))
node.templates[node_name]['properties'] = default_properties node.templates[node_name]['properties'] = default_properties
return node return node
...@@ -165,24 +165,30 @@ class Planner: ...@@ -165,24 +165,30 @@ class Planner:
def add_required_nodes(self, node): def add_required_nodes(self, node):
"""Adds the required nodes in self.required_nodes for an input node.""" """Adds the required nodes in self.required_nodes for an input node."""
if isinstance(node, NodeTemplate): if isinstance(node, NodeTemplate):
logger.info('Resolving requirements for: ' + node.name) logger.debug('Resolving requirements for: ' + node.name)
elif isinstance(node, dict): elif isinstance(node, dict):
logger.info('Resolving requirements for: ' + str(next(iter(node)))) logger.debug('Resolving requirements for: ' + str(next(iter(node))))
# Get all requirements for node. # Get all requirements for node.
all_requirements = self.get_all_requirements(node) all_requirements = self.get_all_requirements(node)
if not all_requirements: if not all_requirements:
logger.debug('Node: ' + tosca_helper.get_node_type_name(node) + ' has no requirements') logger.debug('Node: ' + tosca_helper.get_node_type_name(node) + ' has no requirements')
return return
matching_node = self.find_best_node_for_requirements(all_requirements) matching_nodes_dict = self.find_best_node_for_requirements(all_requirements)
for capability in matching_nodes_dict:
# Only add node that is not in node_templates # Only add node that is not in node_templates
matching_node = matching_nodes_dict[capability]
matching_node_type_name = next(iter(matching_node)) matching_node_type_name = next(iter(matching_node))
matching_node_template = tosca_helper.node_type_2_node_template(matching_node, self.all_custom_def) matching_node_template = tosca_helper.node_type_2_node_template(matching_node, self.all_custom_def)
for req in all_requirements:
req_name = next(iter(req))
requirement_capability = req[req_name]['capability']
if capability == requirement_capability:
# Add the requirements to the node we analyzed. e.g. docker needed host now we added the type and name of host # Add the requirements to the node we analyzed. e.g. docker needed host now we added the type and name of host
node = add_requirements(node, all_requirements, matching_node_template.name) node = add_requirement(node, req, matching_node_template.name)
break
if not tosca_helper.contains_node_type(self.required_nodes, matching_node_type_name) and \ if not tosca_helper.contains_node_type(self.required_nodes, matching_node_type_name) and \
not tosca_helper.contains_node_type(self.tosca_template.nodetemplates, matching_node_type_name): not tosca_helper.contains_node_type(self.tosca_template.nodetemplates, matching_node_type_name):
logger.info(' Adding: ' + str(matching_node_template.name)) logger.debug(' Adding: ' + str(matching_node_template.name))
self.required_nodes.append(matching_node) self.required_nodes.append(matching_node)
# Find matching nodes for the new node's requirements # Find matching nodes for the new node's requirements
self.add_required_nodes(matching_node) self.add_required_nodes(matching_node)
...@@ -191,13 +197,13 @@ class Planner: ...@@ -191,13 +197,13 @@ class Planner:
"""Returns all requirements for an input node including all parents requirements""" """Returns all requirements for an input node including all parents requirements"""
node_type_name = tosca_helper.get_node_type_name(node) node_type_name = tosca_helper.get_node_type_name(node)
logger.info(' Looking for requirements for node: ' + node_type_name) logger.debug(' Looking for requirements for node: ' + node_type_name)
# Get the requirements for this node from its definition e.g. docker: hostedOn k8s # Get the requirements for this node from its definition e.g. docker: hostedOn k8s
def_type = self.all_node_types[node_type_name] def_type = self.all_node_types[node_type_name]
all_requirements = [] all_requirements = []
if 'requirements' in def_type.keys(): if 'requirements' in def_type.keys():
all_requirements = def_type['requirements'] all_requirements = def_type['requirements']
logger.info(' Found requirements: ' + str(all_requirements) + ' for node: ' + node_type_name) logger.debug(' Found requirements: ' + str(all_requirements) + ' for node: ' + node_type_name)
# Get the requirements for this node from the template. e.g. wordpress: connectsTo mysql # Get the requirements for this node from the template. e.g. wordpress: connectsTo mysql
# node_requirements = tosca_helper.get_node_requirements(node) # node_requirements = tosca_helper.get_node_requirements(node)
...@@ -208,7 +214,7 @@ class Planner: ...@@ -208,7 +214,7 @@ class Planner:
parent_requirements = tosca_helper.get_ancestors_requirements(node, self.all_node_types, self.all_custom_def) parent_requirements = tosca_helper.get_ancestors_requirements(node, self.all_node_types, self.all_custom_def)
parent_type = tosca_helper.get_node_type_name(node) parent_type = tosca_helper.get_node_type_name(node)
if parent_type and parent_requirements: if parent_type and parent_requirements:
logger.info( logger.debug(
' Adding to : ' + str(node_type_name) + ' parent requirements from: ' + str(parent_type)) ' Adding to : ' + str(node_type_name) + ' parent requirements from: ' + str(parent_type))
if not all_requirements: if not all_requirements:
all_requirements += parent_requirements all_requirements += parent_requirements
...@@ -255,6 +261,7 @@ class Planner: ...@@ -255,6 +261,7 @@ class Planner:
can cover and return the one which covers the most """ can cover and return the one which covers the most """
matching_nodes = {} matching_nodes = {}
number_of_matching_requirement = {} number_of_matching_requirement = {}
met_requirements = {}
# Loop requirements to find nodes per requirement # Loop requirements to find nodes per requirement
for req in all_requirements: for req in all_requirements:
key = next(iter(req)) key = next(iter(req))
...@@ -263,34 +270,29 @@ class Planner: ...@@ -263,34 +270,29 @@ class Planner:
if 'capability' in req[key]: if 'capability' in req[key]:
capability = req[key]['capability'] capability = req[key]['capability']
# Find all nodes in the definitions that have the capability: capability # Find all nodes in the definitions that have the capability: capability
logger.info(' Looking for nodes in node types with capability: ' + capability) logger.debug(' Looking for nodes in node types with capability: ' + capability)
capable_nodes = self.get_node_types_by_capability(capability) capable_nodes = self.get_node_types_by_capability(capability)
if capable_nodes: if not capable_nodes:
# Add number of matching capabilities for each node.
# Try to score matching_nodes to return one. The more requirements a node meets the better
for node_type in capable_nodes:
matching_requirement_count = 1
if node_type not in number_of_matching_requirement:
number_of_matching_requirement[node_type] = matching_requirement_count
else:
matching_requirement_count = number_of_matching_requirement[node_type]
matching_requirement_count += 1
number_of_matching_requirement[node_type] = matching_requirement_count
logger.info(' Found: ' + str(node_type))
matching_nodes.update(capable_nodes)
else:
logger.error('Did not find any node with required capability: ' + str(capability)) logger.error('Did not find any node with required capability: ' + str(capability))
raise Exception('Did not find any node with required capability: ' + str(capability)) raise Exception('Did not find any node with required capability: ' + str(capability))
matching_nodes[capability] = capable_nodes
# if we only found 1 return it # if we only found 1 return it
if len(matching_nodes) == 1: if len(matching_nodes) == 1:
return matching_nodes return matching_nodes
sorted_number_of_matching_requirement = sorted(number_of_matching_requirement.items(), returning_nodes = {}
key=operator.itemgetter(1)) for capability in matching_nodes:
index = len(sorted_number_of_matching_requirement) - 1 nodes = matching_nodes[capability]
winner_type = next(iter(sorted_number_of_matching_requirement[index])) key = next(iter(nodes))
return {winner_type: matching_nodes[winner_type]} returning_nodes[capability] = {key:nodes[key]}
return returning_nodes
# sorted_number_of_matching_requirement = sorted(number_of_matching_requirement.items(),
# key=operator.itemgetter(1))
# index = len(sorted_number_of_matching_requirement) - 1
# winner_type = next(iter(sorted_number_of_matching_requirement[index]))
# return {winner_type: matching_nodes[winner_type]}
def get_child_nodes(self, parent_node_type_name): def get_child_nodes(self, parent_node_type_name):
child_nodes = {} child_nodes = {}
......
...@@ -3,5 +3,5 @@ pika==1.1.0 ...@@ -3,5 +3,5 @@ pika==1.1.0
names==0.3.0 names==0.3.0
networkx==2.4 networkx==2.4
pyyaml==5.3.1 pyyaml==5.3.1
tosca-parser==2.0.0 tosca-parser==2.1.1
matplotlib==3.2.1 matplotlib==3.2.1
\ No newline at end of file
...@@ -20,46 +20,51 @@ logger.setLevel(logging.DEBUG) ...@@ -20,46 +20,51 @@ logger.setLevel(logging.DEBUG)
class MyTestCase(unittest.TestCase): class MyTestCase(unittest.TestCase):
def test_open_stack(self):
url = 'https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/openstack.yaml'
input_tosca_file_path = self.get_remote_tosca_file(url)
self.run_test(input_tosca_file_path)
def test_tic_gluster_fs(self): def test_tic_gluster_fs(self):
url = 'https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/glusterFS.yaml' url = 'https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/glusterFS.yaml'
input_tosca_file_path = self.get_remote_tosca_file(url) input_tosca_file_path = self.get_remote_tosca_file(url)
self.run_test(input_tosca_file_path) self.run_test(input_tosca_file_path)
def test_tic(self): def test_tic(self):
url = 'https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/TIC.yaml' url = 'https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/TIC.yaml'
input_tosca_file_path = self.get_remote_tosca_file(url) input_tosca_file_path = self.get_remote_tosca_file(url)
self.run_test(input_tosca_file_path) self.run_test(input_tosca_file_path)
def test_docker(self): def test_docker(self):
url = 'https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/application_example_updated.yaml' url = 'https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/application_example_updated.yaml'
input_tosca_file_path = self.get_remote_tosca_file(url) input_tosca_file_path = self.get_remote_tosca_file(url)
self.run_test(input_tosca_file_path) self.run_test(input_tosca_file_path)
url = 'https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/lifeWatch_vre1.yaml' url = 'https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/lifeWatch_vre1.yaml'
input_tosca_file_path = self.get_remote_tosca_file(url) input_tosca_file_path = self.get_remote_tosca_file(url)
self.run_test(input_tosca_file_path) self.run_test(input_tosca_file_path)
def test_kubernetes(self): def test_kubernetes(self):
url = 'https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/kubernetes.yaml' url = 'https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/kubernetes.yaml'
input_tosca_file_path = self.get_remote_tosca_file(url) input_tosca_file_path = self.get_remote_tosca_file(url)
self.run_test(input_tosca_file_path) self.run_test(input_tosca_file_path)
def test_topology(self): def test_topology(self):
url = 'https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/topology.yaml' url = 'https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/topology.yaml'
input_tosca_file_path = self.get_remote_tosca_file(url) input_tosca_file_path = self.get_remote_tosca_file(url)
self.run_test(input_tosca_file_path) self.run_test(input_tosca_file_path)
def test_compute(self): def test_compute(self):
url = 'https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/compute.yaml' url = 'https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/compute.yaml'
input_tosca_file_path = self.get_remote_tosca_file(url) input_tosca_file_path = self.get_remote_tosca_file(url)
self.run_test(input_tosca_file_path) self.run_test(input_tosca_file_path)
def test_lifeWatch(self): def test_lifeWatch(self):
url = 'https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/lifeWatch_vre1.yaml' url = 'https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/lifeWatch_vre1.yaml'
tic_tosca = requests.get(url) tic_tosca = requests.get(url)
input_tosca_file_path = os.path.join(tempfile.gettempdir(),'TIC.yaml') input_tosca_file_path = os.path.join(tempfile.gettempdir(),'lifeWatch_vre1.yaml')
open( input_tosca_file_path, 'wb').write(tic_tosca.content) open( input_tosca_file_path, 'wb').write(tic_tosca.content)
self.run_test(input_tosca_file_path) self.run_test(input_tosca_file_path)
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version> <version>2.2.2.RELEASE</version>
</parent> </parent>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
......
{
"info": {
"_postman_id": "413f892b-e0d4-4300-a556-7dfcea38cb10",
"name": "CONF test deploy",
"description": "CONF allows application developers to seamlessly plan a customized virtual infrastructure based on application level constraints on QoS and resource budgets, provisioning the virtual infrastructure, deploy application components onto the virtual infrastructure, and start execution on demand using TOSCA.\n\n",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "Find topolog template by ID",
"event": [
{
"listen": "test",
"script": {
"id": "291160c7-0f44-42cf-84cc-240f8ef6b7e6",
"exec": [
"tests[\"Status code is 200\"] = responseCode.code === 200;",
"",
"",
"",
"// var data = {",
"// \"data\" : [",
"// {",
"// \"name\" : \"Postmany\"",
"// }",
"// ]",
"// };",
"// var template = `",
"// <table>",
"// <tr>",
"// <th>Name</th>",
"// </tr>",
"",
"// {{#each response.data}}",
"// <tr>",
"// <td>{{name}}</td>",
"// </tr>",
"// {{/each}}",
"// </table>",
"// `;",
"// pm.visualizer.set(template, {",
"// // Pass the responses you need in a single JSON as data",
"// response: data",
"// });",
""
],
"type": "text/javascript"
}
}
],
"protocolProfileBehavior": {
"disableBodyPruning": true
},
"request": {
"auth": {
"type": "basic",
"basic": [
{
"key": "password",
"value": "edvbafeabvafdb",
"type": "string"
},
{
"key": "username",
"value": "deploy_tester",
"type": "string"
}
]
},
"method": "GET",
"header": [
{
"key": "accept",
"value": "text/plain",
"type": "text"
}
],
"body": {
"mode": "raw",
"raw": "",
"options": {
"raw": {}
}
},
"url": {
"raw": "{{baseUrl}}/tosca_template/{{tosca_id}}",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"{{tosca_id}}"
]
},
"description": "Returns a single topology template. "
},
"response": [
{
"name": "Invalid input",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/tosca_template/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"<string>"
]
}
},
"status": "Method Not Allowed",
"code": 405,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": ""
},
{
"name": "Invalid ID supplied",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/tosca_template/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"<string>"
]
}
},
"status": "Bad Request",
"code": 400,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": ""
},
{
"name": "ToscaTemplate not found",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/tosca_template/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"<string>"
]
}
},
"status": "Not Found",
"code": 404,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": ""
},
{
"name": "successful operation",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/tosca_template/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"<string>"
]
}
},
"status": "OK",
"code": 200,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": "<string>"
}
]
},
{
"name": "PLAN tosca template",
"event": [
{
"listen": "test",
"script": {
"id": "3a4a1b37-9f1e-4ff1-8f10-e72639631533",
"exec": [
"// tests[\"Status code is 200\"] = responseCode.code === 200;",
"tests[\"Response Body is not empty\"] = responseBody !== 200;",
"postman.setEnvironmentVariable(\"planed_tosca_id\", responseBody);"
],
"type": "text/javascript"
}
}
],
"request": {
"auth": {
"type": "basic",
"basic": [
{
"key": "username",
"value": "deploy_tester",
"type": "string"
},
{
"key": "password",
"value": "edvbafeabvafdb",
"type": "string"
}
]
},
"method": "GET",
"header": [
{
"key": "accept",
"value": " text/plain",
"type": "text"
},
{
"key": "accept",
"value": "text/plain",
"type": "text",
"disabled": true
}
],
"url": {
"raw": "{{baseUrl}}/planner/plan/{{tosca_id}}",
"host": [
"{{baseUrl}}"
],
"path": [
"planner",
"plan",
"{{tosca_id}}"
]
},
"description": "Planns and returns the ID of the planed topolog template"
},
"response": [
{
"name": "successful operation",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/planner/plan/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"planner",
"plan",
"<string>"
]
}
},
"status": "OK",
"code": 200,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": "<string>"
},
{
"name": "Invalid ID supplied",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/planner/plan/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"planner",
"plan",
"<string>"
]
}
},
"status": "Bad Request",
"code": 400,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": ""
},
{
"name": "ToscaTemplate not found",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/planner/plan/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"planner",
"plan",
"<string>"
]
}
},
"status": "Not Found",
"code": 404,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": ""
},
{
"name": "Invalid input",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/planner/plan/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"planner",
"plan",
"<string>"
]
}
},
"status": "Method Not Allowed",
"code": 405,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": ""
}
]
},
{
"name": "Find planed topolog template by ID",
"event": [
{
"listen": "test",
"script": {
"id": "a566254b-f701-4d5f-af1a-5b479f31532c",
"exec": [
"// tests[\"Status code is 200\"] = responseCode.code === 200;",
"tests[\"Response Body is not empty\"] = responseBody !== 200;"
],
"type": "text/javascript"
}
}
],
"protocolProfileBehavior": {
"disableBodyPruning": true
},
"request": {
"auth": {
"type": "basic",
"basic": [
{
"key": "username",
"value": "deploy_tester",
"type": "string"
},
{
"key": "password",
"value": "edvbafeabvafdb",
"type": "string"
}
]
},
"method": "GET",
"header": [
{
"key": "accept",
"value": "text/plain",
"type": "text"
}
],
"body": {
"mode": "raw",
"raw": "",
"options": {
"raw": {}
}
},
"url": {
"raw": "{{baseUrl}}/tosca_template/{{planed_tosca_id}}",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"{{planed_tosca_id}}"
]
},
"description": "Returns a single topolog template"
},
"response": [
{
"name": "ToscaTemplate not found",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/tosca_template/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"<string>"
]
}
},
"status": "Not Found",
"code": 404,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": ""
},
{
"name": "Invalid input",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/tosca_template/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"<string>"
]
}
},
"status": "Method Not Allowed",
"code": 405,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": ""
},
{
"name": "Invalid ID supplied",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/tosca_template/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"<string>"
]
}
},
"status": "Bad Request",
"code": 400,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": ""
},
{
"name": "successful operation",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/tosca_template/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"<string>"
]
}
},
"status": "OK",
"code": 200,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": "<string>"
}
]
},
{
"name": "PROVISION tosca template",
"event": [
{
"listen": "test",
"script": {
"id": "083634e0-93a7-4f4d-aa66-39c851d2436c",
"exec": [
"postman.setEnvironmentVariable(\"provisioned_tosca_id\", responseBody);"
],
"type": "text/javascript"
}
}
],
"request": {
"auth": {
"type": "basic",
"basic": [
{
"key": "username",
"value": "deploy_tester",
"type": "string"
},
{
"key": "password",
"value": "edvbafeabvafdb",
"type": "string"
}
]
},
"method": "GET",
"header": [
{
"key": "Accept",
"value": "text/plain",
"type": "text"
}
],
"url": {
"raw": "{{baseUrl}}/provisioner/provision/{{planed_tosca_id}}",
"host": [
"{{baseUrl}}"
],
"path": [
"provisioner",
"provision",
"{{planed_tosca_id}}"
]
},
"description": "provosions the operationId: Plan Tosca Template Returns the provision ID"
},
"response": [
{
"name": "successful operation",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/provisioner/provision/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"provisioner",
"provision",
"<string>"
]
}
},
"status": "OK",
"code": 200,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": "<string>"
},
{
"name": "Invalid ID supplied",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/provisioner/provision/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"provisioner",
"provision",
"<string>"
]
}
},
"status": "Bad Request",
"code": 400,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": ""
},
{
"name": "ToscaTemplate not found",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/provisioner/provision/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"provisioner",
"provision",
"<string>"
]
}
},
"status": "Not Found",
"code": 404,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": ""
},
{
"name": "Invalid input",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/provisioner/provision/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"provisioner",
"provision",
"<string>"
]
}
},
"status": "Method Not Allowed",
"code": 405,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": ""
}
]
},
{
"name": "Find provisioned topolog template by ID",
"event": [
{
"listen": "test",
"script": {
"id": "a8e9d158-341d-4344-bd79-ecf0a61984e6",
"exec": [
"// tests[\"Status code is 200\"] = responseCode.code === 200;",
"tests[\"Response Body is not empty\"] = responseBody !== 200;"
],
"type": "text/javascript"
}
}
],
"protocolProfileBehavior": {
"disableBodyPruning": true
},
"request": {
"auth": {
"type": "basic",
"basic": [
{
"key": "username",
"value": "deploy_tester",
"type": "string"
},
{
"key": "password",
"value": "edvbafeabvafdb",
"type": "string"
}
]
},
"method": "GET",
"header": [
{
"key": "accept",
"value": "text/plain",
"type": "text"
}
],
"body": {
"mode": "raw",
"raw": "",
"options": {
"raw": {}
}
},
"url": {
"raw": "{{baseUrl}}/tosca_template/{{provisioned_tosca_id}}",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"{{provisioned_tosca_id}}"
]
},
"description": "Returns a single topolog template"
},
"response": [
{
"name": "Invalid input",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/tosca_template/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"<string>"
]
}
},
"status": "Method Not Allowed",
"code": 405,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": ""
},
{
"name": "ToscaTemplate not found",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/tosca_template/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"<string>"
]
}
},
"status": "Not Found",
"code": 404,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": ""
},
{
"name": "successful operation",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/tosca_template/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"<string>"
]
}
},
"status": "OK",
"code": 200,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": "<string>"
},
{
"name": "Invalid ID supplied",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/tosca_template/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"<string>"
]
}
},
"status": "Bad Request",
"code": 400,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": ""
}
]
},
{
"name": "DEPLOY the software tosca template",
"event": [
{
"listen": "test",
"script": {
"id": "020d63ca-7845-492a-96d8-d36d9f330dfd",
"exec": [
"postman.setEnvironmentVariable(\"deployed_tosca_id\", responseBody);"
],
"type": "text/javascript"
}
}
],
"request": {
"auth": {
"type": "basic",
"basic": [
{
"key": "username",
"value": "deploy_tester",
"type": "string"
},
{
"key": "password",
"value": "edvbafeabvafdb",
"type": "string"
}
]
},
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/deployer/deploy/{{provisioned_tosca_id}}",
"host": [
"{{baseUrl}}"
],
"path": [
"deployer",
"deploy",
"{{provisioned_tosca_id}}"
]
},
"description": "Returns the deployment ID"
},
"response": [
{
"name": "successful operation",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/deployer/deploy/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"deployer",
"deploy",
"<string>"
]
}
},
"status": "OK",
"code": 200,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": "<string>"
},
{
"name": "Invalid input",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/deployer/deploy/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"deployer",
"deploy",
"<string>"
]
}
},
"status": "Method Not Allowed",
"code": 405,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": ""
},
{
"name": "Invalid ID supplied",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/deployer/deploy/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"deployer",
"deploy",
"<string>"
]
}
},
"status": "Bad Request",
"code": 400,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": ""
},
{
"name": "ToscaTemplate not found",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/deployer/deploy/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"deployer",
"deploy",
"<string>"
]
}
},
"status": "Not Found",
"code": 404,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": ""
}
]
},
{
"name": "Find deployed topolog template by ID",
"event": [
{
"listen": "test",
"script": {
"id": "98e68ae8-9e40-4bd2-bdf6-10699ba589e1",
"exec": [
"// tests[\"Status code is 200\"] = responseCode.code === 200;",
"tests[\"Response Body is not empty\"] = responseBody !== 200;"
],
"type": "text/javascript"
}
}
],
"protocolProfileBehavior": {
"disableBodyPruning": true
},
"request": {
"auth": {
"type": "basic",
"basic": [
{
"key": "password",
"value": "edvbafeabvafdb",
"type": "string"
},
{
"key": "username",
"value": "deploy_tester",
"type": "string"
}
]
},
"method": "GET",
"header": [
{
"key": "accept",
"type": "text",
"value": "text/plain"
}
],
"body": {
"mode": "raw",
"raw": "",
"options": {
"raw": {}
}
},
"url": {
"raw": "{{baseUrl}}/tosca_template/{{deployed_tosca_id}}",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"{{deployed_tosca_id}}"
]
},
"description": "Returns a single topolog template"
},
"response": [
{
"name": "Invalid input",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/tosca_template/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"<string>"
]
}
},
"status": "Method Not Allowed",
"code": 405,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": ""
},
{
"name": "ToscaTemplate not found",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/tosca_template/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"<string>"
]
}
},
"status": "Not Found",
"code": 404,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": ""
},
{
"name": "successful operation",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/tosca_template/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"<string>"
]
}
},
"status": "OK",
"code": 200,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": "<string>"
},
{
"name": "Invalid ID supplied",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/tosca_template/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"<string>"
]
}
},
"status": "Bad Request",
"code": 400,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": ""
}
]
},
{
"name": "Delete provisioned topolog template by ID",
"event": [
{
"listen": "test",
"script": {
"id": "40be57b1-b0de-4fab-86da-0a568f403d48",
"exec": [
"// tests[\"Status code is 200\"] = responseCode.code === 200;",
"tests[\"Response Body is not empty\"] = responseBody !== 200;",
"postman.setEnvironmentVariable(\"deleted_tosca_id\", responseBody);"
],
"type": "text/javascript"
}
}
],
"request": {
"auth": {
"type": "basic",
"basic": [
{
"key": "username",
"value": "deploy_tester",
"type": "string"
},
{
"key": "password",
"value": "edvbafeabvafdb",
"type": "string"
}
]
},
"method": "DELETE",
"header": [
{
"key": "accept",
"type": "text",
"value": "text/plain"
}
],
"body": {
"mode": "raw",
"raw": "",
"options": {
"raw": {}
}
},
"url": {
"raw": "{{baseUrl}}/tosca_template/{{provisioned_tosca_id}}",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"{{provisioned_tosca_id}}"
]
},
"description": "Returns a single topolog template"
},
"response": [
{
"name": "successful operation",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/tosca_template/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"<string>"
]
}
},
"status": "OK",
"code": 200,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": "<string>"
},
{
"name": "ToscaTemplate not found",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/tosca_template/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"<string>"
]
}
},
"status": "Not Found",
"code": 404,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": ""
},
{
"name": "Invalid ID supplied",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/tosca_template/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"<string>"
]
}
},
"status": "Bad Request",
"code": 400,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": ""
},
{
"name": "Invalid input",
"originalRequest": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/tosca_template/<string>",
"host": [
"{{baseUrl}}"
],
"path": [
"tosca_template",
"<string>"
]
}
},
"status": "Method Not Allowed",
"code": 405,
"_postman_previewlanguage": "text",
"header": [
{
"key": "Content-Type",
"value": "text/plain"
}
],
"cookie": [],
"body": ""
}
]
}
],
"event": [
{
"listen": "prerequest",
"script": {
"id": "c8620248-6b77-4e71-a078-5ce2397e6eef",
"type": "text/javascript",
"exec": [
""
]
}
},
{
"listen": "test",
"script": {
"id": "ca112a09-3e91-4ad9-8fe8-857d59a75ccc",
"type": "text/javascript",
"exec": [
""
]
}
}
],
"variable": [
{
"id": "123752b8-f664-4303-a32d-96684daad374",
"key": "baseUrl",
"value": "/conf-api/3.0"
}
],
"protocolProfileBehavior": {}
}
...@@ -3,6 +3,7 @@ COPY target/provisioner-3.0.0-jar-with-dependencies.jar provisioner-3.0.0-jar-wi ...@@ -3,6 +3,7 @@ COPY target/provisioner-3.0.0-jar-with-dependencies.jar provisioner-3.0.0-jar-wi
COPY etc/ etc COPY etc/ etc
CMD jar -xf provisioner-3.0.0-jar-with-dependencies.jar application.properties && \ CMD jar -xf provisioner-3.0.0-jar-with-dependencies.jar application.properties && \
echo "----------------------------" && \
cat application.properties && \ cat application.properties && \
sed -ie "s#^message.broker.host=.*#message.broker.host=$RABBITMQ_HOST#" application.properties && \ sed -ie "s#^message.broker.host=.*#message.broker.host=$RABBITMQ_HOST#" application.properties && \
sed -ie "s#^sure-tosca.base.path=.*#sure-tosca.base.path=$SURE_TOSCA_BASE_PATH#" application.properties && \ sed -ie "s#^sure-tosca.base.path=.*#sure-tosca.base.path=$SURE_TOSCA_BASE_PATH#" application.properties && \
...@@ -12,6 +13,7 @@ CMD jar -xf provisioner-3.0.0-jar-with-dependencies.jar application.properties & ...@@ -12,6 +13,7 @@ CMD jar -xf provisioner-3.0.0-jar-with-dependencies.jar application.properties &
echo "" >> application.properties && \ echo "" >> application.properties && \
echo "cloud.storm.db.path=/etc/UD" >> application.properties && \ echo "cloud.storm.db.path=/etc/UD" >> application.properties && \
cat application.properties && \ cat application.properties && \
echo "----------------------------" && \
jar -uf provisioner-3.0.0-jar-with-dependencies.jar application.properties && \ jar -uf provisioner-3.0.0-jar-with-dependencies.jar application.properties && \
sleep 5 && \ sleep 5 && \
java -jar provisioner-3.0.0-jar-with-dependencies.jar java -jar provisioner-3.0.0-jar-with-dependencies.jar
......
...@@ -164,6 +164,7 @@ DCMetaInfo: ...@@ -164,6 +164,7 @@ DCMetaInfo:
AMI: "ami-2581aa40" AMI: "ami-2581aa40"
- domain: "Frankfurt" - domain: "Frankfurt"
endpoint: "ec2.eu-central-1.amazonaws.com" endpoint: "ec2.eu-central-1.amazonaws.com"
country: Germany country: Germany
...@@ -219,3 +220,60 @@ DCMetaInfo: ...@@ -219,3 +220,60 @@ DCMetaInfo:
DefaultSSHAccount: "ubuntu" DefaultSSHAccount: "ubuntu"
extraInfo: extraInfo:
AMI: "ami-0b418580298265d5c" AMI: "ami-0b418580298265d5c"
- domain: "Ireland"
endpoint: "ec2.eu-west-1.amazonaws.com"
country: Ireland
longitude: "-7.77832031"
latitude: "53.2734"
availability: null
VMMetaInfo:
- OS: "Ubuntu 18.04"
CPU: 1
MEM: 0.5
VMType: "t2.nano"
Price: 0.0058
DefaultSSHAccount: "ubuntu"
extraInfo:
AMI: "ami-04137ed1a354f54c4"
- OS: "Ubuntu 18.04"
CPU: 1
MEM: 1
VMType: "t2.micro"
Price: 0.0116
DefaultSSHAccount: "ubuntu"
extraInfo:
AMI: "ami-04137ed1a354f54c4"
- OS: "Ubuntu 18.04"
CPU: 1
MEM: 2
VMType: "t2.small"
Price: 0.0116
DefaultSSHAccount: "ubuntu"
extraInfo:
AMI: "ami-04137ed1a354f54c4"
- OS: "Ubuntu 18.04"
CPU: 2
MEM: 4
VMType: "t2.medium"
Price: 0.0464
DefaultSSHAccount: "ubuntu"
extraInfo:
AMI: "ami-04137ed1a354f54c4"
- OS: "Ubuntu 18.04"
CPU: 2
MEM: 8
VMType: "t2.large"
Price: 0.0464
DefaultSSHAccount: "ubuntu"
extraInfo:
AMI: "ami-04137ed1a354f54c4"
- OS: "Ubuntu 18.04"
CPU: 4
MEM: 16
VMType: "t2.xlarge"
Price: 0.0464
DefaultSSHAccount: "ubuntu"
extraInfo:
AMI: "ami-04137ed1a354f54c4"
...@@ -71,9 +71,10 @@ class SemaphoreHelper: ...@@ -71,9 +71,10 @@ class SemaphoreHelper:
repository = self.find_repository(project_id, name, git_url) repository = self.find_repository(project_id, name, git_url)
return repository.id return repository.id
def create_template(self, project_id,key_id,inventory_id,repository_id,playbook_name): def create_template(self, project_id,key_id,inventory_id,repository_id,playbook_name,arguments=None):
template_request = TemplateRequest(ssh_key_id=key_id, project_id=project_id, inventory_id=inventory_id, template_request = TemplateRequest(ssh_key_id=key_id, project_id=project_id, inventory_id=inventory_id,
repository_id=repository_id, alias=playbook_name, playbook=playbook_name) repository_id=repository_id, alias=playbook_name, playbook=playbook_name,
arguments=arguments)
self.project_api.project_project_id_templates_post(template_request , project_id ) self.project_api.project_project_id_templates_post(template_request , project_id )
templates = self.project_api.project_project_id_templates_get(project_id, playbook_name, 'asc') templates = self.project_api.project_project_id_templates_get(project_id, playbook_name, 'asc')
return self.find_template(templates,playbook_name).id return self.find_template(templates,playbook_name).id
......
...@@ -2,7 +2,12 @@ ...@@ -2,7 +2,12 @@
<project version="4"> <project version="4">
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="3f84153d-6ed1-4691-94d6-53105266f15e" name="Default Changelist" comment=""> <list default="true" id="3f84153d-6ed1-4691-94d6-53105266f15e" name="Default Changelist" comment="">
<change beforePath="$PROJECT_DIR$/../k8s/CONF/manager-deployment.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/../k8s/CONF/manager-deployment.yaml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../k8s/CONF/nginx-configmap.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/../k8s/CONF/nginx-configmap.yaml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../k8s/CONF/provisioner-deployment.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/../k8s/CONF/provisioner-deployment.yaml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../sure_tosca-flask-server/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/../sure_tosca-flask-server/.idea/misc.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../sure_tosca-flask-server/.idea/sure_tosca-flask-server.iml" beforeDir="false" afterPath="$PROJECT_DIR$/../sure_tosca-flask-server/.idea/sure_tosca-flask-server.iml" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
...@@ -20,9 +25,14 @@ ...@@ -20,9 +25,14 @@
</component> </component>
<component name="PropertiesComponent"> <component name="PropertiesComponent">
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" /> <property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="last_opened_file_path" value="$PROJECT_DIR$/../../playbooks/install_nfs.yaml" /> <property name="last_opened_file_path" value="$PROJECT_DIR$/../../sdia-tosca" />
<property name="settings.editor.selected.configurable" value="com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable" /> <property name="settings.editor.selected.configurable" value="com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable" />
</component> </component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/../../sdia-tosca/examples" />
</key>
</component>
<component name="RunManager"> <component name="RunManager">
<configuration name="Unittests in test_default_api.py" type="tests" factoryName="Unittests" temporary="true" nameIsGenerated="true"> <configuration name="Unittests in test_default_api.py" type="tests" factoryName="Unittests" temporary="true" nameIsGenerated="true">
<module name="sure_tosca-client_python_stubs" /> <module name="sure_tosca-client_python_stubs" />
...@@ -58,49 +68,60 @@ ...@@ -58,49 +68,60 @@
<servers /> <servers />
</component> </component>
<component name="WindowStateProjectService"> <component name="WindowStateProjectService">
<state x="723" y="257" width="770" height="700" key="FileChooserDialogImpl" timestamp="1587904825236"> <state x="723" y="257" width="770" height="700" key="FileChooserDialogImpl" timestamp="1594637033414">
<screen x="67" y="34" width="1853" height="1046" /> <screen x="67" y="34" width="1853" height="1046" />
</state> </state>
<state x="723" y="257" width="770" height="700" key="FileChooserDialogImpl/67.34.1853.1046@67.34.1853.1046" timestamp="1587904825236" /> <state x="723" y="257" width="770" height="700" key="FileChooserDialogImpl/67.34.1853.1046@67.34.1853.1046" timestamp="1594637033414" />
<state width="1825" height="255" key="GridCell.Tab.0.bottom" timestamp="1587047773485"> <state width="1825" height="255" key="GridCell.Tab.0.bottom" timestamp="1592388772726">
<screen x="67" y="34" width="1853" height="1046" /> <screen x="67" y="34" width="1853" height="1046" />
</state> </state>
<state width="1825" height="255" key="GridCell.Tab.0.bottom/67.34.1853.1046@67.34.1853.1046" timestamp="1587047773485" /> <state width="1825" height="255" key="GridCell.Tab.0.bottom/67.34.1853.1046@67.34.1853.1046" timestamp="1592388772726" />
<state width="1825" height="255" key="GridCell.Tab.0.center" timestamp="1587047773484"> <state width="1825" height="255" key="GridCell.Tab.0.center" timestamp="1592388772725">
<screen x="67" y="34" width="1853" height="1046" /> <screen x="67" y="34" width="1853" height="1046" />
</state> </state>
<state width="1825" height="255" key="GridCell.Tab.0.center/67.34.1853.1046@67.34.1853.1046" timestamp="1587047773484" /> <state width="1825" height="255" key="GridCell.Tab.0.center/67.34.1853.1046@67.34.1853.1046" timestamp="1592388772725" />
<state width="1825" height="255" key="GridCell.Tab.0.left" timestamp="1587047773484"> <state width="1825" height="255" key="GridCell.Tab.0.left" timestamp="1592388772725">
<screen x="67" y="34" width="1853" height="1046" /> <screen x="67" y="34" width="1853" height="1046" />
</state> </state>
<state width="1825" height="255" key="GridCell.Tab.0.left/67.34.1853.1046@67.34.1853.1046" timestamp="1587047773484" /> <state width="1825" height="255" key="GridCell.Tab.0.left/67.34.1853.1046@67.34.1853.1046" timestamp="1592388772725" />
<state width="1825" height="255" key="GridCell.Tab.0.right" timestamp="1587047773485"> <state width="1825" height="255" key="GridCell.Tab.0.right" timestamp="1592388772725">
<screen x="67" y="34" width="1853" height="1046" /> <screen x="67" y="34" width="1853" height="1046" />
</state> </state>
<state width="1825" height="255" key="GridCell.Tab.0.right/67.34.1853.1046@67.34.1853.1046" timestamp="1587047773485" /> <state width="1825" height="255" key="GridCell.Tab.0.right/67.34.1853.1046@67.34.1853.1046" timestamp="1592388772725" />
<state width="1825" height="383" key="GridCell.Tab.1.bottom" timestamp="1585306552969"> <state width="1825" height="264" key="GridCell.Tab.1.bottom" timestamp="1592388772719">
<screen x="67" y="34" width="1853" height="1046" /> <screen x="67" y="34" width="1853" height="1046" />
</state> </state>
<state width="1825" height="383" key="GridCell.Tab.1.bottom/67.34.1853.1046@67.34.1853.1046" timestamp="1585306552969" /> <state width="1825" height="264" key="GridCell.Tab.1.bottom/67.34.1853.1046@67.34.1853.1046" timestamp="1592388772719" />
<state width="1825" height="383" key="GridCell.Tab.1.center" timestamp="1585306552966"> <state width="1825" height="264" key="GridCell.Tab.1.center" timestamp="1592388772719">
<screen x="67" y="34" width="1853" height="1046" /> <screen x="67" y="34" width="1853" height="1046" />
</state> </state>
<state width="1825" height="383" key="GridCell.Tab.1.center/67.34.1853.1046@67.34.1853.1046" timestamp="1585306552966" /> <state width="1825" height="264" key="GridCell.Tab.1.center/67.34.1853.1046@67.34.1853.1046" timestamp="1592388772719" />
<state width="1825" height="383" key="GridCell.Tab.1.left" timestamp="1585306552965"> <state width="1825" height="264" key="GridCell.Tab.1.left" timestamp="1592388772719">
<screen x="67" y="34" width="1853" height="1046" /> <screen x="67" y="34" width="1853" height="1046" />
</state> </state>
<state width="1825" height="383" key="GridCell.Tab.1.left/67.34.1853.1046@67.34.1853.1046" timestamp="1585306552965" /> <state width="1825" height="264" key="GridCell.Tab.1.left/67.34.1853.1046@67.34.1853.1046" timestamp="1592388772719" />
<state width="1825" height="383" key="GridCell.Tab.1.right" timestamp="1585306552968"> <state width="1825" height="264" key="GridCell.Tab.1.right" timestamp="1592388772719">
<screen x="67" y="34" width="1853" height="1046" /> <screen x="67" y="34" width="1853" height="1046" />
</state> </state>
<state width="1825" height="383" key="GridCell.Tab.1.right/67.34.1853.1046@67.34.1853.1046" timestamp="1585306552968" /> <state width="1825" height="264" key="GridCell.Tab.1.right/67.34.1853.1046@67.34.1853.1046" timestamp="1592388772719" />
<state x="359" y="103" key="SettingsEditor" timestamp="1587036749389"> <state x="359" y="103" key="SettingsEditor" timestamp="1587036749389">
<screen x="67" y="34" width="1853" height="1046" /> <screen x="67" y="34" width="1853" height="1046" />
</state> </state>
<state x="359" y="103" key="SettingsEditor/67.34.1853.1046@67.34.1853.1046" timestamp="1587036749389" /> <state x="359" y="103" key="SettingsEditor/67.34.1853.1046@67.34.1853.1046" timestamp="1587036749389" />
<state x="563" y="235" width="1053" height="732" key="find.popup" timestamp="1584900160970"> <state x="563" y="235" width="1053" height="732" key="find.popup" timestamp="1590670239704">
<screen x="67" y="34" width="1853" height="1046" /> <screen x="67" y="34" width="1853" height="1046" />
</state> </state>
<state x="563" y="235" width="1053" height="732" key="find.popup/67.34.1853.1046@67.34.1853.1046" timestamp="1584900160970" /> <state x="563" y="235" width="1053" height="732" key="find.popup/67.34.1853.1046@67.34.1853.1046" timestamp="1590670239704" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager>
<breakpoints>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/test/test_default_api.py</url>
<line>33</line>
<option name="timeStamp" value="7" />
</line-breakpoint>
</breakpoints>
</breakpoint-manager>
</component> </component>
</project> </project>
\ No newline at end of file
tosca_definitions_version: tosca_simple_yaml_1_0
description: Template for deploying a single server with predefined properties.
topology_template:
node_templates:
my_server:
type: tosca.nodes.Compute
capabilities:
# Host container properties
host:
properties:
num_cpus: 1
disk_size: 10 GB
mem_size: 4096 MB
# Guest Operating System properties
os:
properties:
# host Operating System image properties
architecture: x86_64
type: linux
distribution: rhel
version: 6.5
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (sure_tosca-flask-server)" project-jdk-type="Python SDK" /> <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6 (sure_tosca-flask-server)" project-jdk-type="Python SDK" />
<component name="PyCharmProfessionalAdvertiser"> <component name="PyCharmProfessionalAdvertiser">
<option name="shown" value="true" /> <option name="shown" value="true" />
</component> </component>
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<excludeFolder url="file://$MODULE_DIR$/venv" /> <excludeFolder url="file://$MODULE_DIR$/venv" />
<excludeFolder url="file://$MODULE_DIR$/venv3-7" /> <excludeFolder url="file://$MODULE_DIR$/venv3-7" />
</content> </content>
<orderEntry type="jdk" jdkName="Python 3.7 (sure_tosca-flask-server)" jdkType="Python SDK" /> <orderEntry type="jdk" jdkName="Python 3.6 (sure_tosca-flask-server)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
</module> </module>
\ No newline at end of file
...@@ -21,30 +21,30 @@ class TestDefaultController(BaseTestCase): ...@@ -21,30 +21,30 @@ class TestDefaultController(BaseTestCase):
""" """
id_example = self.upload_file('https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/TIC.yaml') id_example = self.upload_file('https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/TIC.yaml')
doc_id = int(id_example) doc_id = int(id_example)
self.assertIsInstance(doc_id,int) self.assertIsInstance(doc_id,int)
# id_example = self.upload_file('https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/application_example_planed.yaml') # id_example = self.upload_file('https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/application_example_planed.yaml')
# doc_id = int(id_example) # doc_id = int(id_example)
self.assertIsInstance(doc_id,int) self.assertIsInstance(doc_id,int)
id_example = self.upload_file( id_example = self.upload_file(
'https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/application_example_provisioned.yaml') 'https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/application_example_provisioned.yaml')
doc_id = int(id_example) doc_id = int(id_example)
self.assertIsInstance(doc_id,int) self.assertIsInstance(doc_id,int)
id_example = self.upload_file( id_example = self.upload_file(
'https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/glusterFS.yaml') 'https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/glusterFS.yaml')
doc_id = int(id_example) doc_id = int(id_example)
self.assertIsInstance(doc_id,int) self.assertIsInstance(doc_id,int)
id_example = self.upload_file( id_example = self.upload_file(
'https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/kubernetes.yaml') 'https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/kubernetes.yaml')
doc_id = int(id_example) doc_id = int(id_example)
self.assertIsInstance(doc_id,int) self.assertIsInstance(doc_id,int)
id_example = self.upload_file( id_example = self.upload_file(
'https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/lifeWatch_vre1.yaml') 'https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/lifeWatch_vre1.yaml')
doc_id = int(id_example) doc_id = int(id_example)
self.assertIsInstance(doc_id,int) self.assertIsInstance(doc_id,int)
id_example = self.upload_file( id_example = self.upload_file(
'https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/topology.yaml') 'https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/topology.yaml')
doc_id = int(id_example) doc_id = int(id_example)
self.assertIsInstance(doc_id,int) self.assertIsInstance(doc_id,int)
...@@ -54,7 +54,7 @@ class TestDefaultController(BaseTestCase): ...@@ -54,7 +54,7 @@ class TestDefaultController(BaseTestCase):
""" """
id_example = self.upload_file('https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/application_example_2_topologies.yaml') id_example = self.upload_file('https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/application_example_2_topologies.yaml')
self.assertTrue(id_example.strip().isdigit()) self.assertTrue(id_example.strip().isdigit())
response = self.client.open( response = self.client.open(
'/tosca-sure/1.0.0/tosca_template/{id}/topology_template/node_templates/{node_name}/ancestors_properties'.format( '/tosca-sure/1.0.0/tosca_template/{id}/topology_template/node_templates/{node_name}/ancestors_properties'.format(
...@@ -69,7 +69,7 @@ class TestDefaultController(BaseTestCase): ...@@ -69,7 +69,7 @@ class TestDefaultController(BaseTestCase):
""" """
id_example = self.upload_file('https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/application_example_2_topologies.yaml') id_example = self.upload_file('https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/application_example_2_topologies.yaml')
self.assertTrue(id_example.strip().isdigit()) self.assertTrue(id_example.strip().isdigit())
response = self.client.open( response = self.client.open(
'/tosca-sure/1.0.0/tosca_template/{id}/topology_template/node_templates/{node_name}/ancestors_types'.format( '/tosca-sure/1.0.0/tosca_template/{id}/topology_template/node_templates/{node_name}/ancestors_types'.format(
...@@ -84,7 +84,7 @@ class TestDefaultController(BaseTestCase): ...@@ -84,7 +84,7 @@ class TestDefaultController(BaseTestCase):
""" """
id_example = self.upload_file('https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/application_example_2_topologies.yaml') id_example = self.upload_file('https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/application_example_2_topologies.yaml')
self.assertTrue(id_example.strip().isdigit()) self.assertTrue(id_example.strip().isdigit())
response = self.client.open( response = self.client.open(
'/tosca-sure/1.0.0/tosca_template/{id}/topology_template/node_templates/{node_name}/ancestors_requirements'.format( '/tosca-sure/1.0.0/tosca_template/{id}/topology_template/node_templates/{node_name}/ancestors_requirements'.format(
...@@ -100,7 +100,7 @@ class TestDefaultController(BaseTestCase): ...@@ -100,7 +100,7 @@ class TestDefaultController(BaseTestCase):
""" """
# query_string = [('anchors', 'anchors_example'), ('derived_from', 'derived_from_example')] # query_string = [('anchors', 'anchors_example'), ('derived_from', 'derived_from_example')]
id_example = self.upload_file('https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/application_example_2_topologies.yaml') id_example = self.upload_file('https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/application_example_2_topologies.yaml')
self.assertTrue(id_example.strip().isdigit()) self.assertTrue(id_example.strip().isdigit())
response = self.client.open( response = self.client.open(
'/tosca-sure/1.0.0/tosca_template/{id}/dsl_definitions'.format(id=id_example), '/tosca-sure/1.0.0/tosca_template/{id}/dsl_definitions'.format(id=id_example),
...@@ -112,7 +112,7 @@ class TestDefaultController(BaseTestCase): ...@@ -112,7 +112,7 @@ class TestDefaultController(BaseTestCase):
""" """
id_example = self.upload_file('https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/application_example_2_topologies.yaml') id_example = self.upload_file('https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/application_example_2_topologies.yaml')
self.assertTrue(id_example.strip().isdigit()) self.assertTrue(id_example.strip().isdigit())
response = self.client.open( response = self.client.open(
'/tosca-sure/1.0.0/tosca_template/{id}/imports'.format(id=id_example), '/tosca-sure/1.0.0/tosca_template/{id}/imports'.format(id=id_example),
...@@ -124,7 +124,7 @@ class TestDefaultController(BaseTestCase): ...@@ -124,7 +124,7 @@ class TestDefaultController(BaseTestCase):
""" """
id_example = self.upload_file('https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/application_example_outputs.yaml') id_example = self.upload_file('https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/application_example_outputs.yaml')
self.assertTrue(id_example.strip().isdigit()) self.assertTrue(id_example.strip().isdigit())
response = self.client.open( response = self.client.open(
'/tosca-sure/1.0.0/tosca_template/{id}/topology_template/node_templates/{node_name}/outputs'.format( '/tosca-sure/1.0.0/tosca_template/{id}/topology_template/node_templates/{node_name}/outputs'.format(
...@@ -139,7 +139,7 @@ class TestDefaultController(BaseTestCase): ...@@ -139,7 +139,7 @@ class TestDefaultController(BaseTestCase):
""" """
id_example = self.upload_file('https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/application_example_2_topologies.yaml') id_example = self.upload_file('https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/application_example_2_topologies.yaml')
self.assertTrue(id_example.strip().isdigit()) self.assertTrue(id_example.strip().isdigit())
response = self.client.open( response = self.client.open(
'/tosca-sure/1.0.0/tosca_template/{id}/topology_template/node_templates/{node_name}/properties'.format( '/tosca-sure/1.0.0/tosca_template/{id}/topology_template/node_templates/{node_name}/properties'.format(
...@@ -154,7 +154,7 @@ class TestDefaultController(BaseTestCase): ...@@ -154,7 +154,7 @@ class TestDefaultController(BaseTestCase):
""" """
id_example = self.upload_file('https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/application_example_2_topologies.yaml') id_example = self.upload_file('https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/application_example_2_topologies.yaml')
self.assertTrue(id_example.strip().isdigit()) self.assertTrue(id_example.strip().isdigit())
response = self.client.open( response = self.client.open(
'/tosca-sure/1.0.0/tosca_template/{id}/topology_template/node_templates/{node_name}/requirements'.format( '/tosca-sure/1.0.0/tosca_template/{id}/topology_template/node_templates/{node_name}/requirements'.format(
...@@ -169,7 +169,7 @@ class TestDefaultController(BaseTestCase): ...@@ -169,7 +169,7 @@ class TestDefaultController(BaseTestCase):
""" """
id_example = self.upload_file('https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/application_example_2_topologies.yaml') id_example = self.upload_file('https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/application_example_2_topologies.yaml')
self.assertTrue(id_example.strip().isdigit()) self.assertTrue(id_example.strip().isdigit())
query_string = [('type_name', None), query_string = [('type_name', None),
('node_name', 'compute'), ('node_name', 'compute'),
...@@ -240,7 +240,7 @@ class TestDefaultController(BaseTestCase): ...@@ -240,7 +240,7 @@ class TestDefaultController(BaseTestCase):
""" """
id_example = self.upload_file('https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/application_example_2_topologies.yaml') id_example = self.upload_file('https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/application_example_2_topologies.yaml')
self.assertTrue(id_example.strip().isdigit()) self.assertTrue(id_example.strip().isdigit())
response = self.client.open( response = self.client.open(
'/tosca-sure/1.0.0/tosca_template/{id}/topology_template/node_templates/{node_name}/type_name'.format( '/tosca-sure/1.0.0/tosca_template/{id}/topology_template/node_templates/{node_name}/type_name'.format(
...@@ -255,7 +255,7 @@ class TestDefaultController(BaseTestCase): ...@@ -255,7 +255,7 @@ class TestDefaultController(BaseTestCase):
""" """
id_example = self.upload_file('https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/application_example_2_topologies.yaml') id_example = self.upload_file('https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/application_example_2_topologies.yaml')
self.assertTrue(id_example.strip().isdigit()) self.assertTrue(id_example.strip().isdigit())
response = self.client.open( response = self.client.open(
'/tosca-sure/1.0.0/tosca_template/{id}/topology_template/node_templates/{node_name}/derived_from'.format( '/tosca-sure/1.0.0/tosca_template/{id}/topology_template/node_templates/{node_name}/derived_from'.format(
...@@ -270,7 +270,7 @@ class TestDefaultController(BaseTestCase): ...@@ -270,7 +270,7 @@ class TestDefaultController(BaseTestCase):
""" """
id_example = self.upload_file('https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/application_example_2_topologies.yaml') id_example = self.upload_file('https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/application_example_2_topologies.yaml')
self.assertTrue(id_example.strip().isdigit()) self.assertTrue(id_example.strip().isdigit())
response = self.client.open( response = self.client.open(
'/tosca-sure/1.0.0/tosca_template/{id}/topology_template/node_templates/{node_name}/related'.format( '/tosca-sure/1.0.0/tosca_template/{id}/topology_template/node_templates/{node_name}/related'.format(
...@@ -285,7 +285,7 @@ class TestDefaultController(BaseTestCase): ...@@ -285,7 +285,7 @@ class TestDefaultController(BaseTestCase):
""" """
id_example = self.upload_file('https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/application_example_2_topologies.yaml') id_example = self.upload_file('https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/application_example_2_topologies.yaml')
self.assertTrue(id_example.strip().isdigit()) self.assertTrue(id_example.strip().isdigit())
query_string = [('type_name', None), query_string = [('type_name', None),
('derived_from', None)] ('derived_from', None)]
...@@ -300,7 +300,7 @@ class TestDefaultController(BaseTestCase): ...@@ -300,7 +300,7 @@ class TestDefaultController(BaseTestCase):
""" """
id_example = self.upload_file('https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/application_example_2_topologies.yaml') id_example = self.upload_file('https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/application_example_2_topologies.yaml')
self.assertTrue(id_example.strip().isdigit()) self.assertTrue(id_example.strip().isdigit())
response = self.client.open( response = self.client.open(
'/tosca-sure/1.0.0/tosca_template/{id}/topology_template'.format(id=id_example), '/tosca-sure/1.0.0/tosca_template/{id}/topology_template'.format(id=id_example),
...@@ -314,7 +314,7 @@ class TestDefaultController(BaseTestCase): ...@@ -314,7 +314,7 @@ class TestDefaultController(BaseTestCase):
""" """
id_example = self.upload_file('https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/application_example_2_topologies.yaml') id_example = self.upload_file('https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/application_example_2_topologies.yaml')
self.assertTrue(id_example.strip().isdigit()) self.assertTrue(id_example.strip().isdigit())
response = self.client.open( response = self.client.open(
'/tosca-sure/1.0.0/tosca_template/{id}'.format(id=id_example), '/tosca-sure/1.0.0/tosca_template/{id}'.format(id=id_example),
...@@ -328,7 +328,7 @@ class TestDefaultController(BaseTestCase): ...@@ -328,7 +328,7 @@ class TestDefaultController(BaseTestCase):
""" """
id_example = self.upload_file('https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/application_example_2_topologies.yaml') id_example = self.upload_file('https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/application_example_2_topologies.yaml')
self.assertTrue(id_example.strip().isdigit()) self.assertTrue(id_example.strip().isdigit())
query_string = [('kind_of_type', 'interface_types'), query_string = [('kind_of_type', 'interface_types'),
('has_interfaces', None), ('has_interfaces', None),
...@@ -368,7 +368,7 @@ class TestDefaultController(BaseTestCase): ...@@ -368,7 +368,7 @@ class TestDefaultController(BaseTestCase):
""" """
id_example = self.upload_file('https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/application_example_2_topologies.yaml') id_example = self.upload_file('https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/application_example_2_topologies.yaml')
self.assertTrue(id_example.strip().isdigit()) self.assertTrue(id_example.strip().isdigit())
properties = {'properties': {'cpu_frequency': '2 GHz'}} properties = {'properties': {'cpu_frequency': '2 GHz'}}
response = self.client.open( response = self.client.open(
...@@ -388,7 +388,7 @@ class TestDefaultController(BaseTestCase): ...@@ -388,7 +388,7 @@ class TestDefaultController(BaseTestCase):
""" """
id_example = self.upload_file('https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/application_example_2_topologies.yaml') id_example = self.upload_file('https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/application_example_2_topologies.yaml')
self.assertTrue(id_example.strip().isdigit()) self.assertTrue(id_example.strip().isdigit())
response = self.client.open( response = self.client.open(
'/tosca-sure/1.0.0/tosca_template/{id}/topology_template/node_templates'.format(id=id_example), '/tosca-sure/1.0.0/tosca_template/{id}/topology_template/node_templates'.format(id=id_example),
...@@ -404,7 +404,7 @@ class TestDefaultController(BaseTestCase): ...@@ -404,7 +404,7 @@ class TestDefaultController(BaseTestCase):
""" """
id_example = self.upload_file('https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/application_example_2_topologies.yaml') id_example = self.upload_file('https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/application_example_2_topologies.yaml')
self.assertTrue(id_example.strip().isdigit()) self.assertTrue(id_example.strip().isdigit())
query_string = [('instance_name', 'instance_name_example'), query_string = [('instance_name', 'instance_name_example'),
('operation_name', 'provision')] ('operation_name', 'provision')]
......
...@@ -18,7 +18,7 @@ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(messag ...@@ -18,7 +18,7 @@ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(messag
h.setFormatter(formatter) h.setFormatter(formatter)
logger.addHandler(h) logger.addHandler(h)
logger.handler_set = True logger.handler_set = True
base_url = 'https://raw.githubusercontent.com/QCDIS/sdia-tosca/master/examples/' base_url = 'https://raw.githubusercontent.com/qcdis-sdia/sdia-tosca/master/examples/'
class Test(TestCase): class Test(TestCase):
def test_upload(self): def test_upload(self):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment