From c9ccf6908f31a9b6ab7f3f3798225c523e3da857 Mon Sep 17 00:00:00 2001 From: westcl4 Date: Tue, 13 Sep 2022 15:13:54 +1200 Subject: [PATCH 01/14] Created Python Venv --- assignment.py => assignment2/assignment.py | 26 ++++++ assignment2/bin/activate | 84 +++++++++++++++++ assignment2/bin/activate.csh | 55 ++++++++++++ assignment2/bin/activate.fish | 100 +++++++++++++++++++++ assignment2/bin/activate.ps1 | 60 +++++++++++++ assignment2/bin/activate.xsh | 46 ++++++++++ assignment2/bin/activate_this.py | 32 +++++++ assignment2/bin/easy_install | 8 ++ assignment2/bin/easy_install-3.8 | 8 ++ assignment2/bin/easy_install3 | 8 ++ assignment2/bin/pip | 8 ++ assignment2/bin/pip-3.8 | 8 ++ assignment2/bin/pip3 | 8 ++ assignment2/bin/pip3.8 | 8 ++ assignment2/bin/python | 1 + assignment2/bin/python3 | 1 + assignment2/bin/python3.8 | 1 + assignment2/bin/wheel | 8 ++ assignment2/bin/wheel-3.8 | 8 ++ assignment2/bin/wheel3 | 8 ++ assignment2/pyvenv.cfg | 8 ++ 21 files changed, 494 insertions(+) rename assignment.py => assignment2/assignment.py (68%) create mode 100644 assignment2/bin/activate create mode 100644 assignment2/bin/activate.csh create mode 100644 assignment2/bin/activate.fish create mode 100644 assignment2/bin/activate.ps1 create mode 100644 assignment2/bin/activate.xsh create mode 100644 assignment2/bin/activate_this.py create mode 100755 assignment2/bin/easy_install create mode 100755 assignment2/bin/easy_install-3.8 create mode 100755 assignment2/bin/easy_install3 create mode 100755 assignment2/bin/pip create mode 100755 assignment2/bin/pip-3.8 create mode 100755 assignment2/bin/pip3 create mode 100755 assignment2/bin/pip3.8 create mode 120000 assignment2/bin/python create mode 120000 assignment2/bin/python3 create mode 120000 assignment2/bin/python3.8 create mode 100755 assignment2/bin/wheel create mode 100755 assignment2/bin/wheel-3.8 create mode 100755 assignment2/bin/wheel3 create mode 100644 assignment2/pyvenv.cfg diff --git a/assignment.py b/assignment2/assignment.py similarity index 68% rename from assignment.py rename to assignment2/assignment.py index 28758e7..4f07477 100644 --- a/assignment.py +++ b/assignment2/assignment.py @@ -1,8 +1,34 @@ +# Adapted from examples on the openstack github https://github.com/openstack/openstacksdk/tree/master/examples/compute + + + import argparse import openstack +def create_network(conn): + print("Create Network:") + + westcl4_net = conn.network.create_network( + name='westcl4-net' + ) + print(westcl4_net) + + westcl4_subnet = conn.network.create_subnet( + name='westcl4-subnet', + network_id=westcl4_subnet.id, + ip_version='4', + cidr='192.168.50.0/24', + gateway_ip='192.168.50.1') + + print(westcl4_subnet) + + + + def create(): ''' Create a set of Openstack resources ''' + + pass def run(): diff --git a/assignment2/bin/activate b/assignment2/bin/activate new file mode 100644 index 0000000..02d308f --- /dev/null +++ b/assignment2/bin/activate @@ -0,0 +1,84 @@ +# This file must be used with "source bin/activate" *from bash* +# you cannot run it directly + + +if [ "${BASH_SOURCE-}" = "$0" ]; then + echo "You must source this script: \$ source $0" >&2 + exit 33 +fi + +deactivate () { + unset -f pydoc >/dev/null 2>&1 + + # reset old environment variables + # ! [ -z ${VAR+_} ] returns true if VAR is declared at all + if ! [ -z "${_OLD_VIRTUAL_PATH:+_}" ] ; then + PATH="$_OLD_VIRTUAL_PATH" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if ! [ -z "${_OLD_VIRTUAL_PYTHONHOME+_}" ] ; then + PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # This should detect bash and zsh, which have a hash command that must + # be called to get it to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + if [ -n "${BASH-}" ] || [ -n "${ZSH_VERSION-}" ] ; then + hash -r 2>/dev/null + fi + + if ! [ -z "${_OLD_VIRTUAL_PS1+_}" ] ; then + PS1="$_OLD_VIRTUAL_PS1" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + if [ ! "${1-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +VIRTUAL_ENV='/home/conor/virt_assignment/virt-openstack-assignment/assignment2' +export VIRTUAL_ENV + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/bin:$PATH" +export PATH + +# unset PYTHONHOME if set +if ! [ -z "${PYTHONHOME+_}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="$PYTHONHOME" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1-}" + if [ "x" != x ] ; then + PS1="${PS1-}" + else + PS1="(`basename \"$VIRTUAL_ENV\"`) ${PS1-}" + fi + export PS1 +fi + +# Make sure to unalias pydoc if it's already there +alias pydoc 2>/dev/null >/dev/null && unalias pydoc || true + +pydoc () { + python -m pydoc "$@" +} + +# This should detect bash and zsh, which have a hash command that must +# be called to get it to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +if [ -n "${BASH-}" ] || [ -n "${ZSH_VERSION-}" ] ; then + hash -r 2>/dev/null +fi diff --git a/assignment2/bin/activate.csh b/assignment2/bin/activate.csh new file mode 100644 index 0000000..e9a0d6d --- /dev/null +++ b/assignment2/bin/activate.csh @@ -0,0 +1,55 @@ +# This file must be used with "source bin/activate.csh" *from csh*. +# You cannot run it directly. +# Created by Davide Di Blasi . + +set newline='\ +' + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH:q" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT:q" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate && unalias pydoc' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV '/home/conor/virt_assignment/virt-openstack-assignment/assignment2' + +set _OLD_VIRTUAL_PATH="$PATH:q" +setenv PATH "$VIRTUAL_ENV:q/bin:$PATH:q" + + + +if ('' != "") then + set env_name = '' +else + set env_name = '('"$VIRTUAL_ENV:t:q"') ' +endif + +if ( $?VIRTUAL_ENV_DISABLE_PROMPT ) then + if ( $VIRTUAL_ENV_DISABLE_PROMPT == "" ) then + set do_prompt = "1" + else + set do_prompt = "0" + endif +else + set do_prompt = "1" +endif + +if ( $do_prompt == "1" ) then + # Could be in a non-interactive environment, + # in which case, $prompt is undefined and we wouldn't + # care about the prompt anyway. + if ( $?prompt ) then + set _OLD_VIRTUAL_PROMPT="$prompt:q" + if ( "$prompt:q" =~ *"$newline:q"* ) then + : + else + set prompt = "$env_name:q$prompt:q" + endif + endif +endif + +unset env_name +unset do_prompt + +alias pydoc python -m pydoc + +rehash diff --git a/assignment2/bin/activate.fish b/assignment2/bin/activate.fish new file mode 100644 index 0000000..25e3447 --- /dev/null +++ b/assignment2/bin/activate.fish @@ -0,0 +1,100 @@ +# This file must be used using `source bin/activate.fish` *within a running fish ( http://fishshell.com ) session*. +# Do not run it directly. + +function _bashify_path -d "Converts a fish path to something bash can recognize" + set fishy_path $argv + set bashy_path $fishy_path[1] + for path_part in $fishy_path[2..-1] + set bashy_path "$bashy_path:$path_part" + end + echo $bashy_path +end + +function _fishify_path -d "Converts a bash path to something fish can recognize" + echo $argv | tr ':' '\n' +end + +function deactivate -d 'Exit virtualenv mode and return to the normal environment.' + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + # https://github.com/fish-shell/fish-shell/issues/436 altered PATH handling + if test (echo $FISH_VERSION | head -c 1) -lt 3 + set -gx PATH (_fishify_path "$_OLD_VIRTUAL_PATH") + else + set -gx PATH "$_OLD_VIRTUAL_PATH" + end + set -e _OLD_VIRTUAL_PATH + end + + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME "$_OLD_VIRTUAL_PYTHONHOME" + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + and functions -q _old_fish_prompt + # Set an empty local `$fish_function_path` to allow the removal of `fish_prompt` using `functions -e`. + set -l fish_function_path + + # Erase virtualenv's `fish_prompt` and restore the original. + functions -e fish_prompt + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + set -e _OLD_FISH_PROMPT_OVERRIDE + end + + set -e VIRTUAL_ENV + + if test "$argv[1]" != 'nondestructive' + # Self-destruct! + functions -e pydoc + functions -e deactivate + functions -e _bashify_path + functions -e _fishify_path + end +end + +# Unset irrelevant variables. +deactivate nondestructive + +set -gx VIRTUAL_ENV '/home/conor/virt_assignment/virt-openstack-assignment/assignment2' + +# https://github.com/fish-shell/fish-shell/issues/436 altered PATH handling +if test (echo $FISH_VERSION | head -c 1) -lt 3 + set -gx _OLD_VIRTUAL_PATH (_bashify_path $PATH) +else + set -gx _OLD_VIRTUAL_PATH "$PATH" +end +set -gx PATH "$VIRTUAL_ENV"'/bin' $PATH + +# Unset `$PYTHONHOME` if set. +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +function pydoc + python -m pydoc $argv +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # Copy the current `fish_prompt` function as `_old_fish_prompt`. + functions -c fish_prompt _old_fish_prompt + + function fish_prompt + # Run the user's prompt first; it might depend on (pipe)status. + set -l prompt (_old_fish_prompt) + + # Prompt override provided? + # If not, just prepend the environment name. + if test -n '' + printf '%s%s' '' (set_color normal) + else + printf '%s(%s) ' (set_color normal) (basename "$VIRTUAL_ENV") + end + + string join -- \n $prompt # handle multi-line prompts + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" +end diff --git a/assignment2/bin/activate.ps1 b/assignment2/bin/activate.ps1 new file mode 100644 index 0000000..95504d3 --- /dev/null +++ b/assignment2/bin/activate.ps1 @@ -0,0 +1,60 @@ +$script:THIS_PATH = $myinvocation.mycommand.path +$script:BASE_DIR = Split-Path (Resolve-Path "$THIS_PATH/..") -Parent + +function global:deactivate([switch] $NonDestructive) { + if (Test-Path variable:_OLD_VIRTUAL_PATH) { + $env:PATH = $variable:_OLD_VIRTUAL_PATH + Remove-Variable "_OLD_VIRTUAL_PATH" -Scope global + } + + if (Test-Path function:_old_virtual_prompt) { + $function:prompt = $function:_old_virtual_prompt + Remove-Item function:\_old_virtual_prompt + } + + if ($env:VIRTUAL_ENV) { + Remove-Item env:VIRTUAL_ENV -ErrorAction SilentlyContinue + } + + if (!$NonDestructive) { + # Self destruct! + Remove-Item function:deactivate + Remove-Item function:pydoc + } +} + +function global:pydoc { + python -m pydoc $args +} + +# unset irrelevant variables +deactivate -nondestructive + +$VIRTUAL_ENV = $BASE_DIR +$env:VIRTUAL_ENV = $VIRTUAL_ENV + +New-Variable -Scope global -Name _OLD_VIRTUAL_PATH -Value $env:PATH + +$env:PATH = "$env:VIRTUAL_ENV/bin:" + $env:PATH +if (!$env:VIRTUAL_ENV_DISABLE_PROMPT) { + function global:_old_virtual_prompt { + "" + } + $function:_old_virtual_prompt = $function:prompt + + if ("" -ne "") { + function global:prompt { + # Add the custom prefix to the existing prompt + $previous_prompt_value = & $function:_old_virtual_prompt + ("" + $previous_prompt_value) + } + } + else { + function global:prompt { + # Add a prefix to the current prompt, but don't discard it. + $previous_prompt_value = & $function:_old_virtual_prompt + $new_prompt_value = "($( Split-Path $env:VIRTUAL_ENV -Leaf )) " + ($new_prompt_value + $previous_prompt_value) + } + } +} diff --git a/assignment2/bin/activate.xsh b/assignment2/bin/activate.xsh new file mode 100644 index 0000000..9f2110c --- /dev/null +++ b/assignment2/bin/activate.xsh @@ -0,0 +1,46 @@ +"""Xonsh activate script for virtualenv""" +from xonsh.tools import get_sep as _get_sep + +def _deactivate(args): + if "pydoc" in aliases: + del aliases["pydoc"] + + if ${...}.get("_OLD_VIRTUAL_PATH", ""): + $PATH = $_OLD_VIRTUAL_PATH + del $_OLD_VIRTUAL_PATH + + if ${...}.get("_OLD_VIRTUAL_PYTHONHOME", ""): + $PYTHONHOME = $_OLD_VIRTUAL_PYTHONHOME + del $_OLD_VIRTUAL_PYTHONHOME + + if "VIRTUAL_ENV" in ${...}: + del $VIRTUAL_ENV + + if "VIRTUAL_ENV_PROMPT" in ${...}: + del $VIRTUAL_ENV_PROMPT + + if "nondestructive" not in args: + # Self destruct! + del aliases["deactivate"] + + +# unset irrelevant variables +_deactivate(["nondestructive"]) +aliases["deactivate"] = _deactivate + +$VIRTUAL_ENV = r"/home/conor/virt_assignment/virt-openstack-assignment/assignment2" + +$_OLD_VIRTUAL_PATH = $PATH +$PATH = $PATH[:] +$PATH.add($VIRTUAL_ENV + _get_sep() + "bin", front=True, replace=True) + +if ${...}.get("PYTHONHOME", ""): + # unset PYTHONHOME if set + $_OLD_VIRTUAL_PYTHONHOME = $PYTHONHOME + del $PYTHONHOME + +$VIRTUAL_ENV_PROMPT = "" +if not $VIRTUAL_ENV_PROMPT: + del $VIRTUAL_ENV_PROMPT + +aliases["pydoc"] = ["python", "-m", "pydoc"] diff --git a/assignment2/bin/activate_this.py b/assignment2/bin/activate_this.py new file mode 100644 index 0000000..4479986 --- /dev/null +++ b/assignment2/bin/activate_this.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +"""Activate virtualenv for current interpreter: + +Use exec(open(this_file).read(), {'__file__': this_file}). + +This can be used when you must use an existing Python interpreter, not the virtualenv bin/python. +""" +import os +import site +import sys + +try: + abs_file = os.path.abspath(__file__) +except NameError: + raise AssertionError("You must use exec(open(this_file).read(), {'__file__': this_file}))") + +bin_dir = os.path.dirname(abs_file) +base = bin_dir[: -len("bin") - 1] # strip away the bin part from the __file__, plus the path separator + +# prepend bin to PATH (this file is inside the bin directory) +os.environ["PATH"] = os.pathsep.join([bin_dir] + os.environ.get("PATH", "").split(os.pathsep)) +os.environ["VIRTUAL_ENV"] = base # virtual env is right above bin directory + +# add the virtual environments libraries to the host python import mechanism +prev_length = len(sys.path) +for lib in "../lib/python3.8/site-packages".split(os.pathsep): + path = os.path.realpath(os.path.join(bin_dir, lib)) + site.addsitedir(path.decode("utf-8") if "" else path) +sys.path[:] = sys.path[prev_length:] + sys.path[0:prev_length] + +sys.real_prefix = sys.prefix +sys.prefix = base diff --git a/assignment2/bin/easy_install b/assignment2/bin/easy_install new file mode 100755 index 0000000..6476457 --- /dev/null +++ b/assignment2/bin/easy_install @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from setuptools.command.easy_install import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/assignment2/bin/easy_install-3.8 b/assignment2/bin/easy_install-3.8 new file mode 100755 index 0000000..6476457 --- /dev/null +++ b/assignment2/bin/easy_install-3.8 @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from setuptools.command.easy_install import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/assignment2/bin/easy_install3 b/assignment2/bin/easy_install3 new file mode 100755 index 0000000..6476457 --- /dev/null +++ b/assignment2/bin/easy_install3 @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from setuptools.command.easy_install import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/assignment2/bin/pip b/assignment2/bin/pip new file mode 100755 index 0000000..708e064 --- /dev/null +++ b/assignment2/bin/pip @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/assignment2/bin/pip-3.8 b/assignment2/bin/pip-3.8 new file mode 100755 index 0000000..708e064 --- /dev/null +++ b/assignment2/bin/pip-3.8 @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/assignment2/bin/pip3 b/assignment2/bin/pip3 new file mode 100755 index 0000000..708e064 --- /dev/null +++ b/assignment2/bin/pip3 @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/assignment2/bin/pip3.8 b/assignment2/bin/pip3.8 new file mode 100755 index 0000000..708e064 --- /dev/null +++ b/assignment2/bin/pip3.8 @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/assignment2/bin/python b/assignment2/bin/python new file mode 120000 index 0000000..ae65fda --- /dev/null +++ b/assignment2/bin/python @@ -0,0 +1 @@ +/usr/bin/python3 \ No newline at end of file diff --git a/assignment2/bin/python3 b/assignment2/bin/python3 new file mode 120000 index 0000000..d8654aa --- /dev/null +++ b/assignment2/bin/python3 @@ -0,0 +1 @@ +python \ No newline at end of file diff --git a/assignment2/bin/python3.8 b/assignment2/bin/python3.8 new file mode 120000 index 0000000..d8654aa --- /dev/null +++ b/assignment2/bin/python3.8 @@ -0,0 +1 @@ +python \ No newline at end of file diff --git a/assignment2/bin/wheel b/assignment2/bin/wheel new file mode 100755 index 0000000..ce30962 --- /dev/null +++ b/assignment2/bin/wheel @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from wheel.cli import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/assignment2/bin/wheel-3.8 b/assignment2/bin/wheel-3.8 new file mode 100755 index 0000000..ce30962 --- /dev/null +++ b/assignment2/bin/wheel-3.8 @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from wheel.cli import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/assignment2/bin/wheel3 b/assignment2/bin/wheel3 new file mode 100755 index 0000000..ce30962 --- /dev/null +++ b/assignment2/bin/wheel3 @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from wheel.cli import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/assignment2/pyvenv.cfg b/assignment2/pyvenv.cfg new file mode 100644 index 0000000..7ba78fa --- /dev/null +++ b/assignment2/pyvenv.cfg @@ -0,0 +1,8 @@ +home = /usr +implementation = CPython +version_info = 3.8.10.final.0 +virtualenv = 20.0.17 +include-system-site-packages = false +base-prefix = /usr +base-exec-prefix = /usr +base-executable = /usr/bin/python3 From dcebc8fc2402c564319128a880fc11e4d7f88c0a Mon Sep 17 00:00:00 2001 From: westcl4 Date: Tue, 13 Sep 2022 15:29:38 +1200 Subject: [PATCH 02/14] Added catalst cloud connection --- assignment2/assignment.py | 3 +- assignment2/bin/ceilometer | 8 + assignment2/bin/cinder | 8 + assignment2/bin/convert-json | 8 + assignment2/bin/heat | 8 + assignment2/bin/jp.py | 54 ++++++ assignment2/bin/jsondiff | 39 ++++ assignment2/bin/jsonpatch | 107 +++++++++++ assignment2/bin/jsonpointer | 69 +++++++ assignment2/bin/netaddr | 8 + assignment2/bin/neutron | 8 + assignment2/bin/normalizer | 8 + assignment2/bin/nova | 8 + assignment2/bin/openstack | 8 + assignment2/bin/openstack-inventory | 8 + assignment2/bin/oslo-config-generator | 8 + assignment2/bin/oslo-config-validator | 8 + assignment2/bin/pbr | 8 + assignment2/bin/pybabel | 8 + assignment2/bin/swift | 8 + assignment2/clouds.yaml | 19 ++ assignment2/share/man/man1/swift.1 | 214 ++++++++++++++++++++++ assignment2/tom-clark-openrc.sh | 250 ++++++++++++++++++++++++++ 23 files changed, 873 insertions(+), 2 deletions(-) create mode 100755 assignment2/bin/ceilometer create mode 100755 assignment2/bin/cinder create mode 100755 assignment2/bin/convert-json create mode 100755 assignment2/bin/heat create mode 100755 assignment2/bin/jp.py create mode 100755 assignment2/bin/jsondiff create mode 100755 assignment2/bin/jsonpatch create mode 100755 assignment2/bin/jsonpointer create mode 100755 assignment2/bin/netaddr create mode 100755 assignment2/bin/neutron create mode 100755 assignment2/bin/normalizer create mode 100755 assignment2/bin/nova create mode 100755 assignment2/bin/openstack create mode 100755 assignment2/bin/openstack-inventory create mode 100755 assignment2/bin/oslo-config-generator create mode 100755 assignment2/bin/oslo-config-validator create mode 100755 assignment2/bin/pbr create mode 100755 assignment2/bin/pybabel create mode 100755 assignment2/bin/swift create mode 100644 assignment2/clouds.yaml create mode 100644 assignment2/share/man/man1/swift.1 create mode 100644 assignment2/tom-clark-openrc.sh diff --git a/assignment2/assignment.py b/assignment2/assignment.py index 4f07477..34247b4 100644 --- a/assignment2/assignment.py +++ b/assignment2/assignment.py @@ -1,7 +1,6 @@ # Adapted from examples on the openstack github https://github.com/openstack/openstacksdk/tree/master/examples/compute - import argparse import openstack @@ -27,7 +26,7 @@ def create_network(conn): def create(): ''' Create a set of Openstack resources ''' - + print("Create test") pass diff --git a/assignment2/bin/ceilometer b/assignment2/bin/ceilometer new file mode 100755 index 0000000..5173282 --- /dev/null +++ b/assignment2/bin/ceilometer @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from ceilometerclient.shell import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/assignment2/bin/cinder b/assignment2/bin/cinder new file mode 100755 index 0000000..140735f --- /dev/null +++ b/assignment2/bin/cinder @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from cinderclient.shell import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/assignment2/bin/convert-json b/assignment2/bin/convert-json new file mode 100755 index 0000000..ef30af1 --- /dev/null +++ b/assignment2/bin/convert-json @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from oslo_log.cmds.convert_json import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/assignment2/bin/heat b/assignment2/bin/heat new file mode 100755 index 0000000..218bdc4 --- /dev/null +++ b/assignment2/bin/heat @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from heatclient.shell import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/assignment2/bin/jp.py b/assignment2/bin/jp.py new file mode 100755 index 0000000..bdde9a9 --- /dev/null +++ b/assignment2/bin/jp.py @@ -0,0 +1,54 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python + +import sys +import json +import argparse +from pprint import pformat + +import jmespath +from jmespath import exceptions + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('expression') + parser.add_argument('-f', '--filename', + help=('The filename containing the input data. ' + 'If a filename is not given then data is ' + 'read from stdin.')) + parser.add_argument('--ast', action='store_true', + help=('Pretty print the AST, do not search the data.')) + args = parser.parse_args() + expression = args.expression + if args.ast: + # Only print the AST + expression = jmespath.compile(args.expression) + sys.stdout.write(pformat(expression.parsed)) + sys.stdout.write('\n') + return 0 + if args.filename: + with open(args.filename, 'r') as f: + data = json.load(f) + else: + data = sys.stdin.read() + data = json.loads(data) + try: + sys.stdout.write(json.dumps( + jmespath.search(expression, data), indent=4, ensure_ascii=False)) + sys.stdout.write('\n') + except exceptions.ArityError as e: + sys.stderr.write("invalid-arity: %s\n" % e) + return 1 + except exceptions.JMESPathTypeError as e: + sys.stderr.write("invalid-type: %s\n" % e) + return 1 + except exceptions.UnknownFunctionError as e: + sys.stderr.write("unknown-function: %s\n" % e) + return 1 + except exceptions.ParseError as e: + sys.stderr.write("syntax-error: %s\n" % e) + return 1 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/assignment2/bin/jsondiff b/assignment2/bin/jsondiff new file mode 100755 index 0000000..865b08b --- /dev/null +++ b/assignment2/bin/jsondiff @@ -0,0 +1,39 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- + +from __future__ import print_function + +import sys +import json +import jsonpatch +import argparse + + +parser = argparse.ArgumentParser(description='Diff two JSON files') +parser.add_argument('FILE1', type=argparse.FileType('r')) +parser.add_argument('FILE2', type=argparse.FileType('r')) +parser.add_argument('--indent', type=int, default=None, + help='Indent output by n spaces') +parser.add_argument('-v', '--version', action='version', + version='%(prog)s ' + jsonpatch.__version__) + + +def main(): + try: + diff_files() + except KeyboardInterrupt: + sys.exit(1) + + +def diff_files(): + """ Diffs two JSON files and prints a patch """ + args = parser.parse_args() + doc1 = json.load(args.FILE1) + doc2 = json.load(args.FILE2) + patch = jsonpatch.make_patch(doc1, doc2) + if patch.patch: + print(json.dumps(patch.patch, indent=args.indent)) + sys.exit(1) + +if __name__ == "__main__": + main() diff --git a/assignment2/bin/jsonpatch b/assignment2/bin/jsonpatch new file mode 100755 index 0000000..5f99ca8 --- /dev/null +++ b/assignment2/bin/jsonpatch @@ -0,0 +1,107 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- + +import sys +import os.path +import json +import jsonpatch +import tempfile +import argparse + + +parser = argparse.ArgumentParser( + description='Apply a JSON patch on a JSON file') +parser.add_argument('ORIGINAL', type=argparse.FileType('r'), + help='Original file') +parser.add_argument('PATCH', type=argparse.FileType('r'), + nargs='?', default=sys.stdin, + help='Patch file (read from stdin if omitted)') +parser.add_argument('--indent', type=int, default=None, + help='Indent output by n spaces') +parser.add_argument('-b', '--backup', action='store_true', + help='Back up ORIGINAL if modifying in-place') +parser.add_argument('-i', '--in-place', action='store_true', + help='Modify ORIGINAL in-place instead of to stdout') +parser.add_argument('-v', '--version', action='version', + version='%(prog)s ' + jsonpatch.__version__) +parser.add_argument('-u', '--preserve-unicode', action='store_true', + help='Output Unicode character as-is without using Code Point') + +def main(): + try: + patch_files() + except KeyboardInterrupt: + sys.exit(1) + + +def patch_files(): + """ Diffs two JSON files and prints a patch """ + args = parser.parse_args() + doc = json.load(args.ORIGINAL) + patch = json.load(args.PATCH) + result = jsonpatch.apply_patch(doc, patch) + + if args.in_place: + dirname = os.path.abspath(os.path.dirname(args.ORIGINAL.name)) + + try: + # Attempt to replace the file atomically. We do this by + # creating a temporary file in the same directory as the + # original file so we can atomically move the new file over + # the original later. (This is done in the same directory + # because atomic renames do not work across mount points.) + + fd, pathname = tempfile.mkstemp(dir=dirname) + fp = os.fdopen(fd, 'w') + atomic = True + + except OSError: + # We failed to create the temporary file for an atomic + # replace, so fall back to non-atomic mode by backing up + # the original (if desired) and writing a new file. + + if args.backup: + os.rename(args.ORIGINAL.name, args.ORIGINAL.name + '.orig') + fp = open(args.ORIGINAL.name, 'w') + atomic = False + + else: + # Since we're not replacing the original file in-place, write + # the modified JSON to stdout instead. + + fp = sys.stdout + + # By this point we have some sort of file object we can write the + # modified JSON to. + + json.dump(result, fp, indent=args.indent, ensure_ascii=not(args.preserve_unicode)) + fp.write('\n') + + if args.in_place: + # Close the new file. If we aren't replacing atomically, this + # is our last step, since everything else is already in place. + + fp.close() + + if atomic: + try: + # Complete the atomic replace by linking the original + # to a backup (if desired), fixing up the permissions + # on the temporary file, and moving it into place. + + if args.backup: + os.link(args.ORIGINAL.name, args.ORIGINAL.name + '.orig') + os.chmod(pathname, os.stat(args.ORIGINAL.name).st_mode) + os.rename(pathname, args.ORIGINAL.name) + + except OSError: + # In the event we could not actually do the atomic + # replace, unlink the original to move it out of the + # way and finally move the temporary file into place. + + os.unlink(args.ORIGINAL.name) + os.rename(pathname, args.ORIGINAL.name) + + +if __name__ == "__main__": + main() diff --git a/assignment2/bin/jsonpointer b/assignment2/bin/jsonpointer new file mode 100755 index 0000000..be04112 --- /dev/null +++ b/assignment2/bin/jsonpointer @@ -0,0 +1,69 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- + +from __future__ import print_function + +import sys +import os.path +import json +import jsonpointer +import argparse + + +parser = argparse.ArgumentParser( + description='Resolve a JSON pointer on JSON files') + +# Accept pointer as argument or as file +ptr_group = parser.add_mutually_exclusive_group(required=True) + +ptr_group.add_argument('-f', '--pointer-file', type=argparse.FileType('r'), + nargs='?', + help='File containing a JSON pointer expression') + +ptr_group.add_argument('POINTER', type=str, nargs='?', + help='A JSON pointer expression') + +parser.add_argument('FILE', type=argparse.FileType('r'), nargs='+', + help='Files for which the pointer should be resolved') +parser.add_argument('--indent', type=int, default=None, + help='Indent output by n spaces') +parser.add_argument('-v', '--version', action='version', + version='%(prog)s ' + jsonpointer.__version__) + + +def main(): + try: + resolve_files() + except KeyboardInterrupt: + sys.exit(1) + + +def parse_pointer(args): + if args.POINTER: + ptr = args.POINTER + elif args.pointer_file: + ptr = args.pointer_file.read().strip() + else: + parser.print_usage() + sys.exit(1) + + return ptr + + +def resolve_files(): + """ Resolve a JSON pointer on JSON files """ + args = parser.parse_args() + + ptr = parse_pointer(args) + + for f in args.FILE: + doc = json.load(f) + try: + result = jsonpointer.resolve_pointer(doc, ptr) + print(json.dumps(result, indent=args.indent)) + except jsonpointer.JsonPointerException as e: + print('Could not resolve pointer: %s' % str(e), file=sys.stderr) + + +if __name__ == "__main__": + main() diff --git a/assignment2/bin/netaddr b/assignment2/bin/netaddr new file mode 100755 index 0000000..5f857fb --- /dev/null +++ b/assignment2/bin/netaddr @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from netaddr.cli import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/assignment2/bin/neutron b/assignment2/bin/neutron new file mode 100755 index 0000000..c3fa122 --- /dev/null +++ b/assignment2/bin/neutron @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from neutronclient.shell import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/assignment2/bin/normalizer b/assignment2/bin/normalizer new file mode 100755 index 0000000..22e4279 --- /dev/null +++ b/assignment2/bin/normalizer @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from charset_normalizer.cli.normalizer import cli_detect +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(cli_detect()) diff --git a/assignment2/bin/nova b/assignment2/bin/nova new file mode 100755 index 0000000..7f7999f --- /dev/null +++ b/assignment2/bin/nova @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from novaclient.shell import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/assignment2/bin/openstack b/assignment2/bin/openstack new file mode 100755 index 0000000..ff18329 --- /dev/null +++ b/assignment2/bin/openstack @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from openstackclient.shell import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/assignment2/bin/openstack-inventory b/assignment2/bin/openstack-inventory new file mode 100755 index 0000000..7cf1acf --- /dev/null +++ b/assignment2/bin/openstack-inventory @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from openstack.cloud.cmd.inventory import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/assignment2/bin/oslo-config-generator b/assignment2/bin/oslo-config-generator new file mode 100755 index 0000000..11f04bf --- /dev/null +++ b/assignment2/bin/oslo-config-generator @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from oslo_config.generator import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/assignment2/bin/oslo-config-validator b/assignment2/bin/oslo-config-validator new file mode 100755 index 0000000..1d93cfa --- /dev/null +++ b/assignment2/bin/oslo-config-validator @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from oslo_config.validator import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/assignment2/bin/pbr b/assignment2/bin/pbr new file mode 100755 index 0000000..926a7cb --- /dev/null +++ b/assignment2/bin/pbr @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from pbr.cmd.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/assignment2/bin/pybabel b/assignment2/bin/pybabel new file mode 100755 index 0000000..5f465f6 --- /dev/null +++ b/assignment2/bin/pybabel @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from babel.messages.frontend import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/assignment2/bin/swift b/assignment2/bin/swift new file mode 100755 index 0000000..a1faf05 --- /dev/null +++ b/assignment2/bin/swift @@ -0,0 +1,8 @@ +#!/home/conor/virt_assignment/virt-openstack-assignment/assignment2/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from swiftclient.shell import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/assignment2/clouds.yaml b/assignment2/clouds.yaml new file mode 100644 index 0000000..9eb21c5 --- /dev/null +++ b/assignment2/clouds.yaml @@ -0,0 +1,19 @@ +# This is a clouds.yaml file, which can be used by OpenStack tools as a source +# of configuration on how to connect to a cloud. If this is your only cloud, +# just put this file in ~/.config/openstack/clouds.yaml and tools like +# python-openstackclient will just work with no further config. (You will need +# to add your password to the auth section) +# If you have more than one cloud account, add the cloud entry to the clouds +# section of your existing file and you can refer to them by name with +# OS_CLOUD=catalystcloud or --os-cloud=catalystcloud +clouds: + catalystcloud: + auth: + auth_url: https://api.nz-por-1.catalystcloud.io:5000 + username: "WESTCL4@student.op.ac.nz" + project_id: 8e0cb4b58cee49289ea45cd97ea6ef49 + project_name: "tom-clark" + user_domain_name: "Default" + region_name: "nz-por-1" + interface: "public" + identity_api_version: 3 \ No newline at end of file diff --git a/assignment2/share/man/man1/swift.1 b/assignment2/share/man/man1/swift.1 new file mode 100644 index 0000000..00e1440 --- /dev/null +++ b/assignment2/share/man/man1/swift.1 @@ -0,0 +1,214 @@ +.\" +.\" Author: Joao Marcelo Martins or +.\" Copyright (c) 2010-2011 OpenStack Foundation. +.\" +.\" Licensed under the Apache License, Version 2.0 (the "License"); +.\" you may not use this file except in compliance with the License. +.\" You may obtain a copy of the License at +.\" +.\" http://www.apache.org/licenses/LICENSE-2.0 +.\" +.\" Unless required by applicable law or agreed to in writing, software +.\" distributed under the License is distributed on an "AS IS" BASIS, +.\" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +.\" implied. +.\" See the License for the specific language governing permissions and +.\" limitations under the License. +.\" +.TH swift 1 "8/26/2011" "Linux" "OpenStack Swift" + +.SH NAME +.LP +.B swift +\- OpenStack Swift client tool + +.SH SYNOPSIS +.LP +.B swift +[options] [args] + +.SH DESCRIPTION +.PP +The \fBswift\fR tool is a command line utility for communicating with +an OpenStack Object Storage (Swift) environment. It allows one to perform +several types of operations. + +.SH COMMANDS +.PP + +\fBstat\fR [\fIcommand-options\fR] [\fIcontainer\fR] [\fIobject\fR] +.RS 4 +Displays information for the account, container, or object depending on the args given (if any). +In verbose mode, the Storage URL and the authentication token are displayed +as well. Option \-\-lh reports sizes in human readable format similar to ls \-lh. +.RE + +\fBlist\fR [\fIcommand-options\fR] [\fIcontainer\fR] +.RS 4 +Lists the containers for the account or the objects for a container. +The \-p or \-\-prefix is an option that will only list items beginning +with that prefix. The \-d or \-\-delimiter is option +(for container listings only) that will roll up items with the given +delimiter (see OpenStack Swift general documentation for what this means). + +The \-l or \-\-long and \-\-lh options provide more detail, similar to ls \-l and ls \-lh, the latter +providing sizes in human readable format (eg 3K, 12M, etc). These latter 2 switches +use more overhead to get those details, which is directly proportional to the number +of container or objects being listed. With the \-t or \-\-total option they only report totals. +.RE + +\fBupload\fR [\fIcommand-options\fR] container file_or_directory [\fIfile_or_directory\fR] [...] +.RS 4 +Uploads to the given container the files and directories specified by the +remaining args. The \-c or \-\-changed is an option that will only upload files +that have changed since the last upload. The \-\-object\-name is +an option that will upload file and name object to or upload dir +and use as object prefix. If the file name is "-", reads the +content from standard input. In this case, \-\-object\-name is required and no +other files may be given. The \-S or \-\-segment\-size and +\-\-leave\-segments and others are options as well (see swift upload \-\-help +for more). +.RE + +\fBpost\fR [\fIcommand-options\fR] [\fIcontainer\fR] [\fIobject\fR] +.RS 4 +Updates meta information for the account, container, or object depending +on the args given. If the container is not found, it will be created +automatically; but this is not true for accounts and objects. Containers +also allow the \-r (or \-\-read\-acl) and \-w (or \-\-write\-acl) options. The \-m +or \-\-meta option is allowed on all and used to define the user meta data +items to set in the form Name:Value. This option can be repeated. +For more details and options see swift post \-\-help. +\fBExample\fR: post \-m Color:Blue \-m Size:Large +.RE + +\fBcopy\fR [\fIcommand-options\fR] \fIcontainer\fR \fIobject\fR +.RS 4 +Copies an object to a new destination or adds user metadata to the object (current +user metadata will be preserved, in contrast with the post command) depending +on the args given. The \-\-destination option sets the destination in the form +/container/object. If not set, the object will be copied onto itself which is useful +for adding metadata. The \-M or \-\-fresh\-metadata option copies the object without +the existing user metadata. The \-m or \-\-meta option is always allowed and is used +to define the user metadata items to set in the form Name:Value (this option +can be repeated). +For more details and options see swift copy \-\-help. +.RE + +\fBdownload\fR [\fIcommand-options\fR] [\fIcontainer\fR] [\fIobject\fR] [\fIobject\fR] [...] +.RS 4 +Downloads everything in the account (with \-\-all), or everything in a +container, or a list of objects depending on the args given. For a single +object download, you may use the \-o [\-\-output] option to +redirect the output to a specific file or if "-" then just redirect to stdout or +with \-\-no-download actually not to write anything to disk. +The \-\-ignore-checksum is an option that turns off checksum validation. +You can specify optional headers with the repeatable cURL-like option +\-H [\-\-header]. For more details and options see swift download \-\-help. +The \-\-ignore\-mtime option ignores the x\-object\-meta\-mtime metadata entry +on the object (if present) and instead creates the downloaded files with +fresh atime and mtime values. +.RE + +\fBdelete\fR [\fIcommand-options\fR] [\fIcontainer\fR] [\fIobject\fR] [\fIobject\fR] [...] +.RS 4 +Deletes everything in the account (with \-\-all), or everything in a container, +or all objects in a container that start with a given string (given by \-\-prefix), +or a list of objects depending on the args given. Segments of manifest objects +will be deleted as well, unless you specify the \-\-leave\-segments option. +For more details and options see swift delete \-\-help. +.RE + +\fBcapabilities\fR [\fIcommand-options\fR] [\fIproxy-url\fR] +.RS 4 +Displays cluster capabilities. If the proxy-url option is not provided the +storage-url retrieved after authentication is used as proxy-url. + +By default, the output includes the list of the activated Swift middlewares as +well as relevant options for each one. Additionally the command displays +relevant options for the Swift core. + +The \-\-json option will print a json representation of the cluster +capabilities. This is typically more suitable for consumption by other +programs, such as jq. + +\fBExample\fR: capabilities https://swift.example.com + capabilities \-\-json +.RE + +\fBtempurl\fR [\fIcommand-option\fR] \fImethod\fR \fItime\fR \fIpath\fR \fIkey\fR +.RS 4 +Generates a temporary URL allowing unauthenticated access to the Swift object +at the given path, using the given HTTP method, for the given time, +using the given TempURL key. + +The time can be specified either as an integer +denoting the amount of seconds the temporary URL is valid, or as an ISO 8601 +timestamp in one of following formats: Complete date: YYYY\-MM\-DD (eg 1997\-07\-16), +complete date plus hours, minutes and seconds: YYYY\-MM\-DDThh:mm:ss +(eg 1997\-07\-16T19:20:30) or complete date plus hours, minutes and seconds with +UTC designator: YYYY\-MM\-DDThh:mm:ssZ (eg 1997\-07\-16T19:20:30Z). Be aware that +if you do not use the latter format, the timestamp is generated using your locale +timezone. If the first format is used, the time part used will equal to 00:00:00. + +With the \-\-prefix\-based option a +prefix-based URL is generated. + +The option \-\-iso8601 provides ISO 8601 UTC timestamps +instead of Unix timestamps inside the generated URL. + +If optional \-\-absolute argument is +provided and the time argument is specified in seconds, the seconds are +interpreted as a Unix timestamp at which the URL +should expire. + +\fBExample\fR: tempurl GET $(date \-d "Jan 1 2016" +%s) +/v1/AUTH_foo/bar_container/quux.md my_secret_tempurl_key \-\-absolute + +.RE + +\fBauth\fR +.RS 4 +Display auth related authentication variables in shell friendly format. +For examples see swift auth \-\-help. +.RE + +.SH OPTIONS +.PD 0 +.IP "--version Show program's version number and exit" +.IP "-h, --help Show this (or any subcommand if after command) help message and exit" +.IP "-s, --snet Use SERVICENET internal network" +.IP "-v, --verbose Print more info" +.IP "-q, --quiet Suppress status output" +.IP "-A AUTH, --auth=AUTH URL for obtaining an auth token " +.IP "-U USER, --user=USER User name for obtaining an auth token" +.IP "-V 1|2, --auth-version=VERSION Authentication protocol version" +.IP "-K KEY, --key=KEY Key for obtaining an auth token" +.IP "--os-storage-url=URL Use this instead of URL returned from auth" +.IP "--os-help Show all OpenStack authentication options" +.PD +.RS 4 +For more options see swift \-\-help and swift \-\-os\-help. +.RE + + +.SH EXAMPLE +.PP +swift \-A https://127.0.0.1:443/auth/v1.0 \-U swiftops:swiftops \-K swiftops stat + +.RS 2 +.PD 0 +.IP " Account: AUTH_43b42dae-dc0b-4a4b-ac55-97de614d6e6e" +.IP "Containers: 1" +.IP " Objects: 1" +.IP " Bytes: 1124" +.IP "Accept-Ranges: bytes" +.IP "X-Trans-Id: txb21186a9eef64ed295a1e95896a0fc72" +.PD +.RE + + +.SH DOCUMENTATION +.LP +More in depth documentation about OpenStack Swift as a whole can be found at +.BI https://docs.openstack.org/swift/latest/ diff --git a/assignment2/tom-clark-openrc.sh b/assignment2/tom-clark-openrc.sh new file mode 100644 index 0000000..bf9b055 --- /dev/null +++ b/assignment2/tom-clark-openrc.sh @@ -0,0 +1,250 @@ +#!/usr/bin/env bash +############### +# Configuration +############### +#------------------------------------------- +# Configuration variables for Catalyst Cloud +#------------------------------------------- +# Set the authentication API and version. +export OS_AUTH_URL=https://api.nz-por-1.catalystcloud.io:5000/v3 +export OS_IDENTITY_API_VERSION=3 +# Set the domain name for authentication. +export OS_USER_DOMAIN_NAME="Default" +export OS_PROJECT_DOMAIN_ID="default" +# Set the user name. +export OS_USERNAME="WESTCL4@student.op.ac.nz" +# Set the project name and id (the name is sufficient if unique, but it is a +# best practice to set the id in case two projects with the same name exist). +export OS_PROJECT_ID=8e0cb4b58cee49289ea45cd97ea6ef49 +export OS_PROJECT_NAME="tom-clark" +# Set the region name. +export OS_REGION_NAME="nz-por-1" +# Blank variables can result in unexpected errors. Unset variables that were +# left empty. +if [[ -z "${OS_USER_DOMAIN_NAME}" ]]; then unset OS_USER_DOMAIN_NAME; fi +if [[ -z "${OS_PROJECT_DOMAIN_ID}" ]]; then unset OS_PROJECT_DOMAIN_ID; fi +if [[ -z "${OS_REGION_NAME}" ]]; then unset OS_REGION_NAME; fi +# As a precaution, unset deprecated OpenStack auth v2.0 variables (in case they +# have been set by other scripts or applications running on the same host). +unset OS_TENANT_ID +unset OS_TENANT_NAME +# Set BASH_SOURCE for ZSH +SCRIPT_SOURCE="${BASH_SOURCE[0]}" +if [[ -z "${SCRIPT_SOURCE}" ]]; then + SCRIPT_SOURCE="${0}" +fi +########### +# Functions +########### +# Style text output as sucess message (green) +success () { + echo -e "\e[32m${1}\e[0m" +} +# Style text output as warning message (yellow) +warning () { + echo -e "\e[33m${1}\e[0m" +} +# Style text output as error message (red) +error () { + echo -e "\e[31m${1}\e[0m" +} +# Style text output as error message (majenta) +debug () { + echo -e "\e[35m${1}\e[0m" +} +################################################## +# Parses token HTTP Response and sets it in +# environment as OS_TOKEN +# Globals: +# OS_TOKEN +# Arguments: +# String containing raw HTTP Response Text +################################################## +parse_token_from_response () { + OS_TOKEN=$(echo "${1}" \ + | grep -i X-Subject-Token \ + | awk '{print $2}' \ + | tr '\r' ' ' \ + | sed 's/[[:space:]]*$//') +} +################################################## +# Get an openstack token using the first method +# available (openstack, wget, curl) +# Globals: +# OS_AUTH_TYPE +# OS_TOKEN +# OS_AUTH_TOKEN +# Returns: +# 0 if OS_TOKEN was set, non-zero on error. +################################################## +get_cloud_token () { + echo "Requesting a new access token..." + # Clear previous access token stored in memory, if any (because it may have + # expired). + unset OS_AUTH_TYPE + unset OS_TOKEN + unset OS_AUTH_TOKEN + url="${OS_AUTH_URL}/auth/tokens" + data=' + { "auth": { + "identity": { + "methods": ["password"], + "password": { + "user": { + "name": "'${OS_USERNAME}'", + "domain": { "name": "'${OS_USER_DOMAIN_NAME}'" }, + "password": "'${OS_PASSWORD}'" + } + } + }, + "scope": { + "project": { + "id": "'${OS_PROJECT_ID}'" + } + } + } + }' + # Use one of the methods available in order of priority (openstack, wget, + # curl). + if [[ -x "$(command -v openstack)" ]]; then + # Use openstack CLI + OS_TOKEN=$(openstack token issue -f value -c id) + elif [[ -x "$(command -v wget)" ]]; then + # Use wget + response=$(wget -S -q -O - --header="Content-Type: application/json" --post-data "${data}" "${url}" 2>&1) + parse_token_from_response "${response}" + elif [[ -x "$(command -v curl)" ]]; then + # Use curl + response=$(curl -i -H "Content-Type: application/json" -d "${data}" "${url}" 2>&1) + parse_token_from_response "${response}" + else + error "Unable to find 'openstack', 'wget' or 'curl' in \$PATH. Please ensure at least one of 'python-openstackclient', 'wget' or 'curl' are installed and included in \$PATH." + return 1 + fi +} +################################################## +# Parse CLI options +# Globals: +# USE_TOKEN +# Returns: +# 0 if options parsed, non-zero if invalid +# option or help +################################################## +parse_arguments () { + # Reset variables before entering the parse loop, because they may have a + # value set in the current shell session. + USE_TOKEN="true" + while (( $# )); do + case "${1}" in + -n|--no-token) + USE_TOKEN="false" + warning "Warning: The --no-token option cannot be used with accounts that have MFA enabled. Disable MFA if using this option." + shift + ;; + -h|--help) + help + return 1 + ;; + *) # preserve positional arguments + error "Error: Unsupported option: $1" >&2 + display_usage + return 1 + ;; + esac + done +} +################################################## +# Prompts user to enter one time password via +# stdin and if provided, appends OTP to +# OS_PASSWORD. +# Globals: +# OS_PASSWORD +################################################## +prompt_mfa_passcode () { + echo -n "Please enter your MFA verification code (leave blank if not enabled): " + read -r one_time_passcode + if [[ -n "${one_time_passcode}" ]]; then + export OS_PASSWORD="${OS_PASSWORD}${one_time_passcode}" + else + warning "MFA is recommended and can be enabled under the settings tab of the dashboard." + fi + unset one_time_passcode +} +################################################## +# Prompt user to enter account password via stdin +# and sets password in environment as OS_PASSWORD +# Globals: +# OS_PASSWORD +# OS_USERNAME +################################################## +prompt_password (){ + echo -n "Please enter the password for user ${OS_USERNAME}: " + read -sr OS_PASSWORD + export OS_PASSWORD + echo "" +} +################################################## +# Display usage and then help information +# Globals: +# BASH_SOURCE +# Outputs: +# Writes help text to stdout +################################################## +display_usage () { + script_name=$(basename "${SCRIPT_SOURCE}") + echo "Usage: source ${script_name} [-h] [--no-input]" +} +################################################## +# Display usage and then help information +# Globals: +# BASH_SOURCE +# Outputs: +# Writes help text to stdout +################################################## +help () { + display_usage + echo "" + echo "Optional arguments:" + echo " -h, --help Show this help mesage and exit." + echo " -n, --no-token Sets the \$OS_USERNAME and \$OS_PASSWORD" + echo " environment variables, but does not fetch" + echo " or store an auth token on \$OS_AUTH_TOKEN or" + echo " \$OS_TOKEN." +} +########## +# Main () +########## +parse_arguments "$@" +# Exit if parse arguments returns non 0 value. +if [[ $? -ne 0 ]]; then + return 1 +fi +#---------------------------------------------------- +# Prompt for username and password for authentication +#---------------------------------------------------- +prompt_password +# Only prompt for MFA if user is using token based auth +if [[ "${USE_TOKEN}" == "true" ]]; then + prompt_mfa_passcode + get_cloud_token + if [[ -n "${OS_TOKEN}" ]]; then + export OS_TOKEN + export OS_AUTH_TYPE="token" + export OS_AUTH_TOKEN="${OS_TOKEN}" + success "Access token obtained successfully and stored in \$OS_TOKEN." + else + error "Failed to authenticate. Credentials may be incorrect or auth API inaccessible." + fi + # Clear all variables that are no longer needed from memory. + unset OS_PROJECT_NAME + unset OS_PROJECT_DOMAIN_ID + unset OS_USER_DOMAIN_NAME + unset OS_USERNAME + unset OS_PASSWORD +else + unset OS_AUTH_TYPE + unset OS_TOKEN + unset OS_AUTH_TOKEN + success "Environment variables required for authentication are set." + echo "You can use the \"openstack token issue\" command to obtain an auth token." +fi \ No newline at end of file From 5e425acd7da1d86d348393a7bbbfdeb18ab0acc6 Mon Sep 17 00:00:00 2001 From: westcl4 Date: Tue, 13 Sep 2022 15:57:58 +1200 Subject: [PATCH 03/14] Added constants module --- assignment2/assignment.py | 11 ++++++----- assignment2/constant.py | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 assignment2/constant.py diff --git a/assignment2/assignment.py b/assignment2/assignment.py index 34247b4..76ae031 100644 --- a/assignment2/assignment.py +++ b/assignment2/assignment.py @@ -1,25 +1,25 @@ # Adapted from examples on the openstack github https://github.com/openstack/openstacksdk/tree/master/examples/compute - +import constant import argparse import openstack -def create_network(conn): +def create_network(CONN): print("Create Network:") westcl4_net = conn.network.create_network( - name='westcl4-net' + name=constant.NETWORK ) print(westcl4_net) - westcl4_subnet = conn.network.create_subnet( + constant.USER_subnet = conn.network.create_subnet( name='westcl4-subnet', network_id=westcl4_subnet.id, ip_version='4', cidr='192.168.50.0/24', gateway_ip='192.168.50.1') - print(westcl4_subnet) + print(USER_subnet) @@ -27,6 +27,7 @@ def create_network(conn): def create(): ''' Create a set of Openstack resources ''' print("Create test") + print(constant.USER) pass diff --git a/assignment2/constant.py b/assignment2/constant.py new file mode 100644 index 0000000..ee63821 --- /dev/null +++ b/assignment2/constant.py @@ -0,0 +1,19 @@ +# file containing constants for the assignment project. +import openstack + +# network constants +CONN = openstack.connect(cloud_name='openstack', region_name='nz-por-1') + +USER = "westcl4" +NETWORK = "westcl4_net" +SUBNET = "westcl4_subnet" +VPC = "westcl4_vpc" +NETWORK = "westcl4_net" +CIDR = "192.168.50.0/24" +GATEWAY_IP = "192.168.50.1" + +# compute constants + +# run constants + +#stop constants \ No newline at end of file From 7951f0995c0d2464e2c07df640e7254e2e5022c5 Mon Sep 17 00:00:00 2001 From: westcl4 Date: Tue, 13 Sep 2022 16:52:55 +1200 Subject: [PATCH 04/14] Creating network/subnet functional --- README.md | 2 ++ assignment2/assignment.py | 61 ++++++++++++++++++++++++--------------- 2 files changed, 39 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 82cbd4d..f680f68 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +DUE: 17 October + # virt-openstack-assignment OpenStack SDK assignment for ID720 paper diff --git a/assignment2/assignment.py b/assignment2/assignment.py index 76ae031..d3989f9 100644 --- a/assignment2/assignment.py +++ b/assignment2/assignment.py @@ -4,51 +4,63 @@ import argparse import openstack -def create_network(CONN): - print("Create Network:") - - westcl4_net = conn.network.create_network( - name=constant.NETWORK - ) - print(westcl4_net) - - constant.USER_subnet = conn.network.create_subnet( - name='westcl4-subnet', - network_id=westcl4_subnet.id, +conn = openstack.connect(cloud_name='openstack', region_name='nz-por-1') + + +def create_network(): + print("Creating network with name " + constant.NETWORK) + +#check for network and create if non existing + network = conn.network.find_network(constant.NETWORK) + subnet = conn.network.find_subnet(constant.SUBNET) + if (network is None): + network = conn.network.create_network( + name=constant.NETWORK + ) + #print(westcl4_net) +#check for subnet and create if non existing + if (subnet is None): + subnet = conn.network.create_subnet( + name=constant.SUBNET, + network_id=network.id, ip_version='4', cidr='192.168.50.0/24', - gateway_ip='192.168.50.1') - - print(USER_subnet) - + gateway_ip='192.168.50.1' + ) + #print(USER_subnet) def create(): ''' Create a set of Openstack resources ''' print("Create test") - print(constant.USER) + #print(constant.USER) + create_network() pass + def run(): ''' Start a set of Openstack virtual machines if they are not already running. ''' pass + def stop(): ''' Stop a set of Openstack virtual machines if they are running. ''' pass + def destroy(): ''' Tear down the set of Openstack resources produced by the create action ''' pass + def status(): ''' Print a status report on the OpenStack virtual machines created by the create action. @@ -65,12 +77,13 @@ def status(): operation = args.operation operations = { - 'create' : create, - 'run' : run, - 'stop' : stop, - 'destroy' : destroy, - 'status' : status - } - - action = operations.get(operation, lambda: print('{}: no such operation'.format(operation))) + 'create': create, + 'run': run, + 'stop': stop, + 'destroy': destroy, + 'status': status + } + + action = operations.get(operation, lambda: print( + '{}: no such operation'.format(operation))) action() From 9b8cd08a3ee3838b187d651b92759ebb3cdbf915 Mon Sep 17 00:00:00 2001 From: westcl4 Date: Tue, 13 Sep 2022 17:02:25 +1200 Subject: [PATCH 05/14] Updated network creation text output --- assignment2/assignment.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/assignment2/assignment.py b/assignment2/assignment.py index d3989f9..a31cdcb 100644 --- a/assignment2/assignment.py +++ b/assignment2/assignment.py @@ -8,15 +8,18 @@ def create_network(): - print("Creating network with name " + constant.NETWORK) + print ("Checking network status...") #check for network and create if non existing network = conn.network.find_network(constant.NETWORK) subnet = conn.network.find_subnet(constant.SUBNET) + if (network is None): network = conn.network.create_network( name=constant.NETWORK ) + print("Created network with name " + constant.NETWORK) + #print(westcl4_net) #check for subnet and create if non existing if (subnet is None): @@ -24,9 +27,10 @@ def create_network(): name=constant.SUBNET, network_id=network.id, ip_version='4', - cidr='192.168.50.0/24', - gateway_ip='192.168.50.1' + cidr=constant.CIDR, + gateway_ip=constant.GATEWAY_IP ) + print("Created subnet with name " + constant.SUBNET) #print(USER_subnet) From 6ff63aea0a9bcebbc2cc25a49634f7176f0c7ce4 Mon Sep 17 00:00:00 2001 From: Conor Date: Wed, 12 Oct 2022 22:54:45 +1300 Subject: [PATCH 06/14] Added router creation step --- assignment2/assignment.py | 41 +++++++++++++++++++++++++++++---------- assignment2/constant.py | 5 ++++- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/assignment2/assignment.py b/assignment2/assignment.py index a31cdcb..4c95125 100644 --- a/assignment2/assignment.py +++ b/assignment2/assignment.py @@ -6,22 +6,36 @@ conn = openstack.connect(cloud_name='openstack', region_name='nz-por-1') +def getNetwork(): + network = conn.network.find_network(constant.NETWORK) + return network + +def getSubnet(): + subnet = conn.network.find_subnet(constant.SUBNET) + return subnet + +def getRouter(): + router = conn.network.find_router(constant.ROUTERNAME) + return router def create_network(): - print ("Checking network status...") + print("Checking network status...") -#check for network and create if non existing - network = conn.network.find_network(constant.NETWORK) - subnet = conn.network.find_subnet(constant.SUBNET) +#define network variables + network = getNetwork() + subnet = getSubnet() + router = getRouter() + + print(router) +#check for network and create if non existing if (network is None): network = conn.network.create_network( name=constant.NETWORK ) print("Created network with name " + constant.NETWORK) - - #print(westcl4_net) -#check for subnet and create if non existing + +# check for subnet and create if non existing if (subnet is None): subnet = conn.network.create_subnet( name=constant.SUBNET, @@ -32,13 +46,20 @@ def create_network(): ) print("Created subnet with name " + constant.SUBNET) - #print(USER_subnet) - + if (router is None): + try: + router = conn.network.create_router( + name= "westcl4-net", external_gateway_info={"network_id": conn.network.find_network("public-net").id}) + print("Created router with name ") + except: + print("Router creation failed") + router = conn.network.add_interface_to_router(router,subnet_id=subnet.id) + print(router) def create(): ''' Create a set of Openstack resources ''' print("Create test") - #print(constant.USER) + # print(constant.USER) create_network() pass diff --git a/assignment2/constant.py b/assignment2/constant.py index ee63821..be9e68c 100644 --- a/assignment2/constant.py +++ b/assignment2/constant.py @@ -11,9 +11,12 @@ NETWORK = "westcl4_net" CIDR = "192.168.50.0/24" GATEWAY_IP = "192.168.50.1" +ROUTERNAME = "westcl4-rtr" + + # compute constants # run constants -#stop constants \ No newline at end of file +# stop constants \ No newline at end of file From 14ee26d48f0d11abcce1f28deb8a244012dc3655 Mon Sep 17 00:00:00 2001 From: Conor Date: Sat, 15 Oct 2022 16:03:18 +1300 Subject: [PATCH 07/14] Added create compute method skeleton --- assignment2/assignment.py | 18 ++++++++++++++---- assignment2/constant.py | 7 +++++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/assignment2/assignment.py b/assignment2/assignment.py index 4c95125..5635159 100644 --- a/assignment2/assignment.py +++ b/assignment2/assignment.py @@ -6,6 +6,7 @@ conn = openstack.connect(cloud_name='openstack', region_name='nz-por-1') +# checking for existing networks def getNetwork(): network = conn.network.find_network(constant.NETWORK) return network @@ -21,21 +22,21 @@ def getRouter(): def create_network(): print("Checking network status...") -#define network variables + #define network variables network = getNetwork() subnet = getSubnet() router = getRouter() print(router) -#check for network and create if non existing + #check for network and create if non existing if (network is None): network = conn.network.create_network( name=constant.NETWORK ) print("Created network with name " + constant.NETWORK) -# check for subnet and create if non existing + # check for subnet and create if non existing if (subnet is None): subnet = conn.network.create_subnet( name=constant.SUBNET, @@ -46,6 +47,7 @@ def create_network(): ) print("Created subnet with name " + constant.SUBNET) + # Check for router and create if non existing if (router is None): try: router = conn.network.create_router( @@ -56,12 +58,20 @@ def create_network(): router = conn.network.add_interface_to_router(router,subnet_id=subnet.id) print(router) +def get_app(): + app = conn.compute.find_server(constant.APP_NAME) + return app + +def create_compute(): + print("Checking compute status...") + return + def create(): ''' Create a set of Openstack resources ''' print("Create test") # print(constant.USER) create_network() - + create_compute() pass diff --git a/assignment2/constant.py b/assignment2/constant.py index be9e68c..4e0c4db 100644 --- a/assignment2/constant.py +++ b/assignment2/constant.py @@ -13,9 +13,12 @@ GATEWAY_IP = "192.168.50.1" ROUTERNAME = "westcl4-rtr" - - # compute constants +IMAGE = "ubuntu-minimal-22.04-x86_64" +FLAVOUR = "c1.c1r1" +WEB_NAME = "westcl4-web" +APP_NAME = "westcl4-app" +DB_NAME = "westcl4-db" # run constants From d3652fa865abc6be5c29e753615857bf207f7bf4 Mon Sep 17 00:00:00 2001 From: Conor Date: Sun, 16 Oct 2022 16:43:39 +1300 Subject: [PATCH 08/14] Create compute function now fully operational --- assignment2/assignment.py | 70 +++++++++++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 6 deletions(-) diff --git a/assignment2/assignment.py b/assignment2/assignment.py index 5635159..3e8e4ca 100644 --- a/assignment2/assignment.py +++ b/assignment2/assignment.py @@ -1,5 +1,6 @@ # Adapted from examples on the openstack github https://github.com/openstack/openstacksdk/tree/master/examples/compute +from unicodedata import name import constant import argparse import openstack @@ -27,8 +28,6 @@ def create_network(): subnet = getSubnet() router = getRouter() - print(router) - #check for network and create if non existing if (network is None): network = conn.network.create_network( @@ -51,25 +50,84 @@ def create_network(): if (router is None): try: router = conn.network.create_router( - name= "westcl4-net", external_gateway_info={"network_id": conn.network.find_network("public-net").id}) - print("Created router with name ") + name= "westcl4-net", + external_gateway_info={"network_id": conn.network.find_network("public-net").id}) + print("Created router with attributes: ") except: print("Router creation failed") router = conn.network.add_interface_to_router(router,subnet_id=subnet.id) print(router) +# checking for existing compute def get_app(): app = conn.compute.find_server(constant.APP_NAME) return app +def get_web(): + web = conn.compute.find_server(constant.WEB_NAME) + return web + +def get_db(): + db = conn.compute.find_server(constant.DB_NAME) + return db + def create_compute(): print("Checking compute status...") + #define compute variables + app = get_app() + web = get_web() + db = get_db() + + print(app) + + #check for app server and create if non existing + if (app is None): + def create_app(): + print("Creating app server with attributes: ") + app = conn.compute.create_server( + name = constant.APP_NAME, + image_id = conn.compute.find_image(constant.IMAGE).id, + flavor_id = conn.compute.find_flavor(constant.FLAVOUR).id, + networks = [{"uuid": conn.network.find_network(constant.NETWORK).id}] + ) + app = conn.compute.wait_for_server(app) + print(app) + create_app() + + #check for web server and create if non existing + if (web is None): + def create_web(): + print("Creating web server with attributes: ") + web = conn.compute.create_server( + name = constant.WEB_NAME, + image_id = conn.compute.find_image(constant.IMAGE).id, + flavor_id = conn.compute.find_flavor(constant.FLAVOUR).id, + networks = [{"uuid": conn.network.find_network(constant.NETWORK).id}] + ) + web = conn.compute.wait_for_server(web) + print(web) + create_web() + + #check for db server and create if non existing + if (db is None): + def create_db(): + print("Creating db server with attributes: ") + db = conn.compute.create_server( + name = constant.DB_NAME, + image_id = conn.compute.find_image(constant.IMAGE).id, + flavor_id = conn.compute.find_flavor(constant.FLAVOUR).id, + networks = [{"uuid": conn.network.find_network(constant.NETWORK).id}] + ) + db = conn.compute.wait_for_server(db) + print(db) + create_db() return + + def create(): ''' Create a set of Openstack resources ''' - print("Create test") - # print(constant.USER) + print("Creating resources...") create_network() create_compute() pass From 12191cdb26b11175cf0e1da4147eb3a1a1673981 Mon Sep 17 00:00:00 2001 From: Conor Date: Sun, 16 Oct 2022 20:47:56 +1300 Subject: [PATCH 09/14] Tried to get floating IP working unsuccessfully --- assignment2/assignment.py | 120 +++++++++++++++++++++++++++++--------- 1 file changed, 91 insertions(+), 29 deletions(-) diff --git a/assignment2/assignment.py b/assignment2/assignment.py index 3e8e4ca..7a8904c 100644 --- a/assignment2/assignment.py +++ b/assignment2/assignment.py @@ -20,15 +20,22 @@ def getRouter(): router = conn.network.find_router(constant.ROUTERNAME) return router +def get_floating_ip(): + ''' Get a floating IP address from the pool + ''' + floating_ip = conn.network.create_ip(floating_network_id=conn.network.find_network("public-net").id) + return floating_ip + def create_network(): print("Checking network status...") - #define network variables + # define network variables network = getNetwork() subnet = getSubnet() router = getRouter() + floating_ip = get_floating_ip() - #check for network and create if non existing + # check for network and create if non existing if (network is None): network = conn.network.create_network( name=constant.NETWORK @@ -38,25 +45,37 @@ def create_network(): # check for subnet and create if non existing if (subnet is None): subnet = conn.network.create_subnet( - name=constant.SUBNET, - network_id=network.id, - ip_version='4', - cidr=constant.CIDR, - gateway_ip=constant.GATEWAY_IP + name=constant.SUBNET, + network_id=network.id, + ip_version='4', + cidr=constant.CIDR, + gateway_ip=constant.GATEWAY_IP ) print("Created subnet with name " + constant.SUBNET) # Check for router and create if non existing - if (router is None): + if (router is None): try: router = conn.network.create_router( - name= "westcl4-net", + name="westcl4-net", external_gateway_info={"network_id": conn.network.find_network("public-net").id}) print("Created router with attributes: ") except: print("Router creation failed") - router = conn.network.add_interface_to_router(router,subnet_id=subnet.id) + router = conn.network.add_interface_to_router( + router, + subnet_id=subnet.id) print(router) + else: + print("Router already exists") + + print(floating_ip) + # Check for floating IP and create if non existing + if (floating_ip is None): + floating_ip = conn.network.create_ip( + floating_network_id=conn.network.find_network("public-net").id) + print("Created floating IP with attributes: ") + print(floating_ip) # checking for existing compute def get_app(): @@ -71,52 +90,54 @@ def get_db(): db = conn.compute.find_server(constant.DB_NAME) return db + def create_compute(): print("Checking compute status...") - #define compute variables + # define compute variables app = get_app() web = get_web() db = get_db() - print(app) - - #check for app server and create if non existing + # check for app server and create if non existing if (app is None): def create_app(): print("Creating app server with attributes: ") app = conn.compute.create_server( - name = constant.APP_NAME, - image_id = conn.compute.find_image(constant.IMAGE).id, - flavor_id = conn.compute.find_flavor(constant.FLAVOUR).id, - networks = [{"uuid": conn.network.find_network(constant.NETWORK).id}] + name=constant.APP_NAME, + image_id=conn.compute.find_image(constant.IMAGE).id, + flavor_id=conn.compute.find_flavor(constant.FLAVOUR).id, + networks=[ + {"uuid": conn.network.find_network(constant.NETWORK).id}] ) app = conn.compute.wait_for_server(app) print(app) create_app() - #check for web server and create if non existing + # check for web server and create if non existing if (web is None): def create_web(): print("Creating web server with attributes: ") web = conn.compute.create_server( - name = constant.WEB_NAME, - image_id = conn.compute.find_image(constant.IMAGE).id, - flavor_id = conn.compute.find_flavor(constant.FLAVOUR).id, - networks = [{"uuid": conn.network.find_network(constant.NETWORK).id}] + name=constant.WEB_NAME, + image_id=conn.compute.find_image(constant.IMAGE).id, + flavor_id=conn.compute.find_flavor(constant.FLAVOUR).id, + networks=[ + {"uuid": conn.network.find_network(constant.NETWORK).id}] ) web = conn.compute.wait_for_server(web) print(web) create_web() - - #check for db server and create if non existing + + # check for db server and create if non existing if (db is None): def create_db(): print("Creating db server with attributes: ") db = conn.compute.create_server( - name = constant.DB_NAME, - image_id = conn.compute.find_image(constant.IMAGE).id, - flavor_id = conn.compute.find_flavor(constant.FLAVOUR).id, - networks = [{"uuid": conn.network.find_network(constant.NETWORK).id}] + name=constant.DB_NAME, + image_id=conn.compute.find_image(constant.IMAGE).id, + flavor_id=conn.compute.find_flavor(constant.FLAVOUR).id, + networks=[ + {"uuid": conn.network.find_network(constant.NETWORK).id}] ) db = conn.compute.wait_for_server(db) print(db) @@ -124,7 +145,47 @@ def create_db(): return +def run_compute(): + ''' Start the compute resources created by the create action ''' + print("Starting compute resources...") + app = get_app() + web = get_web() + db = get_db() + + print(app.status) + + if (app is not None): + if (app.status == "SHUTOFF"): + try: + conn.compute.start_server(app) + print("App server started") + except: + print("App server failed to start") + else: + print("App server already running") + + if (web is not None): + if (web.status == "SHUTOFF"): + try: + conn.compute.start_server(web) + print("Web server started") + except: + print("Web server failed to start") + else: + print("Web server already running") + + if (db is not None): + if (db.status == "SHUTOFF"): + try: + conn.compute.start_server(db) + print("DB server started") + except: + print("DB server failed to start") + else: + print("DB server already running") + + def create(): ''' Create a set of Openstack resources ''' print("Creating resources...") @@ -137,6 +198,7 @@ def run(): ''' Start a set of Openstack virtual machines if they are not already running. ''' + run_compute() pass From 6e75ff18934c3afa5da26417faea08203923a7ff Mon Sep 17 00:00:00 2001 From: Conor Date: Sun, 16 Oct 2022 20:59:21 +1300 Subject: [PATCH 10/14] Added error check to run script --- assignment2/assignment.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/assignment2/assignment.py b/assignment2/assignment.py index 7a8904c..51ff624 100644 --- a/assignment2/assignment.py +++ b/assignment2/assignment.py @@ -68,7 +68,7 @@ def create_network(): print(router) else: print("Router already exists") - + print(floating_ip) # Check for floating IP and create if non existing if (floating_ip is None): @@ -156,33 +156,33 @@ def run_compute(): print(app.status) if (app is not None): - if (app.status == "SHUTOFF"): + if (app.status != "Running"): try: conn.compute.start_server(app) print("App server started") except: print("App server failed to start") - else: + elif (app.status == "Running"): print("App server already running") if (web is not None): - if (web.status == "SHUTOFF"): + if (web.status != "Running"): try: conn.compute.start_server(web) print("Web server started") except: print("Web server failed to start") - else: + elif (web.status == "Running"): print("Web server already running") if (db is not None): - if (db.status == "SHUTOFF"): + if (db.status != "Running"): try: conn.compute.start_server(db) print("DB server started") except: print("DB server failed to start") - else: + elif (db.status == "Running"): print("DB server already running") From cf42396664a45e7bd055842899cef6bcb12790f2 Mon Sep 17 00:00:00 2001 From: Conor Date: Fri, 21 Oct 2022 16:47:05 +1300 Subject: [PATCH 11/14] Refactored server status and start/stop compute --- assignment2/assignment.py | 82 ++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 39 deletions(-) diff --git a/assignment2/assignment.py b/assignment2/assignment.py index 51ff624..e98806e 100644 --- a/assignment2/assignment.py +++ b/assignment2/assignment.py @@ -1,5 +1,7 @@ # Adapted from examples on the openstack github https://github.com/openstack/openstacksdk/tree/master/examples/compute +# + from unicodedata import name import constant import argparse @@ -77,22 +79,31 @@ def create_network(): print("Created floating IP with attributes: ") print(floating_ip) +def get_current_servers(): + servers = { + f'westcl4-web': conn.compute.find_server(f'westcl4-web', ignore_missing=True), + f'westcl4-app': conn.compute.find_server(f'westcl4-app', ignore_missing=True), + f'westcl4-db': conn.compute.find_server(f'westcl4-db', ignore_missing=True) + } + return servers + # checking for existing compute def get_app(): - app = conn.compute.find_server(constant.APP_NAME) + app = conn.compute.get_server('westcl4-app') return app def get_web(): - web = conn.compute.find_server(constant.WEB_NAME) + web = conn.compute.get_server(constant.WEB_NAME) return web def get_db(): - db = conn.compute.find_server(constant.DB_NAME) + db = conn.compute.get_server(constant.DB_NAME) return db def create_compute(): print("Checking compute status...") + print("Note: Each server instance will take a few minutes to create.") # define compute variables app = get_app() web = get_web() @@ -149,42 +160,34 @@ def run_compute(): ''' Start the compute resources created by the create action ''' print("Starting compute resources...") - app = get_app() - web = get_web() - db = get_db() - - print(app.status) - - if (app is not None): - if (app.status != "Running"): - try: - conn.compute.start_server(app) - print("App server started") - except: - print("App server failed to start") - elif (app.status == "Running"): - print("App server already running") - - if (web is not None): - if (web.status != "Running"): - try: - conn.compute.start_server(web) - print("Web server started") - except: - print("Web server failed to start") - elif (web.status == "Running"): - print("Web server already running") - - if (db is not None): - if (db.status != "Running"): - try: - conn.compute.start_server(db) - print("DB server started") - except: - print("DB server failed to start") - elif (db.status == "Running"): - print("DB server already running") - + #create array and populate with servers + servers = get_current_servers() + for server_name, server in servers.items(): + if(server is not None): + res = conn.compute.get_server(server.id) + if(res.status == "SHUTOFF"): + print("Starting server: {} ".format(server_name)) + conn.compute.start_server(server.id) + else: + print("Server already running: {} ".format(server_name)) + else: + print("Server unavailable: {} ".format(server_name)) + +def stop_compute(): + ''' Stop the compute resources created by the create action ''' + print("Stopping compute resources...") + + servers = get_current_servers() + for server_name, server in servers.items(): + if(server is not None): + res = conn.compute.get_server(server.id) + if(res.status == "ACTIVE"): + print("Stopping server: {} ".format(server_name)) + conn.compute.stop_server(server.id) + else: + print("Server already stopped: {} ".format(server_name)) + else: + print("Server unavailable: {} ".format(server_name)) def create(): ''' Create a set of Openstack resources ''' @@ -206,6 +209,7 @@ def stop(): ''' Stop a set of Openstack virtual machines if they are running. ''' + stop_compute() pass From f437a6de1dd8972727bbe7fa4ac10ea7754e8ec1 Mon Sep 17 00:00:00 2001 From: Conor Date: Tue, 25 Oct 2022 17:58:41 +1300 Subject: [PATCH 12/14] Added floating ip assignment feature --- README.md | 5 ++++- assignment2/assignment.py | 24 ++++++++++++++++++++++-- assignment2/constant.py | 3 +++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f680f68..ead18e7 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ + + + DUE: 17 October # virt-openstack-assignment @@ -21,7 +24,7 @@ be taken for each argument are - names: \-web, \-app, \-db - security-group: assignment2 (You do not need to create this) Assign the floating IP to the web server. - If any of the resources above already exisit when the script is run, then they + If any of the resources above already exist when the script is run, then they should not be recreated. *run*: Start the three servers created above. If any of them do not exist, diff --git a/assignment2/assignment.py b/assignment2/assignment.py index e98806e..3a36d96 100644 --- a/assignment2/assignment.py +++ b/assignment2/assignment.py @@ -2,6 +2,7 @@ # +from configparser import SectionProxy from unicodedata import name import constant import argparse @@ -35,7 +36,6 @@ def create_network(): network = getNetwork() subnet = getSubnet() router = getRouter() - floating_ip = get_floating_ip() # check for network and create if non existing if (network is None): @@ -108,6 +108,9 @@ def create_compute(): app = get_app() web = get_web() db = get_db() + + public = conn.network.find_network(constant.PUBLIC_NET).id + # check for app server and create if non existing if (app is None): @@ -118,9 +121,10 @@ def create_app(): image_id=conn.compute.find_image(constant.IMAGE).id, flavor_id=conn.compute.find_flavor(constant.FLAVOUR).id, networks=[ - {"uuid": conn.network.find_network(constant.NETWORK).id}] + {"uuid": conn.network.find_network(constant.NETWORK).id}], ) app = conn.compute.wait_for_server(app) + conn.compute.add_security_group_to_server(app, constant.SECURITY_GROUP) print(app) create_app() @@ -136,6 +140,9 @@ def create_web(): {"uuid": conn.network.find_network(constant.NETWORK).id}] ) web = conn.compute.wait_for_server(web) + conn.compute.add_security_group_to_server(app, constant.SECURITY_GROUP) + ip = conn.network.create_ip(floating_network_id=public) + conn.compute.add_floating_ip_to_server(app, ip.floating_ip_address) print(web) create_web() @@ -151,6 +158,7 @@ def create_db(): {"uuid": conn.network.find_network(constant.NETWORK).id}] ) db = conn.compute.wait_for_server(db) + conn.compute.add_security_group_to_server(app, constant.SECURITY_GROUP) print(db) create_db() return @@ -189,6 +197,17 @@ def stop_compute(): else: print("Server unavailable: {} ".format(server_name)) +def get_status(): + #get server status and print to terminal + servers = get_current_servers() + for server_name, server in servers.items(): + if(server is not None): + res = conn.compute.get_server(server.id) + print("Server: {} Status: {} ".format(server_name, res.status)) + else: + print("Server unavailable: {} ".format(server_name)) + pass + def create(): ''' Create a set of Openstack resources ''' print("Creating resources...") @@ -224,6 +243,7 @@ def status(): ''' Print a status report on the OpenStack virtual machines created by the create action. ''' + get_status() pass diff --git a/assignment2/constant.py b/assignment2/constant.py index 4e0c4db..01cfc9a 100644 --- a/assignment2/constant.py +++ b/assignment2/constant.py @@ -13,12 +13,15 @@ GATEWAY_IP = "192.168.50.1" ROUTERNAME = "westcl4-rtr" + # compute constants IMAGE = "ubuntu-minimal-22.04-x86_64" FLAVOUR = "c1.c1r1" WEB_NAME = "westcl4-web" APP_NAME = "westcl4-app" DB_NAME = "westcl4-db" +SECURITY_GROUP = "default" +PUBLIC = "public-net" # run constants From 61cf145793ba17fb6d9cb18504c540ad039ff832 Mon Sep 17 00:00:00 2001 From: Conor Date: Tue, 25 Oct 2022 18:10:05 +1300 Subject: [PATCH 13/14] Added destroy function --- assignment2/assignment.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/assignment2/assignment.py b/assignment2/assignment.py index 3a36d96..ccfa3e7 100644 --- a/assignment2/assignment.py +++ b/assignment2/assignment.py @@ -208,6 +208,17 @@ def get_status(): print("Server unavailable: {} ".format(server_name)) pass +def tear_down(): + #delete servers and networks + print("Deleting compute resources...") + servers = get_current_servers() + for server_name, server in servers.items(): + if(server is not None): + print("Deleting server: {} ".format(server_name)) + conn.compute.delete_server(server.id) + else: + print("Server unavailable: {} ".format(server_name)) + def create(): ''' Create a set of Openstack resources ''' print("Creating resources...") @@ -236,6 +247,7 @@ def destroy(): ''' Tear down the set of Openstack resources produced by the create action ''' + tear_down() pass From 25f2355e3c2bc33652d7f80f185d67138f516369 Mon Sep 17 00:00:00 2001 From: Conor Date: Tue, 25 Oct 2022 19:11:28 +1300 Subject: [PATCH 14/14] Added non-functioning delete network function --- assignment2/assignment.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/assignment2/assignment.py b/assignment2/assignment.py index ccfa3e7..85b26ec 100644 --- a/assignment2/assignment.py +++ b/assignment2/assignment.py @@ -218,6 +218,22 @@ def tear_down(): conn.compute.delete_server(server.id) else: print("Server unavailable: {} ".format(server_name)) + + print("Deleting network resources...") + # define network variables + network = getNetwork() + subnet = getSubnet() + router = getRouter() + ports = None + + # delete router + if (router is not None): + print("Deleting router...") + conn.network.remove_interface_from_router(router, subnet.id, ports.id) + conn.network.delete_router(router.id) + else: + print("Router unavailable.") + def create(): ''' Create a set of Openstack resources '''