diff options
233 files changed, 9849 insertions, 303 deletions
@@ -1,54 +1,111 @@ -OPNFV LAB-AS-A-SERVICE - -This project automatically provisions, installs, configures, and provides -access to OPNFV community resources. - -REQUIREMENTS: - This will only install the LaaS software needed to control the lab you are hosting. -It is expected that you already have the community servers, FOG, dhcp, dns etc etc running. -A more comprehensive installer may be created in the future, but for now you need too -stand up infrastructure yourself. Some specific details: - - You will need to have already created all disk images FOG will use - - the root user on the stackstorm machine should have ssh keys in every FOG image you plan to use - - The stackstorm machine needs to be able to reach all machines it will interact with (the community resources) - -TO INSTALL: - clone this repo in a clean ubuntu or centos machine. Stackstorm expects to be the -only process running for the automated install to work. If you want something more complicated, -do it yourself. This does not require much resources, and works well in a dedicated vm. - - run: - ./install.sh - to install stackstorm and the laas addon. - -Now there are two files you must fill out for configuration to be complete. - edit /opt/stackstorm/configs/laas.yaml and /opt/stackstorm/packs/laas/hosts.json -according to the guide below. Once done, you can run - ./setup.sh -to stand up and start the stackstorm service. - -CONFIGURATION: - hosts.json: - This file contains common host configuration and will be loaded into the stackstorm datastore. - It is important to understand the structure of this file. It must be valid JSON. It is a list of objects - with two attribute, name and value. These objects are put directly into the datastore of stackstorm. - The "name" will be the key, and the "value" is the corresponding value put in the datastore. Note that - the value of each key value pair is itself valid json, encoded as a string (hence the escaped quotes). - This is needed because the stackstorm exclusively stores strings. - Lets look at one host entry: - "name": "pod1", # This is an arbitrary name, must be in the "hosts" list - "value": "{\"laas_id\": 999, # this the resource id from the dashboard that corresponds to this host - \"fog_name\": \"vm-1.1\", # this is the name FOG knows the host by - \"hostname\": \"pod1\", # hostname (or ip) that resolves to this host - \"ubuntu_image\": 17, # the FOG image ID for this host that has ubuntu installed - \"centos_image\": 22, # the FOG image ID for this host that has centos installed - \"suse_image\": 21 # the FOG image ID for this host that has open-suse installed - }" - The name of each host ("pod1" in this case) must be in the list of hosts found at the bottom of the file. - The hosts list is what stackstorm uses to tell if you have been assigned a booking. +OPNFV Lab as a Service Backend +============================== + +This project automatically provisions, installs, configures, and provides access to the hardware hosted in Lab-as-a-Service (LaaS). This code is designed to consume the api of the Lab as a Service dashboard ([here](https://git.opnfv.org/laas-reflab)) + +Overview +-------- + +This is an outline of what happens on the backend when a user creates a booking on the dashboard: +``` +--------------------- --------------------- --------------------- --------------------- +| Booking request | | Hardware tasks are| | Machines are | | Network tasks are | +| in api is consumed| | parsed. Host is | | PXE booted and | | parsed. Management| +| by stackstorm | ----->| added to the pxe | ----->| imaged by FOG. | ----->| connection is | ______ +| | | and management | | Hostname is set. | | established with | | +| | | networks | | | | newly imaged | | +| | | | | | | machine | | +--------------------- --------------------- --------------------- --------------------- | + ________________________________________________________________________________________________________| + || + \/ +--------------------- --------------------- --------------------- --------------------- +| Host network | | Switches are | | The new public IP | | Access Tasks are | +| config files are | | configured based | | and hostname is | | parsed. User's SSH| +| written. Host is | | on requested L2 | | gven to the user | | keys are coppied | +| rebooted to apply | ----->| configuration. | ----->| | ----->| to thier machines.| ______ +| new config. | | Wait for host to | | | | VPN credentials | | +| Connection is lost| | connect over new | | | | are generated. | | +| | | network. | | | | | | +--------------------- --------------------- --------------------- --------------------- | + ________________________________________________________________________________________________________| + || + \/ +--------------------- +| Software tasks | +| are parsed. | +| Virtual OPNFV | +| deployments and | +| jenkins sandboxing| +| is performed if | +| requested | +--------------------- + +``` + + +Requirements +------------ + +This code requires infrastructure to be in place for it to use. + +**Networks** + +--- + +At least two seperate L3 networks are used to fulfill a booking: +* IPMI +* PXE / Management + +Stackstorm needs to be able to boot the machine, FOG PXE boots and writes a disk image, and then Stackstorm will ssh over the Management net to finish configuring the server. + +Stackstorm will also need routable access to the admin port of your switches. This could be on the existing management net or on its own network. + + +**FOG** + +--- + +FOG- the Free Opensource Ghost, is what we use to capture and apply disk images. You can read more [here](https://fogproject.org/). +You will need to install FOG on a machine that is routable from the PXE/admin network. You will have to register all your machines with FOG and create appropriate disk images. + +**Stackstorm** + +--- + +Stackstorm, or st2, is an automation server. This is what runs the whole backend booking process. We define all the tasks to be done and stackstorm runs them against the machines that are being booked. +Stackstorm will need to be installed on a machine that has access to the IPMI network and the Management networks. +Stackstorm will also need to be able to talk to FOG in order to manage imaging jobs through FOG's api. +Stackstorm needs passwordless ssh (i.e. ssh keys) to all machines it will manage. + +**DHCP, DNS** + +--- + +It is expected that every network has a DHCP server (except possibly IPMI, if you have static addresses configured). You can configure this project to use hostnames for your machines, in which case a DNS server will also be required. + + +Installation +------------ + +Once the above infrastructure is in place, the following steps will install the code: +1) On the machine with Stackstorm installed, clone this repo +2) Fill out the configuration files, examples below +3) run `./update.sh` and then `./setup.sh` to install the code + + +Configuration +------------- + +We will need to configure the LaaS pack, and preload some important values into the st2 datastore. + +**Pack Configuration** + +--- + +This is the configuration file for the laas pack. Looking at each line: laas.json: - This is the configuration file for the laas pack. Looking at each line: fog: address: # the url of the fog server root api_key: # the api key for FOG (fog configuration -> fog settings -> api system) @@ -65,15 +122,43 @@ CONFIGURATION: objects: # list of object classes to add new users to - top # example -STACKSTORM - You can read about stackstorm here: https://docs.stackstorm.com/overview.html - Stackstorm is an automation server that the LaaS project uses. We have created -a "pack", which is essentially a plugin for stackstorm. When configured, this pack -will automatically detect, start, and clean up bookings. The stackstorm web interface -also allows you to manually run any of the defined actions or workflows. - -FOG - You can read about FOG here: https://fogproject.org/ - FOG - the Free Opensource Ghost, is the tool LaaS uses to capture and deploy disk images to hosts. -This allows us to install a selected operating system in seconds, and always have a clean known state to -revert to. +**Datastore** + +--- + +The pack needs information to be in the stackstorm datastore so it knows how to access the hosts, reach the dashboard, etc. There are a couple template files that you can fill out that will be loaded into the datastore for you. + + +**hosts.json** + +This file contains common host configuration and will be loaded into the stackstorm datastore. +It is important to understand the structure of this file. It must be valid JSON. It is a list of objects +with two attribute, name and value. These objects are put directly into the datastore of stackstorm. +The "name" will be the key, and the "value" is the corresponding value put in the datastore. Note that +the "value" key maps to a string which is itself valid json, encoded as a string (hence the escaped quotes). +This is needed because the stackstorm exclusively stores strings. + +Lets look at one host entry: +``` +"name": "pod1", # This is an arbitrary name, must be in the "hosts" list +"value": "{ + \"dashboard_id\": 999, # this the resource id from the dashboard that corresponds to this host + \"fog_name\": \"vm-1.1\", # this is the name FOG knows the host by + \"hostname\": \"pod1\", # hostname (or ip) that resolves to this host + \"ubuntu_image\": 17, # the FOG image ID for the default ubuntu image for this host + \"centos_image\": 22, # the FOG image ID for the default centos image for this host + \"suse_image\": 21 # the FOG image ID for the default suse image for this host + \"interfaces\": { # object containing all interface information for the host + \"00:11:22:33:44:55\": { # mac address of interface + \"mac\": \"00:11:22:33:44:55\", # mac address of interface + \"bus\": \"0000:04:00.0\", # bus address of interface, reported by `ethtool -i $ifname` + \"switch\": \"10.10.10.10\", # management IP address of the switch connected to this interface + \"port\": \"Ethernet1/34\", # switch port name where this interface is connected to + \"name\": \"eno49\" # interface name + } + } +}" +``` + +The name of each host ("pod1" in this case) must be in the list of hosts found at the bottom of the file. +The hosts list is what stackstorm uses to know which machines to manage. diff --git a/generate_job.py b/generate_job.py new file mode 100755 index 0000000..53a9e9b --- /dev/null +++ b/generate_job.py @@ -0,0 +1,96 @@ +#!/usr/bin/python + + +import json +import sys + + +USER = 1 + + +def make_job(host): + return { + "hardware": make_hardware_task(host), + "software": make_software_task(host), + "network": make_network_task(host), + "access": make_access_task(host), + } + + +def make_network_task(host): + network_task = { + "test_network_task_id": { + "lab_token": "null" + } + } + + interface_config = {mac: [] for mac in host['interfaces'].keys()} # all interfaces are empty + for key in interface_config.keys(): + interface_config[key].append({ + "tagged": False, + "vlan_id": 100 + }) + break # we only want to set one interface, and we dont care which + + network_task["test_network_task_id"][host["hostname"]] = interface_config + + return network_task + + +def make_hardware_task(host): + hardware_task = { + "test_hardware_task_id": { + "lab_token": "null", + "image": host['centos_image'], + "power": "on", + "hostname": "some_hostname", + "id": host['hostname'], + "ipmi_create": True + } + } + + return hardware_task + + +def make_software_task(host): + return { + "test_software_task_id": { + "lab_token": "null", + "opnfv": {} + } + } + + +def make_access_task(host): + return { + "test_access_task_id": { + "lab_token": "null", + "access_type": "ssh", + "revoke": False, + "context": { + "hosts": [host['hostname']], + "key": "my_fake_ssh_key" + }, + "user": USER + }, + "test_access_task_id2": { + "lab_token": "null", + "access_type": "vpn", + "revoke": False, + "user": USER + } + } + + +if __name__ == "__main__": + if len(sys.argv) < 2: + print("Must provide Host definition from st2 datastore!") + sys.exit(1) + try: + host_json = json.loads(sys.argv[1]) + except Exception as e: + print("Host description is not valid JSON: " + str(e)) + sys.exit(2) + print(json.dumps( + make_job(host_json) + )) diff --git a/laas/actions/__init__.py b/laas/actions/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/laas/actions/__init__.py diff --git a/laas/actions/access_master_workflow.yaml b/laas/actions/access_master_workflow.yaml new file mode 100644 index 0000000..35380b3 --- /dev/null +++ b/laas/actions/access_master_workflow.yaml @@ -0,0 +1,27 @@ +--- +############################################################################## +# Copyright 2018 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/access_master_workflow.yaml +name: access_master_workflow +pack: laas +parameters: + job_id: + required: true + type: integer diff --git a/laas/actions/access_workflow.yaml b/laas/actions/access_workflow.yaml new file mode 100644 index 0000000..3fd57b3 --- /dev/null +++ b/laas/actions/access_workflow.yaml @@ -0,0 +1,30 @@ +--- +############################################################################## +# Copyright 2018 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/access_workflow.yaml +name: access_workflow +pack: laas +parameters: + job_id: + required: true + type: integer + task_id: + required: true + type: string diff --git a/laas/actions/actions/__init__.py b/laas/actions/actions/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/laas/actions/actions/__init__.py diff --git a/laas/actions/actions/add_management_vlan.py b/laas/actions/actions/add_management_vlan.py new file mode 100644 index 0000000..399da38 --- /dev/null +++ b/laas/actions/actions/add_management_vlan.py @@ -0,0 +1,45 @@ +############################################################################## +# Copyright 2018 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 st2actions.runners.pythonrunner import Action +from lib.cisco import NXCommand +import json + + +class ManagementVlanAction(Action): + + def run(self, hosts): + self.man_vlan = "98" + self.ipmi_vlan = "99" + commands = [] + for host_id in hosts: + try: + host = json.loads(self.action_service.get_value(host_id, local=False)) + except: + print("cannot find host " + host_id) + continue + for interface in host['interfaces'].values(): + auth = json.loads( + self.action_service.get_value("switch_" + interface['switch'], local=False) + ) + cmd = NXCommand(interface['switch'], auth) + cmd.add_command("interface " + interface['port']) + cmd.add_command("switchport mode trunk") + cmd.add_command("switchport trunk allowed vlan " + ",".join([self.man_vlan, self.ipmi_vlan])) + cmd.add_command("switchport trunk native vlan " + self.man_vlan) + commands.append(cmd) + for command in commands: + print(command.execute()) diff --git a/laas/actions/actions/apex_gambia_virtual_deploy.sh b/laas/actions/actions/apex_gambia_virtual_deploy.sh new file mode 100644 index 0000000..a7db840 --- /dev/null +++ b/laas/actions/actions/apex_gambia_virtual_deploy.sh @@ -0,0 +1,54 @@ +#!/bin/bash +############################################################################## +# Copyright 2018 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. # +############################################################################## + +SCENARIO="$1" + +function install_packages { + yum -y update + yum -y groupinstall "Virtualization Host" + + systemctl start libvirtd + systemctl enable libvirtd + + #special repos and stuff + yum -y install https://repos.fedorapeople.org/repos/openstack/openstack-queens/rdo-release-queens-1.noarch.rpm + yum -y install epel-release + curl -o /etc/yum.repos.d/opnfv-apex.repo http://artifacts.opnfv.org/apex/gambia/opnfv-apex.repo + + yum -y update # synch up repos + + #download special package + + wget https://artifacts.opnfv.org/apex/gambia/opnfv-apex-python34-7.1.noarch.rpm -O /root/opnfv-apex-python34.rpm + + yum -y install /root/opnfv-apex-python34.rpm +} + + +function main { + install_packages + + #configure?? + + opnfv-deploy -v -n /etc/opnfv-apex/network_settings.yaml -d "/etc/opnfv-apex/$SCENARIO.yaml" +} + +if ! main &> /root/opnfv-deploy.log; then + tail -25 /root/opnfv-deploy.log + opnfv-clean + exit 1 +fi diff --git a/laas/actions/actions/check_ipmi_power.sh b/laas/actions/actions/check_ipmi_power.sh new file mode 100644 index 0000000..998ab53 --- /dev/null +++ b/laas/actions/actions/check_ipmi_power.sh @@ -0,0 +1,36 @@ +#!/bin/bash +############################################################################## +# Copyright 2019 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. # +############################################################################## + +HOST="$1" +USER="$2" +PASSWD="$3" + +function get_status { + ipmitool -I lanplus -H "$HOST" -U "$USER" -P "$PASSWD" chassis power status +} +if ! STATUS=$(get_status); then + sleep 45 + STATUS=$(get_status) +fi + +if [ "$STATUS" = "" ]; then + exit 1 +fi + +ONOFF=$(echo "$STATUS" | cut -d ' ' -f 4) + +echo "$ONOFF" diff --git a/laas/actions/actions/compass_gambia_virtual_deploy.sh b/laas/actions/actions/compass_gambia_virtual_deploy.sh new file mode 100644 index 0000000..7e51ffc --- /dev/null +++ b/laas/actions/actions/compass_gambia_virtual_deploy.sh @@ -0,0 +1,28 @@ +#!/bin/bash +############################################################################## +# Copyright 2018 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. # +############################################################################## + +VERSION="$2" + +export SCENARIO="$1.yml" + +function main { + wget "https://git.opnfv.org/compass4nfv/plain/quickstart.sh?h=$VERSION" -O quickstart.sh || exit 1 + chmod +x quickstart.sh + ./quickstart.sh +} + +main &> /root/opnfv-deploy.log diff --git a/laas/actions/actions/configure_host_networking.sh b/laas/actions/actions/configure_host_networking.sh new file mode 100755 index 0000000..2a5f05d --- /dev/null +++ b/laas/actions/actions/configure_host_networking.sh @@ -0,0 +1,140 @@ +#!/bin/bash +############################################################################## +# Copyright 2018 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. # +############################################################################## + + +function detect_os { + [ -d /etc/netplan ] && echo "ubuntu18" && return 0 + [ -f /etc/network/interfaces ] && echo "ubuntu16" && return 0 + [ -d /etc/sysconfig/network ] && echo "suse" && return 0 + [ -d /etc/sysconfig/network-scripts ] && echo "centos" && return 0 +} + +function os_specific_map { + echo "mapping for $1" + case "$1" in + ubuntu16) + echo "do stuff to /etc/network/interfaces" + FILE="/etc/network/interfaces.d/$2.$3" + echo "auto $2.$3" > "$FILE" + echo "iface $2.$3 inet manual" >> "$FILE" + echo " vlan-raw-device $2" >> "$FILE" + ;; + ubuntu18) + echo "do stuff to $FILE" + grep -q "vlans:" "$FILE" || echo " vlans:" >> "$FILE" + echo " vlan$3:" >> "$FILE" + echo " id: $3" >> "$FILE" + echo " link: $2" >> "$FILE" + INTERFACES="$INTERFACES $2" + ;; + suse) + echo "do /etc/sysconfig/network stuff" + FILE="/etc/sysconfig/network/ifcfg-$2.$3" + echo "ETHERDEVICE=$2" >> "$FILE" + echo "BOOTPROTO=none" >> "$FILE" + echo "STARTMODE=auto" >> "$FILE" + echo "VLAN_ID=$3" >> "$FILE" + echo "DEFROUTE=no" >> "$FILE" + ;; + centos) + echo "do /etc/sysconfig/network-scripts stuff" + FILE="/etc/sysconfig/network-scripts/ifcfg-$2.$3" + echo "TYPE=Vlan" > "$FILE" + echo "PHYSDEV=$2" >> "$FILE" + echo "BOOTPROTO=none" >> "$FILE" + echo "ONBOOT=yes" >> "$FILE" + echo "VLAN=yes" >> "$FILE" + echo "VLAN_ID=$3" >> "$FILE" + echo "DEVICE=$2.$3" >> "$FILE" + echo "DEFROUTE=no" >> "$FILE" + echo "IPV4_FAILURE_FATAL=no" >> "$FILE" + ;; + esac +} + +function translate_interface { + mac=$(echo "$1" | awk -F "." '{print $1}') + vlan=$(echo "$1" | awk -F "." '{print $2}') + ifname=$(ip link show | grep -B1 "$mac" | awk -F ': ' 'NR==1{print $2}') + [ -z "$vlan" ] && echo "$ifname" || echo "$ifname.$vlan" +} + +function map { + mac=$(echo "$1" | awk -F "-" '{print $1}') + vlan=$(echo "$1" | awk -F "-" '{print $2}') + ifname=$(ip link show | grep -B1 "$mac" | awk -F ': ' 'NR==1{print $2}') + os=$(detect_os) + os_specific_map "$os" "$ifname" "$vlan" +} + +function make_default { + # TODO: check if iface name is actually a mac, and convert + os=$(detect_os) + case "$os" in + ubuntu16) + echo "do stuff to default in /etc/network/interfaces" + default="ens4f0" + mv "/etc/network/interfaces.d/1-$default" "/etc/network/interfaces.d/$default" + mv "/etc/network/interfaces.d/$1" "/etc/network/interfaces.d/1-$1" + #use dhcp on default interface + sed -i 's/dhcp/manual/' /etc/network/interfaces.d/* + sed -i 's/manual/dhcp/' "/etc/network/interfaces.d/1-$1" + ;; + ubuntu18) + echo "default and others in $FILE" + echo -e " ethernets:\n $1:\n dhcp4: yes" >> "$FILE" + for interface in $INTERFACES; do + [ "$interface" = "$1" ] && continue + echo -e " $interface:\n dhcp4: no" >> "$FILE" + done + ;; + suse) + echo "do default /etc/sysconfig/network stuff" + sed -i "s/DEFROUTE='yes'/DEFROUTE='no'/" /etc/sysconfig/network/ifcfg-* + sed -i "s/DEFROUTE='no'/DEFROUTE='yes'/" "/etc/sysconfig/network/ifcfg-$1" + sed -i "s/DHCLIENT_SET_DEFAULT_ROUTE='yes'/DHCLIENT_SET_DEFAULT_ROUTE='no'/" /etc/sysconfig/network/ifcfg-* + sed -i "s/DHCLIENT_SET_DEFAULT_ROUTE='no'/DHCLIENT_SET_DEFAULT_ROUTE='yes'/" "/etc/sysconfig/network/ifcfg-$1" + sed -i "s/BOOTPROTO='dhcp'/BOOTPROTO='none'/" /etc/sysconfig/network/ifcfg-* + sed -i "s/BOOTPROTO='none'/BOOTPROTO='dhcp'/" "/etc/sysconfig/network/ifcfg-$1" + ;; + centos) + echo "do default /etc/sysconfig stuff" + sed -i 's/DEFROUTE=yes/DEFROUTE=no/' /etc/sysconfig/network-scripts/ifcfg-* + sed -i 's/DEFROUTE=no/DEFROUTE=yes/' "/etc/sysconfig/network-scripts/ifcfg-$1" + sed -i 's/BOOTPROTO=dhcp/BOOTPROTO=none/' /etc/sysconfig/network-scripts/ifcfg-* + sed -i 's/BOOTPROTO=none/BOOTPROTO=dhcp/' "/etc/sysconfig/network-scripts/ifcfg-$1" + ;; + esac +} + + +#main +if [ "$(detect_os)" = "ubuntu18" ]; then + FILE="/etc/netplan/config.yaml" + INTERFACES="" + echo -e "network:\n version: 2\n renderer: networkd" > $FILE +fi + +for mapping in $(echo "$1" | tr '+' '\n'); do + echo "mapping $mapping" + map "$mapping" +done + +DEFAULT=$(translate_interface "$2") + +echo "setting default $DEFAULT" +make_default "$DEFAULT" diff --git a/laas/actions/actions/copy_user_keys.sh b/laas/actions/actions/copy_user_keys.sh new file mode 100644 index 0000000..428fcf5 --- /dev/null +++ b/laas/actions/actions/copy_user_keys.sh @@ -0,0 +1,30 @@ +#!/bin/bash +############################################################################## +# Copyright 2018 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. # +############################################################################## + + +KEY="$1" +HOSTS="$2" +echo "$KEY" > tmpkey.pub + +RET=0 + +for HOST in $(echo "$HOSTS" | tr ',' '\n'); do + ssh-copy-id -f -i tmpkey.pub -o userknownhostsfile=/dev/null -o stricthostkeychecking=no opnfv@"$HOST" || RET=1 +done +rm -f tmpkey.pub + +exit $RET diff --git a/laas/actions/actions/deploy_fuel_gambia_baremetal.sh b/laas/actions/actions/deploy_fuel_gambia_baremetal.sh new file mode 100755 index 0000000..a30c631 --- /dev/null +++ b/laas/actions/actions/deploy_fuel_gambia_baremetal.sh @@ -0,0 +1,40 @@ +#!/bin/bash +############################################################################## +# Copyright 2019 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. # +############################################################################## + +# clone git repo +git clone https://git.opnfv.org/fuel +cd fuel || exit 1 +git checkout stable/gambia + +export TERM="xterm-256color" + +#write out config files +mkdir -p /home/fuel/config/labs/LaaS +mkdir /home/fuel/tmpdir +chmod -R 777 /home/fuel +echo "$1" > /home/fuel/config/labs/LaaS/pod1.yaml +echo "$2" > /home/fuel/config/labs/LaaS/idf-pod1.yaml +echo "$2" > /root/LaaS/idf-pod.yaml + +# deploy command +ci/deploy.sh \ + -l LaaS \ + -p pod1 \ + -b file:///home/fuel/config \ + -s os-nosdn-nofeature-noha \ + -S /home/fuel/tmpdir \ + -D |& tee /home/opnfv/fuel_deploy.log diff --git a/laas/actions/actions/detectHostsToBoot.py b/laas/actions/actions/detectHostsToBoot.py new file mode 100644 index 0000000..2e928fc --- /dev/null +++ b/laas/actions/actions/detectHostsToBoot.py @@ -0,0 +1,52 @@ +############################################################################## +# Copyright 2018 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 st2actions.runners.pythonrunner import Action +import json +import requests + + +class DetectHostsAction(Action): + def __init__(self, *args, **kwargs): + self._config = kwargs.get('config', None) + super(DetectHostsAction, self).__init__(*args, **kwargs) + + server = self._config['dashboard']['address'] + name = self._config['dashboard']['lab_name'] + auth = self.action_service.get_value("lab_auth_token", local=False) + + self.base_url = server + "/api/labs/" + name + "/hosts/" + self.header = {"auth-token": auth} + + def run(self): + hosts_to_boot = set() + my_hosts = json.loads( + self.action_service.get_value(name="hosts", local=False) + ) + for host in my_hosts: + if self.is_booked(host): + hosts_to_boot.add(host) + self.action_service.set_value(name="hosts_to_boot", value=json.dumps(list(hosts_to_boot)), local=False) + + def is_booked(self, hostname): + url = self.base_url + hostname + + try: + response = requests.get(url, timeout=10, headers=self.header) + return response.json()['booked'] + except: + self.logger.exception("Something happened..") + return True # return true on failure to be safe diff --git a/laas/actions/actions/detect_hardware_tasks.py b/laas/actions/actions/detect_hardware_tasks.py new file mode 100644 index 0000000..6eb6ebc --- /dev/null +++ b/laas/actions/actions/detect_hardware_tasks.py @@ -0,0 +1,31 @@ +############################################################################## +# Copyright 2018 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 st2actions.runners.pythonrunner import Action +import json + + +class DetectHardwareTasksAction(Action): + + def run(self, job_id=None, task_id=None): + job = json.loads( + self.action_service.get_value("job_" + str(job_id), local=False) + ) + task = job['hardware'][task_id] + result = {} + for k in task.keys(): + result[k] = True + return result diff --git a/laas/actions/actions/error_task.py b/laas/actions/actions/error_task.py new file mode 100644 index 0000000..c6a2e4d --- /dev/null +++ b/laas/actions/actions/error_task.py @@ -0,0 +1,23 @@ +############################################################################## +# Copyright 2018 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 lib.laas_api import TaskStatusAction + + +class ErrorTaskAction(TaskStatusAction): + + def run(self, job_id=None, task_id=None): + self.set_status(job_id=job_id, task_id=task_id, status=300) diff --git a/laas/actions/actions/finish_job.py b/laas/actions/actions/finish_job.py new file mode 100644 index 0000000..a4b3960 --- /dev/null +++ b/laas/actions/actions/finish_job.py @@ -0,0 +1,26 @@ +############################################################################## +# Copyright 2018 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 st2actions.runners.pythonrunner import Action +import json + + +class FinishJobAction(Action): + + def run(self, job_id=None): + jobs = set(json.loads(self.action_service.get_value("jobs", local=False))) + jobs.remove(job_id) + self.action_service.set_value("jobs", json.dumps(list(jobs)), local=False) diff --git a/laas/actions/actions/finish_task.py b/laas/actions/actions/finish_task.py new file mode 100644 index 0000000..6d164d4 --- /dev/null +++ b/laas/actions/actions/finish_task.py @@ -0,0 +1,22 @@ +############################################################################## +# Copyright 2018 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 lib.laas_api import TaskStatusAction + + +class FinishTaskAction(TaskStatusAction): + + def run(self, job_id=None, task_id=None, lab_token=None): + self.set_status(job_id=job_id, task_id=task_id, lab_token=lab_token, status=200) diff --git a/laas/actions/actions/fog_captureHost.py b/laas/actions/actions/fog_captureHost.py new file mode 100644 index 0000000..fa6fe1e --- /dev/null +++ b/laas/actions/actions/fog_captureHost.py @@ -0,0 +1,35 @@ +############################################################################## +# 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 lib.fog import FogAction + + +class StartCaptureAction(FogAction): + + 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: + self.request(url, data={"taskTypeID": 2}) + except Exception: + self.logger.exception("Failed to start capture!") + raise Exception diff --git a/laas/actions/actions/fog_changeImage.py b/laas/actions/actions/fog_changeImage.py new file mode 100644 index 0000000..d261402 --- /dev/null +++ b/laas/actions/actions/fog_changeImage.py @@ -0,0 +1,41 @@ +############################################################################## +# 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 lib.fog import FogAction + + +class ChangeImageAction(FogAction): + + def run(self, host=None, image=None, os=None, snapshot=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, + snapshot=snapshot + ) + if imgNum < 0: + print("cannot find image") + return + host = self.getFogHost(host) + hostnum = self.getHostNumber(host) + url = self.baseURL + "host/" + str(hostnum) + host_conf = self.request(url) + host_conf['imageID'] = str(imgNum) + self.request(url + "/edit", data=host_conf, method="put") diff --git a/laas/actions/actions/fog_createSnapshot.py b/laas/actions/actions/fog_createSnapshot.py new file mode 100644 index 0000000..375ab4b --- /dev/null +++ b/laas/actions/actions/fog_createSnapshot.py @@ -0,0 +1,24 @@ +############################################################################## +# Copyright 2018 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 lib.fog import FogAction + + +class FogCreateSnapshotAction(FogAction): + + def run(self, host=None, name=None): + currentImageName = self.getFogHostData(host)['imagename'] + print(self.deriveImage(currentImageName, name)) diff --git a/laas/actions/actions/fog_getTargetImage.py b/laas/actions/actions/fog_getTargetImage.py new file mode 100644 index 0000000..0dae140 --- /dev/null +++ b/laas/actions/actions/fog_getTargetImage.py @@ -0,0 +1,44 @@ +############################################################################## +# Copyright 2019 Sawyer Bergeron 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 lib.fog import FogAction + + +class FogGetTargetImageAction(FogAction): + def __init__(self, config=None): + super(FogGetTargetImageAction, self).__init__(config=config) + + def run(self, host="None", from_image="None", from_os="None", target_image="None", target_os="None"): + existing_target = self.getImageID(target_image, target_os, host) + + existing_source = self.getImageID(from_image, from_os, host) + + if existing_source == -1: + raise Exception("Invalid source args, source image not found") + + # we found a matching, existing, target image + if existing_target != -1: + return existing_target + + # handle being given just one operand image, it is both source and target + if target_image == "None" and target_os == "None": + return existing_source + + if target_image == "None": + raise ValueError("GetTargetImage requires a target image if the provided target OS doesn't exist") + + # if we're here, we have valid source and need to create a new target + return self.deriveImage(existing_source, target_image).json()['id'] diff --git a/laas/actions/actions/fog_startImaging.py b/laas/actions/actions/fog_startImaging.py new file mode 100644 index 0000000..18fee0e --- /dev/null +++ b/laas/actions/actions/fog_startImaging.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 lib.fog import FogAction + + +class StartImagingAction(FogAction): + + def run(self, host=None): + """ + Schedules an imaging task for the given host. + This automatically uses the "associated" disk image. + """ + host = self.getFogHost(host) + host_num = str(self.getHostNumber(host)) + url = self.baseURL + 'host/' + host_num + '/task' + try: + self.start_imaging(url) + except Exception: + self.delTask(host_num) + self.start_imaging(url) + + def start_imaging(self, url): + return self.request(url, data={"taskTypeID": 1}, method="post") diff --git a/laas/actions/actions/fog_waitForCapture.py b/laas/actions/actions/fog_waitForCapture.py new file mode 100644 index 0000000..4ef38f0 --- /dev/null +++ b/laas/actions/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 lib.fog import FogAction + + +class waitForCaptureAction(FogAction): + def __init__(self, config=None): # Necessary? + super(waitForCaptureAction, self).__init__(config=config) + + def run(self, host=None): + host = self.getFogHost(host) + captureTaskID = self.getCaptureTaskID(host) + if(captureTaskID < 0): + print("cannot find capture task to wait on!") + raise Exception + 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/actions/fog_waitForImaging.py b/laas/actions/actions/fog_waitForImaging.py new file mode 100644 index 0000000..11ed88a --- /dev/null +++ b/laas/actions/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 lib.fog import FogAction + + +class WaitForImagingAction(FogAction): + def __init__(self, config=None): # why? + 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): + print("Failed to find image task to wait on!") + return + 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/actions/fuel_gambia_virtual_deploy.sh b/laas/actions/actions/fuel_gambia_virtual_deploy.sh new file mode 100644 index 0000000..1b54e51 --- /dev/null +++ b/laas/actions/actions/fuel_gambia_virtual_deploy.sh @@ -0,0 +1,69 @@ +#!/bin/bash +############################################################################## +# Copyright 2018 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. # +############################################################################## + + +#this script will deploy a virtual POD using Fuel gambia + +#this script assumes: +# /home/fuel/config exists and has the configuration files for virtual1 +# /home/fuel/tmpdir exists +# /home/fuel/* permissions are correct + +SCENARIO="$1" +VERSION="$2" + + +function install_packages { + if grep -iq centos /etc/os-release; then #centos + yum -y update + yum -y install epel-release git + yum -y groupinstall "Virtualization Host" + systemctl start libvirtd + systemctl enable libvirtd + elif grep -iq ubuntu /etc/os-release; then #ubuntu + apt update + apt -y upgrade + apt -y install libvirt-bin git + #apt should do this for us, but lets be double safe + systemctl start libvirtd + systemctl enable libvirtd + fi +} + +function install_fuel { + git clone https://git.opnfv.org/fuel + cd fuel || exit 1 + if ! git checkout "$VERSION"; then + echo "failed to checkout $VERSION, defaulting to opnfv-7.1.0" + git checkout opnfv-7.1.0 + fi + chmod -R 777 /home/fuel/ +} + + +function main { + install_packages + + install_fuel + + ci/deploy.sh -l IOL -p virtual1 -b file:///home/fuel/config -s "$SCENARIO" -D -S /home/fuel/tmpdir +} + + +# hack for tput +export TERM=xterm-256color +main &> /root/opnfv-deploy.log diff --git a/laas/actions/actions/fuel_gambia_virtual_prepare.sh b/laas/actions/actions/fuel_gambia_virtual_prepare.sh new file mode 100644 index 0000000..d7a377d --- /dev/null +++ b/laas/actions/actions/fuel_gambia_virtual_prepare.sh @@ -0,0 +1,21 @@ +#!/bin/bash +############################################################################## +# Copyright 2018 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. # +############################################################################## + +TARGET="$1" + +ssh -o userknownhostsfile=/dev/null -o stricthostkeychecking=false root@"$TARGET" mkdir -p /home/fuel +scp -o userknownhostsfile=/dev/null -o stricthostkeychecking=false -r /var/OPNFV/nfs_mnt/OPNFV/config/Fuel/Gambia/virtual/* root@"$TARGET":/home/fuel diff --git a/laas/actions/actions/genPass.sh b/laas/actions/actions/genPass.sh new file mode 100644 index 0000000..e9d435c --- /dev/null +++ b/laas/actions/actions/genPass.sh @@ -0,0 +1,28 @@ +#!/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. # +############################################################################## + +LENGTH=$(echo "$2" | grep -m 1 "^[0-9]*$") + +if [ -z "$LENGTH" ]; then + echo "argument is not a number" + exit 1 +fi + + +pass=$(base64 /dev/urandom | head -c $((LENGTH * 2)) | tr -d '[:punct:]' | head -c "$LENGTH") + +st2 key set "$1" "$pass" --encrypt diff --git a/laas/actions/actions/getNextHost.py b/laas/actions/actions/getNextHost.py new file mode 100644 index 0000000..3e1c0be --- /dev/null +++ b/laas/actions/actions/getNextHost.py @@ -0,0 +1,29 @@ +############################################################################## +# Copyright 2018 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 st2actions.runners.pythonrunner import Action +import json + + +class GetNextHostAction(Action): + def run(self): + hosts = json.loads(self.action_service.get_value("hosts_to_boot", local=False)) + if len(hosts) < 1: + self.action_service.delete_value("hosts_to_boot", local=False) + host = hosts.pop() # will throw error on last iteration + self.action_service.set_value(name="hosts_to_boot", value=json.dumps(hosts), local=False) + + return host diff --git a/laas/actions/actions/get_all_macs.py b/laas/actions/actions/get_all_macs.py new file mode 100644 index 0000000..8a3afd1 --- /dev/null +++ b/laas/actions/actions/get_all_macs.py @@ -0,0 +1,28 @@ +############################################################################## +# Copyright 2018 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 st2actions.runners.pythonrunner import Action +import json + + +class MacAction(Action): + + def run(self, host=None): + host_info = json.loads( + self.action_service.get_value(host, local=False) + ) + macs = [d['mac'] for d in host_info['interfaces'].values()] + print("got macs " + str(macs)) + return "|".join(macs) diff --git a/laas/actions/actions/get_bios_password.py b/laas/actions/actions/get_bios_password.py new file mode 100644 index 0000000..56a37b5 --- /dev/null +++ b/laas/actions/actions/get_bios_password.py @@ -0,0 +1,29 @@ +############################################################################## +# Copyright 2018 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 st2actions.runners.pythonrunner import Action +import sqlite3 + + +class GetBiosPassAction(Action): + + def run(self, host=None): + dbfile = self.action_service.get_value("database", local=False) + db = sqlite3.connect(dbfile) + c = db.cursor() + passwd = c.execute("SELECT bios_pass FROM ipmi WHERE host=?", (host,)).fetchone() + db.close() + return passwd[0] diff --git a/laas/actions/actions/get_dhcp_address.sh b/laas/actions/actions/get_dhcp_address.sh new file mode 100644 index 0000000..2fb4db6 --- /dev/null +++ b/laas/actions/actions/get_dhcp_address.sh @@ -0,0 +1,23 @@ +#!/bin/bash +############################################################################## +# Copyright 2018 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. # +############################################################################## + + +HOST="$1" +host "$HOST" # produces output for debugging +host "$HOST" &> /dev/null || exit 1 + +host "$HOST" | awk '/address/ {print $NF}' diff --git a/laas/actions/actions/get_host_type.py b/laas/actions/actions/get_host_type.py new file mode 100644 index 0000000..5279a3a --- /dev/null +++ b/laas/actions/actions/get_host_type.py @@ -0,0 +1,27 @@ +############################################################################## +# Copyright 2018 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 st2actions.runners.pythonrunner import Action + + +class HostTypeAction(Action): + + def run(self, host=None): + types = ['hpe', 'arm'] + for x in types: + if x in host.lower(): + return x + return "" diff --git a/laas/actions/actions/get_ipmi_hostname.py b/laas/actions/actions/get_ipmi_hostname.py new file mode 100644 index 0000000..e7a8bd7 --- /dev/null +++ b/laas/actions/actions/get_ipmi_hostname.py @@ -0,0 +1,34 @@ +############################################################################## +# Copyright 2018 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 sqlite3 +from st2actions.runners.pythonrunner import Action + + +class ipmi_infoAction(Action): + + def run(self, host=None): + db_file = self.action_service.get_value(name="database", local=False) + db = sqlite3.connect(db_file) + c = db.cursor() + ipmi_host = c.execute("SELECT host FROM ipmi WHERE host=?", (host,)).fetchone() + if ipmi_host: + db.close() + return host + host_number = c.execute("SELECT server_number FROM hosts WHERE hostname=?", (host,)).fetchone()[0] + ipmi_host = c.execute("SELECT host FROM ipmi WHERE server_number=?", (host_number,)).fetchone() + db.close() + return ipmi_host[0] diff --git a/laas/actions/actions/get_ipmi_password.py b/laas/actions/actions/get_ipmi_password.py new file mode 100644 index 0000000..0446378 --- /dev/null +++ b/laas/actions/actions/get_ipmi_password.py @@ -0,0 +1,29 @@ +############################################################################## +# Copyright 2018 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 sqlite3 +from st2actions.runners.pythonrunner import Action + + +class ipmi_passwdAction(Action): # TODO: create base class with other ipmi actions + + def run(self, host=None): + db = self.action_service.get_value(name="database", local=False) + db = sqlite3.connect(db) + c = db.cursor() + password = c.execute("SELECT pass FROM ipmi WHERE host=?", (host,)).fetchone() + db.close() + return password[0] diff --git a/laas/actions/actions/get_ipmi_username.py b/laas/actions/actions/get_ipmi_username.py new file mode 100644 index 0000000..a129c87 --- /dev/null +++ b/laas/actions/actions/get_ipmi_username.py @@ -0,0 +1,29 @@ +############################################################################## +# Copyright 2018 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 sqlite3 +from st2actions.runners.pythonrunner import Action + + +class ipmi_userAction(Action): + + def run(self, host=None): + db = self.action_service.get_value(name="database", local=False) + db = sqlite3.connect(db) + c = db.cursor() + ipmi_user = c.execute("SELECT user FROM ipmi WHERE host=?", (host,)).fetchone() + db.close() + return ipmi_user[0] diff --git a/laas/actions/actions/get_jumphost.py b/laas/actions/actions/get_jumphost.py new file mode 100644 index 0000000..180e5a2 --- /dev/null +++ b/laas/actions/actions/get_jumphost.py @@ -0,0 +1,27 @@ +############################################################################## +# Copyright 2019 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 st2actions.runners.pythonrunner import Action + + +class GetJumphostAction(Action): + + def run(self, hosts=[]): + for role in hosts: + for hostname, roleName in role.items(): + if "jumphost" in roleName.lower(): + return hostname + return None diff --git a/laas/actions/actions/get_mac_from_ip.sh b/laas/actions/actions/get_mac_from_ip.sh new file mode 100644 index 0000000..dce1215 --- /dev/null +++ b/laas/actions/actions/get_mac_from_ip.sh @@ -0,0 +1,26 @@ +#!/bin/bash +############################################################################## +# Copyright 2018 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. # +############################################################################## + +TARGET="$1" +GATEWAY="$2" +USER="$3" +COL="\$5" # string literal '$5' for awk print + +if [ -z "$GATEWAY" ]; then + ping -c 1 "$TARGET" &> /dev/null && ip n | awk "/$TARGET/ {print $COL}" || echo 'unknown' +fi +ssh -o stricthostkeychecking=no -o userknownhostsfile=/dev/null "$USER@$GATEWAY" sh -c "ping -c 1 $TARGET &> /dev/null && ip n | awk '/$TARGET/ {print $5}' || echo 'unknown'" diff --git a/laas/actions/actions/get_task.py b/laas/actions/actions/get_task.py new file mode 100644 index 0000000..0e1d1aa --- /dev/null +++ b/laas/actions/actions/get_task.py @@ -0,0 +1,27 @@ +############################################################################## +# Copyright 2018 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 st2actions.runners.pythonrunner import Action +import json + + +class GetTaskAction(Action): + + def run(self, job_id=None, task_id=None, type=None): + job = json.loads(self.action_service.get_value("job_" + str(job_id), local=False)) + tasks = job[type] + task = tasks[task_id] + return task diff --git a/laas/actions/actions/get_task_list.py b/laas/actions/actions/get_task_list.py new file mode 100644 index 0000000..ca0e22a --- /dev/null +++ b/laas/actions/actions/get_task_list.py @@ -0,0 +1,27 @@ +############################################################################## +# Copyright 2018 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 st2actions.runners.pythonrunner import Action +import json + + +class Task_List_Action(Action): + + def run(self, job_id=None, type=None): + job = json.loads(self.action_service.get_value("job_" + str(job_id), local=False)) + if type not in job: + return [] + return job[type].keys() diff --git a/laas/actions/actions/get_xdf.py b/laas/actions/actions/get_xdf.py new file mode 100644 index 0000000..7104905 --- /dev/null +++ b/laas/actions/actions/get_xdf.py @@ -0,0 +1,33 @@ +############################################################################## +# Copyright 2019 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 st2actions.runners.pythonrunner import Action +import requests + + +class XDF_Action(Action): + def __init__(self, *args, **kwargs): + self._config = kwargs.get('config', None) + super(XDF_Action, self).__init__(*args, **kwargs) + + def run(self, task_data={}): + server = self._config['dashboard']['address'] + pdf_endpoint = task_data['opnfv']['pdf'] + idf_endpoint = task_data['opnfv']['idf'] + header = {"auth-token": self.action_service.get_value("lab_auth_token", local=False)} + pdf = requests.get(server + pdf_endpoint, timeout=10, headers=header) + idf = requests.get(server + idf_endpoint, timeout=10, headers=header) + return {"pdf": pdf.text, "idf": idf.text} diff --git a/laas/actions/actions/ipmi_restartHost.sh b/laas/actions/actions/ipmi_restartHost.sh new file mode 100644 index 0000000..bc9839b --- /dev/null +++ b/laas/actions/actions/ipmi_restartHost.sh @@ -0,0 +1,47 @@ +#!/bin/bash +############################################################################## +# Copyright 2018 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 ! STATUS=$(ipmitool -I lanplus -H "$1" -U "$2" -P "$3" chassis power status); then + sleep 45 + if ! STATUS=$(ipmitool -I lanplus -H "$1" -U "$2" -P "$3" chassis power status); then + exit 1 + fi +fi + +ONOFF=$(echo "$STATUS" | cut -d ' ' -f 4) + +if [ "$ONOFF" == "off" ]; then + case "$4" in + "cycle") + ipmitool -I lanplus -H "$1" -U "$2" -P "$3" chassis power on + exit $? + ;; + "off") + exit 0 + ;; + esac +else # Server is on + case "$4" in + "on") + ipmitool -I lanplus -H "$1" -U "$2" -P "$3" chassis power cycle + exit $? + ;; + esac +fi + +ipmitool -I lanplus -H "$1" -U "$2" -P "$3" chassis power "$4" diff --git a/laas/actions/actions/jenkins_info.py b/laas/actions/actions/jenkins_info.py new file mode 100644 index 0000000..7df7879 --- /dev/null +++ b/laas/actions/actions/jenkins_info.py @@ -0,0 +1,34 @@ +############################################################################## +# Copyright 2018 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 st2actions.runners.pythonrunner import Action +import json + + +class JenkinsInfoAction(Action): + + def run(self, host=None): + retval = {"destination": host} + hostInfo = json.loads( + self.action_service.get_value(name="jenkins_" + host, local=False) + ) + retval['hostname'] = hostInfo['hostname'] + retval['secret'] = hostInfo['secret'] + retval['script'] = self.action_service.get_value( + name="jenkins_script", + local=False + ) + return retval diff --git a/laas/actions/actions/joid_install.sh b/laas/actions/actions/joid_install.sh new file mode 100644 index 0000000..d4bafe0 --- /dev/null +++ b/laas/actions/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 + mapfile -t 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/actions/lib/__init__.py b/laas/actions/actions/lib/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/laas/actions/actions/lib/__init__.py diff --git a/laas/actions/actions/lib/chatbot.py b/laas/actions/actions/lib/chatbot.py new file mode 100644 index 0000000..51f51e2 --- /dev/null +++ b/laas/actions/actions/lib/chatbot.py @@ -0,0 +1,39 @@ +############################################################################## +# Copyright 2019 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 st2actions.runners.pythonrunner import Action +import requests +import json + + +class ChatBotAction(Action): + + def __init__(self, config=None): + super(ChatBotAction, self).__init__(config=config) + self.host = config['bot']['address'] + self.endpoints = config['bot']['endpoints'] + + def send(self, msg_type=None, data={}): + headers = {"Content-Type": "application/json"} + url = self.host + self.endpoints[msg_type] + print("posting to ") + print(url) + return requests.post( + url, + data=json.dumps(data), + headers=headers, + verify=False, + timeout=10 + ) diff --git a/laas/actions/actions/lib/cisco.py b/laas/actions/actions/lib/cisco.py new file mode 100644 index 0000000..6d358a5 --- /dev/null +++ b/laas/actions/actions/lib/cisco.py @@ -0,0 +1,64 @@ +############################################################################## +# Copyright 2019 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 json + + +class NXCommand(object): + + TYPE_SHOW = "cli_show" + TYPE_CONFIG = "cli_config" + + def __init__(self, switch, auth): + self.url = "http://" + switch + "/ins" + self.version = "1.0" + self.type = "cli_conf" + self.chunk = "0" + self.sid = "1" + self.output_format = "json" + self.input = [] + + self.user = auth['user'] + self.password = auth['password'] + + def add_command(self, cmd): + self.input.append(cmd) + + def execute(self): + resp = requests.post( + self.url, + data=json.dumps(self.serialize()), + timeout=10, + headers={"content-type": "text/json"}, + auth=(self.user, self.password) + ) + try: + return resp.json() + except: + return resp.text + + def serialize(self): + return { + "ins_api": { + "version": self.version, + "type": self.type, + "chunk": self.chunk, + "sid": self.sid, + "input": " ;".join(self.input), + "output_format": self.output_format + } + } diff --git a/laas/actions/actions/lib/fog.py b/laas/actions/actions/lib/fog.py new file mode 100644 index 0000000..b60a888 --- /dev/null +++ b/laas/actions/actions/lib/fog.py @@ -0,0 +1,228 @@ +############################################################################## +# 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 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): + super(FogAction, self).__init__(config=config) + 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 = { + 'fog-api-token': self.fogKey, + 'fog-user-token': self.userKey + } + + def run(self): + pass # fake run method to make st2 happy + + def createImage(self, image): + url = self.baseURL + "image" + return requests.post(url, data=json.dumps(image), headers=self.header, timeout=10) + + def getImage(self, img=None, os=None, host=None, snapshot=None): + imgID = self.getImageID(img=img, os=os, host=host, snapshot=snapshot) + url = self.baseURL + "image/" + str(imgID) + image = requests.get(url, headers=self.header, timeout=10) + return image.json() + + def deriveImage(self, from_image="None", to_new_image="None"): + """ + @param from_image: required, expects a string that is the name of the image to be derived from + @param to_image: required, expects a string that is the name of the new image we want to create + @return: request object containing keys related to the image from the fog rest API + @return: no value, most likely addition (if any) would be to parse the response and return image id + """ + if from_image == "None" or to_new_image == "None": + raise ValueError("deriveImage requires defined values for both from_image and to_new_image") + + to_new_image = to_new_image.lower().replace(" ", "_") + newImage = {} + + from_image = self.getImage(from_image) + + basicKeys = [ + 'imagePartitionTypeID', + 'toReplicate', + 'isEnabled', + 'compress', + 'osID', + 'imageTypeID' + ] + for key in basicKeys: + newImage[key] = from_image[key] + + newImage['name'] = to_new_image + newImage['path'] = to_new_image + + return self.createImage(newImage) + + def getImageID(self, img=None, os=None, host=None, snapshot=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 + """ + # if img is an int, return it + try: + return int(img) + except: + pass + + # if given an os, translate to id + # st2 will promote an empty arg to the str "None" :( + if os and os != "None": + return self.getImageIDFromOS(os, host) + + if snapshot and snapshot != "None": + return self.getImageIDFromSnapshot(snapshot) + + if img and img != "None": + url = self.baseURL + "image" + images_api_payload = requests.get(url=url, headers=self.header, timeout=10) + images = images_api_payload.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: + return -1 + host_dict = json.loads( + self.action_service.get_value(name=host, local=False) + ) + return int(host_dict[enum[os]]) + + def getImageIDFromSnapshot(self, snapshot): + try: + enum = json.loads( + self.action_service.get_value( + name="snapshots", + local=False + ) + ) + return int(enum[snapshot]) + except: + self.logger.exception("Could not get ID") + return -1 + + 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, timeout=10) + if req.status_code == 200: + print("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, timeout=10) + 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("Failed to connect to the FOG server") + + def request(self, url, data=None, method="get"): + if data is not None: + if method == "get": + method = "post" # ergonomics - if I'm passing in data, I obviously want to do a POST + return self.dataRequest(url, data, method=method) + try: + response = requests.get(url, headers=self.header, timeout=10) + return response.json() + except Exception: + self.logger.exception("Failed to reach FOG at %s", url) + + def dataRequest(self, url, data, method="post"): + methods = { + "post": requests.post, + "put": requests.put + } + try: + return methods[method](url, json=data, headers=self.header, timeout=10) + except Exception: + self.logger.exception("Failed to reach FOG at %s", url) + + def getFogHost(self, host): + hostData = self.action_service.get_value(host, local=False) + return json.loads(hostData)['fog_name'] + + def getFogHostData(self, host): + hostID = self.getHostNumber(host) + url = self.baseURL + "host/" + str(hostID) + resp = requests.get(url, headers=self.header, timeout=10) + return resp.json() + + 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, + timeout=10 + ).json()['tasks'] + return tasks + except Exception: + self.logger.exception("failed to get tasks") + return [] + + def getTask(self, taskID): + for task in self.getAllTasks(): + if task['id'] == taskID: + return task + return {} diff --git a/laas/actions/actions/lib/laas_api.py b/laas/actions/actions/lib/laas_api.py new file mode 100644 index 0000000..c777daf --- /dev/null +++ b/laas/actions/actions/lib/laas_api.py @@ -0,0 +1,73 @@ +############################################################################## +# Copyright 2019 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 st2actions.runners.pythonrunner import Action +import jinja2 +import requests + + +class DashboardAction(Action): + + def __init__(self, *args, **kwargs): + self._config = kwargs.get('config', None) + super(DashboardAction, self).__init__(*args, **kwargs) + server = self._config['dashboard']['address'] + name = self._config['dashboard']['lab_name'] + self.base_url = server + "/api/labs/" + name + self.header = {"auth-token": self.action_service.get_value("lab_auth_token", local=False)} + + def send_api_message(self, endpoint="", payload={}): + url = self.base_url + endpoint + r = requests.post(url, data=payload, timeout=10, headers=self.header) + print("response " + str(r.status_code)) + return r + + +class TaskStatusAction(DashboardAction): + + def set_status(self, job_id=None, task_id=None, lab_token=None, status=0): + payload = {"status": status} + if lab_token: + payload['lab_token'] = lab_token + + return self.send_api_message( + endpoint="/jobs/" + str(job_id) + "/" + str(task_id), + payload=payload + ) + + +class NotifyAction(DashboardAction): + + def notify(self, template, info, job_id, task_id, lab_token=None): + message = self.render(template, info) + print(message) + self.send_notification( + job_id=job_id, + task_id=task_id, + message=message, + lab_token=lab_token + ) + + def render(self, template, info): + jinja_template = jinja2.Template(template) + return jinja_template.render(info=info) + + def send_notification(self, job_id=None, task_id=None, message="", lab_token=None): + endpoint = "/jobs/" + str(job_id) + "/" + task_id + payload = {"message": message} + if lab_token: + payload['lab_token'] = lab_token + self.send_api_message(endpoint, payload=payload) diff --git a/laas/actions/actions/lib/vpn.py b/laas/actions/actions/lib/vpn.py new file mode 100644 index 0000000..f0770c7 --- /dev/null +++ b/laas/actions/actions/lib/vpn.py @@ -0,0 +1,168 @@ +############################################################################## +# 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 string +import random +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): + """ + generates random alphanumeric string of length n + """ + alpha_num = string.ascii_letters + string.digits + return ''.join(random.choice(alpha_num) for i in range(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'] + ',' + 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 + ) + + return [user[0] for user in ans] diff --git a/laas/actions/actions/network_task.py b/laas/actions/actions/network_task.py new file mode 100644 index 0000000..e9f6acc --- /dev/null +++ b/laas/actions/actions/network_task.py @@ -0,0 +1,68 @@ +############################################################################## +# Copyright 2018 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 st2actions.runners.pythonrunner import Action +from lib.cisco import NXCommand +import json + + +class PodNetworkManagerAction(Action): + + def parse_net_config(self, net_config): + """ + Meaty method to ultimately get a list of NXCommands that need to be run + to fulfill the requested config + """ + commands = [] + for hostId in net_config.keys(): + host = json.loads(self.action_service.get_value(hostId, local=False)) + interfaces = net_config[hostId] + configured_switches = set() # place to remember which switches we have modified + for interface_name in interfaces.keys(): + interface = host['interfaces'][interface_name] + auth = json.loads(self.action_service.get_value("switch_" + interface['switch'], local=False)) + cmd = NXCommand(interface['switch'], auth) + cmd.add_command("interface " + interface['port']) + cmd.add_command("switchport mode trunk") + native_vlan = None + allowed_vlans = set(["99", "98"]) # always allow ipmi vlan TODO config + vlans = interfaces[interface_name] + for vlan in vlans: + allowed_vlans.add(str(vlan['vlan_id'])) + if not vlan['tagged']: + native_vlan = str(vlan['vlan_id']) + vlan_str = "none" + if len(allowed_vlans) > 0: + vlan_str = ",".join(allowed_vlans) + cmd.add_command("switchport trunk allowed vlan " + vlan_str) + if native_vlan: + cmd.add_command("switchport trunk native vlan " + native_vlan) + cmd.add_command("copy run start") + commands.append(cmd) + + if interface['switch'] not in configured_switches: + save_cmd = NXCommand(interface['switch'], auth) + save_cmd.add_command("copy run start") + commands.append(save_cmd) + configured_switches.add(interface['switch']) + + return commands + + def run(self, network_data): + network_data.pop("lab_token", None) + self.commands = self.parse_net_config(network_data) + for cmd in self.commands: + print(cmd.execute()) diff --git a/laas/actions/actions/notify_ip_address.py b/laas/actions/actions/notify_ip_address.py new file mode 100644 index 0000000..0cd6e8b --- /dev/null +++ b/laas/actions/actions/notify_ip_address.py @@ -0,0 +1,37 @@ +############################################################################## +# Copyright 2018 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 lib.laas_api import NotifyAction + + +class NotifyIPAction(NotifyAction): + template = """ + Your host may be reached at any + of the following ip addresses: + {{info.address}} + + {% if info.hostname %} + You may also use the following hostname: + {{info.hostname}} + {% endif %} + """ + + def run(self, addresses=None, hostname=None, job_id=None, task_id=None): + info = { + "address": addresses, + "hostname": hostname + } + self.notify(self.template, info, job_id, task_id) diff --git a/laas/actions/actions/notify_ipmi_api.py b/laas/actions/actions/notify_ipmi_api.py new file mode 100644 index 0000000..93348b8 --- /dev/null +++ b/laas/actions/actions/notify_ipmi_api.py @@ -0,0 +1,34 @@ +############################################################################## +# Copyright 2018 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 lib.laas_api import DashboardAction + + +class NotifyIPMIAPIAction(DashboardAction): + + def run(self, ipmi_key=None, addr=None, mac=None, host=None): + ipmi_pass = self.action_service.get_value(ipmi_key, local=False, decrypt=True) + info = { + 'address': addr, + 'mac_address': mac, + 'pass': ipmi_pass, + 'type': "ipmi", + 'user': "OPNFV", + 'versions': ["2.0"] + } + + endpoint = "/hosts/" + host + "/bmc" + self.send_api_message(endpoint=endpoint, payload=info) diff --git a/laas/actions/actions/notify_ipmi_user.py b/laas/actions/actions/notify_ipmi_user.py new file mode 100644 index 0000000..de3deb6 --- /dev/null +++ b/laas/actions/actions/notify_ipmi_user.py @@ -0,0 +1,44 @@ +############################################################################## +# Copyright 2018 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 lib.laas_api import NotifyAction + + +class NotifyIPMIUserAction(NotifyAction): + template = """ + Your IPMI credentials: + username: {{info.username}} + password: {{info.password}} + + IPMI access information: + hostname: {{info.hostname}} + IP address: {{info.addr}} + + Instructions on using the ipmi interface: + {{info.url}} + """ + + def run(self, ipmi_key=None, job_id=None, task_id=None, hostname=None, addr=None): + ipmi_pass = self.action_service.get_value(ipmi_key, local=False, decrypt=True) + info = { + 'username': "OPNFV", + 'password': ipmi_pass, + 'hostname': hostname, + 'addr': addr, + 'url': "https://wiki.opnfv.org/display/INF/Lab-as-a-Service+at+the+UNH-IOL" + } + + self.notify(self.template, info, job_id, task_id, lab_token=ipmi_key) diff --git a/laas/actions/actions/notify_ssh_access.py b/laas/actions/actions/notify_ssh_access.py new file mode 100644 index 0000000..d4bead5 --- /dev/null +++ b/laas/actions/actions/notify_ssh_access.py @@ -0,0 +1,33 @@ +############################################################################## +# Copyright 2018 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 lib.laas_api import NotifyAction + + +class NotifySSHAction(NotifyAction): + template = """ + Your ssh keys have been copied to your host(s). You may connect with the following: + {% for host in info.hosts %} + ssh {{info.user}}@{{host}} + {% endfor %} + """ + + def run(self, user=None, hosts=None, job_id=None, task_id=None): + info = { + "user": user, + "hosts": hosts + } + self.notify(self.template, info, job_id, task_id) diff --git a/laas/actions/actions/notify_vpn_user.py b/laas/actions/actions/notify_vpn_user.py new file mode 100644 index 0000000..3ab1ca4 --- /dev/null +++ b/laas/actions/actions/notify_vpn_user.py @@ -0,0 +1,39 @@ +############################################################################## +# Copyright 2018 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 lib.laas_api import NotifyAction +import json + + +class NotifyVPNUserAction(NotifyAction): + template = """ + Your VPN credentials: + username: {{info.username}} + password: {{info.password}} + + Instructions on how to connect to the UNH-IOL VPN can be found here: + {{info.url}} + """ + + def run(self, vpn_key=None, job_id=None, task_id=None): + vpn_info = json.loads(self.action_service.get_value(vpn_key, local=False, decrypt=True)) + info = { + 'username': vpn_info['username'], + 'password': vpn_info['password'], + 'url': "https://wiki.opnfv.org/display/INF/Lab-as-a-Service+at+the+UNH-IOL" + } + + self.notify(self.template, info, job_id, task_id, lab_token=vpn_key) diff --git a/laas/actions/actions/parse_network_data.py b/laas/actions/actions/parse_network_data.py new file mode 100644 index 0000000..fdf98e1 --- /dev/null +++ b/laas/actions/actions/parse_network_data.py @@ -0,0 +1,70 @@ +############################################################################## +# Copyright 2018 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 st2actions.runners.pythonrunner import Action + + +class ParseNetworkAction(Action): + + def run(self, task_data): + task_data.pop("lab_token", None) # We dont care, just remove if there + if len(task_data) > 1: + print("There should only be one host here!") + return None + + ret = { + 'host': list(task_data.keys())[0], # hostname + 'mappings': '+'.join(self.get_mappings(task_data)), # mappings as understood by host task + 'default': self.get_default_interface(task_data), # interface that should be def route + 'empty': self.detect_empty(task_data) + } + + return ret + + def detect_empty(self, task_data): + for hostname, iface_dict in task_data.items(): + for mac, vlan_list in iface_dict.items(): + if vlan_list: + return False + return True + + def get_mappings(self, task_data): + mappings = [] + for hostname, iface_dict in task_data.items(): + for mac, vlan_list in iface_dict.items(): + for vlan in vlan_list: + if vlan['tagged']: + mapping = mac + "-" + str(vlan['vlan_id']) + mappings.append(mapping) + return mappings + + def get_default_vlans(self): + vlan_list = json.loads( + self.action_service.get_value("default_vlans", local=False) + ) + return vlan_list + + def get_default_interface(self, task_data): + default = set(self.get_default_vlans()) + for hostname, iface_dict in task_data.items(): + for mac, vlan_list in iface_dict.items(): + for vlan in vlan_list: + if int(vlan['vlan_id']) in default: + default_interface = mac + if vlan['tagged']: + default_interface += "." + str(vlan['vlan_id']) + return default_interface diff --git a/laas/actions/actions/prepare_fuel_gambia_baremetal.sh b/laas/actions/actions/prepare_fuel_gambia_baremetal.sh new file mode 100755 index 0000000..3620e77 --- /dev/null +++ b/laas/actions/actions/prepare_fuel_gambia_baremetal.sh @@ -0,0 +1,151 @@ +#!/bin/bash +############################################################################## +# Copyright 2019 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. # +############################################################################## + + +function detect_os { + [ -f /etc/network/interfaces ] && echo "ubuntu16" && return 0 + [ -d /etc/sysconfig/network ] && echo "suse" && return 0 + [ -d /etc/sysconfig/network-scripts ] && echo "centos" && return 0 +} + +function create_bridge { + os="$1" + bridge="$2" + ifname="$3" + ipaddr="$4" + case "$os" in + ubuntu16) + echo "do stuff to /etc/network/interfaces" + BRFILE="/etc/network/interfaces.d/$bridge" + IFFILE="/etc/network/interfaces.d/$ifname" + + #create bridge config + echo "auto $bridge" >> "$BRFILE" + if [ "$ipaddr" = "dhcp" ]; then + echo "iface $bridge inet dhcp" >> "$BRFILE" + else + echo "iface $bridge inet manual" >> "$BRFILE" + echo "address $ipaddr" >> "$BRFILE" + # network and netmask? + fi + echo "bridge_ports $ifname" >> "$BRFILE" + echo "bridge_stp off" >> "$BRFILE" + echo "bridge_fd 0" >> "$BRFILE" + echo "bridge_maxwait 0" >> "$BRFILE" + + #change old interface + if [ ! -f "$IFFILE" ]; then + IFFILE="/etc/network/interfaces.d/1-$ifname" + fi + rm -f "$IFFILE" + ;; + + suse) + echo "not supported" + ;; + centos) + echo "do /etc/sysconfig/network-scripts stuff" + BRFILE="/etc/sysconfig/network-scripts/ifcfg-$bridge" + IFFILE="/etc/sysconfig/network-scripts/ifcfg-$ifname" + + #change device config + sed -i '/DEFROUTE/d' "$IFFILE" + sed -i '/IPADDR/d' "$IFFILE" + sed -i '/PREFIX/d' "$IFFILE" + sed -i 's/BOOTPROTO=dhcp/BOOTPROTO=none/' "$IFFILE" + echo "BRIDGE=$bridge" >> "$IFFILE" + + #create bridge config + { + echo "DEVICE=$bridge" + echo "TYPE=Bridge" + echo "ONBOOT=yes" + } >> "$BRFILE" + if [ "$ipaddr" = "dhcp" ]; then + { + echo "BOOTPROTO=dhcp" + echo "DEFROUTE=yes" + } >> "$BRFILE" + # create local script that runs even if we lose SSH + { + echo "ifup $bridge" + echo "dhclient -r $ifname" + echo "ip a flush $ifname" + echo "brctl addif $bridge $ifname" + echo "ip l set dev $bridge up" + echo "dhclient $bridge" + } >> /tmp/net.sh + bash /tmp/net.sh & + else + { + echo "IPADDR=$ipaddr" + echo "PREFIX=24" + echo "DEFROUTE=no" + } >> "$BRFILE" + ifup "$bridge" + ip a flush "$ifname" + brctl addif "$bridge" "$ifname" + ip l set dev "$bridge" up + fi + ;; + esac +} + + +function map { + bridge=$(echo "$1" | awk -F ";" '{print $1}') + macVlan=$(echo "$1" | awk -F ";" '{print $2}') + mac=$(echo "$macVlan" | awk -F "." '{print $1}') + vlan=$(echo "$macVlan" | awk -F "." '{print $2}') + ipaddr=$(echo "$1" | awk -F ";" '{print $3}') + ifname=$(ip link show | grep -B1 "$mac" | awk -F ': ' 'NR==1{print $2}') + if [ -n "$vlan" ]; then + ifname="$ifname.$vlan" + fi + os=$(detect_os) + create_bridge "$os" "$bridge" "$ifname" "$ipaddr" +} + +function install_deps { + os=$(detect_os) + case "$os" in + ubuntu16) + apt update && apt upgrade -y + apt install -y git libvirt-bin + systemctl start libvirtd && systemctl enable libvirtd + ;; + + suse) + ;; + centos) + yum -y update > /dev/null + yum -y install git > /dev/null + yum -y groupinstall "Virtualization Host" > /dev/null + systemctl start libvirtd && systemctl enable libvirtd + esac +} + + +#main + +install_deps + +# $1 is structured: br-name;mac.vlan;ip-addr +for mapping in $(echo "$1" | tr '+' '\n'); do + echo "mapping $mapping" + map "$mapping" +done diff --git a/laas/actions/actions/resolve_host.sh b/laas/actions/actions/resolve_host.sh new file mode 100644 index 0000000..8f0d185 --- /dev/null +++ b/laas/actions/actions/resolve_host.sh @@ -0,0 +1,25 @@ +#!/bin/bash +############################################################################## +# Copyright 2018 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. # +############################################################################## + + +HOSTNAME="$1" + +RECORD=$(nslookup "$HOSTNAME" | awk 'NR>2 && /Address/{print $2}') + +[ -z "$RECORD" ] && exit 1 + +echo "$RECORD" diff --git a/laas/actions/actions/restartHost.sh b/laas/actions/actions/restartHost.sh new file mode 100644 index 0000000..b6842d1 --- /dev/null +++ b/laas/actions/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/actions/retry_loop.sh b/laas/actions/actions/retry_loop.sh new file mode 100644 index 0000000..3b9033c --- /dev/null +++ b/laas/actions/actions/retry_loop.sh @@ -0,0 +1,21 @@ +#!/bin/bash +############################################################################## +# Copyright 2018 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. # +############################################################################## + +ITERATION="$1" +MAX="$2" + +((ITERATION < MAX)) && echo $((ITERATION+1)) || exit 255 diff --git a/laas/actions/actions/send_bot_failure.py b/laas/actions/actions/send_bot_failure.py new file mode 100644 index 0000000..bfaf555 --- /dev/null +++ b/laas/actions/actions/send_bot_failure.py @@ -0,0 +1,24 @@ +############################################################################## +# Copyright 2019 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 lib.chatbot import ChatBotAction + + +class BotFailureAction(ChatBotAction): + + def run(self, **kwargs): + resp = self.send(msg_type="failure", data=kwargs) + print(resp) + print(resp.text) diff --git a/laas/actions/actions/send_jenkins_script.sh b/laas/actions/actions/send_jenkins_script.sh new file mode 100644 index 0000000..6b61086 --- /dev/null +++ b/laas/actions/actions/send_jenkins_script.sh @@ -0,0 +1,28 @@ +#!/bin/bash +############################################################################## +# Copyright 2018 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. # +############################################################################## +destination="$1" +hostname="$2" +secret="$3" +script="$4" + +cp "$script" ./tmpscript + +sed -i "s/HOSTNAME_REPLACE/$hostname/" tmpscript +sed -i "s/SECRET_REPLACE/$secret/" tmpscript + +scp -o userknownhostsfile=/dev/null -o stricthostkeychecking=no tmpscript root@"$destination":/root/jenkins_connect.sh +rm tmpscript diff --git a/laas/actions/actions/setPass.sh b/laas/actions/actions/setPass.sh new file mode 100644 index 0000000..08962bd --- /dev/null +++ b/laas/actions/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/actions/set_arm_boot.sh b/laas/actions/actions/set_arm_boot.sh new file mode 100644 index 0000000..42e4a0e --- /dev/null +++ b/laas/actions/actions/set_arm_boot.sh @@ -0,0 +1,19 @@ +#!/bin/bash +############################################################################## +# Copyright 2018 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. # +############################################################################## + + +ipmitool -I lanplus -H "$1" -U "$2" -P "$3" chassis bootdev pxe diff --git a/laas/actions/actions/set_hostname.sh b/laas/actions/actions/set_hostname.sh new file mode 100644 index 0000000..ee70608 --- /dev/null +++ b/laas/actions/actions/set_hostname.sh @@ -0,0 +1,19 @@ +#!/bin/bash +############################################################################## +# Copyright 2018 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. # +############################################################################## +HOST="$2" +HOSTNAME="$1" +ssh -o userknownhostsfile=/dev/null -o stricthostkeychecking=false root@"$HOST" "hostnamectl set-hostname $HOSTNAME" diff --git a/laas/actions/actions/set_hpe_bios_pass.py b/laas/actions/actions/set_hpe_bios_pass.py new file mode 100644 index 0000000..e3b09be --- /dev/null +++ b/laas/actions/actions/set_hpe_bios_pass.py @@ -0,0 +1,27 @@ +############################################################################## +# Copyright 2018 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 st2actions.runners.pythonrunner import Action +import requests + + +class BIOSPassWordAction(Action): + + def run(self, host=None, oldPass=None, newPass=None, user=None, adminPass=None): + data = {"OldAdminPassword": oldPass, "AdminPassword": newPass} + url = "https://" + host + "/rest/v1/systems/1/bios/settings" + headers = {"Content-Type": "application/json"} + auth = (user, adminPass) + requests.patch(url, headers=headers, data=data, auth=auth, verify=False) diff --git a/laas/actions/actions/set_hpe_boot.py b/laas/actions/actions/set_hpe_boot.py new file mode 100644 index 0000000..83dc101 --- /dev/null +++ b/laas/actions/actions/set_hpe_boot.py @@ -0,0 +1,44 @@ +############################################################################## +# Copyright 2018 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 +from st2actions.runners.pythonrunner import Action + + +class HPEBootAction(Action): + + ribcl_script = """ + <?xml version="1.0"?> + <?iol entity-procesing="standard"?> + <?xmlilo output-format="xml"?> + <RIBCL VERSION="2.0"> + <LOGIN USER_LOGIN="CHANGEUSER" PASSWORD="CHANGEPASSWORD"> + <SERVER_INFO MODE="write"> + <SET_PERSISTENT_BOOT> + <DEVICE value="Boot000E"/> + </SET_PERSISTENT_BOOT> + </SERVER_INFO> + </LOGIN> + </RIBCL> + """ + + def run(self, host=None, passwd=None, user=None): + self.ribcl_script = self.ribcl_script.replace("CHANGEUSER", user) + self.ribcl_script = self.ribcl_script.replace("CHANGEPASSWORD", passwd) + url = "http://" + host + "/ribcl" + response = requests.post(url, data=self.ribcl_script, verify=False) + + print("Sent script to set boot order to host " + host) + print("Got response code " + str(response.status_code)) diff --git a/laas/actions/actions/set_ipmi_pass.sh b/laas/actions/actions/set_ipmi_pass.sh new file mode 100644 index 0000000..6877a69 --- /dev/null +++ b/laas/actions/actions/set_ipmi_pass.sh @@ -0,0 +1,37 @@ +#!/bin/bash +############################################################################## +# Copyright 2018 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. # +############################################################################## + +ADMIN_USER="$1" +ADMIN_PASS="$2" +HOST="$3" +USERID="$4" + +USER_PASS=$(st2 key get "$5" --decrypt --attr value --json | tr -d "[:punct:]" | grep value | awk '{print $2}') + +if [ -z "$USER_PASS" ]; then + echo "Failed to read password from keystore!" + exit 1 +fi + +function set_pass { + ipmitool -I lanplus -U "$ADMIN_USER" -P "$ADMIN_PASS" -H "$HOST" user set password "$USERID" "$USER_PASS" +} + +if ! set_pass; then + sleep 30 + set_pass +fi diff --git a/laas/actions/actions/snapshot_task.py b/laas/actions/actions/snapshot_task.py new file mode 100644 index 0000000..d98aefb --- /dev/null +++ b/laas/actions/actions/snapshot_task.py @@ -0,0 +1,46 @@ +############################################################################## +# Copyright 2018 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 lib.fog import FogAction + + +class SnapshotTask(FogAction): + + def run(self, snapshot_data=None): + image_id = None + if "image" in snapshot_data: + image_id = snapshot_data['image'] + else: + image_id = self.createSnapshot(snapshot_data) + + host_id = snapshot_data['host'] + return_value = {"host": host_id, "snapshot_id": image_id} + return return_value + + def createSnapshot(self, data): + template = { + 'imageTypeID': "3", + 'imagePartitionTypeID': "1", + 'name': "snapshot_", # TODO: huh? + 'toReplicate': "1", + 'isEnabled': "1", + 'compress': "6", + 'storagegroups': [1], + 'osID': "50" + } + + response = self.createImage(template) + image_id = response['id'] + return image_id diff --git a/laas/actions/actions/start_job.py b/laas/actions/actions/start_job.py new file mode 100644 index 0000000..b57d78d --- /dev/null +++ b/laas/actions/actions/start_job.py @@ -0,0 +1,27 @@ +############################################################################## +# Copyright 2018 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 st2actions.runners.pythonrunner import Action +import json + + +class StartJobAction(Action): + + def run(self, job_id=None): + jobs = set(json.loads(self.action_service.get_value("jobs", local=False))) + if job_id in jobs: + print("job already started!") + jobs.add(job_id) + self.action_service.set_value("jobs", json.dumps(list(jobs)), local=False) diff --git a/laas/actions/actions/start_task.py b/laas/actions/actions/start_task.py new file mode 100644 index 0000000..53c5641 --- /dev/null +++ b/laas/actions/actions/start_task.py @@ -0,0 +1,23 @@ +############################################################################## +# Copyright 2018 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 lib.laas_api import TaskStatusAction + + +class StartTaskAction(TaskStatusAction): + + def run(self, job_id=None, task_id=None): + self.set_status(job_id=job_id, task_id=task_id, status=100) diff --git a/laas/actions/actions/test_print.py b/laas/actions/actions/test_print.py new file mode 100644 index 0000000..1d28f10 --- /dev/null +++ b/laas/actions/actions/test_print.py @@ -0,0 +1,32 @@ +############################################################################## +# Copyright 2019 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 st2actions.runners.pythonrunner import Action + + +class Test_Print_Action(Action): + def run(self): + print("This is a print") + self.logger.debug("debug log") + self.logger.info("info log") + self.logger.warning("warning log") + self.logger.error("error log") + self.logger.critical("critical log") + + try: + raise Exception + except Exception as e: + self.logger.exception(e) diff --git a/install.sh b/laas/actions/actions/update.sh index c96c290..d4f0581 100755..100644 --- a/install.sh +++ b/laas/actions/actions/update.sh @@ -15,24 +15,15 @@ # limitations under the License. # ############################################################################## -#installs deps -if which apt ; then - apt update && apt -y upgrade - apt -y install libvirt-dev curl gcc libsas12-dev python-dev libldap2-dev libssl-dev -elif which yum ; then - yum -y update - yum -y install curl libvirt-devel gcc python-devel openldap-devel +#check which package manager is used and run appropriate update cmd + +if command -v apt; then + apt -y update && apt -y upgrade +elif command -v yum; then + yum -y upgrade +elif command -v zypper; then + zypper -n update else - echo "Can only run on ubuntu or centos. exiting" + echo "Could not find package manager" exit 1 fi -#run their install script -curl -sSL https://stackstorm.com/packages/install.sh | bash -s -- --user=st2admin --password='admin' -#change ssh user to root -sed -i 's/user = stanley/user = root/' /etc/st2/st2.conf -sed -i 's/ssh_key_file = \/home\/stanley\/.ssh\/stanley_rsa/ssh_key_file = \/root\/.ssh\/id_rsa/' /etc/st2/st2.conf - -mv laaslab/ /opt/stackstorm/packs/ -cp /opt/stackstorm/packs/laaslab/laaslab.yaml.example /opt/stackstorm/configs - -echo "stackstorm should now be installed. Please edit /opt/stackstorm/configs/laaslab.yaml and /opt/stackstorm/packs/laaslab/hosts.json appropriately and run the setup script" diff --git a/laas/actions/actions/update_bios_password.py b/laas/actions/actions/update_bios_password.py new file mode 100644 index 0000000..f35f46e --- /dev/null +++ b/laas/actions/actions/update_bios_password.py @@ -0,0 +1,28 @@ +############################################################################## +# Copyright 2018 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 st2actions.runners.pythonrunner import Action +import sqlite3 + + +class UPDATEBiosPassAction(Action): + + def run(self, host=None, password=None): + dbfile = self.action_service.get_value("database", local=False) + db = sqlite3.connect(dbfile) + c = db.cursor() + c.execute("UPDATE ipmi SET bios_pass=? WHERE host=?", (password, host)) + db.commit() + db.close() diff --git a/laas/actions/actions/vpn_delete_user.py b/laas/actions/actions/vpn_delete_user.py new file mode 100644 index 0000000..0310ee0 --- /dev/null +++ b/laas/actions/actions/vpn_delete_user.py @@ -0,0 +1,57 @@ +############################################################################## +# 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 lib.vpn 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, keys=None): + if dn is not None and dn != "None": # we are provided with a good dn + st2key = 'vpn_' + # get username from dn + for attr in dn.split(','): + if 'uid' in attr: + st2key += attr.split('=')[-1] + self.action_service.delete_value(name=st2key, local=False) + self.deleteUser(dn) + return + + # consolidate all keys into one list + vpn_keys = [] + if keys is not None: + vpn_keys += keys + + if key is not None and key != "None": + vpn_keys.append(key) + + # delete all provided keys + for k in vpn_keys: + vpn_info = json.loads( + self.action_service.get_value( + name=k, + local=False, + decrypt=True + ) + ) + dn = vpn_info['dn'] + st2key = k + self.action_service.delete_value(name=st2key, local=False) + self.deleteUser(dn) diff --git a/laas/actions/actions/vpn_make_user.py b/laas/actions/actions/vpn_make_user.py new file mode 100644 index 0000000..2a686dc --- /dev/null +++ b/laas/actions/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 +import json +from lib.vpn import VPNAction + + +class Make_VPN_User(VPNAction): + + def __init__(self, config=None): + super(Make_VPN_User, self).__init__(config=config) + + def run(self, user=None, passwd=None, job_id=None): + if user == "None": + user = None + if passwd == "None": + passwd = None + name, passwd, dn = self.makeNewUser(name=user, passwd=passwd) + vpn_info = { + "dn": dn, + "username": name, + "password": passwd, + "created": datetime.date.today().isoformat() + } + self.action_service.set_value( + name='vpn_' + name, + value=json.dumps(vpn_info), + local=False, + encrypt=True + ) + if job_id and job_id != "None": + self.addUserToJob(vpn_info, job_id) + return "vpn_" + name + + def addUserToJob(self, vpn_info, job): + name = "job_" + job + job = json.loads( + self.action_service.get_value(name, local=False) + ) + if 'vpn_keys' not in job: + job['vpn_keys'] = [] + job['vpn_keys'].append("vpn_" + vpn_info['username']) + self.action_service.set_value( + name=name, + value=json.dumps(job), + local=False + ) diff --git a/laas/actions/actions/waitForBoot.sh b/laas/actions/actions/waitForBoot.sh new file mode 100644 index 0000000..0b77083 --- /dev/null +++ b/laas/actions/actions/waitForBoot.sh @@ -0,0 +1,27 @@ +#!/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. # +############################################################################## + +sleep 20 #make sure ipmi has enough time to work + +while ! ping -c 1 "$1" ; do + sleep 20 +done + +echo "attempting ssh" +while ! ssh -o stricthostkeychecking=no -o userknownhostsfile=/dev/null root@"$1" "exit 0"; do + sleep 20 +done diff --git a/laas/actions/actions/wait_for_dhcp.sh b/laas/actions/actions/wait_for_dhcp.sh new file mode 100644 index 0000000..603393b --- /dev/null +++ b/laas/actions/actions/wait_for_dhcp.sh @@ -0,0 +1,25 @@ +#!/bin/bash +############################################################################## +# Copyright 2018 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. # +############################################################################## + +MAC="$1" + +TARGET=$(echo "$MAC" | cut -d "." -f 1) +echo "Searching for MAC $TARGET in ARP tables" + +while ! /usr/sbin/ip neigh show | grep -q "$TARGET"; do + sleep 3 +done diff --git a/laas/actions/actions/wait_for_host.sh b/laas/actions/actions/wait_for_host.sh new file mode 100644 index 0000000..780888f --- /dev/null +++ b/laas/actions/actions/wait_for_host.sh @@ -0,0 +1,22 @@ +#!/bin/bash +############################################################################## +# Copyright 2018 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. # +############################################################################## + +HOST="$1" + +until ping -c 1 -q "$HOST"; do + sleep 5 +done diff --git a/laas/actions/add_management_vlan.yaml b/laas/actions/add_management_vlan.yaml new file mode 100644 index 0000000..469c7e7 --- /dev/null +++ b/laas/actions/add_management_vlan.yaml @@ -0,0 +1,26 @@ +--- +############################################################################## +# Copyright 2018 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_management_vlan +entry_point: actions/add_management_vlan.py +runner_type: python-script +enabled: true +parameters: + hosts: + type: array + required: true + description: list of hostnames for accessing the datastore diff --git a/laas/actions/apex_gambia_virtual_deploy.yaml b/laas/actions/apex_gambia_virtual_deploy.yaml new file mode 100644 index 0000000..ca7fb50 --- /dev/null +++ b/laas/actions/apex_gambia_virtual_deploy.yaml @@ -0,0 +1,27 @@ +--- +############################################################################## +# Copyright 2018 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_gambia_virtual_deploy +entry_point: actions/apex_gambia_virtual_deploy.sh +enabled: true +runner_type: remote-shell-script +parameters: + scenario: + type: string + required: true + description: "scenario to deploy" + position: 0 diff --git a/laas/actions/apex_gambia_workflow.yaml b/laas/actions/apex_gambia_workflow.yaml new file mode 100644 index 0000000..e10befc --- /dev/null +++ b/laas/actions/apex_gambia_workflow.yaml @@ -0,0 +1,36 @@ +--- +############################################################################## +# Copyright 2018 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 install and deploy Apex Gambia +enabled: true +runner_type: mistral-v2 +entry_point: workflows/apex_gambia_workflow.yaml +name: apex_gambia_workflow +pack: laas +parameters: + hosts: + required: true + type: array + description: "mapping of OPNFV roles to hostnames" + scenario: + required: true + type: string + description: "Valid OPNFV scenario name" + virtual: + required: true + type: boolean + description: "If true, will perform virtual deploy" diff --git a/laas/actions/apex_master_workflow.yaml b/laas/actions/apex_master_workflow.yaml new file mode 100644 index 0000000..52d0d04 --- /dev/null +++ b/laas/actions/apex_master_workflow.yaml @@ -0,0 +1,44 @@ +--- +############################################################################## +# Copyright 2018 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 install and deploy Apex +enabled: true +runner_type: mistral-v2 +entry_point: workflows/apex_master_workflow.yaml +name: apex_master_workflow +pack: laas +parameters: + hosts: + required: true + type: array + description: "mapping from OPNFV roles to hostnames" + jumphost: + required: true + type: string + description: "hostname of jumphost. Should also be in roles" + scenario: + required: true + type: string + description: "Valid OPNFV scenario name" + virtual: + required: true + type: boolean + description: "If true, will perform virtual deploy" + version: + required: true + type: integer + description: "OPNFV Release. 7 = Gambia" diff --git a/laas/actions/bootBookedHostsWorkflow.yaml b/laas/actions/bootBookedHostsWorkflow.yaml new file mode 100644 index 0000000..3850795 --- /dev/null +++ b/laas/actions/bootBookedHostsWorkflow.yaml @@ -0,0 +1,25 @@ +--- +############################################################################## +# Copyright 2018 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: bootBookedHostsWorkflow +description: | + Will turn on all the hosts that have a current booking. + Must be manually run. The intention is for recovery of power failure +runner_type: mistral-v2 +entry_point: workflows/bootBookedHostsWorkflow.yaml +pack: laas +enabled: true diff --git a/laas/actions/check_ipmi_power.yaml b/laas/actions/check_ipmi_power.yaml new file mode 100644 index 0000000..bf03dee --- /dev/null +++ b/laas/actions/check_ipmi_power.yaml @@ -0,0 +1,33 @@ +--- +############################################################################## +# Copyright 2019 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: check_ipmi_power +runner_type: local-shell-script +entry_point: actions/check_ipmi_power.sh +parameters: + host: + required: true + type: string + position: 0 + user: + required: true + type: string + position: 1 + pass: + required: true + type: string + position: 2 diff --git a/laas/actions/check_power_workflow.yaml b/laas/actions/check_power_workflow.yaml new file mode 100644 index 0000000..88e44d7 --- /dev/null +++ b/laas/actions/check_power_workflow.yaml @@ -0,0 +1,25 @@ +--- +############################################################################## +# Copyright 2019 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: check_power_workflow +enabled: true +runner_type: mistral-v2 +entry_point: workflows/check_power_workflow.yaml +parameters: + host: + type: string + required: true diff --git a/laas/actions/compass_gambia_virtual_deploy.yaml b/laas/actions/compass_gambia_virtual_deploy.yaml new file mode 100644 index 0000000..6c9137e --- /dev/null +++ b/laas/actions/compass_gambia_virtual_deploy.yaml @@ -0,0 +1,32 @@ +--- +############################################################################## +# Copyright 2018 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_gambia_virtual_deploy +entry_point: actions/compass_gambia_virtual_deploy.sh +enabled: true +runner_type: remote-shell-script +parameters: + scenario: + type: string + required: true + description: "scenario to deploy" + position: 0 + subversion: + type: string + required: true + description: "git tag to checkout" + position: 1 diff --git a/laas/actions/compass_gambia_workflow.yaml b/laas/actions/compass_gambia_workflow.yaml new file mode 100644 index 0000000..969f84c --- /dev/null +++ b/laas/actions/compass_gambia_workflow.yaml @@ -0,0 +1,40 @@ +--- +############################################################################## +# Copyright 2018 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 install and deploy Compass Gambia +enabled: true +runner_type: mistral-v2 +entry_point: workflows/compass_gambia_workflow.yaml +name: compass_gambia_workflow +pack: laas +parameters: + hosts: + required: true + type: array + description: "mapping of OPNFV roles to hostnames" + scenario: + required: true + type: string + description: "Valid OPNFV scenario name" + virtual: + required: true + type: boolean + description: "If true, will perform virtual deploy" + subversion: + required: true + type: string + description: "git tag" diff --git a/laas/actions/compass_master_workflow.yaml b/laas/actions/compass_master_workflow.yaml new file mode 100644 index 0000000..d782899 --- /dev/null +++ b/laas/actions/compass_master_workflow.yaml @@ -0,0 +1,48 @@ +--- +############################################################################## +# Copyright 2018 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 install and deploy Compass +enabled: true +runner_type: mistral-v2 +entry_point: workflows/compass_master_workflow.yaml +name: compass_master_workflow +pack: laas +parameters: + hosts: + required: true + type: array + description: "mapping from OPNFV roles to hostnames" + jumphost: + required: true + type: string + description: "hostname of jumphost. Should also be in roles" + scenario: + required: true + type: string + description: "Valid OPNFV scenario name" + virtual: + required: true + type: boolean + description: "If true, will perform virtual deploy" + version: + required: true + type: integer + description: "OPNFV Release. 7 = Gambia" + subversion: + required: true + type: string + description: "git tag" diff --git a/laas/actions/configure_host_networking.yaml b/laas/actions/configure_host_networking.yaml new file mode 100644 index 0000000..411ea9b --- /dev/null +++ b/laas/actions/configure_host_networking.yaml @@ -0,0 +1,35 @@ +--- +############################################################################## +# Copyright 2018 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: configure_host_networking +enabled: true +runner_type: remote-shell-script +entry_point: actions/configure_host_networking.sh +parameters: + mapping: + type: string + position: 0 + required: true + description: | + mapping multiple mappings of MAC address and vlan. For example, + '00:11:22:33:44:55-40+11:11:11:11:11:11-700' provides two mappings. + The format is 'mac-vlan+mac-vlan+mac-vlan' as many times as you need + default: + type: string + position: 1 + required: true + description: the name of the interface to be used for the default route diff --git a/laas/actions/copy_user_keys.yaml b/laas/actions/copy_user_keys.yaml new file mode 100644 index 0000000..d5288b7 --- /dev/null +++ b/laas/actions/copy_user_keys.yaml @@ -0,0 +1,30 @@ +--- +############################################################################## +# Copyright 2018 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: copy_user_keys +runner_type: local-shell-script +entry_point: actions/copy_user_keys.sh +enabled: true +parameters: + key: + required: true + description: contents of public key file + position: 0 + hosts: + required: true + description: comman delimited list of hostnames to inject keys into + position: 1 diff --git a/laas/actions/delete_password.yaml b/laas/actions/delete_password.yaml new file mode 100644 index 0000000..60375ef --- /dev/null +++ b/laas/actions/delete_password.yaml @@ -0,0 +1,25 @@ +--- +############################################################################## +# Copyright 2018 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: delete_password +entry_point: actions/delete_password.py +enabled: true +runner_type: python-script +parameters: + host: + type: string + required: true diff --git a/laas/actions/deploy_fuel_gambia_baremetal.yaml b/laas/actions/deploy_fuel_gambia_baremetal.yaml new file mode 100644 index 0000000..257f185 --- /dev/null +++ b/laas/actions/deploy_fuel_gambia_baremetal.yaml @@ -0,0 +1,32 @@ +--- +############################################################################## +# Copyright 2019 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: deploy_fuel_gambia_baremetal +enabled: true +runner_type: remote-shell-script +entry_point: actions/deploy_fuel_gambia_baremetal.sh +parameters: + pdf: + type: string + description: the provided pdf file as a string + required: true + position: 0 + idf: + type: string + description: the provided idf file as a string + required: true + position: 1 diff --git a/laas/actions/detectHostsToBoot.yaml b/laas/actions/detectHostsToBoot.yaml new file mode 100644 index 0000000..31512a7 --- /dev/null +++ b/laas/actions/detectHostsToBoot.yaml @@ -0,0 +1,21 @@ +--- +############################################################################## +# Copyright 2018 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: detectHostsToBoot +runner_type: python-script +entry_point: actions/detectHostsToBoot.py +enabled: true diff --git a/laas/actions/detect_hardware_tasks.yaml b/laas/actions/detect_hardware_tasks.yaml new file mode 100644 index 0000000..d5458b8 --- /dev/null +++ b/laas/actions/detect_hardware_tasks.yaml @@ -0,0 +1,28 @@ +--- +############################################################################## +# Copyright 2018 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: detect_hardware_tasks +entry_point: actions/detect_hardware_tasks.py +runner_type: python-script +enabled: true +parameters: + job_id: + type: integer + required: true + task_id: + type: string + required: true diff --git a/laas/actions/error_task.yaml b/laas/actions/error_task.yaml new file mode 100644 index 0000000..323a773 --- /dev/null +++ b/laas/actions/error_task.yaml @@ -0,0 +1,28 @@ +--- +############################################################################## +# Copyright 2018 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: error_task +enabled: true +runner_type: python-script +entry_point: actions/error_task.py +parameters: + job_id: + type: integer + required: true + task_id: + type: string + required: true diff --git a/laas/actions/finish_job.yaml b/laas/actions/finish_job.yaml new file mode 100644 index 0000000..7e08536 --- /dev/null +++ b/laas/actions/finish_job.yaml @@ -0,0 +1,25 @@ +--- +############################################################################## +# Copyright 2018 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: finish_job +description: marks job as completed internally +entry_point: actions/finish_job.py +runner_type: python-script +parameters: + job_id: + type: integer + required: true diff --git a/laas/actions/finish_task.yaml b/laas/actions/finish_task.yaml new file mode 100644 index 0000000..3da0c91 --- /dev/null +++ b/laas/actions/finish_task.yaml @@ -0,0 +1,31 @@ +--- +############################################################################## +# Copyright 2018 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: finish_task +enabled: true +runner_type: python-script +entry_point: actions/finish_task.py +parameters: + job_id: + type: integer + required: true + task_id: + type: string + required: true + lab_token: + type: string + required: false diff --git a/laas/actions/fog_createSnapshot.yaml b/laas/actions/fog_createSnapshot.yaml new file mode 100644 index 0000000..c2671b3 --- /dev/null +++ b/laas/actions/fog_createSnapshot.yaml @@ -0,0 +1,28 @@ +--- +############################################################################## +# Copyright 2018 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_createSnapshot +entry_point: actions/fog_createSnapshot.py +enabled: true +runner_type: python-script +parameters: + host: + type: string + required: true + name: + type: string + required: true diff --git a/laas/actions/fog_getTargetImage.yaml b/laas/actions/fog_getTargetImage.yaml new file mode 100644 index 0000000..9ba2510 --- /dev/null +++ b/laas/actions/fog_getTargetImage.yaml @@ -0,0 +1,45 @@ +--- +############################################################################## +# Copyright 2019 Sawyer Bergeron 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. # +############################################################################## + +# Note to caller: one of from_image or from_os is required +# if only a from_x operand is given and no target_x operand is given, +# the target is assumed to be the source +# +# if a non-existing target OS is given and no target image, an error is raised +# +# if a non-existing target image is given, one is created and its id is returned + +name: fog_getTargetImage +entry_point: actions/fog_getTargetImage.py +runner_type: python-script +enabled: true +parameters: + host: + type: string + required: true + from_image: + type: string + required: false + from_os: + type: string + required: false + target_image: + type: string + required: false + target_os: + type: string + required: false diff --git a/laas/actions/fog_snapshotWorkflow.yaml b/laas/actions/fog_snapshotWorkflow.yaml new file mode 100644 index 0000000..25f8af1 --- /dev/null +++ b/laas/actions/fog_snapshotWorkflow.yaml @@ -0,0 +1,30 @@ +--- +############################################################################## +# Copyright 2018 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_snapshotWorkflow +entry_point: workflows/fog_snapshotWorkflow +enabled: true +runner_type: action-chain +parameters: + name: + type: string + required: true + description: "name of snapshot to create" + host: + type: string + required: true + description: "host to snapshot" diff --git a/laas/actions/fuel_gambia_virtual_deploy.yaml b/laas/actions/fuel_gambia_virtual_deploy.yaml new file mode 100644 index 0000000..1ff5e22 --- /dev/null +++ b/laas/actions/fuel_gambia_virtual_deploy.yaml @@ -0,0 +1,48 @@ +--- +############################################################################## +# Copyright 2018 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_gambia_virtual_deploy +entry_point: actions/fuel_gambia_virtual_deploy.sh +enabled: true +runner_type: remote-shell-script +parameters: + host: + type: array + required: true + description: "role mapping from dashboard api" + jumphost: + type: string + required: true + description: "hostname of jumphost" + scenario: + type: string + required: true + description: "scenario to deploy" + position: 0 + subversion: + type: string + required: true + description: "tag to git checkout" + position: 1 + pdf: + required: false + type: string + default: "not available" + idf: + required: false + type: string + default: "not available" diff --git a/laas/actions/fuel_gambia_virtual_prepare.yaml b/laas/actions/fuel_gambia_virtual_prepare.yaml new file mode 100644 index 0000000..ee0eb45 --- /dev/null +++ b/laas/actions/fuel_gambia_virtual_prepare.yaml @@ -0,0 +1,27 @@ +--- +############################################################################## +# Copyright 2018 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_gambia_virtual_prepare +entry_point: actions/fuel_gambia_virtual_prepare.sh +enabled: true +runner_type: local-shell-script +parameters: + host: + type: string + required: true + description: "host to prepare" + position: 0 diff --git a/laas/actions/fuel_gambia_workflow.yaml b/laas/actions/fuel_gambia_workflow.yaml new file mode 100644 index 0000000..7670d4d --- /dev/null +++ b/laas/actions/fuel_gambia_workflow.yaml @@ -0,0 +1,52 @@ +--- +############################################################################## +# Copyright 2018 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 install and deploy Fuel Gambia +enabled: true +runner_type: mistral-v2 +entry_point: workflows/fuel_gambia_workflow.yaml +name: fuel_gambia_workflow +pack: laas +parameters: + hosts: + required: true + type: array + description: "mapping of OPNFV roles to hostnames" + jumphost: + required: true + type: string + description: "jumphost hostname" + scenario: + required: true + type: string + description: "Valid OPNFV scenario name" + virtual: + required: true + type: boolean + description: "If true, will perform virtual deploy" + subversion: + required: true + type: string + description: "point release to git checkout, opnfv-7.1.0" + pdf: + required: false + type: string + default: "not available" + idf: + required: false + type: string + default: "not available" diff --git a/laas/actions/fuel_master_workflow.yaml b/laas/actions/fuel_master_workflow.yaml new file mode 100644 index 0000000..d913e76 --- /dev/null +++ b/laas/actions/fuel_master_workflow.yaml @@ -0,0 +1,56 @@ +--- +############################################################################## +# Copyright 2018 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 install and deploy Fuel +enabled: true +runner_type: mistral-v2 +entry_point: workflows/fuel_master_workflow.yaml +name: fuel_master_workflow +pack: laas +parameters: + hosts: + required: true + type: array + description: "mapping from OPNFV roles to hostnames" + jumphost: + required: true + type: string + description: "legacy param: hostname of jumphost. Also present in $hosts" + scenario: + required: true + type: string + description: "Valid OPNFV scenario name" + virtual: + required: true + type: boolean + description: "If true, will perform virtual deploy" + version: + required: true + type: integer + description: "OPNFV Release. 7 = Gambia" + subversion: + required: true + type: string + description: "point release to git checkout, opnfv-7.1.0" + pdf: + required: false + type: string + default: "not available" + idf: + required: false + type: string + default: "not available" diff --git a/laas/actions/getNextHost.yaml b/laas/actions/getNextHost.yaml new file mode 100644 index 0000000..4736f0a --- /dev/null +++ b/laas/actions/getNextHost.yaml @@ -0,0 +1,21 @@ +--- +############################################################################## +# Copyright 2018 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: getNextHost +runner_type: python-script +entry_point: actions/getNextHost.py +enabled: true diff --git a/laas/actions/get_all_macs.yaml b/laas/actions/get_all_macs.yaml new file mode 100644 index 0000000..24f71b2 --- /dev/null +++ b/laas/actions/get_all_macs.yaml @@ -0,0 +1,25 @@ +--- +############################################################################## +# Copyright 2018 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: get_all_macs +enabled: true +runner_type: python-script +entry_point: actions/get_all_macs.py +parameters: + host: + required: true + type: string diff --git a/laas/actions/get_bios_password.yaml b/laas/actions/get_bios_password.yaml new file mode 100644 index 0000000..874b1c3 --- /dev/null +++ b/laas/actions/get_bios_password.yaml @@ -0,0 +1,26 @@ +--- +############################################################################## +# Copyright 2018 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: get_bios_password +entry_point: actions/get_bios_password.py +runner_type: python-script +enabled: true +parameters: + host: + type: string + required: true + description: ipmi hostname diff --git a/laas/actions/get_dhcp_address.yaml b/laas/actions/get_dhcp_address.yaml new file mode 100644 index 0000000..b980033 --- /dev/null +++ b/laas/actions/get_dhcp_address.yaml @@ -0,0 +1,26 @@ +--- +############################################################################## +# Copyright 2018 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: get_dhcp_address +entry_point: actions/get_dhcp_address.sh +runner_type: local-shell-script +enabled: true +parameters: + host: + required: true + type: string + position: 0 diff --git a/laas/actions/get_host_type.yaml b/laas/actions/get_host_type.yaml new file mode 100644 index 0000000..9158614 --- /dev/null +++ b/laas/actions/get_host_type.yaml @@ -0,0 +1,24 @@ +--- +############################################################################## +# Copyright 2018 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: get_host_type +entry_point: actions/get_host_type.py +runner_type: python-script +parameters: + host: + required: true + type: string diff --git a/laas/actions/get_ipmi_hostname.yaml b/laas/actions/get_ipmi_hostname.yaml new file mode 100644 index 0000000..5869148 --- /dev/null +++ b/laas/actions/get_ipmi_hostname.yaml @@ -0,0 +1,26 @@ +--- +############################################################################## +# Copyright 2018 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: get_ipmi_hostname +enabled: true +entry_point: actions/get_ipmi_hostname.py +runner_type: python-script +parameters: + host: + type: string + required: true + description: "hostname, example: HPE_3" diff --git a/laas/actions/get_ipmi_password.yaml b/laas/actions/get_ipmi_password.yaml new file mode 100644 index 0000000..0631509 --- /dev/null +++ b/laas/actions/get_ipmi_password.yaml @@ -0,0 +1,25 @@ +--- +############################################################################## +# Copyright 2018 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: get_ipmi_password +enabled: true +entry_point: actions/get_ipmi_password.py +runner_type: python-script +parameters: + host: + type: string + required: true diff --git a/laas/actions/get_ipmi_username.yaml b/laas/actions/get_ipmi_username.yaml new file mode 100644 index 0000000..1f14145 --- /dev/null +++ b/laas/actions/get_ipmi_username.yaml @@ -0,0 +1,25 @@ +--- +############################################################################## +# Copyright 2018 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: get_ipmi_username +enabled: true +entry_point: actions/get_ipmi_username.py +runner_type: python-script +parameters: + host: + type: string + required: true diff --git a/laas/actions/get_jumphost.yaml b/laas/actions/get_jumphost.yaml new file mode 100644 index 0000000..5d88225 --- /dev/null +++ b/laas/actions/get_jumphost.yaml @@ -0,0 +1,25 @@ +--- +############################################################################## +# Copyright 2019 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: get_jumphost +entry_point: actions/get_jumphost.py +runner_type: python-script +enabled: true +parameters: + hosts: + type: array + required: true diff --git a/laas/actions/get_mac_from_ip.yaml b/laas/actions/get_mac_from_ip.yaml new file mode 100644 index 0000000..b317010 --- /dev/null +++ b/laas/actions/get_mac_from_ip.yaml @@ -0,0 +1,34 @@ +--- +############################################################################## +# Copyright 2019 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: get_mac_from_ip +runner_type: local-shell-script +entry_point: actions/get_mac_from_ip.sh +enabled: true +parameters: + host: + required: true + description: ip/hostname to get MAC from + position: 0 + gateway: + required: false + description: ip/hostname of gateway, if not machine running stackstorm + position: 1 + user: + required: false + description: user to ssh into gateway as + position: 2 diff --git a/laas/actions/get_task.yaml b/laas/actions/get_task.yaml new file mode 100644 index 0000000..49300e1 --- /dev/null +++ b/laas/actions/get_task.yaml @@ -0,0 +1,31 @@ +--- +############################################################################## +# Copyright 2018 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: get_task +entry_point: actions/get_task.py +runner_type: python-script +enabled: true +parameters: + job_id: + type: integer + required: true + task_id: + type: string + required: true + type: + type: string + required: true diff --git a/laas/actions/get_task_list.yaml b/laas/actions/get_task_list.yaml new file mode 100644 index 0000000..11c5a6d --- /dev/null +++ b/laas/actions/get_task_list.yaml @@ -0,0 +1,28 @@ +--- +############################################################################## +# Copyright 2018 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: get_task_list +entry_point: actions/get_task_list.py +runner_type: python-script +enabled: true +parameters: + job_id: + type: integer + required: true + type: + type: string + required: true diff --git a/laas/actions/get_xdf.yaml b/laas/actions/get_xdf.yaml new file mode 100644 index 0000000..6c659c3 --- /dev/null +++ b/laas/actions/get_xdf.yaml @@ -0,0 +1,25 @@ +--- +############################################################################## +# Copyright 2019 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: get_xdf +entry_point: actions/get_xdf.py +runner_type: python-script +enabled: true +parameters: + task_data: + type: object + required: true diff --git a/laas/actions/hardware_master_workflow.yaml b/laas/actions/hardware_master_workflow.yaml new file mode 100644 index 0000000..3e42599 --- /dev/null +++ b/laas/actions/hardware_master_workflow.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. # +############################################################################## + +description: This is the workflow that will provision the host as requested. +enabled: true +runner_type: mistral-v2 +entry_point: workflows/hardware_master_workflow.yaml +name: hardware_master_workflow +pack: laas +parameters: + job_id: + required: true + type: integer diff --git a/laas/actions/hardware_workflow.yaml b/laas/actions/hardware_workflow.yaml new file mode 100644 index 0000000..9c3f641 --- /dev/null +++ b/laas/actions/hardware_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. # +############################################################################## + +description: This is the workflow that will provision the host as requested. +enabled: true +runner_type: mistral-v2 +entry_point: workflows/hardware_workflow.yaml +name: hardware_workflow +pack: laas +parameters: + job_id: + required: true + type: integer + task_id: + required: true + type: string diff --git a/laas/actions/ipmi_restartHost.yaml b/laas/actions/ipmi_restartHost.yaml new file mode 100644 index 0000000..26b6ad7 --- /dev/null +++ b/laas/actions/ipmi_restartHost.yaml @@ -0,0 +1,38 @@ +--- +############################################################################## +# Copyright 2018 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: ipmi_restartHost +runner_type: local-shell-script +entry_point: actions/ipmi_restartHost.sh +parameters: + host: + required: true + type: string + position: 0 + user: + required: true + type: string + position: 1 + password: + required: true + type: string + position: 2 + cmd: + required: true + type: string + position: 3 + description: may either be on off cycle diff --git a/laas/actions/jenkins_info.yaml b/laas/actions/jenkins_info.yaml new file mode 100644 index 0000000..41ca19b --- /dev/null +++ b/laas/actions/jenkins_info.yaml @@ -0,0 +1,25 @@ +--- +############################################################################## +# Copyright 2018 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: jenkins_info +runner_type: python-script +enabled: true +entry_point: actions/jenkins_info.py +parameters: + host: + type: string + required: true diff --git a/laas/actions/jenkins_workflow.yaml b/laas/actions/jenkins_workflow.yaml new file mode 100644 index 0000000..800b9aa --- /dev/null +++ b/laas/actions/jenkins_workflow.yaml @@ -0,0 +1,25 @@ +--- +############################################################################## +# Copyright 2018 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: jenkins_workflow +entry_point: workflows/jenkins_workflow.yaml +runner_type: mistral-v2 +enabled: true +parameters: + host: + required: true + type: string diff --git a/laas/actions/master_workflow.yaml b/laas/actions/master_workflow.yaml new file mode 100644 index 0000000..f3d1712 --- /dev/null +++ b/laas/actions/master_workflow.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. # +############################################################################## + +description: This is the workflow that will provision the host as requested. +enabled: true +runner_type: mistral-v2 +entry_point: workflows/master_workflow.yaml +name: master_workflow +pack: laas +parameters: + job_id: + required: true + type: integer diff --git a/laas/actions/network_master_workflow.yaml b/laas/actions/network_master_workflow.yaml new file mode 100644 index 0000000..77813d2 --- /dev/null +++ b/laas/actions/network_master_workflow.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. # +############################################################################## + +description: This is the workflow that will provision the host as requested. +enabled: true +runner_type: mistral-v2 +entry_point: workflows/network_master_workflow.yaml +name: network_master_workflow +pack: laas +parameters: + job_id: + required: true + type: integer diff --git a/laas/actions/network_task.yaml b/laas/actions/network_task.yaml new file mode 100644 index 0000000..aca3771 --- /dev/null +++ b/laas/actions/network_task.yaml @@ -0,0 +1,26 @@ +--- +############################################################################## +# Copyright 2018 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: network_task +runner_type: python-script +entry_point: actions/network_task.py +enabled: true +parameters: + network_data: + type: object + required: true + description: "json from the dashbaord describing this task" diff --git a/laas/actions/network_workflow.yaml b/laas/actions/network_workflow.yaml new file mode 100644 index 0000000..9aceaa1 --- /dev/null +++ b/laas/actions/network_workflow.yaml @@ -0,0 +1,35 @@ +--- +############################################################################## +# 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/network_workflow.yaml +name: network_workflow +pack: laas +parameters: + job_id: + required: true + type: integer + task_id: + required: true + type: string + to_configure_host: + required: false + type: boolean + default: false + description: "Whether we need to manually tag vlans on this host" diff --git a/laas/actions/notify_ip_address.yaml b/laas/actions/notify_ip_address.yaml new file mode 100644 index 0000000..4e787d9 --- /dev/null +++ b/laas/actions/notify_ip_address.yaml @@ -0,0 +1,37 @@ +--- +############################################################################## +# Copyright 2018 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: notify_ip_address +description: "sends ip info to the dashboard for the user" +enabled: true +runner_type: python-script +entry_point: actions/notify_ip_address.py +parameters: + addresses: + required: true + description: host address information + type: string + hostname: + required: false + description: DNS name of host + type: string + job_id: + required: true + type: integer + task_id: + required: true + type: string diff --git a/laas/actions/notify_ipmi_api.yaml b/laas/actions/notify_ipmi_api.yaml new file mode 100644 index 0000000..f3ff846 --- /dev/null +++ b/laas/actions/notify_ipmi_api.yaml @@ -0,0 +1,39 @@ +--- +############################################################################## +# Copyright 2019 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: notify_ipmi_api +description: "sends ipmi info to the dashboard for the api" +enabled: true +runner_type: python-script +entry_point: actions/notify_ipmi_api.py +parameters: + ipmi_key: + required: true + description: key to ipmi info in st2 datastore + type: string + addr: + required: true + type: string + description: ip address of ipmi interface + mac: + required: true + type: string + description: mac address of ipmi interface + host: + required: true + type: string + description: host id that owns this ipmi diff --git a/laas/actions/notify_ipmi_user.yaml b/laas/actions/notify_ipmi_user.yaml new file mode 100644 index 0000000..79d5b7c --- /dev/null +++ b/laas/actions/notify_ipmi_user.yaml @@ -0,0 +1,41 @@ +--- +############################################################################## +# Copyright 2018 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: notify_ipmi_user +description: "sends ipmi info to the dashboard for the user" +enabled: true +runner_type: python-script +entry_point: actions/notify_ipmi_user.py +parameters: + ipmi_key: + required: true + description: key to ipmi info in st2 datastore + type: string + job_id: + required: true + type: integer + task_id: + required: true + type: string + hostname: + required: true + type: string + description: ipmi hostname + addr: + required: true + type: string + description: ip address of ipmi interface diff --git a/laas/actions/notify_ipmi_workflow.yaml b/laas/actions/notify_ipmi_workflow.yaml new file mode 100644 index 0000000..11ee1ee --- /dev/null +++ b/laas/actions/notify_ipmi_workflow.yaml @@ -0,0 +1,39 @@ +--- +############################################################################## +# Copyright 2019 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 notify parties about ipmi info +enabled: true +runner_type: mistral-v2 +entry_point: workflows/notify_ipmi_workflow.yaml +name: notify_ipmi_workflow +pack: laas +parameters: + job_id: + required: true + type: integer + task_id: + required: true + type: string + ipmi_key: + required: true + type: string + ipmi_name: + required: true + type: string + host: + required: true + type: string diff --git a/laas/actions/notify_ssh_access.yaml b/laas/actions/notify_ssh_access.yaml new file mode 100644 index 0000000..2f8c2ba --- /dev/null +++ b/laas/actions/notify_ssh_access.yaml @@ -0,0 +1,37 @@ +--- +############################################################################## +# Copyright 2018 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: notify_ssh_access +description: "sends ssh info to the user" +enabled: true +runner_type: python-script +entry_point: actions/notify_ssh_access.py +parameters: + user: + required: true + description: user with ssh keys on host + type: string + hosts: + required: true + description: list of DNS name of host or ip address + type: array + job_id: + required: true + type: integer + task_id: + required: true + type: string diff --git a/laas/actions/notify_vpn_user.yaml b/laas/actions/notify_vpn_user.yaml new file mode 100644 index 0000000..902547d --- /dev/null +++ b/laas/actions/notify_vpn_user.yaml @@ -0,0 +1,33 @@ +--- +############################################################################## +# Copyright 2018 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: notify_vpn_user +description: "sends vpn info to the dashboard for the user" +enabled: true +runner_type: python-script +entry_point: actions/notify_vpn_user.py +parameters: + vpn_key: + required: true + description: key to vpn info in st2 datastore + type: string + job_id: + required: true + type: string + task_id: + required: true + type: string diff --git a/laas/actions/opnfv_master_workflow.yaml b/laas/actions/opnfv_master_workflow.yaml new file mode 100644 index 0000000..28afb98 --- /dev/null +++ b/laas/actions/opnfv_master_workflow.yaml @@ -0,0 +1,57 @@ +--- +############################################################################## +# Copyright 2018 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 install and deploy OPNFV +enabled: true +runner_type: mistral-v2 +entry_point: workflows/opnfv_master_workflow.yaml +name: opnfv_master_workflow +pack: laas +parameters: + hosts: + required: true + type: array + description: "[{hostname: role}]" + installer: + required: true + type: string + description: "One of: fuel, compass, apex" + scenario: + required: true + type: string + description: "Valid OPNFV scenario name" + virtual: + required: true + type: boolean + description: "If true, will perform virtual deploy" + version: + required: false + type: integer + default: 7 + description: OPNFV release version + subversion: + required: false + type: string + default: "opnfv-7.1.0" + pdf: + required: false + type: string + default: "not available" + idf: + required: false + type: string + default: "not available" diff --git a/laas/actions/parse_network_data.yaml b/laas/actions/parse_network_data.yaml new file mode 100644 index 0000000..4f02a43 --- /dev/null +++ b/laas/actions/parse_network_data.yaml @@ -0,0 +1,26 @@ +--- +############################################################################## +# Copyright 2018 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: parse_network_data +entry_point: actions/parse_network_data.py +runner_type: python-script +enabled: true +parameters: + task_data: + type: object + required: true + description: jsonized task data diff --git a/laas/actions/prepare_fuel_gambia_baremetal.yaml b/laas/actions/prepare_fuel_gambia_baremetal.yaml new file mode 100644 index 0000000..7559482 --- /dev/null +++ b/laas/actions/prepare_fuel_gambia_baremetal.yaml @@ -0,0 +1,32 @@ +--- +############################################################################## +# Copyright 2019 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: prepare_fuel_gambia_baremetal +enabled: true +runner_type: remote-shell-script +entry_point: actions/prepare_fuel_gambia_baremetal.sh +parameters: + mapping: + type: string + position: 0 + required: true + description: | + maps bridge, interface, and IP address. + 'br-admin;00:11:22:33:44:55:66.576;127.0.5.5' is an example. + The format is 'brName;mac.vlan;ip+brName;mac.vlan;ip' for as many + mappings as you need + for the public net, ip should be 'dhcp' diff --git a/laas/actions/provision_workflow.yaml b/laas/actions/provision_workflow.yaml new file mode 100644 index 0000000..ae284f7 --- /dev/null +++ b/laas/actions/provision_workflow.yaml @@ -0,0 +1,36 @@ +--- +############################################################################## +# Copyright 2018 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: workflow to prep hosts and image +enabled: true +runner_type: mistral-v2 +entry_point: workflows/provision_workflow.yaml +name: provision_workflow +pack: laas +parameters: + host: + type: string + required: true + os: + required: false + type: string + ipmi: + required: true + type: boolean + powercmd: + type: string + required: true diff --git a/laas/actions/remove_booking.yaml b/laas/actions/remove_booking.yaml new file mode 100644 index 0000000..9638bbc --- /dev/null +++ b/laas/actions/remove_booking.yaml @@ -0,0 +1,26 @@ +--- +############################################################################## +# Copyright 2018 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: remove_booking +entry_point: actions/remove_booking.py +runner_type: python-script +description: stops tracking the supplied booking id +enabled: true +parameters: + booking: + type: integer + required: true diff --git a/laas/actions/resolve_host.yaml b/laas/actions/resolve_host.yaml new file mode 100644 index 0000000..8d7c239 --- /dev/null +++ b/laas/actions/resolve_host.yaml @@ -0,0 +1,25 @@ +--- +############################################################################## +# Copyright 2018 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: resolve_host +entry_point: actions/resolve_host.sh +enabled: true +runner_type: local-shell-script +parameters: + hostname: + required: true + description: The thing to query the nameserver with + position: 0 diff --git a/laas/actions/restart_workflow.yaml b/laas/actions/restart_workflow.yaml new file mode 100644 index 0000000..e3908fa --- /dev/null +++ b/laas/actions/restart_workflow.yaml @@ -0,0 +1,32 @@ +--- +############################################################################## +# Copyright 2018 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: restart_workflow +entry_point: workflows/restart_workflow.yaml +runner_type: mistral-v2 +parameters: + host: + type: string + required: true + ipmi: + type: boolean + required: false + default: true + cmd: + type: string + required: false + default: cycle diff --git a/laas/actions/send_bot_failure.yaml b/laas/actions/send_bot_failure.yaml new file mode 100644 index 0000000..ec06bac --- /dev/null +++ b/laas/actions/send_bot_failure.yaml @@ -0,0 +1,31 @@ +--- +############################################################################## +# Copyright 2019 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: send_bot_failure +entry_point: actions/send_bot_failure.py +runner_type: python-script +enabled: true +parameters: + job_id: + type: integer + required: false + execution_id: + type: string + required: false + message: + type: string + required: false diff --git a/laas/actions/send_jenkins_script.yaml b/laas/actions/send_jenkins_script.yaml new file mode 100644 index 0000000..3c240d5 --- /dev/null +++ b/laas/actions/send_jenkins_script.yaml @@ -0,0 +1,42 @@ +--- +############################################################################## +# Copyright 2018 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: send_jenkins_script +runner_type: local-shell-script +enabled: true +entry_point: actions/send_jenkins_script.sh +parameters: + destination: + required: true + position: 0 + type: string + description: hostname or ip to copy script to + hostname: + required: true + position: 1 + type: string + description: hostname to put into script + secret: + required: true + position: 2 + type: string + description: host's jenkins secret + script: + required: true + position: 3 + type: string + description: script template diff --git a/laas/actions/set_arm_boot.yaml b/laas/actions/set_arm_boot.yaml new file mode 100644 index 0000000..67e5d35 --- /dev/null +++ b/laas/actions/set_arm_boot.yaml @@ -0,0 +1,33 @@ +--- +############################################################################## +# Copyright 2018 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: set_arm_boot +entry_point: actions/set_arm_boot.sh +runner_type: local-shell-script +parameters: + host: + required: true + type: string + position: 0 + user: + required: true + type: string + position: 1 + passwd: + required: true + type: string + position: 2 diff --git a/laas/actions/set_boot_workflow.yaml b/laas/actions/set_boot_workflow.yaml new file mode 100644 index 0000000..71d2bc0 --- /dev/null +++ b/laas/actions/set_boot_workflow.yaml @@ -0,0 +1,25 @@ +--- +############################################################################## +# Copyright 2018 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: set_boot_workflow +entry_point: workflows/set_boot_workflow.yaml +runner_type: mistral-v2 +parameters: + host: + required: true + type: string + description: hostname of server diff --git a/laas/actions/set_hostname.yaml b/laas/actions/set_hostname.yaml new file mode 100644 index 0000000..93277f4 --- /dev/null +++ b/laas/actions/set_hostname.yaml @@ -0,0 +1,31 @@ +--- +############################################################################## +# Copyright 2018 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: set_hostname +entry_point: actions/set_hostname.sh +enabled: true +runner_type: local-shell-script +parameters: + hostname: + type: string + required: true + position: 0 + + host: + type: string + required: true + position: 1 diff --git a/laas/actions/set_hpe_bios_pass.yaml b/laas/actions/set_hpe_bios_pass.yaml new file mode 100644 index 0000000..b268f14 --- /dev/null +++ b/laas/actions/set_hpe_bios_pass.yaml @@ -0,0 +1,44 @@ +--- +############################################################################## +# Copyright 2018 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: set_hpe_bios_pass +entry_point: actions/set_hpe_bios_pass.py +enabled: true +runner_type: python-script +parameters: + host: + type: string + required: true + description: address or hostname of the ilo rest api + oldPass: + type: string + required: false + default: "" + description: current bios password + newPass: + type: string + required: true + description: password to set + user: + type: string + required: false + default: Administrator + description: admin iLo user to authenticate as + adminPass: + type: string + required: true + description: admin iLo pass to authenticate with diff --git a/laas/actions/set_hpe_bios_pass_workflow.yaml b/laas/actions/set_hpe_bios_pass_workflow.yaml new file mode 100644 index 0000000..e676e19 --- /dev/null +++ b/laas/actions/set_hpe_bios_pass_workflow.yaml @@ -0,0 +1,29 @@ +--- +############################################################################## +# Copyright 2018 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: set_hpe_bios_pass_workflow +entry_point: workflows/set_hpe_bios_pass_workflow.yaml +runner_type: mistral-v2 +enabled: true +parameters: + host: + type: string + required: true + password: + type: string + required: true + description: password to set on bios diff --git a/laas/actions/set_hpe_boot.yaml b/laas/actions/set_hpe_boot.yaml new file mode 100644 index 0000000..d456bd9 --- /dev/null +++ b/laas/actions/set_hpe_boot.yaml @@ -0,0 +1,30 @@ +--- +############################################################################## +# Copyright 2018 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: set_hpe_boot +runner_type: python-script +entry_point: actions/set_hpe_boot.py +parameters: + host: + required: true + type: string + user: + required: true + type: string + passwd: + required: true + type: string diff --git a/laas/actions/set_ipmi_account_worklfow.yaml b/laas/actions/set_ipmi_account_worklfow.yaml new file mode 100644 index 0000000..7db792c --- /dev/null +++ b/laas/actions/set_ipmi_account_worklfow.yaml @@ -0,0 +1,34 @@ +--- +############################################################################## +# Copyright 2018 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: set_ipmi_account_workflow +enabled: true +runner_type: mistral-v2 +entry_point: workflows/set_ipmi_account_workflow.yaml +parameters: + host: + type: string + required: true + notify_user: + type: boolean + required: false + default: false + description: "Whether or not to post data to dashboard" + url: + type: string + required: false + description: "url to post to if notify is true" diff --git a/laas/actions/set_ipmi_pass.yaml b/laas/actions/set_ipmi_pass.yaml new file mode 100644 index 0000000..ccd01a4 --- /dev/null +++ b/laas/actions/set_ipmi_pass.yaml @@ -0,0 +1,48 @@ +--- +############################################################################## +# Copyright 2018 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: set_ipmi_pass +runner_type: local-shell-script +entry_point: actions/set_ipmi_pass.sh +enabled: true +parameters: + user: + type: string + required: true + description: admin username + position: 0 + pass: + type: string + required: true + description: admin password + position: 1 + host: + type: string + required: true + description: ipmi address or hostname + position: 2 + mod_user: + type: string + required: false + default: "4" + description: user id of user to modify + position: 3 + pass_key: + type: string + required: true + description: stackstorm key containing password + position: 4 diff --git a/laas/actions/snapshot_master_workflow.yaml b/laas/actions/snapshot_master_workflow.yaml new file mode 100644 index 0000000..3c2457f --- /dev/null +++ b/laas/actions/snapshot_master_workflow.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. # +############################################################################## + +description: This is the workflow that will capture an image of the host +enabled: true +runner_type: mistral-v2 +entry_point: workflows/snapshot_master_workflow.yaml +name: snapshot_master_workflow +pack: laas +parameters: + job_id: + required: true + type: integer diff --git a/laas/actions/snapshot_task.yaml b/laas/actions/snapshot_task.yaml new file mode 100644 index 0000000..27d6eb9 --- /dev/null +++ b/laas/actions/snapshot_task.yaml @@ -0,0 +1,26 @@ +--- +############################################################################## +# Copyright 2018 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: snapshot_task +runner_type: python-script +entry_point: actions/snapshot_task.py +enabled: true +parameters: + snapshot_data: + type: string + required: true + description: "json from the dashbaord describing this task" diff --git a/laas/actions/snapshot_workflow.yaml b/laas/actions/snapshot_workflow.yaml new file mode 100644 index 0000000..25747ae --- /dev/null +++ b/laas/actions/snapshot_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. # +############################################################################## + +description: This is the workflow that will provision the host as requested. +enabled: true +runner_type: mistral-v2 +entry_point: workflows/snapshot_workflow.yaml +name: snapshot_workflow +pack: laas +parameters: + job_id: + required: true + type: integer + task_id: + required: true + type: string diff --git a/laas/actions/software_master_workflow.yaml b/laas/actions/software_master_workflow.yaml new file mode 100644 index 0000000..ad61391 --- /dev/null +++ b/laas/actions/software_master_workflow.yaml @@ -0,0 +1,27 @@ +--- +############################################################################## +# Copyright 2018 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/software_master_workflow.yaml +name: software_master_workflow +pack: laas +parameters: + job_id: + required: true + type: integer diff --git a/laas/actions/software_workflow.yaml b/laas/actions/software_workflow.yaml new file mode 100644 index 0000000..38d1c88 --- /dev/null +++ b/laas/actions/software_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. # +############################################################################## + +description: This is the workflow that will provision the host as requested. +enabled: true +runner_type: mistral-v2 +entry_point: workflows/software_workflow.yaml +name: software_workflow +pack: laas +parameters: + job_id: + required: true + type: integer + task_id: + required: true + type: string diff --git a/laas/actions/ssh_key_workflow.yaml b/laas/actions/ssh_key_workflow.yaml new file mode 100644 index 0000000..b9dbcc0 --- /dev/null +++ b/laas/actions/ssh_key_workflow.yaml @@ -0,0 +1,28 @@ +--- +############################################################################## +# Copyright 2018 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: ssh_key_workflow +enabled: true +runner_type: mistral-v2 +entry_point: workflows/ssh_key_workflow.yaml +parameters: + booking: + type: string + required: true + host: + type: string + required: true diff --git a/laas/actions/start_job.yaml b/laas/actions/start_job.yaml new file mode 100644 index 0000000..fdcfb50 --- /dev/null +++ b/laas/actions/start_job.yaml @@ -0,0 +1,25 @@ +--- +############################################################################## +# Copyright 2018 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: start_job +description: marks job as started internally +entry_point: actions/start_job.py +runner_type: python-script +parameters: + job_id: + type: integer + required: true diff --git a/laas/actions/start_task.yaml b/laas/actions/start_task.yaml new file mode 100644 index 0000000..16f81f0 --- /dev/null +++ b/laas/actions/start_task.yaml @@ -0,0 +1,28 @@ +--- +############################################################################## +# Copyright 2018 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: start_task +enabled: true +runner_type: python-script +entry_point: actions/start_task.py +parameters: + job_id: + type: integer + required: true + task_id: + type: string + required: true diff --git a/laas/actions/test_print.yaml b/laas/actions/test_print.yaml new file mode 100644 index 0000000..ac6d970 --- /dev/null +++ b/laas/actions/test_print.yaml @@ -0,0 +1,21 @@ +--- +############################################################################## +# Copyright 2019 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: test_print +enabled: true +runner_type: python-script +entry_point: actions/test_print.py diff --git a/laas/actions/update_bios_password.yaml b/laas/actions/update_bios_password.yaml new file mode 100644 index 0000000..52ce927 --- /dev/null +++ b/laas/actions/update_bios_password.yaml @@ -0,0 +1,30 @@ +--- +############################################################################## +# Copyright 2018 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_bios_password +entry_point: actions/update_bios_password.py +runner_type: python-script +enabled: true +parameters: + host: + type: string + required: true + description: ipmi hostname + password: + type: string + required: true + description: new password diff --git a/laas/actions/update_image_workflow.yaml b/laas/actions/update_image_workflow.yaml new file mode 100644 index 0000000..4934960 --- /dev/null +++ b/laas/actions/update_image_workflow.yaml @@ -0,0 +1,50 @@ +--- +############################################################################## +# Copyright 2019 Sawyer Bergeron 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_image_workflow +enabled: true +runner_type: orquesta +entry_point: workflows/update_image_workflow.yaml +# Caller note: provide one of [update_from_image, update_from_os] +# and optionally one of [update_into_image, update_into_os] in any combination +# if only one of [update_from_image, update_from_os] is provided, it is also +# used as the [update_into_x] target + +parameters: + host: + type: string + required: true + + update_from_image: + type: string + required: false + default: "None" + + update_into_image: + type: string + required: false + default: "None" + + update_from_os: + type: string + required: false + default: "None" + + update_into_os: + type: string + required: false + default: "None" diff --git a/laas/actions/wait_for_dhcp.yaml b/laas/actions/wait_for_dhcp.yaml new file mode 100644 index 0000000..bded28c --- /dev/null +++ b/laas/actions/wait_for_dhcp.yaml @@ -0,0 +1,26 @@ +--- +############################################################################## +# Copyright 2018 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: wait_for_dhcp +enabled: true +runner_type: remote-shell-script +entry_point: actions/wait_for_dhcp.sh +parameters: + mac: + type: string + required: true + position: 0 diff --git a/laas/actions/wait_for_host.yaml b/laas/actions/wait_for_host.yaml new file mode 100644 index 0000000..20214ea --- /dev/null +++ b/laas/actions/wait_for_host.yaml @@ -0,0 +1,26 @@ +--- +############################################################################## +# Copyright 2018 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: wait_for_host +entry_point: actions/wait_for_host.sh +enabled: true +runner_type: local-shell-script +parameters: + hostname: + type: string + required: true + position: 0 diff --git a/laas/actions/workflows/access_master_workflow.yaml b/laas/actions/workflows/access_master_workflow.yaml new file mode 100644 index 0000000..bccb7a2 --- /dev/null +++ b/laas/actions/workflows/access_master_workflow.yaml @@ -0,0 +1,61 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' +laas.access_master_workflow: + description: fulfills all access tasks from the dashboard + input: + - job_id + + tasks: + + get_tasks: + action: laas.get_task_list job_id=<% $.job_id %> type="access" + publish: + tasklist: <% task(get_tasks).result.result %> + on-success: + - get_start_index + + get_start_index: + action: core.local cmd="echo 0" + publish: + index: <% int(task(get_start_index).result.stdout) %> + on-success: + - finish: <% $.index >= len($.tasklist) %> + - access_task: <% $.index < len($.tasklist) %> + + loop: + action: core.local + input: + cmd: 'echo $((<% $.index %>+1))' + publish: + index: <% task(loop).result.stdout %> + on-success: + - finish: <% $.index >= len($.tasklist) %> + - access_task: <% $.index < len($.tasklist) %> + + access_task: + action: laas.access_workflow + input: + task_id: <% $.tasklist[$.index] %> + job_id: <% $.job_id %> + on-success: + - loop + + finish: + action: core.local cmd="exit 0" + on-success: succeed diff --git a/laas/actions/workflows/access_workflow.yaml b/laas/actions/workflows/access_workflow.yaml new file mode 100644 index 0000000..0563750 --- /dev/null +++ b/laas/actions/workflows/access_workflow.yaml @@ -0,0 +1,116 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' +laas.access_workflow: + description: fulfills a single access task from the dashboard + input: + - task_id + - job_id + + tasks: + + start_task: + action: laas.start_task + input: + task_id: <% $.task_id %> + job_id: <% $.job_id %> + on-success: get_task + + get_task: + action: laas.get_task + input: + task_id: <% $.task_id %> + job_id: <% $.job_id %> + type: "access" + publish: + task_data: <% task(get_task).result.result %> + lab_token: "null" + on-success: + - create_access: <% not $.task_data.get("revoke", false) %> + - remove_access: <% $.task_data.get("revoke", false) %> + + remove_access: + action: core.local cmd="exit 0" + on-success: + - delete_vpn_user: <% not $.task_data.get("lab_token") = "null" %> + + create_access: + action: core.local cmd="exit 0" + on-success: + - make_vpn_user: <% $.task_data.access_type = "vpn" %> + - make_ssh_access: <% $.task_data.access_type = "ssh" %> + + delete_vpn_user: + action: laas.vpn_delete_user key=<% $.task_data.lab_token %> + on-success: finish + on-error: task-error + + make_vpn_user: + action: laas.vpn_make_user + input: + job_id: <% str($.job_id) %> + publish: + vpn_key: <% task(make_vpn_user).result.result %> + lab_token: <% task(make_vpn_user).result.result %> + on-success: notify_vpn + on-error: task-error + + notify_vpn: + action: laas.notify_vpn_user + input: + vpn_key: <% $.vpn_key %> + job_id: <% str($.job_id) %> + task_id: <% $.task_id %> + on-success: finish + on-error: task-error + + make_ssh_access: + action: laas.copy_user_keys + input: + key: <% $.task_data.context.key %> + hosts: <% $.task_data.context.hosts.join(",") %> + publish: + lab_token: "null" + on-success: notify_ssh + on-error: task-error + + notify_ssh: + action: laas.notify_ssh_access + input: + hosts: <% $.task_data.context.hosts %> + user: "opnfv" + job_id: <% str($.job_id) %> + task_id: <% $.task_id %> + on-success: finish + on-error: task-error + + + finish: + action: laas.finish_task + input: + job_id: <% $.job_id %> + task_id: <% $.task_id %> + lab_token: <% $.lab_token %> + + task-error: + action: laas.error_task + input: + job_id: <% $.job_id %> + task_id: <% $.task_id %> + on-complete: + - fail diff --git a/laas/actions/workflows/apex_gambia_workflow.yaml b/laas/actions/workflows/apex_gambia_workflow.yaml new file mode 100644 index 0000000..967440b --- /dev/null +++ b/laas/actions/workflows/apex_gambia_workflow.yaml @@ -0,0 +1,45 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' +laas.apex_gambia_workflow: + description: the workflow to deploy apex version Gambia + input: + - hosts + - scenario + - virtual + + tasks: + check_virtual: + action: core.local cmd="exit 0" + on-success: + - virt_deploy: <% $.virtual %> + - hardware_deploy: <% not $.virtual %> + + virt_deploy: + action: laas.apex_gambia_virtual_deploy + input: + hosts: <% $.hosts[0].keys().first() %> + scenario: <% $.scenario %> + timeout: 7200 + retry: + count: 2 + on-success: + - succeed + + hardware_deploy: + action: core.local cmd="echo 'not implemented'" diff --git a/laas/actions/workflows/apex_master_workflow.yaml b/laas/actions/workflows/apex_master_workflow.yaml new file mode 100644 index 0000000..2878b4e --- /dev/null +++ b/laas/actions/workflows/apex_master_workflow.yaml @@ -0,0 +1,41 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' +laas.apex_master_workflow: + description: the workflow to install apex + input: + - hosts + - scenario + - virtual + - version + - jumphost + + tasks: + check_version: + action: core.local cmd="exit 0" + on-success: + - gambia: <% $.version = 7 %> + # More versions to come + # default? + + gambia: + action: laas.apex_gambia_workflow + input: + hosts: <% $.hosts %> + scenario: <% $.scenario %> + virtual: <% $.virtual %> diff --git a/laas/actions/workflows/bootBookedHostsWorkflow.yaml b/laas/actions/workflows/bootBookedHostsWorkflow.yaml new file mode 100644 index 0000000..63e872b --- /dev/null +++ b/laas/actions/workflows/bootBookedHostsWorkflow.yaml @@ -0,0 +1,46 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: "2.0" +laas.bootBookedHostsWorkflow: + description: "boots all booked hosts" + tasks: + detectHosts: + action: laas.detectHostsToBoot + on-success: getNextHost + + getNextHost: + action: laas.getNextHost + publish: + host: <% task(getNextHost).result.result %> + on-success: bootHost + on-error: exit + + bootHost: + action: laas.restart_workflow + input: + host: <% $.host %> + cmd: 'on' + ipmi: true + on-success: sleep + + sleep: + action: core.local cmd="sleep 45" + on-success: getNextHost + + exit: + action: core.local cmd="exit 0" diff --git a/laas/actions/workflows/check_power_workflow.yaml b/laas/actions/workflows/check_power_workflow.yaml new file mode 100644 index 0000000..52cdcf6 --- /dev/null +++ b/laas/actions/workflows/check_power_workflow.yaml @@ -0,0 +1,51 @@ +--- +############################################################################## +# Copyright 2019 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. # +############################################################################## + +version: '2.0' + +laas.check_power_workflow: + description: "Will use the ipmi to check power" + type: direct + input: + - host + + tasks: + + get_ipmi_hostname: + action: laas.get_ipmi_hostname host=<% $.host %> + publish: + ipmi_name: <% task(get_ipmi_hostname).result.result %> + on-success: get_ipmi_password + + get_ipmi_password: + action: laas.get_ipmi_password host=<% $.ipmi_name %> + publish: + password: <% task(get_ipmi_password).result.result %> + on-success: get_ipmi_username + + get_ipmi_username: + action: laas.get_ipmi_username host=<% $.ipmi_name %> + publish: + ipmi_user: <% task(get_ipmi_username).result.result %> + on-success: check_power_status + + check_power_status: + action: laas.check_ipmi_power + input: + host: <% $.ipmi_name %> + user: <% $.ipmi_user %> + pass: <% $.password %> diff --git a/laas/actions/workflows/compass_gambia_workflow.yaml b/laas/actions/workflows/compass_gambia_workflow.yaml new file mode 100644 index 0000000..3576739 --- /dev/null +++ b/laas/actions/workflows/compass_gambia_workflow.yaml @@ -0,0 +1,44 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' +laas.compass_gambia_workflow: + description: the workflow to deploy compass version Gambia + input: + - hosts + - scenario + - virtual + - subversion + + tasks: + check_virtual: + action: core.local cmd="exit 0" + on-success: + - hardware_deploy: <% not $.virtual %> + + virt_deploy: + action: laas.compass_gambia_virtual_deploy + input: + hosts: <% $.hosts[0].keys().first() %> + scenario: <% $.scenario %> + subversion: <% $.subversion %> + timeout: 7200 + on-success: + - succeed + + hardware_deploy: + action: core.local cmd="echo 'not implemented'" diff --git a/laas/actions/workflows/compass_master_workflow.yaml b/laas/actions/workflows/compass_master_workflow.yaml new file mode 100644 index 0000000..6dc06a1 --- /dev/null +++ b/laas/actions/workflows/compass_master_workflow.yaml @@ -0,0 +1,43 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' +laas.compass_master_workflow: + description: the workflow to install compass + input: + - hosts + - jumphost + - scenario + - virtual + - version + - subversion + + tasks: + check_version: + action: core.local cmd="exit 0" + on-success: + - gambia: <% $.version = 7 %> + # More versions to come + # default? + + gambia: + action: laas.compass_gambia_workflow + input: + hosts: <% $.hosts %> + scenario: <% $.scenario %> + virtual: <% $.virtual %> + subversion: <% $.subversion %> diff --git a/laas/actions/workflows/fog_snapshotWorkflow.yaml b/laas/actions/workflows/fog_snapshotWorkflow.yaml new file mode 100644 index 0000000..5f6d1ee --- /dev/null +++ b/laas/actions/workflows/fog_snapshotWorkflow.yaml @@ -0,0 +1,36 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +chain: + - + name: "createSnapshot" + ref: "laas.fog_createSnapshot" + parameters: + host: "{{host}}" + name: "{{name}}" + + - + name: "changeImage" + ref: "laas.fog_changeImage" + parameters: + host: "{{host}}" + snapshot: "{{name}}" + - + name: "startCapture" + ref: "laas.fog_captureWorkflow" + parameters: + host: "{{host}}" diff --git a/laas/actions/workflows/fuel_gambia_workflow.yaml b/laas/actions/workflows/fuel_gambia_workflow.yaml new file mode 100644 index 0000000..b7a758a --- /dev/null +++ b/laas/actions/workflows/fuel_gambia_workflow.yaml @@ -0,0 +1,77 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' +laas.fuel_gambia_workflow: + description: the workflow to deploy fuel version Gambia + input: + - hosts + - jumphost + - scenario + - virtual + - subversion + - pdf + - idf + + tasks: + check_virtual: + action: core.local cmd="exit 0" + on-success: + - prepare_virt_deploy: <% $.virtual %> + - start_hardware_deploy: <% not $.virtual %> + + prepare_virt_deploy: + action: laas.fuel_gambia_virtual_prepare + input: + host: <% $.hosts[0].keys().first() %> + on-success: virt_deploy + + virt_deploy: + action: laas.fuel_gambia_virtual_deploy + input: + roles: <% $.hosts[0].keys().first() %> + scenario: <% $.scenario %> + subversion: <% $.subversion %> + timeout: 7200 + on-success: + - succeed + + start_hardware_deploy: + action: laas.get_fuel_bridges + input: + hosts: <% $.hosts %> + publish: + bridges: <% task(start_hardware_deploy).result.result %> + on-success: + - prepare_hardware_deploy + + prepare_hardware_deploy: + action: laas.prepare_fuel_gambia_baremetal + input: + hosts: <% $.jumphost %> + mapping: <% $.bridges %> + timeout: 300 + on-success: + - hardware_deploy + + hardware_deploy: + action: laas.deploy_fuel_gambia_baremetal + input: + pdf: <% $.pdf %> + idf: <% $.idf %> + on-success: + - succeed diff --git a/laas/actions/workflows/fuel_master_workflow.yaml b/laas/actions/workflows/fuel_master_workflow.yaml new file mode 100644 index 0000000..aed839b --- /dev/null +++ b/laas/actions/workflows/fuel_master_workflow.yaml @@ -0,0 +1,44 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' +laas.fuel_master_workflow: + description: the workflow to install fuel + input: + - hosts + - jumphost + - scenario + - virtual + - version + - subversion + + tasks: + check_version: + action: core.local cmd="exit 0" + on-success: + - gambia: <% $.version = 7 %> + # More versions to come + # default? + + gambia: + action: laas.fuel_gambia_workflow + input: + hosts: <% $.hosts %> + jumphost: <% $.jumphost %> + scenario: <% $.scenario %> + virtual: <% $.virtual %> + subversion: <% $.subversion %> diff --git a/laas/actions/workflows/hardware_master_workflow.yaml b/laas/actions/workflows/hardware_master_workflow.yaml new file mode 100644 index 0000000..06b4bf9 --- /dev/null +++ b/laas/actions/workflows/hardware_master_workflow.yaml @@ -0,0 +1,42 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' +laas.hardware_master_workflow: + description: fulfills all hardware tasks from the dashboard + type: direct + input: + - job_id + + tasks: + + get_tasks: + action: laas.get_task_list + input: + job_id: <% $.job_id %> + type: "hardware" + publish: + tasklist: <% task(get_tasks).result.result %> + on-success: + - hardware_task + + hardware_task: + with-items: task_id in <% $.tasklist %> + action: laas.hardware_workflow + input: + task_id: <% $.task_id %> + job_id: <% $.job_id %> diff --git a/laas/actions/workflows/hardware_workflow.yaml b/laas/actions/workflows/hardware_workflow.yaml new file mode 100644 index 0000000..93feb3b --- /dev/null +++ b/laas/actions/workflows/hardware_workflow.yaml @@ -0,0 +1,170 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' +laas.hardware_workflow: + description: fulfills a single hardware task from the dashboard + input: + - task_id + - job_id + + tasks: + + start_task: + action: laas.start_task + input: + task_id: <% $.task_id %> + job_id: <% $.job_id %> + publish: + retry_count: <% int(0) %> + retry_max: <% int(1) %> + on-success: get_task + + get_task: + action: laas.get_task + input: + task_id: <% $.task_id %> + type: "hardware" + job_id: <% $.job_id %> + publish: + task_data: <% task(get_task).result.result %> + on-success: + - detect_tasks + + detect_tasks: + action: laas.detect_hardware_tasks + input: + job_id: <% $.job_id %> + task_id: <% $.task_id %> + publish: + todo_tasks: <% task(detect_tasks).result.result %> + on-success: prepare_host + + prepare_host: + action: laas.add_management_vlan + input: + hosts: <% list($.task_data.id) %> + on-complete: wait_for_ipmi + + wait_for_ipmi: + action: laas.get_ipmi_hostname host=<% $.task_data.id %> + publish: + ipmi_name: <% task(wait_for_ipmi).result.result %> + on-complete: ping_ipmi + + ping_ipmi: + action: laas.wait_for_host + input: + hostname: <% $.ipmi_name %> + timeout: 200 + on-complete: do_image + on-error: task_error + + do_image: + action: core.local cmd="exit 0" + on-success: + - set_boot: <% $.todo_tasks.get(image, false) %> + - do_hostname: <% not $.todo_tasks.get(image, false) %> + + set_boot: + action: laas.set_boot_workflow + input: + host: <% $.task_data.get(id) %> + on-success: image_host + on-error: task_error + + image_host: + action: laas.fog_imageWorkflow + input: + host: <% $.task_data.get(id) %> + image: <% str($.task_data.get(image)) %> + on-success: do_hostname + on-error: retry + + do_hostname: + action: core.local cmd="exit 0" + on-success: + - set_hostname: <% $.todo_tasks.get(hostname, false) %> + - do_ipmi: <% not $.todo_tasks.get(hostname, false) %> + + set_hostname: + action: laas.set_hostname + input: + hostname: <% $.task_data.get(hostname) %> + host: <% $.task_data.get(id) %> + on-error: task_error + on-success: do_ipmi + + do_ipmi: + action: core.local cmd="exit 0" + on-success: + - ipmi_create: <% $.todo_tasks.get(ipmi_create, false) %> + - do_power: <% not $.todo_tasks.get(ipmi_create, false) %> + + ipmi_create: + action: laas.set_ipmi_account_workflow + input: + host: <% $.task_data.get(id) %> + on-error: task_error + on-success: notify_ipmi + + notify_ipmi: + action: laas.notify_ipmi_workflow + input: + ipmi_key: "ipmiuser_<% $.task_data.get(id) %>" + job_id: <% $.job_id %> + task_id: <% $.task_id %> + ipmi_name: <% $.ipmi_name %> + host: <% $.task_data.get(id) %> + on-success: do_power + + do_power: + action: core.local cmd="exit 0" + on-success: + - power: <% $.todo_tasks.get(power, false) %> + - finish: <% not $.todo_tasks.get(power, false) %> + + power: + action: laas.restart_workflow + input: + host: <% $.task_data.get(id) %> + ipmi: true + cmd: <% $.task_data.get(power) %> + on-success: finish + on-error: task_error + + retry: + action: core.local cmd="exit 0" + publish: + retry_count: <% $.retry_count + 1 %> + on-success: + - set_boot: <% $.retry_count <= $.retry_max %> + - task_error: <% $.retry_count > $.retry_max %> + + finish: + action: laas.finish_task + input: + task_id: <% $.task_id %> + job_id: <% $.job_id %> + + task_error: + action: laas.error_task + input: + task_id: <% $.task_id %> + job_id: <% $.job_id %> + on-complete: + - fail diff --git a/laas/actions/workflows/jenkins_workflow.yaml b/laas/actions/workflows/jenkins_workflow.yaml new file mode 100644 index 0000000..77d32e5 --- /dev/null +++ b/laas/actions/workflows/jenkins_workflow.yaml @@ -0,0 +1,40 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' +laas.jenkins_workflow: + description: "workflow to send jenkins sandbox script to remote host" + input: + - host + + tasks: + gather_info: + action: laas.jenkins_info host=<% $.host %> + publish: + destination: <% task(gather_info).result.result.get(destination) %> + hostname: <% task(gather_info).result.result.get(hostname) %> + secret: <% task(gather_info).result.result.get(secret) %> + script: <% task(gather_info).result.result.get(script) %> + on-success: send_script + + send_script: + action: laas.send_jenkins_script + input: + destination: <% $.destination %> + hostname: <% $.hostname %> + secret: <% $.secret %> + script: <% $.script %> diff --git a/laas/actions/workflows/master_workflow.yaml b/laas/actions/workflows/master_workflow.yaml new file mode 100644 index 0000000..821cfb8 --- /dev/null +++ b/laas/actions/workflows/master_workflow.yaml @@ -0,0 +1,74 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' +laas.master_workflow: + description: master workflow to fulfill a job + input: + - job_id + + tasks: + start_job: + action: laas.start_job job_id=<% $.job_id %> + on-success: + - hardware_master_workflow + on-error: + - fail_job + + hardware_master_workflow: + action: laas.hardware_master_workflow job_id=<% $.job_id %> + on-success: + - network_master_workflow + on-error: + - fail_job + + network_master_workflow: + action: laas.network_master_workflow job_id=<% $.job_id %> + on-success: + - access_master_workflow + on-error: + - fail_job + + access_master_workflow: + action: laas.access_master_workflow job_id=<% $.job_id %> + on-success: + - software_master_workflow + on-error: + - fail_job + + software_master_workflow: + action: laas.software_master_workflow job_id=<% $.job_id %> + on-success: + - snapshot_master_workflow + on-error: + - fail_job + + snapshot_master_workflow: + action: laas.snapshot_master_workflow job_id=<% $.job_id %> + on-success: + - finish_job + on-error: + - fail_job + + fail_job: + action: laas.send_bot_failure + input: + job_id: <% $.job_id %> + execution_id: <% env().st2_execution_id %> + + finish_job: + action: laas.finish_job job_id=<% $.job_id %> diff --git a/laas/actions/workflows/network_master_workflow.yaml b/laas/actions/workflows/network_master_workflow.yaml new file mode 100644 index 0000000..819759c --- /dev/null +++ b/laas/actions/workflows/network_master_workflow.yaml @@ -0,0 +1,74 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' +laas.network_master_workflow: + description: fulfills all network tasks from the dashboard + input: + - job_id + + tasks: + + get_tasks: + action: laas.get_task_list + input: + job_id: <% $.job_id %> + type: "network" + publish: + tasklist: <% task(get_tasks).result.result %> + on-success: + - get_start_index + + get_start_index: + action: core.local cmd="echo 0" + publish: + index: <% int(task(get_start_index).result.stdout) %> + on-success: + - finish: <% $.index >= len($.tasklist) %> + - network_task: <% $.index < len($.tasklist) %> + + loop: + action: core.local + input: + cmd: 'echo $((<% $.index %>+1))' + publish: + index: <% int(task(loop).result.stdout) %> + on-success: + - finish: <% $.index >= len($.tasklist) %> + - network_task: <% $.index < len($.tasklist) %> + + network_task: + action: laas.network_workflow + input: + task_id: <% $.tasklist[$.index] %> + job_id: <% $.job_id %> + on-success: + - loop + on-error: + - retry_network_task + + retry_network_task: + action: laas.network_workflow + input: + task_id: <% $.tasklist[$.index] %> + job_id: <% $.job_id %> + on-success: + - loop + + finish: + action: core.local cmd="exit 0" + on-success: succeed diff --git a/laas/actions/workflows/network_workflow.yaml b/laas/actions/workflows/network_workflow.yaml new file mode 100644 index 0000000..db24fcf --- /dev/null +++ b/laas/actions/workflows/network_workflow.yaml @@ -0,0 +1,157 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' +laas.network_workflow: + input: + - task_id + - job_id + - to_configure_host + + tasks: + + start_task: + action: laas.start_task + input: + task_id: <% $.task_id %> + job_id: <% $.job_id %> + on-success: get_task + + get_task: + action: laas.get_task + input: + task_id: <% $.task_id %> + type: "network" + job_id: <% $.job_id %> + publish: + task_data: <% task(get_task).result.result %> + on-success: + - parse_data: <% to_configure_host %> + - configure_switch: <% not to_configure_host %> + + parse_data: + action: laas.parse_network_data task_data=<% $.task_data %> + publish: + mappings: <% task(parse_data).result.result.mappings %> + default: <% task(parse_data).result.result.default %> + host: <% task(parse_data).result.result.host %> + empty: <% task(parse_data).result.result.empty %> + on-success: + - prepare_host: <% not bool($.empty) %> + - configure_switch: <% bool($.empty) %> + on-error: task_error + + prepare_host: + action: laas.add_management_vlan + input: + hosts: <% $.task_data.keys() %> + on-success: wait_for_host + on-error: task_error + + wait_for_host: + action: laas.waitForBoot host=<% $.host %> timeout=1200 + on-success: configure_host + on-error: task_error + + configure_host: + action: laas.configure_host_networking + input: + mapping: <% $.mappings %> + default: <% $.default %> + hosts: <% $.host %> + on-success: configure_switch + on-error: task_error + + configure_switch: + action: laas.network_task network_data=<% $.task_data %> + on-success: + - wait_for_ipmi: <% not bool($.empty) %> + - finish: <% bool($.empty) %> + on-error: task_error + + wait_for_ipmi: + action: laas.get_ipmi_hostname host=<% $.host %> + publish: + ipmi_name: <% task(wait_for_ipmi).result.result %> + on-success: wait_for_ipmi_connection + + wait_for_ipmi_connection: + action: laas.wait_for_host + input: + hostname: <% $.ipmi_name %> + timeout: 300 + on-success: restart_host + + restart_host: + action: laas.restart_workflow + input: + host: <% $.host %> + on-success: second_wait_for_host + on-error: task_error + + second_wait_for_host: + action: laas.waitForBoot host=<% $.host %> timeout=1200 + on-success: find_address + on-error: task_error + + find_address: + action: laas.get_dhcp_address + input: + host: <% $.host %> + publish: + address: <% task(find_address).result.stdout %> + on-success: notify_ip + on-error: retry_find_address + + retry_find_address: + action: core.local + input: + cmd: sleep 30 + on-complete: second_find_address + + second_find_address: + action: laas.get_dhcp_address + input: + host: <% $.host %> + publish: + address: <% task(second_find_address).result.stdout %> + on-success: notify_ip + on-error: task_error + + notify_ip: + action: laas.notify_ip_address + input: + addresses: <% $.address %> + hostname: <% $.host %> + job_id: <% $.job_id %> + task_id: <% $.task_id %> + on-success: finish + on-error: task_error + + finish: + action: laas.finish_task + input: + task_id: <% $.task_id %> + job_id: <% $.job_id %> + + task_error: + action: laas.error_task + input: + task_id: <% $.task_id %> + job_id: <% $.job_id %> + on-complete: + - fail diff --git a/laas/actions/workflows/notify_ipmi_workflow.yaml b/laas/actions/workflows/notify_ipmi_workflow.yaml new file mode 100644 index 0000000..42d3a66 --- /dev/null +++ b/laas/actions/workflows/notify_ipmi_workflow.yaml @@ -0,0 +1,61 @@ +--- +############################################################################## +# Copyright 2019 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. # +############################################################################## + +version: '2.0' +laas.notify_ipmi_workflow: + description: ipmi notification workflow + input: + - ipmi_key + - job_id + - task_id + - ipmi_name + - host + + tasks: + resolve_ipmi: + action: laas.resolve_host hostname=<% $.ipmi_name %> + publish: + ipmi_ip: <% task(resolve_ipmi).result.stdout %> + on-success: notify_ipmi_user + + notify_ipmi_user: + action: laas.notify_ipmi_user + input: + ipmi_key: <% $.ipmi_key %> + job_id: <% $.job_id %> + task_id: <% $.task_id %> + hostname: <% $.ipmi_name %> + addr: <% $.ipmi_ip %> + on-success: get_ipmi_mac + + get_ipmi_mac: + action: laas.get_mac_from_ip + input: + host: <% $.ipmi_ip %> + gateway: "10.10.29.1" + user: "st2" + publish: + ipmi_mac: <% task(get_ipmi_mac).result.stdout %> + on-success: notify_ipmi_api + + notify_ipmi_api: + action: laas.notify_ipmi_api + input: + ipmi_key: <% $.ipmi_key %> + addr: <% $.ipmi_ip %> + mac: <% $.ipmi_mac %> + host: <% $.host %> diff --git a/laas/actions/workflows/opnfv_master_workflow.yaml b/laas/actions/workflows/opnfv_master_workflow.yaml new file mode 100644 index 0000000..f25f087 --- /dev/null +++ b/laas/actions/workflows/opnfv_master_workflow.yaml @@ -0,0 +1,72 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' +laas.opnfv_master_workflow: + description: The master workflow to provision, install, deploy hosts + input: + - hosts + - installer + - scenario + - virtual + - version + - subversion + - pdf + - idf + tasks: + find_jumphost: + action: laas.get_jumphost hosts=<% $.hosts %> + publish: + jumphost: <% task(find_jumphost).result.result %> + on-success: + - install_fuel: <% $.installer.toLower() = 'fuel' %> + - install_apex: <% $.installer.toLower() = 'apex' %> + - install_compass: <% $.installer.toLower() = 'compass' %> + + install_fuel: + action: laas.fuel_master_workflow + input: + hosts: <% $.hosts %> + jumphost: <% $.jumphost %> + scenario: <% $.scenario %> + virtual: <% $.virtual %> + version: <% $.version %> + subversion: <% $.subversion %> + pdf: <% $.pdf %> + idf: <% $.idf %> + on-success: succeed + + install_apex: + action: laas.apex_master_workflow + input: + hosts: <% $.hosts %> + jumphost: <% $.jumphost %> + scenario: <% $.scenario %> + virtual: <% $.virtual %> + version: <% $.version %> + on-success: succeed + + install_compass: + action: laas.compass_master_workflow + input: + hosts: <% $.hosts %> + jumphost: <% $.jumphost %> + scenario: <% $.scenario %> + virtual: <% $.virtual %> + version: <% $.version %> + subversion: <% $.subversion %> + on-success: succeed diff --git a/laas/actions/workflows/provision_workflow.yaml b/laas/actions/workflows/provision_workflow.yaml new file mode 100644 index 0000000..e51facb --- /dev/null +++ b/laas/actions/workflows/provision_workflow.yaml @@ -0,0 +1,37 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' +laas.provision_workflow: + description: Prepares and images a host + input: + - host + - os + - image + - hostname + tasks: + set_boot: + action: laas.set_boot_workflow host=<% $.host %> + on-success: set_ipmi + + image_host: + action: laas.fog_imageWorkflow + input: + host: <% $.host %> + os: <% $.os %> + image: <% $.image %> + on-success: inject_ssh_keys diff --git a/laas/actions/workflows/restart_workflow.yaml b/laas/actions/workflows/restart_workflow.yaml new file mode 100644 index 0000000..bd30b1c --- /dev/null +++ b/laas/actions/workflows/restart_workflow.yaml @@ -0,0 +1,59 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' +laas.restart_workflow: + description: restarts given host, using ipmi if asked + input: + - host + - ipmi + - cmd + tasks: + branch: + action: core.local cmd="exit 0" + on-success: + - get_ipmi_hostname: <% $.ipmi = true %> + - restart: <% $.ipmi = false %> + + get_ipmi_hostname: + action: laas.get_ipmi_hostname host=<% $.host %> + publish: + ipmi_name: <% task(get_ipmi_hostname).result.result %> + on-success: get_ipmi_password + + get_ipmi_password: + action: laas.get_ipmi_password host=<% $.ipmi_name %> + publish: + password: <% task(get_ipmi_password).result.result %> + on-success: get_ipmi_username + + get_ipmi_username: + action: laas.get_ipmi_username host=<% $.ipmi_name %> + publish: + username: <% task(get_ipmi_username).result.result %> + on-success: ipmi_restart + + ipmi_restart: + action: laas.ipmi_restartHost + input: + host: <% $.ipmi_name %> + user: <% $.username %> + password: <% $.password %> + cmd: <% $.cmd %> + + restart: + action: laas.restartHost host=<% $.host %> diff --git a/laas/actions/workflows/set_boot_workflow.yaml b/laas/actions/workflows/set_boot_workflow.yaml new file mode 100644 index 0000000..53529b6 --- /dev/null +++ b/laas/actions/workflows/set_boot_workflow.yaml @@ -0,0 +1,60 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' + +laas.set_boot_workflow: + description: "Will set the host's boot option to the correct pxe option" + type: direct + input: + - host + + tasks: + + get_ipmi_hostname: + action: laas.get_ipmi_hostname host=<% $.host %> + publish: + ipmi_name: <% task(get_ipmi_hostname).result.result %> + on-success: get_ipmi_password + + get_ipmi_password: + action: laas.get_ipmi_password host=<% $.ipmi_name %> + publish: + password: <% task(get_ipmi_password).result.result %> + on-success: get_host_type + + get_host_type: + action: laas.get_host_type host=<% $.host %> + publish: + type: <% task(get_host_type).result.result %> + on-success: + - hpe: <% $.type = "hpe" %> + - arm: <% $.type = "arm" %> + + hpe: + action: laas.set_hpe_boot + input: + user: "Administrator" + passwd: <% $.password %> + host: <% $.ipmi_name %> + + arm: + action: laas.set_arm_boot + input: + user: "ADMIN" + passwd: <% $.password %> + host: <% $.ipmi_name %> diff --git a/laas/actions/workflows/set_hpe_bios_pass_workflow.yaml b/laas/actions/workflows/set_hpe_bios_pass_workflow.yaml new file mode 100644 index 0000000..d17413e --- /dev/null +++ b/laas/actions/workflows/set_hpe_bios_pass_workflow.yaml @@ -0,0 +1,68 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' + +laas.set_hpe_bios_pass_workflow: + description: "Will set the password for the bios" + type: direct + input: + - host + - password + + tasks: + + get_ipmi_hostname: + action: laas.get_ipmi_hostname host=<% $.host %> + publish: + ipmi_name: <% task(get_ipmi_hostname).result.result %> + on-success: get_ipmi_password + + get_ipmi_password: + action: laas.get_ipmi_password host=<% $.ipmi_name %> + publish: + ipmi_password: <% task(get_ipmi_password).result.result %> + on-success: get_ipmi_username + + get_ipmi_username: + action: laas.get_ipmi_username host=<% $.ipmi_name %> + publish: + ipmi_user: <% task(get_ipmi_username).result.result %> + on-success: get_bios_password + + get_bios_password: + action: laas.get_bios_password host=<% $.ipmi_name %> + publish: + bios_password: <% task(get_bios_password).result.result %> + on-success: set_hpe_bios_pass + + + set_hpe_bios_pass: + action: laas.set_hpe_bios_pass + input: + host: <% $.ipmi_name %> + user: <% $.ipmi_user %> + adminPass: <% $.ipmi_password %> + oldPass: <% $.bios_password %> + newPass: <% $.password %> + on-success: update_db + + update_db: + action: laas.update_bios_password + input: + host: <% $.host %> + password: <% $.password %> diff --git a/laas/actions/workflows/set_ipmi_account_workflow.yaml b/laas/actions/workflows/set_ipmi_account_workflow.yaml new file mode 100644 index 0000000..0c5c0f1 --- /dev/null +++ b/laas/actions/workflows/set_ipmi_account_workflow.yaml @@ -0,0 +1,61 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' + +laas.set_ipmi_account_workflow: + description: "Will set the password for the ipmi account on the host" + type: direct + input: + - host + - notify_user + - url + + tasks: + + get_ipmi_hostname: + action: laas.get_ipmi_hostname host=<% $.host %> + publish: + ipmi_name: <% task(get_ipmi_hostname).result.result %> + on-success: get_ipmi_password + + get_ipmi_password: + action: laas.get_ipmi_password host=<% $.ipmi_name %> + publish: + password: <% task(get_ipmi_password).result.result %> + on-success: get_ipmi_username + + get_ipmi_username: + action: laas.get_ipmi_username host=<% $.ipmi_name %> + publish: + ipmi_user: <% task(get_ipmi_username).result.result %> + on-success: gen_pass + + gen_pass: + action: laas.genPass + input: + key: "ipmiuser_<% $.host %>" + length: 15 + on-success: set_ipmi_pass + + set_ipmi_pass: + action: laas.set_ipmi_pass + input: + user: <% $.ipmi_user %> + pass: <% $.password %> + host: <% $.ipmi_name %> + pass_key: "ipmiuser_<% $.host %>" diff --git a/laas/actions/workflows/snapshot_master_workflow.yaml b/laas/actions/workflows/snapshot_master_workflow.yaml new file mode 100644 index 0000000..4964003 --- /dev/null +++ b/laas/actions/workflows/snapshot_master_workflow.yaml @@ -0,0 +1,64 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' +laas.snapshot_master_workflow: + description: fulfills all snapshot tasks from the dashboard + input: + - job_id + + tasks: + + get_tasks: + action: laas.get_task_list + input: + job_id: <% $.job_id %> + type: "snapshot" + publish: + tasklist: <% task(get_tasks).result.result %> + on-success: + - get_start_index + + get_start_index: + action: core.local cmd="echo 0" + publish: + index: <% int(task(get_start_index).result.stdout) %> + on-success: + - finish: <% $.index >= len($.tasklist) %> + - snapshot_task: <% $.index < len($.tasklist) %> + + loop: + action: core.local + input: + cmd: 'echo $((<% $.index %>+1))' + publish: + index: <% task(loop).result.stdout %> + on-success: + - finish: <% $.index >= len($.tasklist) %> + - snapshot_task: <% $.index < len($.tasklist) %> + + snapshot_task: + action: laas.snapshot_workflow + input: + task_id: <% $.tasklist[$.index] %> + job_id: <% $.job_id %> + on-success: + - loop + + finish: + action: core.local cmd="exit 0" + on-success: succeed diff --git a/laas/actions/workflows/snapshot_workflow.yaml b/laas/actions/workflows/snapshot_workflow.yaml new file mode 100644 index 0000000..0babf84 --- /dev/null +++ b/laas/actions/workflows/snapshot_workflow.yaml @@ -0,0 +1,71 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' +laas.snapshot_workflow: + input: + - task_id + - job_id + + tasks: + + start_task: + action: laas.start_task + input: + task_id: <% $.task_id %> + job_id: <% $.job_id %> + on-success: get_task + + get_task: + action: laas.get_task + input: + task_id: <% $.task_id %> + type: "snapshot" + job_id: <% $.job_id %> + publish: + task_data: <% task(get_task).result.result %> + on-success: snapshot_task + + snapshot_task: + action: laas.fog_snapshotWorkflow + input: + name: <% concat("snapshot_", str($.task_data.dashboard_id) + host: <% $.task_data.host %> + publish: + snapshot_id: <% task(snapshot_task).result.result.snapshot_id %> + host: <% task(snapshot_task).result.result.host %> + on-success: finish + on-error: retry + + finish: + action: laas.finish_task + input: + task_id: <% $.task_id %> + job_id: <% $.job_id %> + + retry: + action: core.local cmd="exit 0" + on-success: finish + on-error: task_error + + task_error: + action: laas.error_task + input: + task_id: <% $.task_id %> + job_id: <% $.job_id %> + on-complete: + - fail diff --git a/laas/actions/workflows/software_master_workflow.yaml b/laas/actions/workflows/software_master_workflow.yaml new file mode 100644 index 0000000..51c63b4 --- /dev/null +++ b/laas/actions/workflows/software_master_workflow.yaml @@ -0,0 +1,70 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' +laas.software_master_workflow: + description: fulfills all software tasks from the dashboard + input: + - job_id + + tasks: + + jenkins: + action: core.local + input: + cmd: "echo 'use laas.jenkins_workflow'" + on-complete: get_tasks + + get_tasks: + action: laas.get_task_list + input: + job_id: <% $.job_id %> + type: "software" + publish: + tasklist: <% task(get_tasks).result.result %> + on-success: + - get_start_index + + get_start_index: + action: core.local cmd="echo 0" + publish: + index: <% int(task(get_start_index).result.stdout) %> + on-success: + - finish: <% $.index >= len($.tasklist) %> + - software_task: <% $.index < len($.tasklist) %> + + loop: + action: core.local + input: + cmd: 'echo $((<% $.index %>+1))' + publish: + index: <% task(loop).result.stdout %> + on-success: + - finish: <% $.index >= len($.tasklist) %> + - software_task: <% $.index < len($.tasklist) %> + + software_task: + action: laas.software_workflow + input: + task_id: <% $.tasklist[$.index] %> + job_id: <% $.job_id %> + on-complete: + - loop + + finish: + action: core.local cmd="exit 0" + on-success: succeed diff --git a/laas/actions/workflows/software_workflow.yaml b/laas/actions/workflows/software_workflow.yaml new file mode 100644 index 0000000..4f22117 --- /dev/null +++ b/laas/actions/workflows/software_workflow.yaml @@ -0,0 +1,90 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' +laas.software_workflow: + description: fulfills a software install job + input: + - task_id + - job_id + + tasks: + + start_task: + action: laas.start_task + input: + task_id: <% $.task_id %> + job_id: <% $.job_id %> + on-success: get_task + + get_task: + action: laas.get_task + input: + job_id: <% $.job_id %> + task_id: <% $.task_id %> + type: "software" + publish: + task_data: <% task(get_task).result.result %> + on-success: + - software_task + + software_task: + action: core.local cmd="exit 0" + on-success: + - opnfv_install: <% $.task_data.containsKey("opnfv") + and $.task_data.opnfv.containsKey("installer") %> + on-error: retry + + opnfv_install: + action: laas.get_xdf + input: + task_data: <% $.task_data %> + publish: + pdf: <% task(opnfv_install).result.result.pdf %> + idf: <% task(opnfv_install).result.result.idf %> + on-success: + start_opnfv_install + + start_opnfv_install: + action: laas.opnfv_master_workflow + input: + hosts: <% $.task_data.opnfv.get("roles") %> + installer: <% $.task_data.opnfv.get("installer") %> + scenario: <% $.task_data.opnfv.get("scenario") %> + virtual: <% len($.task_data.opnfv.get("roles", [])) = 1 %> + pdf: <% $.pdf %> + idf: <% $.idf %> + on-complete: finish + + finish: + action: laas.finish_task + input: + task_id: <% $.task_id %> + job_id: <% $.job_id %> + + retry: + action: core.local cmd="exit 0" + on-success: software_task + on-error: task_error + + task_error: + action: laas.error_task + input: + task_id: <% $.task_id %> + job_id: <% $.job_id %> + on-complete: + - fail diff --git a/laas/actions/workflows/ssh_key_workflow.yaml b/laas/actions/workflows/ssh_key_workflow.yaml new file mode 100644 index 0000000..b8f5255 --- /dev/null +++ b/laas/actions/workflows/ssh_key_workflow.yaml @@ -0,0 +1,33 @@ +--- +############################################################################## +# Copyright 2018 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. # +############################################################################## + +version: '2.0' +laas.ssh_key_workflow: + description: "workflow to inject user's keys from the dashboard" + input: + - booking + - host + + tasks: + get_key: + action: laas.find_user_keys booking=<% $.booking %> + publish: + url: <% task(get_key).result.result %> + on-success: inject_key + + inject_key: + action: laas.copy_user_keys url=<% $.url %> host=<% $.host %> diff --git a/laas/actions/workflows/update_image_workflow.yaml b/laas/actions/workflows/update_image_workflow.yaml new file mode 100644 index 0000000..812b829 --- /dev/null +++ b/laas/actions/workflows/update_image_workflow.yaml @@ -0,0 +1,100 @@ +--- +############################################################################## +# Copyright 2019 Sawyer Bergeron 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. # +############################################################################## + +version: 1.0 + +description: "Updates the given image using the given host for scratch space" +input: + - host # stackstorm recognized host handle + - update_from_image # image to apply to the host and update + - update_from_os # os to apply to the host and update + - update_into_image # image to save the updated image into + - update_into_os # os to save the updated image into +tasks: + get_target_image: # primary entry point + action: laas.fog_getTargetImage + input: + host: <% ctx().host %> + from_image: <% ctx().update_from_image %> + from_os: <% ctx().update_from_os %> + target_image: <% ctx().update_into_image %> + target_os: <% ctx().update_into_os %> + next: + - when: <% succeeded() %> + publish: + - target_image: <% result().result %> + do: prepare_host + + prepare_host: + action: laas.add_management_vlan + input: + hosts: <% list(ctx().host) %> + next: + - when: <% succeeded() %> + do: get_ipmi_name + + get_ipmi_name: + action: laas.get_ipmi_hostname + input: + host: <% ctx().host %> + next: + - when: <% succeeded() %> + publish: + - ipmi_name: <% result().result %> + do: ping_ipmi + + ping_ipmi: + action: laas.wait_for_host + input: + hostname: <% ctx().ipmi_name %> + timeout: 200 + next: + - when: <% succeeded() %> + do: set_boot + + set_boot: + action: laas.set_boot_workflow + input: + host: <% ctx().host %> + next: + - when: <% succeeded %> + do: image_host + + image_host: + action: laas.fog_imageWorkflow + input: + host: <% ctx().host %> + image: <% ctx().update_from_image %> + os: <% ctx().update_from_os %> + next: + - when: <% succeeded() %> + do: run_updates + + run_updates: + action: laas.update + input: + hosts: <% ctx().host %> + timeout: 900 + next: + - when: <% succeeded() %> + do: capture_image + + capture_image: # exit node + action: laas.fog_captureWorkflow + input: + host: <% ctx().host %> + image: <% ctx().target_image %> diff --git a/laas/aliases/imaging_alias.yaml b/laas/aliases/imaging_alias.yaml new file mode 100644 index 0000000..eba4b9a --- /dev/null +++ b/laas/aliases/imaging_alias.yaml @@ -0,0 +1,11 @@ +--- +name: imaging_alias +pack: laas +action_ref: laas.fog_imageWorkflow +formats: + - "(image|provision|ghost) {{host}}" + - "(image|provision|ghost) {{host}} using image {{image}}" + - "(image|provision|ghost) {{host}} with {{os}}" + - "(image|provision|ghost) {{host}} without ipmi {{ipmi=false}}" + - "(image|provision|ghost) {{host}} using image {{image}} without ipmi {{ipmi=false}}" + - "(image|provision|ghost) {{host}} with {{os}} without ipmi {{ipmi=false}}" diff --git a/laas/aliases/power_alias.yaml b/laas/aliases/power_alias.yaml new file mode 100644 index 0000000..b584573 --- /dev/null +++ b/laas/aliases/power_alias.yaml @@ -0,0 +1,11 @@ +--- +name: power_alias.yaml +pack: laas +action_ref: laas.restart_workflow +formats: + - "restart {{host}} {{cmd=cycle}}" + - "restart {{host}} without ipmi {{cmd=cycle}} {{ipmi=false}}" + - "boot {{host}} {{cmd=on}}" + - "boot {{host}} without ipmi {{cmd=on}} {{ipmi=false}}" + - "(shutdown|poweroff) {{host}} {{cmd=off}}" + - "(shutdown|poweroff) {{host}} without ipmi {{cmd=off}} {{ipmi=false}}" diff --git a/laas/laas.yaml.example b/laas/laas.yaml.example index 954e0d7..ce8a9cb 100644 --- a/laas/laas.yaml.example +++ b/laas/laas.yaml.example @@ -16,3 +16,13 @@ vpn: objects: - top - inetOrgPerson + +bot: + address: "http://my-bot.com/endpoint" + endpoints: + notification: "/notification" + failure: "/failure" + +dashboard: + address: "https://labs.lfnetworking.org" + lab_name: "MY_LAB" diff --git a/laas/rules/job.yaml b/laas/rules/job.yaml new file mode 100644 index 0000000..4bdf0fc --- /dev/null +++ b/laas/rules/job.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: on_job_trigger +pack: laas +description: "rule to link deployment trigger to deployment action" +enabled: true +trigger: + type: laas.start_job_trigger +action: + ref: laas.master_workflow + parameters: + job_id: "{{ trigger.job_id }}" diff --git a/laas/rules/notify_bot.yaml b/laas/rules/notify_bot.yaml new file mode 100644 index 0000000..6d7bd7f --- /dev/null +++ b/laas/rules/notify_bot.yaml @@ -0,0 +1,20 @@ +--- +name: "notify_bot" +pack: "laas" +description: "sends a notification to the registered chat bot" +enabled: true + +trigger: + type: "core.st2.generic.notifytrigger" + parameters: {} + +criteria: + trigger.channel: + pattern: "chatbot" + type: "equals" + +action: + ref: "laas.send_bot_notification" + parameters: + message: "{{trigger.message}}" + execution_id: "{{trigger.data.execution_id}}" diff --git a/laas/sensors/laas.py b/laas/sensors/laas.py index 5d17fb2..29ce505 100755..100644 --- a/laas/sensors/laas.py +++ b/laas/sensors/laas.py @@ -1,5 +1,5 @@ ############################################################################## -# Copyright 2017 Parker Berberian and Others # +# Copyright 2018 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. # @@ -13,214 +13,47 @@ # 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) +class LaaS_Sensor(PollingSensor): - 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 setup(self): + self.logger = self.sensor_service.get_logger(name=self.__class__.__name__) + self.auth_token = self.sensor_service.get_value(name="lab_auth_token", local=False) + self.logger.info("got auth token %s", self.auth_token) - def getBooking(self, booking_id): - name = "booking_" + str(booking_id) - return json.loads( - self.sensor_service.get_value( - name=name, + def poll(self): + try: + jobs = json.loads(self.sensor_service.get_value("jobs", local=False)) + dashboard = self._config['dashboard']['address'] + name = self._config['dashboard']['lab_name'] + url = dashboard + "/api/labs/" + name + "/jobs/new" + self.logger.info("polling at url %s", url) + header = {"auth-token": self.auth_token} + todo_jobs = requests.get(url, timeout=10, headers=header).json() + for job_data in todo_jobs: + if job_data['id'] in jobs: + continue + self.logger.info("doing job %s", str(job_data['id'])) + # put job into datastore for workflow + self.sensor_service.set_value( + "job_" + str(job_data['id']), + json.dumps(job_data['payload']), 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 + # dispatch trigger + self.sensor_service.dispatch( + trigger="laas.start_job_trigger", + payload={"job_id": job_data['id']} ) - - 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) + except Exception as e: + self.logger.exception("Failed to poll(): %s", str(e)) # 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 diff --git a/laas/sensors/dashboard_listener.yaml b/laas/sensors/laas.yaml index b83d412..fe6b171 100644 --- a/laas/sensors/dashboard_listener.yaml +++ b/laas/sensors/laas.yaml @@ -1,6 +1,6 @@ --- ############################################################################## -# Copyright 2017 Parker Berberian and Others # +# Copyright 2018 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. # @@ -15,31 +15,16 @@ # limitations under the License. # ############################################################################## -class_name: "Laas_api" -entry_point: "lass.py" +class_name: "LaaS_Sensor" +entry_point: "laas.py" description: "polls the dashboard api for deployments" -poll_interval: 30 +poll_interval: 60 trigger_types: - - name: "start_deployment_trigger" + name: "start_job_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" + job_id: + type: integer diff --git a/laas/tests/test_action_add_management_vlan.py b/laas/tests/test_action_add_management_vlan.py new file mode 100644 index 0000000..608e3d8 --- /dev/null +++ b/laas/tests/test_action_add_management_vlan.py @@ -0,0 +1,87 @@ +############################################################################## +# Copyright 2019 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 st2tests.base import BaseActionTestCase +from actions.actions import add_management_vlan +import json +import mock + + +class ManagementVlanTest(BaseActionTestCase): + action_cls = add_management_vlan.ManagementVlanAction + + def setUp(self): + super(ManagementVlanTest, self).setUp() + self.action = self.get_action_instance() + host_info = { + "interfaces": { + "mac1": { + "mac": "mac1", + "bus": "bus1", + "switch": "switch1", + "port": "Ethernet1/1", + "name": "ifname1" + }, + "mac2": { + "mac": "mac2", + "bus": "bus2", + "switch": "switch1", + "port": "Ethernet1/2", + "name": "ifname2" + } + } + } + self.action.action_service.set_value("host1", json.dumps(host_info), local=False) + switch_info = {"user": "user", "password": "password"} + self.action.action_service.set_value("switch_switch1", json.dumps(switch_info), local=False) + + def hasConsecutiveCalls(self, args, mock_obj): + """ + args is a list of arguments as tuples. This method asserts that + mock was called with those arguments in that order + """ + if len(args) < 1: + return True + for call_index in range(len(mock_obj.call_args_list)): + arg_index = 0 + while mock_obj.call_args_list[call_index] == (args[arg_index],): + call_index += 1 + arg_index += 1 + if arg_index == len(args): + return True + return False + + def test_vlans(self): + with mock.patch('actions.actions.add_management_vlan.NXCommand') as Mocked: + self.action.run(["host1"]) + self.assertTrue(Mocked.called) + + # assert that the correct commands are run in order for each interface + # but we dont care about the order of the interfaces + mocked = Mocked.return_value + self.assertTrue(mocked.add_command.called) + expected_calls = [ + ("interface Ethernet1/1",), + ("switchport mode trunk",), + ("switchport trunk allowed vlan 98,99",), + ("switchport trunk native vlan 98",), + ] + self.assertTrue(self.hasConsecutiveCalls(expected_calls, mocked.add_command)) + + expected_calls[0] = ("interface Ethernet1/2",) + self.assertTrue(self.hasConsecutiveCalls(expected_calls, mocked.add_command)) + + self.assertEqual(mocked.add_command.call_count, 8) + self.assertEqual(Mocked.call_count, mocked.execute.call_count) diff --git a/laas/tests/test_action_detectHostsToBoot.py b/laas/tests/test_action_detectHostsToBoot.py new file mode 100644 index 0000000..d7a990e --- /dev/null +++ b/laas/tests/test_action_detectHostsToBoot.py @@ -0,0 +1,74 @@ +############################################################################## +# Copyright 2019 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 st2tests.base import BaseActionTestCase +from actions.actions import detectHostsToBoot +import json +import responses + + +class DetectHostsTest(BaseActionTestCase): + action_cls = detectHostsToBoot.DetectHostsAction + + def setUp(self): + super(DetectHostsTest, self).setUp() + # this is not documented + self.action_service.set_value("lab_auth_token", "my_auth_token", local=False) + self.action = self.get_action_instance(config={ + "dashboard": { + "address": "http://my.dashboard.com", + "lab_name": "my_lab" + } + }) + self.hosts_url = "http://my.dashboard.com/api/labs/my_lab/hosts/" + self.action.action_service.set_value("hosts_to_boot", "[]", local=False) + + def hostDetected(self, host): + detected_hosts = json.loads(self.action.action_service.get_value("hosts_to_boot", local=False)) + return host in detected_hosts + + @responses.activate + def test_single_host_detected(self): + self.action.action_service.set_value("hosts", '["host1"]', local=False) + responses.add(responses.GET, self.hosts_url + "host1", json={"booked": True}) + self.action.run() + self.assertEqual(len(responses.calls), 1) + self.assertEqual(responses.calls[0].request.headers['auth-token'], "my_auth_token") + self.assertTrue(self.hostDetected("host1")) + + @responses.activate + def test_single_host_not_detected(self): + self.action.action_service.set_value("hosts", '["host1"]', local=False) + responses.add(responses.GET, self.hosts_url + "host1", json={"booked": False}) + self.action.run() + self.assertEqual(len(responses.calls), 1) + self.assertEqual(responses.calls[0].request.headers['auth-token'], "my_auth_token") + self.assertEqual(self.action.action_service.get_value("hosts_to_boot", local=False), "[]") + + @responses.activate + def test_multiple_hosts(self): + self.action.action_service.set_value("hosts", '["host1", "host2", "host3"]', local=False) + responses.add(responses.GET, self.hosts_url + "host1", json={"booked": True}) + responses.add(responses.GET, self.hosts_url + "host2", json={"booked": True}) + responses.add(responses.GET, self.hosts_url + "host3", json={"booked": False}) + + self.action.run() + self.assertEqual(len(responses.calls), 3) + self.assertEqual(responses.calls[0].request.headers['auth-token'], "my_auth_token") + self.assertEqual(responses.calls[1].request.headers['auth-token'], "my_auth_token") + self.assertEqual(responses.calls[2].request.headers['auth-token'], "my_auth_token") + self.assertTrue(self.hostDetected("host1")) + self.assertTrue(self.hostDetected("host2")) + self.assertFalse(self.hostDetected("host3")) diff --git a/laas/tests/test_action_detect_hardware_tasks.py b/laas/tests/test_action_detect_hardware_tasks.py new file mode 100644 index 0000000..d27ac1d --- /dev/null +++ b/laas/tests/test_action_detect_hardware_tasks.py @@ -0,0 +1,42 @@ +############################################################################## +# Copyright 2019 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 st2tests.base import BaseActionTestCase +from actions.actions import detect_hardware_tasks +import json + + +class DetectHWTestCase(BaseActionTestCase): + action_cls = detect_hardware_tasks.DetectHardwareTasksAction + + def setUp(self): + super(DetectHWTestCase, self).setUp() + self.action = self.get_action_instance() + job_data = { + "hardware": { + "task1": { + "power": "on", + "image": 1, + "hostname": "host1" + } + } + } + self.action.action_service.set_value("job_1", json.dumps(job_data), local=False) + + def test_detect_hardware_tasks(self): + result = self.action.run(job_id=1, task_id="task1") + self.assertTrue(result['power']) + self.assertTrue(result['hostname']) + self.assertTrue(result['image']) diff --git a/laas/tests/test_action_error_task.py b/laas/tests/test_action_error_task.py new file mode 100644 index 0000000..c1f9fe5 --- /dev/null +++ b/laas/tests/test_action_error_task.py @@ -0,0 +1,40 @@ +############################################################################## +# Copyright 2019 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 st2tests.base import BaseActionTestCase +from actions.actions import error_task +import responses + + +class ErrorTaskTestCase(BaseActionTestCase): + action_cls = error_task.ErrorTaskAction + + def setUp(self): + super(ErrorTaskTestCase, self).setUp() + self.action_service.set_value("lab_auth_token", "my_auth_token", local=False) + self.action = self.get_action_instance(config={ + "dashboard": { + "address": "http://my.dashboard.com", + "lab_name": "my_lab" + } + }) + + @responses.activate + def test_error_task(self): + responses.add(responses.POST, "http://my.dashboard.com/api/labs/my_lab/jobs/1/task1") + self.action.run(job_id=1, task_id="task1") + self.assertEqual(len(responses.calls), 1) + self.assertEqual(responses.calls[0].request.headers['auth-token'], "my_auth_token") + self.assertEqual(responses.calls[0].request.body, "status=300") diff --git a/laas/tests/test_action_finish_task.py b/laas/tests/test_action_finish_task.py new file mode 100644 index 0000000..85a842e --- /dev/null +++ b/laas/tests/test_action_finish_task.py @@ -0,0 +1,40 @@ +############################################################################## +# Copyright 2019 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 st2tests.base import BaseActionTestCase +from actions.actions import finish_task +import responses + + +class FinishTaskTestCase(BaseActionTestCase): + action_cls = finish_task.FinishTaskAction + + def setUp(self): + super(FinishTaskTestCase, self).setUp() + self.action_service.set_value("lab_auth_token", "my_auth_token", local=False) + self.action = self.get_action_instance(config={ + "dashboard": { + "address": "http://my.dashboard.com", + "lab_name": "my_lab" + } + }) + + @responses.activate + def test_error_task(self): + responses.add(responses.POST, "http://my.dashboard.com/api/labs/my_lab/jobs/1/task1") + self.action.run(job_id=1, task_id="task1") + self.assertEqual(len(responses.calls), 1) + self.assertEqual(responses.calls[0].request.headers['auth-token'], "my_auth_token") + self.assertEqual(responses.calls[0].request.body, "status=200") diff --git a/laas/tests/test_action_fog.py b/laas/tests/test_action_fog.py new file mode 100644 index 0000000..fcbc0c0 --- /dev/null +++ b/laas/tests/test_action_fog.py @@ -0,0 +1,84 @@ +############################################################################## +# Copyright 2019 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 st2tests.base import BaseActionTestCase +from actions.actions.lib import fog +import responses +import json + + +class FogTestCase(BaseActionTestCase): + action_cls = fog.FogAction + + def setUp(self): + super(FogTestCase, self).setUp() + self.action = self.get_action_instance(config={ + "fog": { + "address": "http://my.fog.com/fog/", + "api_key": "my_api_key", + "user_key": "my_user_key", + } + }) + + def assertGoodHeader(self, request): + self.assertEqual(request.headers['fog-api-token'], "my_api_key") + self.assertEqual(request.headers['fog-user-token'], "my_user_key") + # TODO: content type? only required when I send a body + + @responses.activate + def test_fog_create_image(self): + responses.add(responses.POST, "http://my.fog.com/fog/image") + payload = {"key1": "v1", "key2": "v2"} + self.action.createImage(payload) + self.assertEqual(len(responses.calls), 1) + self.assertGoodHeader(responses.calls[0].request) + self.assertEqual(payload, json.loads(responses.calls[0].request.body)) + + @responses.activate + def test_fog_get_image(self): + payload = { + "id": 42, + "key": "value", + "name": "fakeImage" + } + responses.add(responses.GET, "http://my.fog.com/fog/image/42", json=payload) + result = self.action.getImage(img=42) + self.assertEqual(len(responses.calls), 1) + self.assertGoodHeader(responses.calls[0].request) + self.assertEqual(result, payload) + + @responses.activate + def test_fog_delete_task(self): + responses.add(responses.DELETE, "http://my.fog.com/fog/fog/host/42/cancel") + self.action.delTask(42) + self.assertEqual(len(responses.calls), 1) + self.assertGoodHeader(responses.calls[0].request) + + @responses.activate + def test_get_host_number(self): + payload = { + "hosts": [ + {"name": "host1", "id": 1}, + {"name": "host2", "id": 2}, + {"name": "host3", "id": 3}, + {"name": "host4", "id": 4}, + {"name": "host5", "id": 5}, + ] + } + responses.add(responses.GET, "http://my.fog.com/fog/host", json=payload) + result = self.action.getHostNumber("host4") + self.assertEqual(len(responses.calls), 1) + self.assertGoodHeader(responses.calls[0].request) + self.assertEqual(result, 4) diff --git a/laas/tests/test_action_fog_capture_host.py b/laas/tests/test_action_fog_capture_host.py new file mode 100644 index 0000000..03cf44b --- /dev/null +++ b/laas/tests/test_action_fog_capture_host.py @@ -0,0 +1,53 @@ +############################################################################## +# Copyright 2019 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 st2tests.base import BaseActionTestCase +from actions.actions import fog_captureHost +import responses +import json + + +class FogCaptureHostTestCase(BaseActionTestCase): + action_cls = fog_captureHost.StartCaptureAction + + def setUp(self): + super(FogCaptureHostTestCase, self).setUp() + self.action = self.get_action_instance(config={ + "fog": { + "address": "http://my.fog.com/fog/", + "api_key": "my_api_key", + "user_key": "my_user_key", + } + }) + + def assertGoodHeader(self, request): + self.assertEqual(request.headers['fog-api-token'], "my_api_key") + self.assertEqual(request.headers['fog-user-token'], "my_user_key") + # TODO: content type? only required when I send a body + + @responses.activate + def test_fog_capture_host(self): + responses.add(responses.POST, "http://my.fog.com/fog/host/42/task") + self.action.action_service.set_value("host1", json.dumps({"fog_name": "fog_host1"}), local=False) + responses.add(responses.GET, "http://my.fog.com/fog/host", json={ + "hosts": [ + {"name": "fog_host1", "id": 42}, + ] + }) + self.action.run(host="host1") + self.assertEqual(len(responses.calls), 2) + self.assertGoodHeader(responses.calls[0].request) + self.assertGoodHeader(responses.calls[1].request) + self.assertEqual(json.loads(responses.calls[1].request.body), {"taskTypeID": 2}) diff --git a/laas/tests/test_action_fog_change_image.py b/laas/tests/test_action_fog_change_image.py new file mode 100644 index 0000000..fd11a46 --- /dev/null +++ b/laas/tests/test_action_fog_change_image.py @@ -0,0 +1,59 @@ +############################################################################## +# Copyright 2019 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 st2tests.base import BaseActionTestCase +from actions.actions import fog_changeImage +import responses +import json + + +class FogChangeImageTestCase(BaseActionTestCase): + action_cls = fog_changeImage.ChangeImageAction + + def setUp(self): + super(FogChangeImageTestCase, self).setUp() + self.action = self.get_action_instance(config={ + "fog": { + "address": "http://my.fog.com/fog/", + "api_key": "my_api_key", + "user_key": "my_user_key", + } + }) + + def assertGoodHeader(self, request): + self.assertEqual(request.headers['fog-api-token'], "my_api_key") + self.assertEqual(request.headers['fog-user-token'], "my_user_key") + # TODO: content type? only required when I send a body + + @responses.activate + def test_fog_change_image(self): + responses.add(responses.POST, "http://my.fog.com/fog/host/42/edit") + self.action.action_service.set_value("host1", json.dumps({"fog_name": "fog_host1"}), local=False) + responses.add(responses.GET, "http://my.fog.com/fog/host", json={ + "hosts": [ + {"name": "fog_host1", "id": 42}, + ] + }) + responses.add(responses.GET, "http://my.fog.com/fog/host/42", json={ + "name": "fog_host1", + "imageID": 99, + "description": "test host" + }) + self.action.run(host="host1", image=3) + self.assertEqual(len(responses.calls), 3) + self.assertGoodHeader(responses.calls[0].request) + self.assertGoodHeader(responses.calls[1].request) + self.assertGoodHeader(responses.calls[2].request) + self.assertEqual(int(json.loads(responses.calls[2].request.body)['imageID']), 3) diff --git a/laas/tests/test_action_fog_create_snapshot.py b/laas/tests/test_action_fog_create_snapshot.py new file mode 100644 index 0000000..8cb52a0 --- /dev/null +++ b/laas/tests/test_action_fog_create_snapshot.py @@ -0,0 +1,76 @@ +############################################################################## +# Copyright 2019 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 st2tests.base import BaseActionTestCase +from actions.actions import fog_createSnapshot +import responses +import json + + +class FogCreateSnapshotTestCase(BaseActionTestCase): + action_cls = fog_createSnapshot.FogCreateSnapshotAction + + def setUp(self): + super(FogCreateSnapshotTestCase, self).setUp() + self.action = self.get_action_instance(config={ + "fog": { + "address": "http://my.fog.com/fog/", + "api_key": "my_api_key", + "user_key": "my_user_key", + } + }) + + def assertGoodHeader(self, request): + self.assertEqual(request.headers['fog-api-token'], "my_api_key") + self.assertEqual(request.headers['fog-user-token'], "my_user_key") + # TODO: content type? only required when I send a body + + @responses.activate + def test_fog_create_snapshot(self): + responses.add(responses.GET, "http://my.fog.com/fog/host", json={ + "hosts": [ + {"name": "fog_host1", "id": 42}, + ] + }) + responses.add(responses.GET, "http://my.fog.com/fog/host/42", json={ + "name": "fog_host1", + "imagename": "orig_img", + "description": "test host" + }) + responses.add(responses.GET, "http://my.fog.com/fog/image", json={ + "images": [ + {"name": "orig_img", "id": 10}, + ] + }) + responses.add(responses.GET, "http://my.fog.com/fog/image/10", json={ + "imagePartitionTypeID": 1, + "toReplicate": False, + "isEnabled": True, + "compress": 6, + "storagegroups": 1, + "osID": 50, + "imageTypeID": 4 + }) + responses.add(responses.POST, "http://my.fog.com/fog/image") + self.action.action_service.set_value("host1", json.dumps({"fog_name": "fog_host1"}), local=False) + + self.action.run(host="host1", name="my_snapshot") + self.assertEqual(len(responses.calls), 5) + self.assertGoodHeader(responses.calls[0].request) + self.assertGoodHeader(responses.calls[1].request) + self.assertGoodHeader(responses.calls[2].request) + self.assertGoodHeader(responses.calls[3].request) + self.assertGoodHeader(responses.calls[4].request) + self.assertEqual(json.loads(responses.calls[-1].request.body)['name'], "my_snapshot") diff --git a/laas/tests/test_action_fog_start_imaging.py b/laas/tests/test_action_fog_start_imaging.py new file mode 100644 index 0000000..97601e9 --- /dev/null +++ b/laas/tests/test_action_fog_start_imaging.py @@ -0,0 +1,54 @@ +############################################################################## +# Copyright 2019 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 st2tests.base import BaseActionTestCase +from actions.actions import fog_startImaging +import responses +import json + + +class FogStartImageTestCase(BaseActionTestCase): + action_cls = fog_startImaging.StartImagingAction + + def setUp(self): + super(FogStartImageTestCase, self).setUp() + self.action = self.get_action_instance(config={ + "fog": { + "address": "http://my.fog.com/fog/", + "api_key": "my_api_key", + "user_key": "my_user_key", + } + }) + + def assertGoodHeader(self, request): + self.assertEqual(request.headers['fog-api-token'], "my_api_key") + self.assertEqual(request.headers['fog-user-token'], "my_user_key") + # TODO: content type? only required when I send a body + + @responses.activate + def test_fog_start_imaging(self): + responses.add(responses.GET, "http://my.fog.com/fog/host", json={ + "hosts": [ + {"name": "fog_host1", "id": 42}, + ] + }) + responses.add(responses.POST, "http://my.fog.com/fog/host/42/task") + self.action.action_service.set_value("host1", json.dumps({"fog_name": "fog_host1"}), local=False) + + self.action.run(host="host1") + self.assertEqual(len(responses.calls), 2) + self.assertGoodHeader(responses.calls[0].request) + self.assertGoodHeader(responses.calls[1].request) + self.assertEqual(int(json.loads(responses.calls[-1].request.body)['taskTypeID']), 1) diff --git a/laas/tests/test_action_get_all_macs.py b/laas/tests/test_action_get_all_macs.py new file mode 100644 index 0000000..015b826 --- /dev/null +++ b/laas/tests/test_action_get_all_macs.py @@ -0,0 +1,62 @@ +############################################################################## +# Copyright 2019 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 st2tests.base import BaseActionTestCase +from actions.actions import get_all_macs +import json + + +class GetMacsTestCase(BaseActionTestCase): + action_cls = get_all_macs.MacAction + + def setUp(self): + super(GetMacsTestCase, self).setUp() + self.action = self.get_action_instance() + + def test_single_mac(self): + self.action.action_service.set_value("host1", json.dumps({ + "interfaces": { + "mac1": { + "mac": "mac1", + "speed": 42 + } + } + }), local=False) + result = self.action.run(host="host1") + self.assertEqual(result, "mac1") + + def test_multiple_macs(self): + self.action.action_service.set_value("host1", json.dumps({ + "interfaces": { + "mac1": { + "mac": "mac1", + "speed": 42 + }, + "mac2": { + "mac": "mac2", + "speed": 42 + }, + "mac3": { + "mac": "mac3", + "speed": 42 + } + } + }), local=False) + result = self.action.run(host="host1") + parsed_results = set(result.split("|")) + expected_results = set(["mac1", "mac2", "mac3"]) + self.assertTrue( + parsed_results.issubset(expected_results) and expected_results.issubset(parsed_results) + ) diff --git a/laas/tests/test_action_get_host_type.py b/laas/tests/test_action_get_host_type.py new file mode 100644 index 0000000..5858dcb --- /dev/null +++ b/laas/tests/test_action_get_host_type.py @@ -0,0 +1,37 @@ +############################################################################## +# Copyright 2019 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 st2tests.base import BaseActionTestCase +from actions.actions import get_host_type + + +class FinishTaskTestCase(BaseActionTestCase): + action_cls = get_host_type.HostTypeAction + + def setUp(self): + super(FinishTaskTestCase, self).setUp() + self.action = self.get_action_instance() + + def test_hpe_host_type(self): + result = self.action.run(host="hpe5") + self.assertEqual(result, "hpe") + + def test_arm_host_type(self): + result = self.action.run(host="arm50") + self.assertEqual(result, "arm") + + def test_bad_host_type(self): + result = self.action.run(host="unknown") + self.assertFalse(result) diff --git a/laas/tests/test_action_get_ipmi_hostname.py b/laas/tests/test_action_get_ipmi_hostname.py new file mode 100644 index 0000000..418241a --- /dev/null +++ b/laas/tests/test_action_get_ipmi_hostname.py @@ -0,0 +1,46 @@ +############################################################################## +# Copyright 2018 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 st2tests.base import BaseActionTestCase + +from actions.actions import get_ipmi_hostname +import socket + +hosts = {"host1": "ipmi_host1", "host2": "ipmi_host2"} + + +class IpmiHostnameActionTestCase(BaseActionTestCase): + action_cls = get_ipmi_hostname.ipmi_infoAction + + def setUp(self): + super(IpmiHostnameActionTestCase, self).setUp() + self.skipTest("not read") + + def test_goodHostname_givesRightResult(self): + action = self.get_action_instance() + for key in hosts.keys(): + self.assertEquals(hosts[key], action.run(host=key)) + + def test_results_resolvable(self): + action = self.get_action_instance() + for key in hosts.keys(): + # socket will return ip as a string if it can, which is truthy + self.asserTrue(socket.gethostbyname(action.run(host=key))) + + def test_badHostname_throwsError(self): + bad_host = "abc_I_dont_know_thee" + action = self.get_action_instance() + with self.assertRaises(IndexError): + action.run(host=bad_host) diff --git a/laas/tests/test_action_get_ipmi_password.py b/laas/tests/test_action_get_ipmi_password.py new file mode 100644 index 0000000..b9bc8bc --- /dev/null +++ b/laas/tests/test_action_get_ipmi_password.py @@ -0,0 +1,38 @@ +############################################################################## +# Copyright 2018 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 st2tests.base import BaseActionTestCase +from actions.actions import get_ipmi_password + +hosts = ["ipmi_hostname1", "ipmi_hostname2"] + + +class IpmiPasswordActionTestCase(BaseActionTestCase): + action_cls = get_ipmi_password.ipmi_passwdAction + + def setUp(self): + super(IpmiPasswordActionTestCase, self).setUp() + self.skipTest("not read") + + def test_goodHost_returnsValue(self): + action = self.get_action_instance() + for host in hosts: + self.assertTrue(action.run(host=host)) + + def test_badHost_throwsError(self): + bad_host = "abc_IDontKnowThee" + action = self.get_action_instance() + with self.assertRaises(IndexError): + action.run(host=bad_host) diff --git a/laas/tests/test_action_get_ipmi_username.py b/laas/tests/test_action_get_ipmi_username.py new file mode 100644 index 0000000..1b71683 --- /dev/null +++ b/laas/tests/test_action_get_ipmi_username.py @@ -0,0 +1,38 @@ +############################################################################## +# Copyright 2018 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 st2tests.base import BaseActionTestCase +from actions.actions import get_ipmi_username + +hosts = ["ipmi_host1", "ipmi_host2"] + + +class IpmiUserActionTestCase(BaseActionTestCase): + action_cls = get_ipmi_username.ipmi_userAction + + def setUp(self): + super(IpmiUserActionTestCase, self).setUp() + self.skipTest("not ready") + + def test_goodHost_returnsValue(self): + action = self.get_action_instance() + for host in hosts: + self.assertTrue(action.run(host=host)) + + def test_badHost_throwsError(self): + bad_host = "abc_IDontKnowThee" + action = self.get_action_instance() + with self.assertRaises(IndexError): + action.run(host=bad_host) diff --git a/laas/tests/test_action_get_jumphost.py b/laas/tests/test_action_get_jumphost.py new file mode 100644 index 0000000..a2eb9a9 --- /dev/null +++ b/laas/tests/test_action_get_jumphost.py @@ -0,0 +1,33 @@ +############################################################################## +# Copyright 2019 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 st2tests.base import BaseActionTestCase +from actions.actions import get_jumphost + + +class FinishTaskTestCase(BaseActionTestCase): + action_cls = get_jumphost.GetJumphostAction + + def setUp(self): + super(FinishTaskTestCase, self).setUp() + self.action = self.get_action_instance() + + def test_get_jumphost(self): + result = self.action.run(hosts=[{"host1": "Compute"}, {"host2": "Jumphost"}]) + self.assertEqual(result, "host2") + + def test_with_no_jumphost(self): + result = self.action.run(hosts=[{"host1": "Compute"}, {"host2": "Controller"}]) + self.assertFalse(result) diff --git a/laas/tests/test_action_get_task.py b/laas/tests/test_action_get_task.py new file mode 100644 index 0000000..f9a37af --- /dev/null +++ b/laas/tests/test_action_get_task.py @@ -0,0 +1,44 @@ +############################################################################## +# Copyright 2019 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 st2tests.base import BaseActionTestCase +from actions.actions import get_task +import json + + +class GetTaskTestCase(BaseActionTestCase): + action_cls = get_task.GetTaskAction + + def setUp(self): + super(GetTaskTestCase, self).setUp() + self.action = self.get_action_instance() + + def test_get_task_multiple_tasks(self): + self.action.action_service.set_value("job_1", json.dumps({ + "access": { + "task1": "asdf", + "task2": "fdsa" + } + }), local=False) + result = self.action.run(job_id=1, type="access", task_id="task1") + self.assertEqual(result, "asdf") + + def test_get_single_task(self): + self.action.action_service.set_value("job_1", json.dumps({ + "access": {"task1": "asdf"}, + "hardware": {"task10": "foobar"} + }), local=False) + result = self.action.run(job_id=1, type="hardware", task_id="task10") + self.assertEqual("foobar", result) diff --git a/laas/tests/test_action_get_task_list.py b/laas/tests/test_action_get_task_list.py new file mode 100644 index 0000000..790e47e --- /dev/null +++ b/laas/tests/test_action_get_task_list.py @@ -0,0 +1,52 @@ +############################################################################## +# Copyright 2019 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 st2tests.base import BaseActionTestCase +from actions.actions import get_task_list +import json + + +class GetTaskListTestCase(BaseActionTestCase): + action_cls = get_task_list.Task_List_Action + + def setUp(self): + super(GetTaskListTestCase, self).setUp() + self.action = self.get_action_instance() + + def test_tasklist_multiple_tasks(self): + self.action.action_service.set_value("job_1", json.dumps({ + "access": { + "task1": "asdf", + "task2": "fdsa" + } + }), local=False) + result = self.action.run(job_id=1, type="access") + self.assertEqual(set(result), set(["task1", "task2"])) + + def test_tasklist_single_task(self): + self.action.action_service.set_value("job_1", json.dumps({ + "access": {"task1": "asdf"}, + "hardware": {"task10": "asdf"} + }), local=False) + result = self.action.run(job_id=1, type="hardware") + self.assertEqual(set(result), set(["task10"])) + + def test_empty_tasklist(self): + self.action.action_service.set_value("job_1", json.dumps({ + "access": {"task1": "asdf"}, + "hardware": {"task10": "asdf"} + }), local=False) + result = self.action.run(job_id=1, type="unknown") + self.assertFalse(result) diff --git a/laas/tests/test_action_get_xdf.py b/laas/tests/test_action_get_xdf.py new file mode 100644 index 0000000..09ce98f --- /dev/null +++ b/laas/tests/test_action_get_xdf.py @@ -0,0 +1,56 @@ +############################################################################## +# Copyright 2019 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 st2tests.base import BaseActionTestCase +from actions.actions import get_xdf +import responses + + +class GetXDFTestCase(BaseActionTestCase): + action_cls = get_xdf.XDF_Action + + def setUp(self): + super(GetXDFTestCase, self).setUp() + self.action_service.set_value("lab_auth_token", "my_auth_token", local=False) + self.action = self.get_action_instance(config={ + "dashboard": { + "address": "http://my.dashboard.com", + "lab_name": "my_lab" + } + }) + + @responses.activate + def test_xdf_retrieved(self): + urls = [ + "http://my.dashboard.com/api/some/endpoint/pdf", + "http://my.dashboard.com/api/some/endpoint/idf" + ] + responses.add(responses.GET, urls[0]) + responses.add(responses.GET, urls[1]) + self.action.run(task_data={ + "opnfv": { + "pdf": "/api/some/endpoint/pdf", + "idf": "/api/some/endpoint/idf", + } + }) + self.assertEqual(len(responses.calls), 2) + self.assertEqual(responses.calls[0].request.headers['auth-token'], "my_auth_token") + self.assertEqual(responses.calls[1].request.headers['auth-token'], "my_auth_token") + + try: + urls.remove(responses.calls[0].request.url) + urls.remove(responses.calls[1].request.url) + except ValueError: + self.fail("Requests were sent to the wrong URLs") diff --git a/laas/tests/test_action_network_task.py b/laas/tests/test_action_network_task.py new file mode 100644 index 0000000..5efb8a9 --- /dev/null +++ b/laas/tests/test_action_network_task.py @@ -0,0 +1,110 @@ +############################################################################## +# Copyright 2019 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 st2tests.base import BaseActionTestCase +from actions.actions import network_task +import json +import mock + + +class NetworkTaskTest(BaseActionTestCase): + action_cls = network_task.PodNetworkManagerAction + + def setUp(self): + super(NetworkTaskTest, self).setUp() + self.action = self.get_action_instance() + host_info = { + "interfaces": { + "mac1": { + "mac": "mac1", + "bus": "bus1", + "switch": "switch1", + "port": "Ethernet1/1", + "name": "ifname1" + }, + "mac2": { + "mac": "mac2", + "bus": "bus2", + "switch": "switch1", + "port": "Ethernet1/2", + "name": "ifname2" + } + } + } + self.action.action_service.set_value("host1", json.dumps(host_info), local=False) + switch_info = {"user": "user", "password": "password"} + self.action.action_service.set_value("switch_switch1", json.dumps(switch_info), local=False) + + def hasConsecutiveCalls(self, args, mock_obj): + """ + args is a list of arguments as tuples. This method asserts that + mock was called with those arguments in that order + """ + if len(args) < 1: + return True + for call_index in range(len(mock_obj.call_args_list)): + arg_index = 0 + while mock_obj.call_args_list[call_index] == (args[arg_index],): + call_index += 1 + arg_index += 1 + if arg_index == len(args): + return True + return False + + def assertInterfaceConfigured(self, mocked_object, config): + all_calls = mocked_object.add_command.call_args_list + all_args = [c[0][0] for c in all_calls] + # first, we set the interface context + self.assertEqual(all_args[0], "interface " + config[0]['port']) + # next, the port must be trunked + self.assertEqual(all_args[1], "switchport mode trunk") + # next, check that the correct vlans are added + vlan_cmd = all_args[2] + self.assertTrue(vlan_cmd.startswith("switchport trunk allowed vlan ")) + parsed = vlan_cmd.split(" ") + self.assertEqual(len(parsed), 5) + expected_vlans = set([98, 99]) + for vlan in config: + expected_vlans.add(vlan['vlan_id']) + + requested_vlans = parsed[-1].split(",") + requested_vlans = set([int(v) for v in requested_vlans]) + self.assertEqual(requested_vlans, expected_vlans) + # TODO: native vlan + # TODO: assert executed + + def test_simple_net_config(self): + with mock.patch('actions.actions.network_task.NXCommand') as Mocked: + mocks = [] + for i in range(2): + mocks.append(mock.Mock()) + Mocked.side_effect = mocks + + net_conf = { + "host1": { + "mac1": [{"tagged": True, "vlan_id": 100}], + "mac2": [{"tagged": False, "vlan_id": 10}], + } + } + self.action.run(net_conf) + + Mocked.assert_any_call("switch1", {"user": "user", "password": "password"}) + config_map = { + "Ethernet1/1": [{"tagged": True, "vlan_id": 100, "port": "Ethernet1/1"}], + "Ethernet1/2": [{"tagged": False, "vlan_id": 10, "port": "Ethernet1/2"}], + } + for mocked_cmd in mocks: + target_iface = mocked_cmd.add_command.call_args_list[0][0][0].split(" ")[-1] + self.assertInterfaceConfigured(mocked_cmd, config_map[target_iface]) diff --git a/laas/tests/test_action_notify_ip_address.py b/laas/tests/test_action_notify_ip_address.py new file mode 100644 index 0000000..c6cd8bf --- /dev/null +++ b/laas/tests/test_action_notify_ip_address.py @@ -0,0 +1,41 @@ +############################################################################## +# Copyright 2019 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 st2tests.base import BaseActionTestCase +from actions.actions import notify_ip_address +import responses + + +class NotifyIPTestCase(BaseActionTestCase): + action_cls = notify_ip_address.NotifyIPAction + + def setUp(self): + super(NotifyIPTestCase, self).setUp() + self.action_service.set_value("lab_auth_token", "my_auth_token", local=False) + self.action = self.get_action_instance(config={ + "dashboard": { + "address": "http://my.dashboard.com", + "lab_name": "my_lab" + } + }) + + @responses.activate + def test_notify_ip(self): + responses.add(responses.POST, "http://my.dashboard.com/api/labs/my_lab/jobs/1/task1") + self.action.run(addresses="my_address", hostname="my_host", job_id=1, task_id="task1") + self.assertEqual(len(responses.calls), 1) + self.assertEqual(responses.calls[0].request.headers['auth-token'], "my_auth_token") + self.assertTrue("my_address" in responses.calls[0].request.body) + self.assertTrue("my_host" in responses.calls[0].request.body) diff --git a/laas/tests/test_action_notify_ipmi_user.py b/laas/tests/test_action_notify_ipmi_user.py new file mode 100644 index 0000000..a534158 --- /dev/null +++ b/laas/tests/test_action_notify_ipmi_user.py @@ -0,0 +1,43 @@ +############################################################################## +# Copyright 2019 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 st2tests.base import BaseActionTestCase +from actions.actions import notify_ipmi_user +import responses + + +class IPMINotificationTestCase(BaseActionTestCase): + action_cls = notify_ipmi_user.NotifyIPMIUserAction + + def setUp(self): + super(IPMINotificationTestCase, self).setUp() + self.action_service.set_value("lab_auth_token", "my_auth_token", local=False) + self.action = self.get_action_instance(config={ + "dashboard": { + "address": "http://my.dashboard.com", + "lab_name": "my_lab" + } + }) + + @responses.activate + def test_notify_ipmi_user(self): + responses.add(responses.POST, "http://my.dashboard.com/api/labs/my_lab/jobs/1/task1") + self.action.action_service.set_value("my_ipmi_key", "my_ipmi_password", local=False) + self.action.run(ipmi_key="my_ipmi_key", hostname="my_host", addr="my_ipmi_addr", job_id=1, task_id="task1") + self.assertEqual(len(responses.calls), 1) + self.assertEqual(responses.calls[0].request.headers['auth-token'], "my_auth_token") + self.assertTrue("my_ipmi_addr" in responses.calls[0].request.body) + self.assertTrue("my_host" in responses.calls[0].request.body) + self.assertTrue("my_ipmi_password" in responses.calls[0].request.body) diff --git a/laas/tests/test_action_notify_ssh_access.py b/laas/tests/test_action_notify_ssh_access.py new file mode 100644 index 0000000..65b015e --- /dev/null +++ b/laas/tests/test_action_notify_ssh_access.py @@ -0,0 +1,41 @@ +############################################################################## +# Copyright 2019 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 st2tests.base import BaseActionTestCase +from actions.actions import notify_ssh_access +import responses + + +class SSHNotificationTestCase(BaseActionTestCase): + action_cls = notify_ssh_access.NotifySSHAction + + def setUp(self): + super(SSHNotificationTestCase, self).setUp() + self.action_service.set_value("lab_auth_token", "my_auth_token", local=False) + self.action = self.get_action_instance(config={ + "dashboard": { + "address": "http://my.dashboard.com", + "lab_name": "my_lab" + } + }) + + @responses.activate + def test_notify_ssh_user(self): + responses.add(responses.POST, "http://my.dashboard.com/api/labs/my_lab/jobs/1/task1") + self.action.run(user="my_ssh_user", hosts=["my_host"], job_id=1, task_id="task1") + self.assertEqual(len(responses.calls), 1) + self.assertEqual(responses.calls[0].request.headers['auth-token'], "my_auth_token") + self.assertTrue("my_ssh_user" in responses.calls[0].request.body) + self.assertTrue("my_host" in responses.calls[0].request.body) diff --git a/laas/tests/test_action_notify_vpn_user.py b/laas/tests/test_action_notify_vpn_user.py new file mode 100644 index 0000000..6e9b687 --- /dev/null +++ b/laas/tests/test_action_notify_vpn_user.py @@ -0,0 +1,46 @@ +############################################################################## +# Copyright 2019 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 st2tests.base import BaseActionTestCase +from actions.actions import notify_vpn_user +import responses +import json + + +class VPNNotificationTestCase(BaseActionTestCase): + action_cls = notify_vpn_user.NotifyVPNUserAction + + def setUp(self): + super(VPNNotificationTestCase, self).setUp() + self.action_service.set_value("lab_auth_token", "my_auth_token", local=False) + self.action = self.get_action_instance(config={ + "dashboard": { + "address": "http://my.dashboard.com", + "lab_name": "my_lab" + } + }) + + @responses.activate + def test_notify_vpn_user(self): + responses.add(responses.POST, "http://my.dashboard.com/api/labs/my_lab/jobs/1/task1") + self.action_service.set_value("my_vpn_key", json.dumps({ + "username": "vpn_username", + "password": "vpn_password" + }), local=False) + self.action.run(vpn_key="my_vpn_key", job_id=1, task_id="task1") + self.assertEqual(len(responses.calls), 1) + self.assertEqual(responses.calls[0].request.headers['auth-token'], "my_auth_token") + self.assertTrue("vpn_username" in responses.calls[0].request.body) + self.assertTrue("vpn_password" in responses.calls[0].request.body) diff --git a/laas/tests/test_action_parse_network_data.py b/laas/tests/test_action_parse_network_data.py new file mode 100644 index 0000000..fc0e487 --- /dev/null +++ b/laas/tests/test_action_parse_network_data.py @@ -0,0 +1,92 @@ +############################################################################## +# Copyright 2019 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 st2tests.base import BaseActionTestCase + +from actions.actions import parse_network_data + + +class ParseNetworkTestCase(BaseActionTestCase): + action_cls = parse_network_data.ParseNetworkAction + + def setUp(self): + super(ParseNetworkTestCase, self).setUp() + self.action = self.get_action_instance() + self.action.action_service.set_value("default_vlans", "[5, 10]", local=False) + + def test_empty_returns_true(self): + data = { + "host1": { + "mac1": [], + "mac2": [] + } + } + result = self.action.run(data) + self.assertTrue(result['empty']) + + def test_single_vlan(self): + data = { + "host1": { + "mac1": [{ + "tagged": False, + "vlan_id": 10 + }], + "mac2": [] + } + } + result = self.action.run(data) + self.assertFalse(result['empty']) + self.assertEqual("mac1", result['default']) + self.assertEqual("host1", result['host']) + # should be empty string because there are no tagged vlans to map + self.assertFalse(result['mappings']) + + def test_single_tagged_vlan(self): + data = { + "host1": { + "mac1": [{ + "tagged": True, + "vlan_id": 10 + }], + "mac2": [] + } + } + result = self.action.run(data) + self.assertFalse(result['empty']) + self.assertEqual("mac1.10", result['default']) + self.assertEqual("host1", result['host']) + self.assertEqual("mac1-10", result['mappings']) + + def test_complex_case(self): + data = { + "host1": { + "mac1": [ + {"tagged": True, "vlan_id": 50}, + {"tagged": True, "vlan_id": 500}, + {"tagged": False, "vlan_id": 100} + ], + "mac2": [ + {"tagged": True, "vlan_id": 10}, + {"tagged": False, "vlan_id": 1000} + ] + } + } + result = self.action.run(data) + self.assertFalse(result['empty']) + self.assertEqual("mac2.10", result['default']) + self.assertEqual("host1", result['host']) + mapping = set(result['mappings'].split("+")) + expected = set(["mac1-50", "mac1-500", "mac2-10"]) + self.assertTrue(mapping.issubset(expected) and expected.issubset(mapping)) diff --git a/laas/tests/test_action_send_bot_failure.py b/laas/tests/test_action_send_bot_failure.py new file mode 100644 index 0000000..986cb54 --- /dev/null +++ b/laas/tests/test_action_send_bot_failure.py @@ -0,0 +1,45 @@ +############################################################################## +# Copyright 2019 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 st2tests.base import BaseActionTestCase +from actions.actions import send_bot_failure +import responses +import json + + +class SendBotFailureTestCase(BaseActionTestCase): + action_cls = send_bot_failure.BotFailureAction + + def setUp(self): + super(SendBotFailureTestCase, self).setUp() + self.action_service.set_value("lab_auth_token", "my_auth_token", local=False) + self.action = self.get_action_instance(config={ + "bot": { + "endpoints": { + "failure": "failure", + "notification": "notification" + }, + "address": "http://my.bot.com/endpoint/" + } + }) + + @responses.activate + def test_send_bot_failure(self): + responses.add(responses.POST, "http://my.bot.com/endpoint/failure") + payload = {"k1": "v1", "k2": "v2"} + self.action.run(**payload) + self.assertEqual(len(responses.calls), 1) + self.assertEqual(responses.calls[0].request.headers['Content-Type'], "application/json") + self.assertEqual(json.dumps(payload), responses.calls[0].request.body) diff --git a/laas/tests/test_action_start_task.py b/laas/tests/test_action_start_task.py new file mode 100644 index 0000000..d060c4b --- /dev/null +++ b/laas/tests/test_action_start_task.py @@ -0,0 +1,40 @@ +############################################################################## +# Copyright 2019 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 st2tests.base import BaseActionTestCase +from actions.actions import start_task +import responses + + +class FinishTaskTestCase(BaseActionTestCase): + action_cls = start_task.StartTaskAction + + def setUp(self): + super(FinishTaskTestCase, self).setUp() + self.action_service.set_value("lab_auth_token", "my_auth_token", local=False) + self.action = self.get_action_instance(config={ + "dashboard": { + "address": "http://my.dashboard.com", + "lab_name": "my_lab" + } + }) + + @responses.activate + def test_error_task(self): + responses.add(responses.POST, "http://my.dashboard.com/api/labs/my_lab/jobs/1/task1") + self.action.run(job_id=1, task_id="task1") + self.assertEqual(len(responses.calls), 1) + self.assertEqual(responses.calls[0].request.headers['auth-token'], "my_auth_token") + self.assertEqual(responses.calls[0].request.body, "status=100") diff --git a/laas/tests/test_sensor_laas_api.py b/laas/tests/test_sensor_laas_api.py new file mode 100644 index 0000000..c5181b6 --- /dev/null +++ b/laas/tests/test_sensor_laas_api.py @@ -0,0 +1,118 @@ +############################################################################## +# Copyright 2018 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 st2tests.base import BaseSensorTestCase +import laas +import responses +import json + + +class LaaSSensorTest(BaseSensorTestCase): + sensor_cls = laas.LaaS_Sensor + + def setUp(self): + super(LaaSSensorTest, self).setUp() + self.sensor = self.get_sensor_instance(config={ + "dashboard": { + "address": "http://my.dashboard.com", + "lab_name": "my_lab" + } + }) + self.jobs_url = "http://my.dashboard.com/api/labs/my_lab/jobs/new" + self.sensor.sensor_service.set_value("jobs", "[]", local=False) + self.sensor.sensor_service.set_value("lab_auth_token", "my_auth_token", local=False) + self.sensor.setup() + + def clean(self, sensor): + # Removes all existing bookings from the keystore + kvps = sensor.sensor_service.list_values(local=False, prefix="job_") + for kvp in kvps: + sensor.sensor_service.delete_value(local=False, name=kvp.name) + + def get_job(self, job_id): + return { + "id": job_id, + "payload": { + "hardware": "stuff", + "network": "stuff", + "access": "stuff", + } + } + + def assertJobCreated(self, job_id): + self.assertTriggerDispatched( + trigger="laas.start_job_trigger", + payload={"job_id": job_id} + ) + self.assertTrue(json.loads( + self.sensor.sensor_service.get_value("job_" + str(job_id), local=False) + )) + # TODO: solve concurrency issues in job stop / start + # started_jobs = json.loads(self.sensor.sensor_service.get_value("jobs", local=False)) + # self.assertTrue(job_id in started_jobs) + + # Testing Methods + + @responses.activate + def test_empty_throws_no_triggers(self): + responses.add(responses.GET, self.jobs_url, json=[]) + self.sensor.poll() + self.assertEqual(len(responses.calls), 1) + self.assertEqual(responses.calls[0].request.headers['auth-token'], 'my_auth_token') + self.assertEqual(self.get_dispatched_triggers(), []) + + @responses.activate + def test_new_job_throws_trigger(self): + responses.add(responses.GET, self.jobs_url, json=[self.get_job(1)]) + self.sensor.poll() + self.assertEqual(len(responses.calls), 1) + self.assertEqual(responses.calls[0].request.headers['auth-token'], 'my_auth_token') + self.assertJobCreated(1) + + @responses.activate + def test_job_not_restarted(self): + self.sensor.sensor_service.set_value("jobs", "[1]", local=False) + responses.add(responses.GET, self.jobs_url, json=[self.get_job(1)]) + self.sensor.poll() + self.assertEqual(len(responses.calls), 1) + self.assertEqual(responses.calls[0].request.headers['auth-token'], 'my_auth_token') + self.assertEqual(self.get_dispatched_triggers(), []) + + @responses.activate + def test_sensor_does_not_die(self): + # no endpoint added to responses - will throw an error to the sensor + self.sensor.poll() # shouldn't throw, should still work next time + self.assertEqual(len(responses.calls), 1) + self.assertEqual(responses.calls[0].request.headers['auth-token'], 'my_auth_token') + + responses.add(responses.GET, self.jobs_url, json=[self.get_job(1)]) + self.sensor.poll() + self.assertEqual(len(responses.calls), 2) + self.assertEqual(responses.calls[1].request.headers['auth-token'], 'my_auth_token') + self.assertJobCreated(1) + + @responses.activate + def test_multiple_jobs_started(self): + responses.add(responses.GET, self.jobs_url, json=[ + self.get_job(1), + self.get_job(2), + self.get_job(3) + ]) + self.sensor.poll() + self.assertEqual(len(responses.calls), 1) + self.assertEqual(responses.calls[0].request.headers['auth-token'], 'my_auth_token') + self.assertJobCreated(1) + self.assertJobCreated(2) + self.assertJobCreated(3) diff --git a/run_test_deployment.sh b/run_test_deployment.sh new file mode 100755 index 0000000..1aa214f --- /dev/null +++ b/run_test_deployment.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +HOST="$1" + +[ -z "$HOST" ] && echo "only arg must be the test target's hostname" && exit 1 + + +JSON="$(st2 key get "$HOST" --json -a value | jq '.value' | head -c -2 | tail -c +2 | tr -d "\\")" +echo "Got JSON $JSON" + + +TEST_JOB="$(./generate_job.py "$JSON")" + +[ $? -gt 0 ] && echo "$TEST_JOB" && exit 1 + +st2 key set "job_1" "$TEST_JOB" @@ -17,5 +17,5 @@ st2ctl restart st2ctl reload --register-all -st2 run packs.setup_virtualenv packs=laaslab -st2 key load /opt/stackstorm/packs/laaslab/hosts.json +st2 run packs.setup_virtualenv packs=laas +st2 key load /opt/stackstorm/packs/laas/hosts.json @@ -0,0 +1,40 @@ +#!/bin/bash + +function lint { + echo "######################################################" + echo "## Running Linters ##" + echo "######################################################" + + local status=0 + + echo "=========================" + echo " flake8 " + echo "=========================" + find . -name "*.py" -print0 | xargs -0 flake8 + + (( status = status + "$?" )) + + echo "" + echo "=========================" + echo " yamllint " + echo "=========================" + + find . -name "*.yaml" -print0 | xargs -0 yamllint + + (( status = status + "$?" )) + + echo "" + echo "=========================" + echo " shellcheck " + echo "=========================" + find . -name "*.sh" -print0 | xargs -0 shellcheck + + (( status = status + "$?" )) + + exit "$status" +} + + + +lint + @@ -14,8 +14,16 @@ # See the License for the specific language governing permissions and # # limitations under the License. # ############################################################################## +case "$1" in + "--no-git") + true;; # noop + "") + git pull;; + *) + echo "I did not understand the arg $1" + exit 1 + ;; +esac -if git pull ; then - rm -rf /opt/stackstorm/packs/laas/* && cp -r laas/ /opt/stackstorm/packs/ - st2ctl reload --register-all -fi +rm -rf /opt/stackstorm/packs/laas/* && cp -r laas/ /opt/stackstorm/packs/ +st2ctl reload --register-all |