Compare commits

...

5 commits

Author SHA1 Message Date
Neill Cox
0681468b83 🚧 Too much stuff for one commit. Do better Neill 2023-11-15 10:04:47 +11:00
Neill Cox
dc510177bb Split validation into src and dst 2023-11-03 19:41:01 +11:00
Neill Cox
5ae30a44cc 🚧 update teardown script 2023-11-03 19:21:35 +11:00
Neill Cox
77a5a9369c 🚧 update open stack_command to accept a cloud parameter 2023-11-03 19:11:10 +11:00
Neill Cox
897052b246 🚧 Update teardown example 2023-11-03 19:09:40 +11:00
9 changed files with 432 additions and 147 deletions

View file

@ -7,5 +7,4 @@ os_migrate_teardown \
--username test-user \ --username test-user \
--cloud standalone \ --cloud standalone \
--ssh stack@$AIO_HOST \ --ssh stack@$AIO_HOST \
--delete-instances \ --delete-all
--delete-networks

View file

@ -25,5 +25,6 @@ classifiers = [
create_aio_vm = "tripleo_aio_helpers.create_aio_vm:main" create_aio_vm = "tripleo_aio_helpers.create_aio_vm:main"
os_migrate_setup = "tripleo_aio_helpers.os_migrate_setup:main" os_migrate_setup = "tripleo_aio_helpers.os_migrate_setup:main"
os_migrate_teardown = "tripleo_aio_helpers.os_migrate_teardown:main" os_migrate_teardown = "tripleo_aio_helpers.os_migrate_teardown:main"
os_migrate_validate = "tripleo_aio_helpers.os_migrate_validate:main" os_migrate_validate_dst = "tripleo_aio_helpers.os_migrate_validate_dst:main"
os_migrate_validate_src = "tripleo_aio_helpers.os_migrate_validate_src:main"
prepare_deployment = "tripleo_aio_helpers.prepare_deployment:main" prepare_deployment = "tripleo_aio_helpers.prepare_deployment:main"

View file

@ -23,12 +23,8 @@ def parse_args():
parser.add_argument("--local-hostname", required=True) parser.add_argument("--local-hostname", required=True)
parser.add_argument("--user-data", default=template_path / "user-data.tpl") parser.add_argument("--user-data", default=template_path / "user-data.tpl")
parser.add_argument("--meta-data", default=template_path / "meta-data.tpl") parser.add_argument("--meta-data", default=template_path / "meta-data.tpl")
parser.add_argument( parser.add_argument("--network-data", default=template_path / "network-config.tpl")
"--network-data", default=template_path / "network-config.tpl" parser.add_argument("--instance-id", required=True, help="Hostname for the new VM")
)
parser.add_argument(
"--instance-id", required=True, help="Hostname for the new VM"
)
parser.add_argument("--output-image", required=True) parser.add_argument("--output-image", required=True)
parser.add_argument("--image-size", default="800G") parser.add_argument("--image-size", default="800G")
parser.add_argument("--input-image", required=True) parser.add_argument("--input-image", required=True)
@ -148,10 +144,7 @@ def create_image(args):
print(result) print(result)
print("Resizing image") print("Resizing image")
cmd = ( cmd = f"virt-resize --expand /dev/sda3 {args.input_image} " f"{args.output_image}"
f"virt-resize --expand /dev/sda3 {args.input_image} "
f"{args.output_image}"
)
result = subprocess.check_output(cmd, shell=True, universal_newlines=True) result = subprocess.check_output(cmd, shell=True, universal_newlines=True)
@ -202,17 +195,12 @@ def delete_user_data():
def install_packages(args): def install_packages(args):
"""Install the packages needed for virt-install to work""" """Install the packages needed for virt-install to work"""
cmd = ( cmd = "sudo dnf install -y virt-install virt-viewer qemu-img " "libguestfs.x86_64"
"sudo dnf install -y virt-install virt-viewer qemu-img "
"libguestfs.x86_64"
)
print("installing needed packages...") print("installing needed packages...")
if args.verbose: if args.verbose:
print( print(subprocess.check_output(cmd, shell=True, universal_newlines=True))
subprocess.check_output(cmd, shell=True, universal_newlines=True)
)
def main(): def main():

View file

@ -77,9 +77,7 @@ def parse_args():
) )
if not args.public_net_end: if not args.public_net_end:
args.public_net_end = get_from_env( args.public_net_end = get_from_env("--public-net-end", "AIO_PUBLIC_NET_END")
"--public-net-end", "AIO_PUBLIC_NET_END"
)
if not args.dns_server: if not args.dns_server:
args.dns_server = get_from_env("--dns-server", "AIO_DNS_SERVER") args.dns_server = get_from_env("--dns-server", "AIO_DNS_SERVER")
@ -133,9 +131,7 @@ def create_user(args):
cmd = "user list -f json" cmd = "user list -f json"
user_exists = [ user_exists = [
x x for x in json.loads(openstack_cmd(cmd, args)) if x["Name"] == args.username
for x in json.loads(openstack_cmd(cmd, args))
if x["Name"] == args.username
] ]
if user_exists: if user_exists:
@ -234,16 +230,14 @@ def create_private_network(args):
args.private_network_id = network_exists[0]["ID"] args.private_network_id = network_exists[0]["ID"]
else: else:
cmd = ( cmd = (
f"network create -f json --internal private " f"network create -f json --internal private " f"--project {args.project_id}"
f"--project {args.project_id}"
) )
args.private_network_id = json.loads(openstack_cmd(cmd, args))["id"] args.private_network_id = json.loads(openstack_cmd(cmd, args))["id"]
print("Private network created.") print("Private network created.")
subnet_exists = json.loads( subnet_exists = json.loads(
openstack_cmd( openstack_cmd(
f"subnet list -f json --project {args.project_id} " f"subnet list -f json --project {args.project_id} " f"--name private-net",
f"--name private-net",
args, args,
) )
) )
@ -393,8 +387,7 @@ def create_instance(args, name, flavor, image, security_group, boot_size):
"floating ip create -f json public", args, as_json=True "floating ip create -f json public", args, as_json=True
) )
_ = test_user_openstack_cmd( _ = test_user_openstack_cmd(
f"server add floating ip {server['id']} " f"server add floating ip {server['id']} " f"{fip['floating_ip_address']}",
f"{fip['floating_ip_address']}",
args, args,
) )
@ -441,9 +434,7 @@ def create_keypair(args):
key_exists = [ key_exists = [
kp kp
for kp in json.loads( for kp in json.loads(test_user_openstack_cmd("keypair list -f json ", args))
test_user_openstack_cmd("keypair list -f json ", args)
)
if kp["Name"] == "test_keypair" if kp["Name"] == "test_keypair"
] ]
@ -458,8 +449,7 @@ def create_keypair(args):
args.keypair_name = json.loads( args.keypair_name = json.loads(
test_user_openstack_cmd( test_user_openstack_cmd(
f"keypair create -f json " f"keypair create -f json " f"--public-key {fname} test_keypair",
f"--public-key {fname} test_keypair",
args, args,
) )
)[ )[
@ -478,9 +468,7 @@ def create_router(args):
try: try:
router_id = [ router_id = [
router router
for router in openstack_cmd( for router in openstack_cmd("router list -f json", args, as_json=True)
"router list -f json", args, as_json=True
)
if router["Name"] == "test-router" if router["Name"] == "test-router"
][0]["ID"] ][0]["ID"]
except IndexError: except IndexError:
@ -492,16 +480,13 @@ def create_router(args):
)["id"] )["id"]
print("router created") print("router created")
router_info = openstack_cmd( router_info = openstack_cmd(f"router show -f json {router_id}", args, as_json=True)
f"router show -f json {router_id}", args, as_json=True
)
if router_info["external_gateway_info"]: if router_info["external_gateway_info"]:
print("router gateway already set") print("router gateway already set")
else: else:
openstack_cmd( openstack_cmd(
f"router set {router_id} " f"router set {router_id} " f"--external-gateway {args.public_network_id}",
f"--external-gateway {args.public_network_id}",
args, args,
) )
print("router gateway added") print("router gateway added")
@ -536,9 +521,7 @@ def create_security_group(args):
args.sg_id = sg_exists[0]["ID"] args.sg_id = sg_exists[0]["ID"]
else: else:
sec_grp = json.loads( sec_grp = json.loads(
test_user_openstack_cmd( test_user_openstack_cmd("security group create test-sg -f json", args)
"security group create test-sg -f json", args
)
) )
args.sg_id = sec_grp["id"] args.sg_id = sec_grp["id"]

