Commit aca9a5ad authored by Noe Nieto's avatar Noe Nieto 💬
Browse files

implement forbidden commands; prune vagrant boxes; improve status report; ref...

implement forbidden commands; prune vagrant boxes; improve status report; ref liberty/ldh_developer#8
parent 97cdafdd
Pipeline #3832 failed with stage
in 46 seconds
...@@ -27,6 +27,35 @@ XDG_PB_CONFIG_HOME = Path(os.environ['HOME'],'.config','ldh_developer','playbook ...@@ -27,6 +27,35 @@ XDG_PB_CONFIG_HOME = Path(os.environ['HOME'],'.config','ldh_developer','playbook
VG_REQ_PLUGINS = {'libvirt': 'vagrant-libvirt', 'digital_ocean': 'vagrant-digitalocean'} VG_REQ_PLUGINS = {'libvirt': 'vagrant-libvirt', 'digital_ocean': 'vagrant-digitalocean'}
HERE = Path(__file__).parent HERE = Path(__file__).parent
DO_SSH_KEY_PATH = Path('~/.ssh/shipwright/').expanduser() DO_SSH_KEY_PATH = Path('~/.ssh/shipwright/').expanduser()
VAGRANT_CONFIG_HOME = Path(os.environ.get('VAGRANT_HOME', str(Path.home().joinpath('.vagrant.d'))))
VAGRANT_DB_PATH = Path(VAGRANT_CONFIG_HOME, 'data', 'machine-index', 'index')
class VagrantDB(object):
@property
def boxes(self):
data = json.loads(VAGRANT_DB_PATH.open().read())
vgt_boxes = data['machines']
return {
vgt_boxes[box_id]['name']:{
'uid': box_id,
'provider': vgt_boxes[box_id]['provider'],
'state': vgt_boxes[box_id]['state'],
'vagrantfile_path': vgt_boxes[box_id]['vagrantfile_path'],
} for box_id in vgt_boxes
}
def provider_for(self, hostname):
try:
return self.boxes[hostname]['provider']
except KeyError:
return None
@classmethod
def prune(cls):
print("Removing vagrant's invalid entries ...")
subprocess.run(['vagrant', 'global-status', '--prune'], capture_output=True)
print("Done")
def ensure_plugins(): def ensure_plugins():
...@@ -36,7 +65,7 @@ def ensure_plugins(): ...@@ -36,7 +65,7 @@ def ensure_plugins():
universal_newlines=True universal_newlines=True
) )
if cp.returncode != 0: if cp.returncode != 0:
print("Ooops, there's be something wrong with vagrant!!?") print("Ooops, there's something wrong with vagrant!!?")
print(cp.stdout) print(cp.stdout)
print(cp.stderr) print(cp.stderr)
sys.exit(1) sys.exit(1)
...@@ -48,6 +77,18 @@ def ensure_plugins(): ...@@ -48,6 +77,18 @@ def ensure_plugins():
sys.exit(1) sys.exit(1)
def forbdden_for_digital_ocean(func):
def wrapper(*args, **kwargs):
vg_db = VagrantDB()
hostname = args[0]
if vg_db.provider_for(hostname) == 'digital_ocean':
print("Error: This command is forbidden for the digital_ocean provider.")
exit(1)
else:
func(*args, **kwargs)
return wrapper
def only_if_box_exist(func): def only_if_box_exist(func):
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
hostname = args[0] hostname = args[0]
...@@ -60,6 +101,13 @@ def only_if_box_exist(func): ...@@ -60,6 +101,13 @@ def only_if_box_exist(func):
return wrapper return wrapper
def prune_after_call(func):
def wrapper(*args, **kwargs):
func(*args, **kwargs)
VagrantDB.prune()
return wrapper
def is_ipaddress(ip_addr): def is_ipaddress(ip_addr):
try: try:
ipaddress.ip_address(ip_addr) ipaddress.ip_address(ip_addr)
...@@ -73,15 +121,13 @@ def print_status(): ...@@ -73,15 +121,13 @@ def print_status():
Prints the status of all the boxes managed by Shipwright Prints the status of all the boxes managed by Shipwright
""" """
box_paths = [str(d) for d in XDG_BOX_CONFIG_HOME.iterdir() if d.is_dir()] box_paths = [str(d) for d in XDG_BOX_CONFIG_HOME.iterdir() if d.is_dir()]
vgt_db = Path(
os.environ.get('VAGRANT_HOME', str(Path.home().joinpath('.vagrant.d'))),
'data', 'machine-index', 'index'
)
count = 0 count = 0
if vgt_db.exists(): if VAGRANT_CONFIG_HOME.exists():
print('hostname \t State\t IP Address \t Provider') print('-----------------------------------------------------------------')
db = json.loads(vgt_db.open().read()) print('| hostname | State | Provider | IP Address |')
for k, v in db['machines'].items(): print('-----------------------------------------------------------------')
db = VagrantDB()
for hostname, v in db.boxes.items():
vagrant_wd = v['vagrantfile_path'] vagrant_wd = v['vagrantfile_path']
if vagrant_wd in box_paths: if vagrant_wd in box_paths:
# get the ip address # get the ip address
...@@ -97,11 +143,13 @@ def print_status(): ...@@ -97,11 +143,13 @@ def print_status():
if is_ipaddress(str(fld)): if is_ipaddress(str(fld)):
ip_addr = str(fld) ip_addr = str(fld)
break break
print(f"{v['name']} \t {v['state']}\t {ip_addr}") print(f"| {hostname:15}| {v['state']:10}| {v['provider']:15}| {ip_addr:15} |")
count+=1 count+=1
print('Total {} box(es)'.format(count)) print('-----------------------------------------------------------------')
print(f'Total {count} box(es)')
@prune_after_call
def box_create(hostname, ram, cpus, provider, token): def box_create(hostname, ram, cpus, provider, token):
""" """
This creates a box using the template This creates a box using the template
...@@ -142,16 +190,21 @@ def box_create(hostname, ram, cpus, provider, token): ...@@ -142,16 +190,21 @@ def box_create(hostname, ram, cpus, provider, token):
subprocess.run(['vagrant','up'], cwd=vagrant_wd) subprocess.run(['vagrant','up'], cwd=vagrant_wd)
@prune_after_call
@forbdden_for_digital_ocean
@only_if_box_exist @only_if_box_exist
def box_destroy(hostname): def box_destroy(hostname):
""" """
Destroy a box, or all Destroy a box, or all
""" """
vagrant_wd = XDG_BOX_CONFIG_HOME.joinpath(hostname) vagrant_wd = XDG_BOX_CONFIG_HOME.joinpath(hostname)
subprocess.run(['vagrant','destroy'], cwd=vagrant_wd) r = subprocess.run(['vagrant','destroy'], cwd=vagrant_wd)
shutil.rmtree(vagrant_wd) if r.returncode == 0:
shutil.rmtree(vagrant_wd)
@prune_after_call
@forbdden_for_digital_ocean
@only_if_box_exist @only_if_box_exist
def run_playbook(hostname, playbook, retry_file=None): def run_playbook(hostname, playbook, retry_file=None):
""" """
...@@ -171,6 +224,7 @@ def run_playbook(hostname, playbook, retry_file=None): ...@@ -171,6 +224,7 @@ def run_playbook(hostname, playbook, retry_file=None):
subprocess.run(_args, cwd=vagrant_wd) subprocess.run(_args, cwd=vagrant_wd)
@forbdden_for_digital_ocean
@only_if_box_exist @only_if_box_exist
def box_start(hostname): def box_start(hostname):
""" """
...@@ -180,6 +234,8 @@ def box_start(hostname): ...@@ -180,6 +234,8 @@ def box_start(hostname):
subprocess.run(['vagrant','up'], cwd=vagrant_wd) subprocess.run(['vagrant','up'], cwd=vagrant_wd)
@prune_after_call
@forbdden_for_digital_ocean
@only_if_box_exist @only_if_box_exist
def box_halt(hostname): def box_halt(hostname):
""" """
...@@ -190,7 +246,7 @@ def box_halt(hostname): ...@@ -190,7 +246,7 @@ def box_halt(hostname):
@only_if_box_exist @only_if_box_exist
def invoke_shell(hostname): def box_ssh_connect(hostname):
""" """
Open a SSH session to the hostname Open a SSH session to the hostname
""" """
...@@ -199,7 +255,7 @@ def invoke_shell(hostname): ...@@ -199,7 +255,7 @@ def invoke_shell(hostname):
@only_if_box_exist @only_if_box_exist
def which(hostname): def box_get_working_directory(hostname):
""" """
Print the directory of a box by it's hostname Print the directory of a box by it's hostname
""" """
...@@ -281,9 +337,9 @@ if __name__ == '__main__': ...@@ -281,9 +337,9 @@ if __name__ == '__main__':
elif cmd_args.command == 'destroy': elif cmd_args.command == 'destroy':
box_destroy(sub_args.hostname) box_destroy(sub_args.hostname)
elif cmd_args.command == 'ssh': elif cmd_args.command == 'ssh':
invoke_shell(sub_args.hostname) box_ssh_connect(sub_args.hostname)
elif cmd_args.command == 'which': elif cmd_args.command == 'which':
which(sub_args.hostname) box_get_working_directory(sub_args.hostname)
elif cmd_args.command == 'open': elif cmd_args.command == 'open':
box_gio_open(sub_args.hostname) box_gio_open(sub_args.hostname)
else: else:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment