diff options
Diffstat (limited to 'laas')
67 files changed, 2424 insertions, 0 deletions
diff --git a/laas/actions/add_booking.py b/laas/actions/add_booking.py new file mode 100644 index 0000000..b34c23d --- /dev/null +++ b/laas/actions/add_booking.py @@ -0,0 +1,61 @@ +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## +import json +import requests +import time +import calendar +from st2actions.runners.pythonrunner import Action + + +class Add_Booking_Action(Action): + + def run(self, booking_id): + dashboard = self.action_service.get_value(name="dashboard_url") + url = dashboard + "api/bookings/" + str(booking_id) + try: + booking = requests.get(url).json() + booking['start'] = self.convert_time(booking['start']) + booking['end'] = self.convert_time(booking['end']) + booking['status'] = 1 + + # add booking id to bookings list + bookings = json.loads( + self.action_service.get_value(name="bookings", local=False) + ) + if booking['id'] in bookings: + return + bookings.append(booking['id']) + self.action_service.set_value( + name="bookings", + value=json.dumps(bookings), + local=False + ) + + # add booking to datastore + name = "booking_" + str(booking['id']) + self.action_service.set_value( + name=name, + value=json.dumps(booking), + local=False + ) + + except Exception: + pass + + def convert_time(self, timestr): + time_struct = time.strptime(timestr, '%Y-%m-%dT%H:%M:%SZ') + epoch_time = calendar.timegm(time_struct) + return epoch_time diff --git a/laas/actions/add_booking.yaml b/laas/actions/add_booking.yaml new file mode 100644 index 0000000..0851599 --- /dev/null +++ b/laas/actions/add_booking.yaml @@ -0,0 +1,26 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: add_booking +enabled: true +runner_type: python-script +entry_point: add_booking.py +parameters: + booking: + type: string + required: true + description: "id of booking to add" diff --git a/laas/actions/apex_install.sh b/laas/actions/apex_install.sh new file mode 100644 index 0000000..f3ca83b --- /dev/null +++ b/laas/actions/apex_install.sh @@ -0,0 +1,18 @@ +#!/bin/bash +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +echo "not implemented" diff --git a/laas/actions/apex_install.yaml b/laas/actions/apex_install.yaml new file mode 100644 index 0000000..1956997 --- /dev/null +++ b/laas/actions/apex_install.yaml @@ -0,0 +1,22 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: apex_install +description: "placeholder for apex isntallation action" +runner_type: remote-shell-script +entry_point: apex_install.sh +enabled: false diff --git a/laas/actions/apex_workflow.yaml b/laas/actions/apex_workflow.yaml new file mode 100644 index 0000000..43adf4a --- /dev/null +++ b/laas/actions/apex_workflow.yaml @@ -0,0 +1,30 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: "apex_workflow" +runner_type: "action-chain" +description: "This workflow installs apex" +enabled: true +entry_point: "workflows.apex_workflow.yaml" +parameters: + host: + type: "string" + required: true + + scenario: + type: "string" + required: false diff --git a/laas/actions/clean-workflow.yaml b/laas/actions/clean-workflow.yaml new file mode 100644 index 0000000..cc93afb --- /dev/null +++ b/laas/actions/clean-workflow.yaml @@ -0,0 +1,31 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: "clean-workflow" +runner_type: "action-chain" +description: "This workflow cleans a host after a deployment" +entry_point: "workflows/clean-workflow.yaml" +enabled: true +parameters: + host: + type: "string" + required: true + description: "hostname of host to be cleaned" + key: + type: "string" + required: false + description: "st2 key of vpn user to delete" diff --git a/laas/actions/compass_install.sh b/laas/actions/compass_install.sh new file mode 100644 index 0000000..4d5d829 --- /dev/null +++ b/laas/actions/compass_install.sh @@ -0,0 +1,18 @@ +#!/bin/bash +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +curl https://raw.githubusercontent.com/opnfv/compass4nfv/stable/euphrates/quickstart.sh | bash diff --git a/laas/actions/compass_install.yaml b/laas/actions/compass_install.yaml new file mode 100644 index 0000000..9f88314 --- /dev/null +++ b/laas/actions/compass_install.yaml @@ -0,0 +1,22 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: compass_install +description: "placeholder for compass action" +runner_type: remote-shell-script +entry_point: compass_install.sh +enabled: true diff --git a/laas/actions/compass_workflow.yaml b/laas/actions/compass_workflow.yaml new file mode 100644 index 0000000..8e78372 --- /dev/null +++ b/laas/actions/compass_workflow.yaml @@ -0,0 +1,29 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: "compass_workflow" +runner_type: "action-chain" +entry_point: "workflows/compass_workflow.yaml" +enabled: true +parameters: + host: + type: "string" + required: true + + scenario: + type: "string" + required: false diff --git a/laas/actions/deployment_workflow.yaml b/laas/actions/deployment_workflow.yaml new file mode 100644 index 0000000..83066d5 --- /dev/null +++ b/laas/actions/deployment_workflow.yaml @@ -0,0 +1,39 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +description: This is the workflow that will provision the host as requested. +enabled: true +runner_type: mistral-v2 +entry_point: workflows/deployment_workflow.yaml +name: deployment_workflow +pack: laas +parameters: + installer: + required: true + type: string + host: + required: true + type: string + scenario: + required: false + type: string + os: + required: false + type: string + booking: + required: false + type: string diff --git a/laas/actions/fogAction.py b/laas/actions/fogAction.py new file mode 100644 index 0000000..ef74939 --- /dev/null +++ b/laas/actions/fogAction.py @@ -0,0 +1,153 @@ +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +import requests +import sys +import json +import time +from st2actions.runners.pythonrunner import Action + + +class FogAction(Action): + """ + This class talks with the REST web api for the FOG server. + """ + def __init__(self, config=None): + self.baseURL = config['fog']['address'] + self.fogKey = config['fog']['api_key'] + self.userKey = config['fog']['user_key'] + self.updateHeader() + + def updateHeader(self): + """ + recreates the http header used to talk to the fog api + """ + self.header = {} + self.header['fog-api-token'] = self.fogKey + self.header['fog-user-token'] = self.userKey + + def getImageID(self, img=None, os=None, host=None): + """ + returns the numerical id associated with the given img name or + operating system. If both are given, the img gets priority. + if img is a number, it is assumed to be a valid id + """ + # st2 will promote an empty arg to the str "None" :( + if not img or img == "None": + return self.getImageIDFromOS(os, host) + try: + return int(img) + except: + url = self.baseURL+"image" + images = requests.get(url=url, headers=self.header) + images = images.json()['images'] + for image in images: + if img == image['name']: + return image['id'] + return -1 + + def getImageIDFromOS(self, os, host): + enum = {"ubuntu": "ubuntu_image", + "centos": "centos_image", + "suse": "suse_image" + } + os = os.lower() + if os not in enum.keys(): + return -1 + host_dict = json.loads( + self.action_service.get_value(name=host, local=False) + ) + return int(host_dict[enum[os]]) + + def delTask(self, hostNum): + """ + Tries to delete an existing task for the host + with hostNum as a host number + """ + try: + url = self.baseURL+'fog/host/'+str(hostNum)+'/cancel' + req = requests.delete(url, headers=self.header) + if req.status_code == 200: + self.logger.info("%s", "successfully deleted image task") + except Exception: + self.logger.exception("Failed to delete the imaging task!") + + def getHostNumber(self, hostname): + """ + returns the host number of given host + """ + try: + req = requests.get(self.baseURL+"host", headers=self.header) + hostData = req.json() + if hostData is not None: + for hostDict in hostData['hosts']: + if hostname == hostDict['name']: + return hostDict['id'] + return -1 + except Exception: + self.logger.exception('%s', "Failed to connect to the FOG server") + + def request(self, url, data=None, method="get"): + if data is not None: + return self.dataRequest(url, data, method=method) + try: + response = requests.get(url, headers=self.header) + return response.json() + except Exception: + self.logger.exception("Failed to reach FOG at %s", url) + sys.exit(1) + + def dataRequest(self, url, data, method="post"): + methods = { + "post": requests.post, + "put": requests.put + } + try: + return methods[method](url, json=data, headers=self.header) + except Exception: + self.logger.exception("Failed to reach FOG at %s", url) + sys.exit(1) + + def getFogHost(self, host): + hostData = self.action_service.get_value(host, local=False) + return json.loads(hostData)['fog_name'] + + def waitForTask(self, taskID): + """ + Watches a task and waits for it to finish (disapear). + There may be a smarter way to do this and track errors, + but st2 will timeout for me if something goes wrong + """ + task = self.getTask(taskID) + while(task): + time.sleep(15) + task = self.getTask(taskID) + + def getAllTasks(self): + try: + tasks = requests.get( + self.baseURL+'task/current', + headers=self.header + ).json()['tasks'] + return tasks + except Exception: + return [] + + def getTask(self, taskID): + for task in self.getAllTasks(): + if task['id'] == taskID: + return task + return {} diff --git a/laas/actions/fog_captureHost.py b/laas/actions/fog_captureHost.py new file mode 100644 index 0000000..d8ee343 --- /dev/null +++ b/laas/actions/fog_captureHost.py @@ -0,0 +1,37 @@ +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +############################################################################## + +from fogAction import FogAction +import requests +import sys + + +class StartCaptureAction(FogAction): + def __init__(self, config=None): + super(StartCaptureAction, self).__init__(config=config) + + def run(self, host=None): + """ + Schedules a capture for the given host with its + assigned image + """ + host = self.getFogHost(host) + num = str(self.getHostNumber(host)) + url = self.baseURL+'host/'+num+'/task' + try: + requests.post(url, headers=self.header, json={"taskTypeID": 2}) + except Exception: + sys.exit(1) diff --git a/laas/actions/fog_captureHost.yaml b/laas/actions/fog_captureHost.yaml new file mode 100644 index 0000000..3e38825 --- /dev/null +++ b/laas/actions/fog_captureHost.yaml @@ -0,0 +1,25 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: fog_captureHost +entry_point: fog_captureHost.py +runner_type: python-script +enabled: true +parameters: + host: + type: string + required: true diff --git a/laas/actions/fog_captureWorkflow.yaml b/laas/actions/fog_captureWorkflow.yaml new file mode 100644 index 0000000..a951d55 --- /dev/null +++ b/laas/actions/fog_captureWorkflow.yaml @@ -0,0 +1,25 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: fog_captureWorkflow +entry_point: workflows/fog_captureWorkflow.yaml +runner_type: action-chain +enabled: true +parameters: + host: + type: string + required: true diff --git a/laas/actions/fog_changeImage.py b/laas/actions/fog_changeImage.py new file mode 100644 index 0000000..3586a75 --- /dev/null +++ b/laas/actions/fog_changeImage.py @@ -0,0 +1,38 @@ +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +############################################################################## + +from fogAction import FogAction +import requests + + +class ChangeImageAction(FogAction): + def __init__(self, config): + super(ChangeImageAction, self).__init__(config=config) + + def run(self, host=None, image=None, os=None): + """ + Sets the image to be used during ghosting to the image + with id imgNum. host can either be a hostname or number. + """ + imgNum = self.getImageID(img=image, os=os, host=host) + if imgNum < 0: + return + host = self.getFogHost(host) + hostnum = self.getHostNumber(host) + url = self.baseURL+"host/"+str(hostnum) + host_conf = requests.get(url, headers=self.header).json() + host_conf['imageID'] = str(imgNum) + requests.put(url+"/edit", headers=self.header, json=host_conf) diff --git a/laas/actions/fog_changeImage.yaml b/laas/actions/fog_changeImage.yaml new file mode 100644 index 0000000..36deff9 --- /dev/null +++ b/laas/actions/fog_changeImage.yaml @@ -0,0 +1,31 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: "fog_changeImage" +enabled: true +runner_type: python-script +entry_point: "fog_changeImage.py" +parameters: + host: + type: string + required: true + image: + required: false + type: string + os: + required: false + type: string diff --git a/laas/actions/fog_imageWorkflow.yaml b/laas/actions/fog_imageWorkflow.yaml new file mode 100644 index 0000000..f8c4aef --- /dev/null +++ b/laas/actions/fog_imageWorkflow.yaml @@ -0,0 +1,31 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: "fog_imageWorkflow" +entry_point: "workflows/fog_imageWorkflow.yaml" +runner_type: "action-chain" +enabled: true +parameters: + host: + type: "string" + required: true + image: + required: false + type: "string" + os: + required: false + type: "string" diff --git a/laas/actions/fog_startImaging.py b/laas/actions/fog_startImaging.py new file mode 100644 index 0000000..f775efe --- /dev/null +++ b/laas/actions/fog_startImaging.py @@ -0,0 +1,55 @@ +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +############################################################################## + +from fogAction import FogAction +import requests +import sys + + +class StartImagingAction(FogAction): + def __init__(self, config=None): + super(StartImagingAction, self).__init__(config=config) + + def run(self, host=None): + """ + Schedules an imaging task for the given host. + This automatically uses the "associated" disk image. + """ + host = self.getFogHost(host) + num = str(self.getHostNumber(host)) + url = self.baseURL+'host/'+num+'/task' + try: + req = requests.post( + url, + headers=self.header, + json={"taskTypeID": 1} + ) + if req.status_code == 200: + # self.logger.info("%s", "Scheduled image task for host") + pass + except Exception: + # self.logger.warning("%s", "Failed to schedule host imaging") + # self.logger.warning("%s", "Trying to delete existing image task") + self.delTask(num) + req = requests.post( + url, + headers=self.header, + json={"taskTypeID": 1} + ) + if req.status_code == 200: + # self.logger.info("%s", "Scheduled image task for host") + pass + sys.exit(0) diff --git a/laas/actions/fog_startImaging.yaml b/laas/actions/fog_startImaging.yaml new file mode 100644 index 0000000..2a24f4d --- /dev/null +++ b/laas/actions/fog_startImaging.yaml @@ -0,0 +1,27 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: "fog_startImaging" +description: "This will use FOG to image the given host" +runner_type: "python-script" +enabled: true +entry_point: "fog_startImaging.py" +parameters: + host: + type: "string" + description: "the hostname of the host (eg pod2)" + required: true diff --git a/laas/actions/fog_waitForCapture.py b/laas/actions/fog_waitForCapture.py new file mode 100644 index 0000000..7f7c488 --- /dev/null +++ b/laas/actions/fog_waitForCapture.py @@ -0,0 +1,37 @@ +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +############################################################################## + +from fogAction import FogAction +import sys + + +class waitForCaptureAction(FogAction): + def __init__(self, config=None): + super(waitForCaptureAction, self).__init__(config=config) + + def run(self, host=None): + host = self.getFogHost(host) + captureTaskID = self.getCaptureTaskID(host) + if(captureTaskID < 0): + sys.exit(1) + self.waitForTask(captureTaskID) + + def getCaptureTaskID(self, host=None): + for task in self.getAllTasks(): + hostname = str(task['host']['name']) + if hostname == host and int(task['typeID']) == 2: + return task['id'] + return -1 diff --git a/laas/actions/fog_waitForCapture.yaml b/laas/actions/fog_waitForCapture.yaml new file mode 100644 index 0000000..2d0364e --- /dev/null +++ b/laas/actions/fog_waitForCapture.yaml @@ -0,0 +1,25 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: fog_waitForCapture +enabled: true +runner_type: python-script +entry_point: fog_waitForCapture.py +parameters: + host: + type: string + required: true diff --git a/laas/actions/fog_waitForImaging.py b/laas/actions/fog_waitForImaging.py new file mode 100644 index 0000000..ea73f8f --- /dev/null +++ b/laas/actions/fog_waitForImaging.py @@ -0,0 +1,44 @@ +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +############################################################################## + +from fogAction import FogAction +import sys + + +class WaitForImagingAction(FogAction): + def __init__(self, config=None): + super(WaitForImagingAction, self).__init__(config=config) + + def run(self, host): + """ + tracks the imaging task to completion. + """ + host = self.getFogHost(host) + imageTaskID = self.getImagingTaskID(host) + if(imageTaskID < 0): + sys.exit(1) + self.waitForTask(imageTaskID) + + def getImagingTaskID(self, host): + """ + Sorts through all current tasks to find the image task + associated with the given host. + """ + for task in self.getAllTasks(): + hostname = str(task['host']['name']) + if hostname == host and int(task['typeID']) == 1: + return task['id'] + return -1 diff --git a/laas/actions/fog_waitForImaging.yaml b/laas/actions/fog_waitForImaging.yaml new file mode 100644 index 0000000..4be325c --- /dev/null +++ b/laas/actions/fog_waitForImaging.yaml @@ -0,0 +1,25 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: "fog_waitForImaging" +entry_point: "fog_waitForImaging.py" +runner_type: "python-script" +enabled: true +parameters: + host: + required: true + type: "string" diff --git a/laas/actions/fuel_horizon_nat.sh b/laas/actions/fuel_horizon_nat.sh new file mode 100644 index 0000000..a58516d --- /dev/null +++ b/laas/actions/fuel_horizon_nat.sh @@ -0,0 +1,34 @@ +#!/bin/bash +############################################################################# +#Copyright 2017 Parker Berberian and others # +# # +#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. # +############################################################################# + +ctlprivip=$(virsh domifaddr ctl01 | grep 10.20.0 | awk '{print $4}' | cut -d "/" -f 1) +ctlpubip=$(ssh -i fuel/mcp/scripts/mcp.rsa ubuntu@"$ctlprivip" ip r | grep 10.16.0.0/24 | awk '{print $9}') +#default is 10.16.0.101? +MYIP=$1 +DESTINATION=$ctlpubip +MYBRIDGE=10.16.0.1 +DESTNETWORK=10.16.0.0/24 +PORT=8078 + +iptables -I INPUT 2 -d "$MYIP" -p tcp --dport "$PORT" -j ACCEPT +iptables -t nat -I INPUT 1 -d "$MYIP" -p tcp --dport "$PORT" -j ACCEPT +iptables -I FORWARD -p tcp --dport "$PORT" -j ACCEPT + +iptables -t nat -I PREROUTING -p tcp -d "$MYIP" --dport "$PORT" -j DNAT --to-destination "$DESTINATION:$PORT" +iptables -t nat -I POSTROUTING -p tcp -s "$DESTINATION" ! -d "$DESTNETWORK" -j SNAT --to-source "$MYIP" + +iptables -t nat -I POSTROUTING 2 -d "$DESTINATION" -j SNAT --to-source "$MYBRIDGE" diff --git a/laas/actions/fuel_horizon_nat.yaml b/laas/actions/fuel_horizon_nat.yaml new file mode 100644 index 0000000..15bc7d8 --- /dev/null +++ b/laas/actions/fuel_horizon_nat.yaml @@ -0,0 +1,31 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: fuel_horizon_nat +runner_type: remote-shell-script +entry_point: fuel_horizon_nat.sh +parameters: + my_ip: + type: string + description: "ip of remote host" + required: true + position: 0 + destination: + type: string + description: "ip of horizon dashboard" + required: true + position: 1 diff --git a/laas/actions/fuel_install.sh b/laas/actions/fuel_install.sh new file mode 100644 index 0000000..b5913f1 --- /dev/null +++ b/laas/actions/fuel_install.sh @@ -0,0 +1,26 @@ +#!/bin/bash +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +git clone https://git.opnfv.org/fuel + +export TERM='xterm-256color' # hack to avoid tput error + +#make idf and pdf virtual +mv fuel/mcp/config/labs/local/pod1.yaml fuel/mcp/config/labs/local/virtual_pod1.yaml +mv fuel/mcp/config/labs/local/idf-pod1.yaml fuel/mcp/config/labs/local/idf-virtual_pod1.yaml + +fuel/ci/deploy.sh -b file://"$(pwd)"/fuel/mcp/config -l local -p virtual_pod1 -s os-nosdn-nofeature-noha diff --git a/laas/actions/fuel_install.yaml b/laas/actions/fuel_install.yaml new file mode 100644 index 0000000..301ac77 --- /dev/null +++ b/laas/actions/fuel_install.yaml @@ -0,0 +1,21 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: "fuel_install" +enabled: true +runner_type: remote-shell-script +entry_point: "fuel_install.sh" diff --git a/laas/actions/fuel_workflow.yaml b/laas/actions/fuel_workflow.yaml new file mode 100644 index 0000000..6975054 --- /dev/null +++ b/laas/actions/fuel_workflow.yaml @@ -0,0 +1,28 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: "fuel_workflow" +runner_type: "action-chain" +enabled: true +entry_point: "workflows/fuel_workflow.yaml" +parameters: + host: + type: "string" + required: true + scenario: + type: "string" + required: false diff --git a/laas/actions/genPass.sh b/laas/actions/genPass.sh new file mode 100644 index 0000000..5eba059 --- /dev/null +++ b/laas/actions/genPass.sh @@ -0,0 +1,20 @@ +#!/bin/bash +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +pass=$(base64 /dev/urandom | head -c 50 | tr -d '/' | tr -d '+' | head -c 25) + +st2 key set "$1" "$pass" --encrypt diff --git a/laas/actions/genPass.yaml b/laas/actions/genPass.yaml new file mode 100644 index 0000000..c56daa6 --- /dev/null +++ b/laas/actions/genPass.yaml @@ -0,0 +1,26 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: genPass +entry_point: genPass.sh +enabled: true +runner_type: local-shell-script +parameters: + key: + type: string + required: true + position: 0 diff --git a/laas/actions/joid_install.sh b/laas/actions/joid_install.sh new file mode 100644 index 0000000..bab13e2 --- /dev/null +++ b/laas/actions/joid_install.sh @@ -0,0 +1,64 @@ +#!/bin/bash +############################################################################# +#Copyright 2017 Parker Berberian and others # +# # +#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. # +############################################################################# + +if [ "$1" ]; then + # parses the passed scenario + args=($(echo "$1" | tr "-" "\n")) + # args is array: [os, nosdn, nofeature, noha] +else + args=('os' 'nosdn' 'nofeature' 'noha') +fi +# the deploy script expects 'none' rather than 'nofeature' +if [ "nofeature" == "${args[2]}" ]; then + args[2]="none" +fi +if [ "os" == "${args[0]}" ]; then + args[0]="openstack" +fi +# grabs the joid repo +git clone "https://gerrit.opnfv.org/gerrit/joid.git" +# working directory has to be where 03-maasdeploy is +cd joid/ci || exit 1 +# virtualy deploy maas +./03-maasdeploy.sh virtual +# deploys OPNFV with the given scenario +./deploy.sh -o newton -s "${args[1]}" -t "${args[3]}" -l default -d xenial -m "${args[0]}" -f "${args[2]}" + +juju gui --show-credentials --no-browser &>output.juju + +DESTINATION=$( grep -E -o "[0-9].*[0-9]" output.juju | tr -d '/' | sed s/:.*//g ) +MYIP=$( ip a | grep -E -o "10.10.30.[0-9]+" | sed s/^.*255.*$//g | tr -d '\n' ) + +rm -f output.juju + + +############## Uses NAT to make juju gui available at my public address #################### + +MYIP=$1 +DESTINATION=$2 +MYBRIDGE=192.168.122.1 +DESTNETWORK=192.168.122.0/24 +PORT=17070 + +iptables -I INPUT 2 -d "$MYIP" -p tcp --dport "$PORT" -j ACCEPT +iptables -t nat -I INPUT 1 -d "$MYIP" -p tcp --dport "$PORT" -j ACCEPT +iptables -I FORWARD -p tcp --dport "$PORT" -j ACCEPT + +iptables -t nat -I PREROUTING -p tcp -d "$MYIP" --dport "$PORT" -j DNAT --to-destination "$DESTINATION:$PORT" +iptables -t nat -I POSTROUTING -p tcp -s "$DESTINATION" ! -d "$DESTNETWORK" -j SNAT --to-source "$MYIP" + +iptables -t nat -I POSTROUTING 2 -d "$DESTINATION" -j SNAT --to-source "$MYBRIDGE" diff --git a/laas/actions/joid_install.yaml b/laas/actions/joid_install.yaml new file mode 100644 index 0000000..8b26cb2 --- /dev/null +++ b/laas/actions/joid_install.yaml @@ -0,0 +1,27 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: "joid_install" +runner_type: "remote-shell-script" +description: "This action will install Joid onto a given host" +enabled: true +entry_point: "joid_install.sh" +parameters: + scenario: + type: string + required: false + position: 1 diff --git a/laas/actions/joid_workflow.yaml b/laas/actions/joid_workflow.yaml new file mode 100644 index 0000000..7273cf7 --- /dev/null +++ b/laas/actions/joid_workflow.yaml @@ -0,0 +1,31 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: "joid_workflow" +description: "installs joid" +runner_type: "action-chain" +entry_point: "workflows/joid_workflow.yaml" +enabled: true +parameters: + host: + type: "string" + required: true + scenario: + type: "string" + required: false + timeout: + default: 7200 diff --git a/laas/actions/password_workflow.yaml b/laas/actions/password_workflow.yaml new file mode 100644 index 0000000..7798d64 --- /dev/null +++ b/laas/actions/password_workflow.yaml @@ -0,0 +1,26 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: password_workflow +description: "sets a rand pass on host and stores it encrypted" +enabled: true +runner_type: action-chain +entry_point: "workflows/password_workflow.yaml" +parameters: + host: + type: string + required: true diff --git a/laas/actions/restartHost.sh b/laas/actions/restartHost.sh new file mode 100644 index 0000000..b6842d1 --- /dev/null +++ b/laas/actions/restartHost.sh @@ -0,0 +1,20 @@ +#!/bin/bash +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +ssh -o userknownhostsfile=/dev/null -o stricthostkeychecking=false root@"$1" "shutdown -r now" + +exit 0 diff --git a/laas/actions/restartHost.yaml b/laas/actions/restartHost.yaml new file mode 100644 index 0000000..f274caf --- /dev/null +++ b/laas/actions/restartHost.yaml @@ -0,0 +1,27 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: restartHost +description: restarts given host imediately and returns 0 +runner_type: local-shell-script +entry_point: restartHost.sh +parameters: + host: + type: string + required: true + description: host to restart + position: 0 diff --git a/laas/actions/setPass.sh b/laas/actions/setPass.sh new file mode 100644 index 0000000..8b1ddfc --- /dev/null +++ b/laas/actions/setPass.sh @@ -0,0 +1,19 @@ +#!/bin/bash +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +pass=$(st2 key get "$2" --decrypt | grep 'value' | awk '{print $4}') +ssh -o userknownhostsfile=/dev/null -o stricthostkeychecking=no root@$1 "echo -e '$pass\n$pass' | passwd" diff --git a/laas/actions/setPass.yaml b/laas/actions/setPass.yaml new file mode 100644 index 0000000..0c12cba --- /dev/null +++ b/laas/actions/setPass.yaml @@ -0,0 +1,30 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: setPass +enabled: true +entry_point: setPass.sh +runner_type: local-shell-script +parameters: + host: + required: true + type: string + position: 0 + key: + required: true + type: string + position: 1 diff --git a/laas/actions/update.sh b/laas/actions/update.sh new file mode 100644 index 0000000..6635864 --- /dev/null +++ b/laas/actions/update.sh @@ -0,0 +1,29 @@ +#!/bin/bash +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +#check which package manager is used and run appropriate update cmd + +if which apt; then + apt -y update && apt -y upgrade +elif which yum; then + yum -y upgrade +elif which zypper; then + zypper -n update +else + echo "Could not find package manager" + exit 1 +fi diff --git a/laas/actions/update.yaml b/laas/actions/update.yaml new file mode 100644 index 0000000..7c11a6d --- /dev/null +++ b/laas/actions/update.yaml @@ -0,0 +1,21 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: update +entry_point: update.sh +enabled: true +runner_type: remote-shell-script diff --git a/laas/actions/update_workflow.yaml b/laas/actions/update_workflow.yaml new file mode 100644 index 0000000..27bbbba --- /dev/null +++ b/laas/actions/update_workflow.yaml @@ -0,0 +1,31 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: update_workflow +entry_point: workflows/update_workflow.yaml +enabled: true +runner_type: action-chain +parameters: + host: + required: true + type: string + os: + required: false + type: string + disk: + required: false + type: string diff --git a/laas/actions/vpnAction.py b/laas/actions/vpnAction.py new file mode 100644 index 0000000..819ba13 --- /dev/null +++ b/laas/actions/vpnAction.py @@ -0,0 +1,183 @@ +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +import ldap +import os +import random +from base64 import b64encode +from st2actions.runners.pythonrunner import Action + +names = [ + 'frodo_baggins', 'samwise_gamgee', 'peregrin_took', 'meriadoc_brandybuck', + 'bilbo_baggins', 'gandalf_grey', 'aragorn_dunadan', 'arwen_evenstar', + 'saruman_white', 'pippin_took', 'merry _randybuck', 'legolas_greenleaf', + 'gimli_gloin', 'anakin_skywalker', 'padme_amidala', 'han_solo', + 'jabba_hut', 'mace_windu', 'count_dooku', 'qui-gon_jinn', + 'admiral_ackbar', 'emperor_palpatine' +] + + +class VPNAction(Action): + """ + This class communicates with the ldap server to manage vpn users. + This class extends the above ABC, and implements the makeNewUser, + removeOldUser, and __init__ abstract functions you must override to + extend the VPN_BaseClass + """ + + def __init__(self, config=None): + """ + init takes the parsed vpn config file as an arguement. + automatically connects and authenticates on the ldap server + based on the configuration file + """ + self.config = config['vpn'] + server = self.config['server'] + self.uri = "ldap://"+server + + self.conn = None + user = self.config['authentication']['user'] + pswd = self.config['authentication']['pass'] + if os.path.isfile(pswd): + pswd = open(pswd).read() + self.connect(user, pswd) + + def connect(self, root_dn, root_pass): + """ + Opens a connection to the server in the config file + and authenticates as the given user + """ + self.conn = ldap.initialize(self.uri) + self.conn.simple_bind_s(root_dn, root_pass) + + def addUser(self, full_name, passwd): + """ + Adds a user to the ldap server. Creates the new user with the classes + and in the directory given in the config file. + full_name should be two tokens seperated by a space. The first token + will become the username + private helper function for the makeNewUser() + """ + full_name = str(full_name) + passwd = str(passwd) # avoids unicode bug + first = full_name.split('_')[0] + last = full_name.split('_')[1] + user_dir = self.config['directory']['user'] + user_dir += ','+self.config['directory']['root'] + user_dir = str(user_dir) + dn = "uid=" + first + ',' + user_dir + record = [ + ('objectclass', ['top', 'inetOrgPerson']), + ('uid', first), + ('cn', full_name), + ('sn', last), + ('userpassword', passwd), + ('ou', str(self.config['directory']['user'].split('=')[1])) + ] + self.conn.add_s(dn, record) + return first, dn + + def makeNewUser(self, name=None, passwd=None): + """ + creates a new user in the ldap database, with the given name + if supplied. If no name is given, we will try to select from the + pre-written list above, and will resort to generating a random string + as a username if the preconfigured names are all taken. + Returns the username and password the user needs to authenticate, and + the dn that we can use to manage the user. + """ + if name is None: + i = 0 + while not self.checkName(name): + i += 1 + if i == 20: + name = self.randoString(8) + name += ' '+self.randoString(8) + break # generates a random name to prevent infinite loop + name = self.genUserName() + if passwd is None: + passwd = self.randoString(15) + username, dn = self.addUser(name, passwd) + return username, passwd, dn + + def checkName(self, name): + """ + returns true if the name is available + """ + if name is None: + return False + uid = name.split('_')[0] + base = self.config['directory']['user'] + ',' + base += self.config['directory']['root'] + filtr = '(uid=' + uid + ')' + timeout = 5 + ans = self.conn.search_st( + base, + ldap.SCOPE_SUBTREE, + filtr, + timeout=timeout + ) + return len(ans) < 1 + + @staticmethod + def randoString(n): + """ + uses /dev/urandom to generate a random string of length n + """ + n = int(n) + # defines valid characters + alpha = 'abcdefghijklmnopqrstuvwxyz' + alpha_num = alpha + alpha_num += alpha.upper() + alpha_num += "0123456789" + + # generates random string from /dev/urandom + rnd = b64encode(os.urandom(3*n)).decode('utf-8') + random_string = '' + for char in rnd: + if char in alpha_num: + random_string += char + return str(random_string[:n]) + + def genUserName(self): + """ + grabs a random name from the list above + """ + i = random.randint(0, len(names) - 1) + return names[i] + + def deleteUser(self, dn): + dn = str(dn) # avoids unicode bug + self.conn.delete(dn) + + def getAllUsers(self): + """ + returns all the user dn's in the ldap database in a list + """ + base = self.config['directory']['user'] + ',' + base += self.config['directory']['root'] + filtr = '(objectclass='+self.config['user']['objects'][-1]+')' + timeout = 10 + ans = self.conn.search_st( + base, + ldap.SCOPE_SUBTREE, + filtr, + timeout=timeout + ) + users = [] + for user in ans: + users.append(user[0]) # adds the dn of each user + return users diff --git a/laas/actions/vpn_delete_user.py b/laas/actions/vpn_delete_user.py new file mode 100644 index 0000000..eac5f78 --- /dev/null +++ b/laas/actions/vpn_delete_user.py @@ -0,0 +1,47 @@ +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +import json +from vpnAction import VPNAction + + +class Del_VPN_User(VPNAction): + + def __init__(self, config=None): + super(Del_VPN_User, self).__init__(config=config) + + def run(self, dn=None, key=None): + if not dn or dn == "None": + if not key or key == "None": + return + vpn_info = json.loads( + self.action_service.get_value( + name=key, + local=False, + decrypt=True + ) + ) + dn = vpn_info['dn'] + st2key = key + else: + st2key = 'vpn_' + # get username from dn + for attr in dn.split(','): + if 'uid' in attr: + st2key += attr.split('=')[-1] + # we have the dn and key now + self.action_service.delete_value(name=st2key, local=False) + self.deleteUser(dn) diff --git a/laas/actions/vpn_delete_user.yaml b/laas/actions/vpn_delete_user.yaml new file mode 100644 index 0000000..4e06411 --- /dev/null +++ b/laas/actions/vpn_delete_user.yaml @@ -0,0 +1,30 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: vpn_delete_user +entry_point: vpn_delete_user.py +enabled: true +runner_type: python-script +parameters: + dn: + required: false + type: string + description: "dn of user to delete" + key: + required: false + type: string + description: "key in st2 datastore with vpn info" diff --git a/laas/actions/vpn_make_user.py b/laas/actions/vpn_make_user.py new file mode 100644 index 0000000..56cf9e6 --- /dev/null +++ b/laas/actions/vpn_make_user.py @@ -0,0 +1,61 @@ +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +import datetime +from vpnAction import VPNAction +import json + + +class Make_VPN_User(VPNAction): + + def __init__(self, config=None): + super(Make_VPN_User, self).__init__(config=config) + + def run(self, booking=None, user=None, passwd=None): + if user == "None": + user = None + if passwd == "None": + passwd = None + name, passwd, dn = self.makeNewUser(name=user, passwd=passwd) + vpn_info = {} + vpn_info['dn'] = dn + vpn_info['username'] = name + vpn_info['password'] = passwd + now = datetime.date.today() + vpn_info['created'] = now.isoformat() # 'YYYY-MM-DD' today + self.action_service.set_value( + name='vpn_'+name, + value=json.dumps(vpn_info), + local=False, + encrypt=True + ) + if booking is not None: + self.addUserToBooking(vpn_info, booking) + + def addUserToBooking(self, vpn_info, booking): + name = "booking_" + str(booking) + booking = json.loads( + self.action_service.get_value( + name=name, + local=False + ) + ) + booking['vpn_key'] = "vpn_" + vpn_info['username'] + self.action_service.set_value( + name=name, + value=json.dumps(booking), + local=False + ) diff --git a/laas/actions/vpn_make_user.yaml b/laas/actions/vpn_make_user.yaml new file mode 100644 index 0000000..eb90956 --- /dev/null +++ b/laas/actions/vpn_make_user.yaml @@ -0,0 +1,31 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: vpn_make_user +entry_point: vpn_make_user.py +runner_type: python-script +enabled: true +parameters: + booking: + required: false + type: string + user: + required: false + type: string + passwd: + required: false + type: string diff --git a/laas/actions/waitForBoot.sh b/laas/actions/waitForBoot.sh new file mode 100644 index 0000000..399795e --- /dev/null +++ b/laas/actions/waitForBoot.sh @@ -0,0 +1,29 @@ +#!/bin/bash +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +ping -c 1 "$1" + +while [ $? -gt 0 ] ; do + ping -c 1 "$1" && sleep 5 +done + +false + +while [ $? -gt 0 ] ; do + ping -c 1 "$1" && sleep 5 +done +exit 0 diff --git a/laas/actions/waitForBoot.yaml b/laas/actions/waitForBoot.yaml new file mode 100644 index 0000000..0700980 --- /dev/null +++ b/laas/actions/waitForBoot.yaml @@ -0,0 +1,26 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: waitForBoot +entry_point: waitForBoot.sh +runner_type: local-shell-script +enabled: true +parameters: + host: + type: string + required: true + position: 0 diff --git a/laas/actions/workflows/apex_workflow.yaml b/laas/actions/workflows/apex_workflow.yaml new file mode 100644 index 0000000..881fb8d --- /dev/null +++ b/laas/actions/workflows/apex_workflow.yaml @@ -0,0 +1,7 @@ +--- +chain: + - + name: "apex_install" + ref: "laas.apex_install" + parameters: + hosts: "{{host}}" diff --git a/laas/actions/workflows/clean-workflow.yaml b/laas/actions/workflows/clean-workflow.yaml new file mode 100644 index 0000000..60fd40b --- /dev/null +++ b/laas/actions/workflows/clean-workflow.yaml @@ -0,0 +1,16 @@ +--- +chain: + - + name: "image" + ref: "laas.fog_imageWorkflow" + parameters: + host: "{{host}}" + on-success: "delete_vpn_user" + + - + name: "delete_vpn_user" + ref: "laas.vpn_delete_user" + parameters: + key: "{{key}}" + +default: "image" diff --git a/laas/actions/workflows/compass_workflow.yaml b/laas/actions/workflows/compass_workflow.yaml new file mode 100644 index 0000000..6a03511 --- /dev/null +++ b/laas/actions/workflows/compass_workflow.yaml @@ -0,0 +1,8 @@ +--- +chain: + - + name: "compass_install" + ref: "opnfv.compass_install" + parameters: + hosts: "{{host}}" + timeout: 7200 diff --git a/laas/actions/workflows/deployment_workflow.yaml b/laas/actions/workflows/deployment_workflow.yaml new file mode 100644 index 0000000..35af6b7 --- /dev/null +++ b/laas/actions/workflows/deployment_workflow.yaml @@ -0,0 +1,47 @@ +--- +version: '2.0' +laas.deployment_workflow: + description: The master workflow to provision, install, deploy hosts + input: + - host + - installer + - scenario + - os + - booking + tasks: + image_host: + action: laas.fog_imageWorkflow host=<% $.host %> os=<% $.os %> + on-success: + - install_fuel: <% $.installer = 'Fuel' %> + - install_joid: <% $.installer = 'Joid' %> + - install_apex: <% $.installer = 'Apex' %> + - install_compass: <% $.installer = 'Compass' %> + - change_password: <% not $.installer in list('Fuel','Joid','Apex','Compass') %> + + install_fuel: + action: laas.fuel_workflow host=<% $.host %> scenario=<% $.scenario %> + on-success: + - change_password + + install_joid: + action: laas.joid_workflow host=<% $.host %> scenario=<% $.scenario %> + on-success: + - change_password + + install_apex: + action: laas.apex_workflow host=<% $.host %> scenario=<% $.scenario %> + on-success: + - change_password + + install_compass: + action: laas.compass_workflow host=<% $.host %> scenario=<% $.scenario %> + on-success: + - change_password + + change_password: + action: laas.password_workflow host=<% $.host %> + on-success: + - make_vpn_user + + make_vpn_user: + action: laas.vpn_make_user booking=<% $.booking %> diff --git a/laas/actions/workflows/fog_captureWorkflow.yaml b/laas/actions/workflows/fog_captureWorkflow.yaml new file mode 100644 index 0000000..4641802 --- /dev/null +++ b/laas/actions/workflows/fog_captureWorkflow.yaml @@ -0,0 +1,27 @@ +--- +chain: + - + name: "startCapture" + ref: "laas.fog_captureHost" + parameters: + host: "{{host}}" + on-success: "restartHost" + - + name: "restartHost" + ref: "laas.restartHost" + parameters: + host: "{{host}}" + on-success: "waitForCapture" + - + name: "waitForCapture" + ref: "laas.fog_waitForCapture" + parameters: + host: "{{host}}" + on-success: "waitForBoot" + + - + name: "waitForBoot" + ref: laas.waitForBoot + parameters: + host: "{{host}}" + timeout: 60 diff --git a/laas/actions/workflows/fog_imageWorkflow.yaml b/laas/actions/workflows/fog_imageWorkflow.yaml new file mode 100644 index 0000000..0f6e645 --- /dev/null +++ b/laas/actions/workflows/fog_imageWorkflow.yaml @@ -0,0 +1,39 @@ +--- +chain: + - + name: "changeImage" + ref: "laas.fog_changeImage" + parameters: + image: "{{image}}" + host: "{{host}}" + os: "{{os}}" + on-success: "startImaging" + + - + name: "startImaging" + ref: laas.fog_startImaging + parameters: + host: "{{host}}" + on-success: "restartHost" + + - + name: "restartHost" + ref: laas.restartHost + parameters: + host: "{{host}}" + on-success: "waitForImaging" + + - + name: "waitForImaging" + ref: laas.fog_waitForImaging + parameters: + host: "{{host}}" + timeout: 180 + on-success: "waitForBoot" + + - + name: "waitForBoot" + ref: laas.waitForBoot + parameters: + host: "{{host}}" + timeout: 60 diff --git a/laas/actions/workflows/fuel_workflow.yaml b/laas/actions/workflows/fuel_workflow.yaml new file mode 100644 index 0000000..9263a84 --- /dev/null +++ b/laas/actions/workflows/fuel_workflow.yaml @@ -0,0 +1,8 @@ +--- +chain: + - + name: 'fuel_install' + ref: 'laas.fuel_install' + parameters: + hosts: "{{host}}" + timeout: 7200 diff --git a/laas/actions/workflows/joid_workflow.yaml b/laas/actions/workflows/joid_workflow.yaml new file mode 100644 index 0000000..a0b98f8 --- /dev/null +++ b/laas/actions/workflows/joid_workflow.yaml @@ -0,0 +1,11 @@ +--- +chain: + + - + name: "joid_install" + ref: "laas.joid_install" + parameters: + hosts: "{{host}}" + timeout: "{{timeout}}" + +default: "joid_install" diff --git a/laas/actions/workflows/password_workflow.yaml b/laas/actions/workflows/password_workflow.yaml new file mode 100644 index 0000000..8090941 --- /dev/null +++ b/laas/actions/workflows/password_workflow.yaml @@ -0,0 +1,18 @@ +--- +chain: + + - + name: genPasswd + ref: laas.genPass + parameters: + key: "{{host}}-pass" + on-success: setPasswd + + - + name: setPasswd + ref: laas.setPass + parameters: + host: "{{host}}" + key: "{{host}}-pass" + +default: genPasswd diff --git a/laas/actions/workflows/update_workflow.yaml b/laas/actions/workflows/update_workflow.yaml new file mode 100644 index 0000000..725f1ee --- /dev/null +++ b/laas/actions/workflows/update_workflow.yaml @@ -0,0 +1,24 @@ +--- +chain: + + - + name: "imageHost" + ref: "laas.fog_imageWorkflow" + parameters: + image: "{{image}}" + os: "{{os}}" + host: "{{host}}" + on-success: "updateHost" + + - + name: "updateHost" + ref: "laas.update" + parameters: + hosts: "{{host}}" + on-success: "captureHost" + + - + name: "captureHost" + ref: "laas.fog_captureWorkflow" + parameters: + host: "{{host}}" diff --git a/laas/config.schema.yaml b/laas/config.schema.yaml new file mode 100644 index 0000000..309afe8 --- /dev/null +++ b/laas/config.schema.yaml @@ -0,0 +1,40 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +fog: + description: "FOG server configuration" + type: "object" + required: true + properties: + address: + type: "string" + description: "where to reach the fog server" + required: true + api_key: + type: "string" + description: "FOG api key" + required: true + secret: true + user_key: + type: "string" + description: "FOG api user key" + required: true + secret: true + +vpn: + type: object + required: false diff --git a/laas/hosts.json b/laas/hosts.json new file mode 100644 index 0000000..4a8c0c2 --- /dev/null +++ b/laas/hosts.json @@ -0,0 +1,22 @@ +[ + { + "name": "pod1", + "value": "{\"laas_id\": 999, \"fog_name\": \"fog_host1\", \"hostname\": \"pod1\", \"ubuntu_image\": 1, \"centos_image\": 2, \"suse_image\": 3}" + }, + { + "name": "pod2", + "value": "{\"laas_id\": 998, \"fog_name\": \"fog_host2\", \"hostname\": \"pod2\", \"ubuntu_image\": 1, \"centos_image\": 2, \"suse_image\": 3}" + }, + { + "name": "pod3", + "value": "{\"laas_id\": 997, \"fog_name\": \"fog_name3\", \"hostname\": \"pod3\", \"ubuntu_image\": 1, \"centos_image\": 2, \"suse_image\": 3}" + }, + { + "name": "hosts", + "value" : "[\"pod1\", \"pod2\", \"pod3\"]" + }, + { + "name": "bookings", + "value": "[]" + } +] diff --git a/laas/laas.yaml.example b/laas/laas.yaml.example new file mode 100644 index 0000000..954e0d7 --- /dev/null +++ b/laas/laas.yaml.example @@ -0,0 +1,18 @@ +--- +fog: + address: "http://myfogserver.com/fog/" + api_key: "MySecretAPIKey" + user_key: "MySecretAPIUserKey" + +vpn: + server: "myvpn.ldap.server.org" + authentication: + pass: "password" + user: "cn=root,o=opnfv,dc=iol,dc=unh,dc=edu" + directory: + root: "o=opnfv,dc=iol,dc=unh,dc=edu" + user: "ou=People" + user: + objects: + - top + - inetOrgPerson diff --git a/laas/pack.yaml b/laas/pack.yaml new file mode 100644 index 0000000..65862d8 --- /dev/null +++ b/laas/pack.yaml @@ -0,0 +1,28 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: laas +description: Provides all tools needed to host your own OPNFV lab +keywords: + - OPNFV + - Lab-as-a-Service + - LaaS + - Linux + - Openstack +version: 0.0.1 +author: pberberian +email: pberberian@iol.unh.edu diff --git a/laas/requirements.txt b/laas/requirements.txt new file mode 100644 index 0000000..697fe47 --- /dev/null +++ b/laas/requirements.txt @@ -0,0 +1,3 @@ +requests +libvirt-python +python-ldap diff --git a/laas/rules/clean.yaml b/laas/rules/clean.yaml new file mode 100644 index 0000000..e8655a0 --- /dev/null +++ b/laas/rules/clean.yaml @@ -0,0 +1,28 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: on_end_deployment_trigger +pack: laas +description: dummy rule to link end deployment trigger to clean action +enabled: true +trigger: + type: laas.end_deployment_trigger +action: + ref: laas.clean-workflow + parameters: + host: "{{ trigger.host }}" + key: "{{trigger.key}}" diff --git a/laas/rules/deployment.yaml b/laas/rules/deployment.yaml new file mode 100644 index 0000000..211ca3e --- /dev/null +++ b/laas/rules/deployment.yaml @@ -0,0 +1,30 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +name: on_deployment_trigger +pack: laas +description: "rule to link deployment trigger to deployment action" +enabled: true +trigger: + type: laas.start_deployment_trigger +action: + ref: laas.deployment_workflow + parameters: + installer: "{{ trigger.installer }}" + host: "{{ trigger.host }}" + scenario: "{{ trigger.scenario }}" + booking: "{{ trigger.booking }}" diff --git a/laas/sensors/dashboard_listener.yaml b/laas/sensors/dashboard_listener.yaml new file mode 100644 index 0000000..b83d412 --- /dev/null +++ b/laas/sensors/dashboard_listener.yaml @@ -0,0 +1,45 @@ +--- +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +class_name: "Laas_api" +entry_point: "lass.py" +description: "polls the dashboard api for deployments" +poll_interval: 30 +trigger_types: + - + name: "start_deployment_trigger" + descrition: "a simple deployment trigger" + payload_schema: + type: "object" + properties: + host: + type: "string" + installer: + type: "string" + scenario: + type: "string" + booking: + type: "string" + + - + name: "end_deployment_trigger" + description: "marks the end of a booking" + payload_schema: + host: + type: "string" + key: + type: "string" diff --git a/laas/sensors/laas.py b/laas/sensors/laas.py new file mode 100755 index 0000000..5d17fb2 --- /dev/null +++ b/laas/sensors/laas.py @@ -0,0 +1,238 @@ +############################################################################## +# Copyright 2017 Parker Berberian and Others # +# # +# 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. # +############################################################################## + +import requests +import time +import calendar +import json +from st2reactor.sensor.base import PollingSensor + + +class Laas_api(PollingSensor): + """ + This class listens to the dashboard and starts/stops bookings accordingly. + """ + + def getBookingList(self): + return json.loads( + self.sensor_service.get_value(name='bookings', local=False) + ) + + def updateBookingList(self, blist): + self.sensor_service.set_value( + name='bookings', + value=json.dumps(blist), + local=False + ) + + def AddBooking(self, new_booking): + """ + checks if booking is in the database, and adds it if it isnt + """ + # first, check if booking is already expired + if time.time() > new_booking['end']: + return + # check if booking already in db + booking_list = self.getBookingList() + if new_booking['id'] in booking_list: + return + new_booking['status'] = 0 # add status code + booking_list.append(new_booking['id']) + name = "booking_" + str(new_booking['id']) + self.sensor_service.set_value( + name=name, + value=json.dumps(new_booking), + local=False + ) + self.updateBookingList(booking_list) + + def convertTimes(self, booking): + """ + this method will take the time reported by Laas in the + format yyyy-mm-ddThh:mm:ssZ + and convert it into seconds since the epoch, + for easier management + """ + booking['start'] = self.laasToEpoch(booking['start']) + booking['end'] = self.laasToEpoch(booking['end']) + + def laasToEpoch(self, timeStr): + """ + Converts the dates from the dashboard to epoch time. + """ + time_struct = time.strptime(timeStr, '%Y-%m-%dT%H:%M:%SZ') + epoch_time = calendar.timegm(time_struct) + return epoch_time + + def checkBookings(self): + """ + This method checks all the bookings in our database to see if any + action is required. + """ + + # get all active bookings from database into a usable form + booking_list = self.getBookingList() + for booking_id in booking_list: + booking = self.getBooking(booking_id) + # first, check if booking is over + if time.time() > booking['end']: + self.log.info("ending the booking with id %i", booking_id) + self.endBooking(booking) + # Then check if booking has begun and the host is still idle + elif time.time() > booking['start'] and booking['status'] < 1: + self.log.info("starting the booking with id %i", booking['id']) + self.startBooking(booking) + + def startBooking(self, booking): + """ + Starts the scheduled booking on the requested host with + the correct config file. + The provisioning process gets spun up in a subproccess, + so the api listener is not interupted. + """ + host = self.getServer(laas_id=booking['resource_id'])['hostname'] + self.log.info("Detected a new booking started for host %s", host) + self.setBookingStatus(booking['id'], 1) # mark booking started + # dispatch trigger into system + trigger = "laas.start_deployment_trigger" + payload = {"host": host, "installer": booking['installer_name']} + payload['scenario'] = booking['scenario_name'] + payload['booking'] = booking['id'] + self.sensor_service.dispatch(trigger=trigger, payload=payload) + + def endBooking(self, booking): + """ + Resets a host once its booking has ended. + """ + host = self.getServer(laas_id=booking['resource_id'])['hostname'] + self.log.info('Lease expired. Resetting host %s', host) + self.setBookingStatus(booking['id'], 3) + self.removeBooking(booking['id']) + # dispatch trigger to clean + host = self.getServer(laas_id=booking['resource_id'])['hostname'] + trigger = "laas.end_deployment_trigger" + payload = {"host": host, "booking": booking['id']} + if 'vpn_key' in booking.keys(): + payload['key'] = booking['vpn_key'] + else: + payload['key'] = '' + self.sensor_service.dispatch(trigger=trigger, payload=payload) + + def getServer(self, fog_name=None, hostname=None, laas_id=None): + key = "" + value = "" + if fog_name is not None: + key = "fog_name" + value = fog_name + elif hostname is not None: + key = "hostname" + value = hostname + elif laas_id is not None: + key = "laas_id" + value = laas_id + for server in self.servers: + if server[key] == value: + return server + + def getBooking(self, booking_id): + name = "booking_" + str(booking_id) + return json.loads( + self.sensor_service.get_value( + name=name, + local=False + ) + ) + + def setBookingStatus(self, booking_id, status): + booking = self.getBooking(booking_id) + booking['status'] = status + name = "booking_" + str(booking_id) + self.sensor_service.set_value( + name=name, + value=json.dumps(booking), + local=False + ) + + def removeBooking(self, booking_id): + blist = self.getBookingList() + blist.remove(booking_id) + self.updateBookingList(blist) + name = "booking_" + str(booking_id) + self.sensor_service.delete_value(name=name, local=False) + + # Sensor Interface Methods # + + def setup(self): + """ + This method is called by stackstorm once to setup this polling sensor. + Basically __init__, assigns instance variables, etc + """ + server_names = json.loads( + self.sensor_service.get_value('hosts', local=False) + ) + self.servers = [] + for server in server_names: + self.servers.append( + json.loads( + self.sensor_service.get_value(server, local=False) + ) + ) + self.resource_ids = [] + for host in self.servers: + self.resource_ids.append(host['laas_id']) + self.log = self.sensor_service.get_logger(name=self.__class__.__name__) + self.dashboard = self.sensor_service.get_value( + name='dashboard_url', + local=False + ) + self.log.info("connecting to dashboard at %s", self.dashboard) + # get token here for when dashboard supports it + + def poll(self): + """ + this method will continuously poll the laas dashboard. + If a booking is found on our server, + we will start a deployment in the background with the + proper config file for the requested + installer and scenario. + """ + self.log.debug("%s", "Beginning polling of dashboard") + try: + url = self.dashboard+"/api/bookings/" + bookings = requests.get(url).json() + for booking in bookings: + if booking['resource_id'] in self.resource_ids: + self.convertTimes(booking) + self.AddBooking(booking) + self.checkBookings() + except Exception: + self.log.exception('%s', "failed to connect to dashboard") + + def cleanup(self): + # called when st2 goes down + pass + + def add_trigger(self, trigger): + # called when trigger is created + pass + + def update_trigger(self, trigger): + # called when trigger is updated + pass + + def remove_trigger(self, trigger): + # called when trigger is deleted + pass |