View file

@ -3,6 +3,7 @@ Quick and dirty script to help setup project, flavors, networks, images
""" """
import argparse import argparse
import json import json
import sys
from .utils import openstack_cmd, test_user_openstack_cmd from .utils import openstack_cmd, test_user_openstack_cmd
@ -16,11 +17,12 @@ def parse_args():
parser.add_argument("-n", "--project-name", default="test-project") parser.add_argument("-n", "--project-name", default="test-project")
parser.add_argument("-u", "--username", default="test-user") parser.add_argument("-u", "--username", default="test-user")
parser.add_argument("-p", "--password", default="secrete123") parser.add_argument("-p", "--password", default="secrete123")
parser.add_argument("-c", "--cloud", default="standalone") parser.add_argument("-c", "--cloud", default="dst_admin")
parser.add_argument("--delete-all", action="store_true") parser.add_argument("--delete-all", action="store_true")
parser.add_argument("--delete-images", action="store_true") parser.add_argument("--delete-images", action="store_true")
parser.add_argument("--delete-flavors", action="store_true") parser.add_argument("--delete-flavors", action="store_true")
parser.add_argument("--delete-networks", action="store_true") parser.add_argument("--delete-private-network", action="store_true")
parser.add_argument("--delete-public-network", action="store_true")
parser.add_argument("--delete-instances", action="store_true") parser.add_argument("--delete-instances", action="store_true")
parser.add_argument("--delete-user", action="store_true") parser.add_argument("--delete-user", action="store_true")
parser.add_argument("--delete-project", action="store_true") parser.add_argument("--delete-project", action="store_true")
@ -60,9 +62,7 @@ def destroy_user(args):
"""Delete the user if it exists""" """Delete the user if it exists"""
cmd = "user list -f json" cmd = "user list -f json"
user_exists = [ user_exists = [
x x for x in json.loads(openstack_cmd(cmd, args)) if x["Name"] == args.username
for x in json.loads(openstack_cmd(cmd, args))
if x["Name"] == args.username
] ]
if user_exists: if user_exists:
@ -80,16 +80,12 @@ def destroy_public_network(args):
public_network_exists = [ public_network_exists = [
network network
for network in openstack_cmd( for network in openstack_cmd("network list -f json", args, as_json=True)
"network list -f json", args, as_json=True
)
if network["Name"] == "public" if network["Name"] == "public"
] ]
if public_network_exists: if public_network_exists:
routers = test_user_openstack_cmd( routers = test_user_openstack_cmd("router list -f json", args, as_json=True)
"router list -f json", args, as_json=True
)
for router in routers: for router in routers:
router_details = test_user_openstack_cmd( router_details = test_user_openstack_cmd(
@ -98,8 +94,7 @@ def destroy_public_network(args):
for interface in router_details["interfaces_info"]: for interface in router_details["interfaces_info"]:
test_user_openstack_cmd( test_user_openstack_cmd(
f"router remove port {router['ID']} " f"router remove port {router['ID']} " f"{interface['port_id']}",
f"{interface['port_id']}",
args, args,
) )
@ -112,57 +107,62 @@ def destroy_private_network(args):
"""Delete the private network""" """Delete the private network"""
private_network_exists = [ private_network_exists = [
network network
for network in openstack_cmd( for network in test_user_openstack_cmd("network list -f json", args, as_json=True)
"network list -f json", args, as_json=True
)
if network["Name"] == "private" if network["Name"] == "private"
] ]
if private_network_exists: if private_network_exists:
print("deleting private network") print("deleting private network")
test_user_openstack_cmd("network delete private", args) test_user_openstack_cmd(f"network delete private", args)
def delete_flavor(args,name):
def delete_flavor(args, name):
flavor_exists = [ flavor_exists = [
flavor flavor
for flavor in openstack_cmd( for flavor in openstack_cmd("flavor list -f json --all", args, as_json=True)
"flavor list -f json", args, as_json=True if flavor["Name"] == name
)
if flavor["Name"] == "cirros"
] ]
if flavor_exists: if flavor_exists:
flavor_id = flavor_exists[0]["ID"]
print(f"deleting {name} flavor") print(f"deleting {name} flavor")
test_user_openstack_cmd("flavor delete f{name}", args) openstack_cmd(f"flavor delete {flavor_id}", args)
else:
print(f"{name} flavour not found")
def destroy_cirros_flavor(args): def destroy_cirros_flavor(args):
"""Delete the cirros flavor""" """Delete the cirros flavor"""
delete_flavor(args, "cirros") delete_flavor(args, "cirros")
def destroy_rhel_flavor(args): def destroy_rhel_flavor(args):
"""Delete the rhel flavor""" """Delete the rhel flavor"""
delete_flavor(args, "rhel") delete_flavor(args, "rhel")
def delete_image(args, name): def delete_image(args, name):
image_exists = [ image_exists = [
image image
for image in openstack_cmd( for image in openstack_cmd("image list -f json", args, as_json=True)
"image list -f json", args, as_json=True if image["Name"] == name
)
if image["Name"] == "cirros"
] ]
if image_exists: if image_exists:
print(f"deleting {name} image") print(f"deleting {name} image")
test_user_openstack_cmd("image delete f{name}", args) openstack_cmd(f"image delete {name}", args)
else:
print(f"{name} image not found")
def destroy_cirros_image(args): def destroy_cirros_image(args):
"""Delete the cirros image""" """Delete the cirros image"""
delete_image(args, "cirros") delete_image(args, "cirros_image")
def destroy_rhel_image(args): def destroy_rhel_image(args):
"""Delete the rhel image""" """Delete the rhel image"""
delete_image(args, "rhel") delete_image(args, "rhel_image")
def destroy_cirros_instance(args): def destroy_cirros_instance(args):
"""Delete the cirros instance""" """Delete the cirros instance"""
@ -199,9 +199,11 @@ def destroy_rhel_instance(args):
def get_project_id(args): def get_project_id(args):
"""Get the id of the test project""" """Get the id of the test project"""
result = openstack_cmd("project list -f json", args, as_json=True) result = openstack_cmd("project list -f json", args, as_json=True)
args.project_id = [r for r in result if r["Name"] == args.project_name][0][
"ID" try:
] args.project_id = [r for r in result if r["Name"] == args.project_name][0]["ID"]
except IndexError:
args.project_id = None
def main(): def main():
@ -211,8 +213,11 @@ def main():
get_project_id(args) get_project_id(args)
if args.delete_instances or args.delete_all: if args.delete_instances or args.delete_all:
destroy_cirros_instance(args) if args.project_id:
destroy_rhel_instance(args) destroy_cirros_instance(args)
destroy_rhel_instance(args)
else:
print("Project not found, no instances to delete")
if args.delete_images or args.delete_all: if args.delete_images or args.delete_all:
destroy_cirros_image(args) destroy_cirros_image(args)
@ -222,15 +227,23 @@ def main():
destroy_cirros_flavor(args) destroy_cirros_flavor(args)
destroy_rhel_flavor(args) destroy_rhel_flavor(args)
if args.delete_networks or args.delete_all: if args.delete_public_network:
destroy_public_network(args) destroy_public_network(args)
destroy_private_network(args)
if args.delete_private_network or args.delete_all:
if args.project_id:
destroy_private_network(args)
else:
print("Project not found, no private network to delete")
if args.delete_user or args.delete_all: if args.delete_user or args.delete_all:
destroy_user(args) destroy_user(args)
if args.delete_project or args.delete_all: if args.delete_project or args.delete_all:
destroy_project(args) if args.project_id:
destroy_project(args)
else:
print("Project not found. Can't delete.")
if __name__ == "__main__": if __name__ == "__main__":

View file

@ -0,0 +1,308 @@
"""
Quick and dirty script to validate that the necessary project, user,roles,
flavors, networks, images have not been created
"""
import argparse
import json
from rich import print
from .utils import openstack_cmd
def failed(msg, args):
args.failed = True
print(f"[red]{msg} :x:[/red]")
def passed(msg):
print(f"[green]{msg} :white_heavy_check_mark:[/green]")
def parse_args():
"""Parse the command line arguments"""
parser = argparse.ArgumentParser()
parser.add_argument("-n", "--project-name", default="test-project")
parser.add_argument("-u", "--username", default="test-user")
parser.add_argument("-c", "--cloud", default="dst_admin")
parser.add_argument("--private-network-name", default="private")
parser.add_argument("--cirros-flavor-name", default="cirros")
parser.add_argument("--rhel-flavor-name", default="rhel")
parser.add_argument("--cirros-instance-name", default="cirros-test-instance")
parser.add_argument("--rhel-instance-name", default="rhel-test-instance")
parser.add_argument("--router-name", default="test-router")
parser.add_argument("--group-name", default="os-migrate")
# parser.add_argument(
# "--ssh", help="Connection string to run commands on a remote host."
# )
args = parser.parse_args()
return args
def validate_project(args):
"""Validate that the project exists"""
cmd = "project list -f json"
project_exists = [
x
for x in json.loads(openstack_cmd(cmd, args))
if x["Name"] == args.project_name
]
if project_exists:
passed(f"project {args.project_name} exists with id {project_exists[0]['ID']}")
else:
failed("Project {args.project_name} not found.", args)
def validate_user(args):
"""Validate that the user exists"""
cmd = "user list -f json"
user_exists = [
x for x in json.loads(openstack_cmd(cmd, args)) if x["Name"] == args.username
]
if user_exists:
passed(f"user {args.username} exists with ID: {user_exists[0]['ID']}")
else:
failed("User not found", args)
def validate_member_role(args):
"""
Validate that the member role has been assigned to the user.
"""
cmd = f"role assignment list --user {args.username} --names --project {args.project_name} --role member -f json"
if len(openstack_cmd(cmd, args, as_json=True)) > 0:
passed(f"User has member role in {args.project_name}")
else:
failed(f"User does not have member role in {args.project_name}")
def validate_group(args):
check(
args,
"group list -f json",
"group",
f"group {args.group_name} exists",
"Name",
"os-migrate",
fail_if="not found"
)
def validate_groups_has_member_role(args):
cmd = f"role assignment list --group {args.group_name} --names --project {args.project_name} --role member -f json"
if len(openstack_cmd(cmd, args, as_json=True)) > 0:
passed(f"Group {args.group_name} has member role in {args.project_name}")
else:
failed(f"Group {args.group_name} does not have member role in {args.project_name}")
def validate_admin_in_group(args):
cmd = f"group contains user {args.group_name} admin"
result = openstack_cmd(cmd, args, as_json=False)
if "admin in group" in result:
passed(result[:-1])
else:
failed(result[:-1], args)
def validate_public_network(args):
"""Coming soon - validate the public network"""
# pylint: disable=unused-argument,unused-variable
cmd = "network list -f json"
try:
network_exists = [
n for n in openstack_cmd(cmd, args, as_json=True) if n["Name"] == "public"
][0]
passed(f"public network exists with id: {network_exists['ID']}")
except IndexError:
failed("public network not found", args)
cmd = f"subnet list -f json"
try:
subnet = [
s
for s in openstack_cmd(cmd, args, as_json=True)
if s["Name"] == "public-net"
][0]
subnet_details = openstack_cmd(
f"subnet show -f json {subnet['ID']}", args, as_json=True
)
passed(
f"public subnet found allocation pool: {subnet_details['allocation_pools'][0]}"
)
except IndexError:
failed("public subnet not found", args)
def validate_private_network(args):
"""Coming soon - validate the private network"""
# pylint: disable=unused-argument,unused-variable
cmd = "network list -f json"
try:
network_exists = [
n
for n in openstack_cmd(cmd, args, as_json=True)
if n["Name"] == args.private_network_name
][0]
failed(
f"private ({args.private_network_name}) network exists with id: {network_exists['ID']}",
args,
)
except IndexError:
passed("private network not found")
def validate_cirros_flavor(args):
"""Validate that the cirros flavor doesn't exist"""
cmd = "flavor list -f json --all"
try:
flavor = [
f
for f in openstack_cmd(cmd, args, as_json=True)
if f["Name"] == args.cirros_flavor_name
][0]
failed(f"cirros flavor found (ID:{flavor['ID']})", args)
except IndexError:
passed("Cirros flavor not found.")
def validate_rhel_flavor(args):
"""Validate that the rhel flavor doesn't exist"""
cmd = "flavor list -f json --all"
try:
flavor = [
f
for f in openstack_cmd(cmd, args, as_json=True)
if f["Name"] == args.rhel_flavor_name
][0]
failed(f"rhel flavor found (ID:{flavor['ID']})", args)
except IndexError:
passed("RHEL flavor not found.")
def validate_cirros_image(args):
"""Validate that the cirros image does not exist"""
cmd = "image list -f json --all"
try:
image = [
f
for f in openstack_cmd(cmd, args, as_json=True)
if f["Name"] == args.cirros_image_name
][0]
failed(f"Cirros image found (ID:{image['ID']})", args)
except IndexError:
passed("Cirros image not found.")
def validate_rhel_image(args):
"""Validate that the rhel image does not exist"""
# pylint: disable=unused-argument
cmd = "image list -f json --all"
try:
image = [
f
for f in openstack_cmd(cmd, args, as_json=True)
if f["Name"] == args.rhel_image_name
][0]
failed(f"RHEL image found (ID:{image['ID']})", args)
except IndexError:
passed("RHEL image not found.")
def validate_cirros_instance(args):
"""Validate that the cirros instance does not exist"""
cmd = "server list -f json --all"
try:
instance = [
f
for f in openstack_cmd(cmd, args, as_json=True)
if f["Name"] == args.cirros_instance_name
][0]
failed(f"Cirros instance found (ID:{instance['ID']})", args)
except IndexError:
passed("Cirros instance not found.")
def validate_rhel_instance(args):
"""Validate that the RHEL instance does not exist"""
cmd = "server list -f json --all"
try:
instance = [
f
for f in openstack_cmd(cmd, args, as_json=True)
if f["Name"] == args.rhel_instance_name
][0]
failed(f"RHEL instance found (ID:{instance['ID']})", args)
except IndexError:
passed("RHEL instance not found.")
def check(args, cmd, thing, msg, key, value, id_key="ID", fail_if="found"):
if fail_if not in ["found", "not found"]:
raise ValueError("fail_if must be eitther 'found' or 'not found'")
try:
found = [i for i in openstack_cmd(cmd, args, as_json=True) if i[key] == value][0]
if fail_if == "found":
failed(msg.format(key=id_key, value=found[id_key]), args)
else:
passed(f"{thing} not found")
except IndexError:
if fail_if == "found":
passed(f"{thing} not found")
else:
failed(msg.format(key=id_key, value=found[id_key]), args)
def validate_router(args):
check(
args,
f"router list --project {args.project_name} -f json",
"router",
"router found ",
"Name",
args.router_name,
)
def main():
"""main function"""
args = parse_args()
validate_user(args)
validate_project(args)
validate_member_role(args)
validate_group(args)
validate_groups_has_member_role(args)
validate_admin_in_group(args)
validate_public_network(args)
validate_private_network(args)
validate_cirros_flavor(args)
validate_rhel_flavor(args)
validate_cirros_image(args)
validate_rhel_image(args)
validate_cirros_instance(args)
validate_rhel_instance(args)
validate_router(args)
if __name__ == "__main__":
main()

View file

@ -5,39 +5,19 @@ flavors, networks, images have been created
import argparse import argparse
import json import json
from .utils import openstack_cmd from .utils import openstack_cmd, passed, failed
def parse_args(): def parse_args():
"""Parse the command line arguments""" """Parse the command line arguments"""
# home = os.environ.get('HOME')
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
# parser.add_argument("-d", "--project-domain", default="default")
parser.add_argument("-n", "--project-name", default="test-project") parser.add_argument("-n", "--project-name", default="test-project")
# parser.add_argument( parser.add_argument("-u", "--username", default="test-user")
# "-D", "--project-description", default="Test project" parser.add_argument("-c", "--cloud", default="src_admin")
# ) parser.add_argument("--private-network-name", default="private")
# parser.add_argument("-u", "--username", default="test-user") parser.add_argument("--cirros-flavor-name", default="cirros")
# parser.add_argument("-p", "--password", default="secrete123") parser.add_argument("--rhel-flavor-name", default="rhel")
# parser.add_argument("-c", "--cloud", default="standalone")
# parser.add_argument("-g", "--gateway", default="10.76.23.254")
# parser.add_argument(
# "-C", "--public-network-cider", default="10.76.23.0/24"
# )
# parser.add_argument("--private-network-cidr", default="192.168.100.0/24")
# parser.add_argument("--publice-net-start", default="10.76.23.50")
# parser.add_argument("--publice-net-end", default="10.76.23.52")
# parser.add_argument("--dns-server", default="10.76.23.245")
# parser.add_argument("--dry-run", action="store_true")
parser.add_argument(
"--ssh", help="Connection string to run commands on a remote host."
)
# export OS_CLOUD=standalone
# export STANDALONE_HOST=10.76.23.39
args = parser.parse_args() args = parser.parse_args()
@ -54,24 +34,34 @@ def validate_project(args):
] ]
if project_exists: if project_exists:
print(project_exists) passed(project_exists)
else: else:
print("Project {args.project_name} not found.") failed("Project {args.project_name} not found.", args)
def validate_user(args): def validate_user(args):
"""Validate that the user exists""" """Validate that the user exists"""
cmd = "user list -f json" cmd = "user list -f json"
user_exists = [ user_exists = [
x x for x in json.loads(openstack_cmd(cmd, args)) if x["Name"] == args.username
for x in json.loads(openstack_cmd(cmd, args))
if x["Name"] == args.username
] ]
if user_exists: if user_exists:
print(user_exists) passed(user_exists)
else: else:
print("User not found") failed("User not found", args)
def validate_group_exists(args):
failed("NYI", args)
def validate_admin_in_group(args):
failed("NYI", args)
def validate_group_has_member_role(args):
failed("NYI", args)
def validate_member_role(args): def validate_member_role(args):
@ -96,7 +86,7 @@ def validate_member_role(args):
def validate_public_network(args): def validate_public_network(args):
"""Coming soon - validate the public network""" """Coming soon - validate the public network"""
# pylint: disable=unused-argument,unused-variable # pylint: disable=unused-argument,unused-variable
print("Validate public network - NYI") failed("Validate public network - NYI", args)
cmd = ( cmd = (
"network create --external --provider-physical-network datacentre " "network create --external --provider-physical-network datacentre "
"--provider-network-type flat public" "--provider-network-type flat public"
@ -118,43 +108,43 @@ def validate_private_network(args):
"openstack subnet create private-net " "openstack subnet create private-net "
f"--subnet-range {args.private_network_cidr} --network private" f"--subnet-range {args.private_network_cidr} --network private"
) )
print("validate private network - NYI") failed("validate private network - NYI", args)
def validate_cirros_flavor(args): def validate_cirros_flavor(args):
"""Coming soon - create the cirros flavor""" """Coming soon - create the cirros flavor"""
# pylint: disable=unused-argument # pylint: disable=unused-argument
print("validate cirros flavor - NYI") failed("validate cirros flavor - NYI", args)
def validate_rhel_flavor(args): def validate_rhel_flavor(args):
"""Coming soon - validate the rhel flavor""" """Coming soon - validate the rhel flavor"""
# pylint: disable=unused-argument # pylint: disable=unused-argument
print("validate rhel flavor - NYI") failed("validate rhel flavor - NYI", args)
def validate_cirros_image(args): def validate_cirros_image(args):
"""Coming soon - validate the cirros image""" """Coming soon - validate the cirros image"""
# pylint: disable=unused-argument # pylint: disable=unused-argument
print("validate cirros image - NYI") failed("validate cirros image - NYI", args)
def validate_rhel_image(args): def validate_rhel_image(args):
"""Coming soon - validate the rhel image""" """Coming soon - validate the rhel image"""
# pylint: disable=unused-argument # pylint: disable=unused-argument
print("validate rhel image - NYI") failed("validate rhel image - NYI", args)
def validate_cirros_instance(args): def validate_cirros_instance(args):
"""Coming soon - validate the cirros instance""" """Coming soon - validate the cirros instance"""
# pylint: disable=unused-argument # pylint: disable=unused-argument
print("validate cirros instance - NYI") failed("validate cirros instance - NYI", args)
def validate_rhel_instance(args): def validate_rhel_instance(args):
"""Coming soon - create the rhel instance""" """Coming soon - create the rhel instance"""
# pylint: disable=unused-argument # pylint: disable=unused-argument
print("validate rhel instance - NYI") failed("validate rhel instance - NYI", args)
def main(): def main():
@ -162,8 +152,9 @@ def main():
args = parse_args() args = parse_args()
validate_user(args) validate_user(args)
validate_project(args) validate_group_exists(args)
validate_member_role(args) validate_admin_in_group(args)
validate_group_has_member_role(args)
validate_public_network(args) validate_public_network(args)
validate_private_network(args) validate_private_network(args)
validate_cirros_flavor(args) validate_cirros_flavor(args)

View file

@ -19,9 +19,7 @@ def parse_args():
parser.add_argument("-a", "--address", required=True) parser.add_argument("-a", "--address", required=True)
parser.add_argument("-i", "--interface", required=True) parser.add_argument("-i", "--interface", required=True)
parser.add_argument("-m", "--netmask", default=24) parser.add_argument("-m", "--netmask", default=24)
parser.add_argument( parser.add_argument("-d", "--dns", nargs="+", action="append", required=True)
"-d", "--dns", nargs="+", action="append", required=True
)
parser.add_argument("-D", "--domain", default="aio") parser.add_argument("-D", "--domain", default="aio")
parser.add_argument("--using-multiple-nics", action="store_true") parser.add_argument("--using-multiple-nics", action="store_true")
parser.add_argument("-U", "--deployment-user") parser.add_argument("-U", "--deployment-user")
@ -41,8 +39,7 @@ def parse_args():
parser.add_argument( parser.add_argument(
"--cinder-pool-size", "--cinder-pool-size",
default="500280", default="500280",
help="Size of the loopback device allocated to cinder. " help="Size of the loopback device allocated to cinder. " "Defaults to 500280",
"Defaults to 500280",
) )
args = parser.parse_args() args = parser.parse_args()
@ -141,16 +138,12 @@ def main():
args = parse_args() args = parse_args()
containers_yaml = build_containers_yaml(args) containers_yaml = build_containers_yaml(args)
with open( with open(args.containers_yaml_out, "w", encoding="utf-8") as containers_out:
args.containers_yaml_out, "w", encoding="utf-8"
) as containers_out:
containers_out.write(yaml.dump(containers_yaml)) containers_out.write(yaml.dump(containers_yaml))
print(f"containers yaml written to {args.containers_yaml_out}") print(f"containers yaml written to {args.containers_yaml_out}")
standalone_parameters = get_standalone_parameters(args) standalone_parameters = get_standalone_parameters(args)
with open( with open(args.standalone_yaml_out, "w", encoding="utf-8") as parameters_out:
args.standalone_yaml_out, "w", encoding="utf-8"
) as parameters_out:
parameters_out.write(yaml.dump(standalone_parameters)) parameters_out.write(yaml.dump(standalone_parameters))
print(f"standalone parameters yaml written to {args.standalone_yaml_out}") print(f"standalone parameters yaml written to {args.standalone_yaml_out}")

View file

@ -4,6 +4,8 @@ import os
import subprocess import subprocess
import sys import sys
from rich import print
def get_from_env(name, envvar, required=True): def get_from_env(name, envvar, required=True):
"""Get the value for a parameter from an environment variable""" """Get the value for a parameter from an environment variable"""
@ -25,20 +27,18 @@ def openstack_cmd(cmd, args, as_json=False):
""" """
cmd = cmd.replace("\n", " ") cmd = cmd.replace("\n", " ")
cmd = "OS_CLOUD=standalone openstack " + cmd cmd = f"OS_CLOUD={args.cloud} openstack " + cmd
if args.ssh: if "ssh" in args and args.ssh:
cmd = f'ssh {args.ssh} "{cmd}"' cmd = f'ssh {args.ssh} "{cmd}"'
if args.dry_run: if "dry_run" in args and args.dry_run:
print("dry-run specified. Not executing cmd. cmd was:") print("dry-run specified. Not executing cmd. cmd was:")
print(cmd) print(cmd)
return None return None
try: try:
result = subprocess.check_output( result = subprocess.check_output(cmd, shell=True, universal_newlines=True)
cmd, shell=True, universal_newlines=True
)
if as_json: if as_json:
result = json.loads(result) result = json.loads(result)
@ -64,3 +64,12 @@ def test_user_openstack_cmd(cmd, args, as_json=False):
print(cmd) print(cmd)
return openstack_cmd(cmd, args, as_json=as_json) return openstack_cmd(cmd, args, as_json=as_json)
def failed(msg, args):
args.failed = True
print(f"[red]{msg} :x:[/red]")
def passed(msg):
print(f"[green]{msg} :white_heavy_check_mark:[/green]")