Does this work
This commit is contained in:
89
secdep.py
89
secdep.py
@@ -26,11 +26,12 @@ import subprocess
|
|||||||
import libcloud.security
|
import libcloud.security
|
||||||
import inspect
|
import inspect
|
||||||
import paramiko
|
import paramiko
|
||||||
|
import socket
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from libcloud.compute.types import Provider
|
from libcloud.compute.types import Provider
|
||||||
from libcloud.compute.providers import get_driver
|
from libcloud.compute.providers import get_driver
|
||||||
from libcloud.compute.base import NodeAuthSSHKey
|
from libcloud.compute.base import NodeAuthSSHKey
|
||||||
from libcloud.compute.deployment import ScriptDeployment
|
from libcloud.compute.deployment import ScriptDeployment, SSHKeyDeployment, MultiStepDeployment
|
||||||
|
|
||||||
# Disable SSL certificate verification
|
# Disable SSL certificate verification
|
||||||
# Disable SHA-2 variants of RSA key verification algorithm for backward compatibility reasons
|
# Disable SHA-2 variants of RSA key verification algorithm for backward compatibility reasons
|
||||||
@@ -76,10 +77,12 @@ if not os.path.exists(SECDEP_SSH_PUBLIC_KEY) or not os.path.exists(SECDEP_SSH_PR
|
|||||||
# The public key is stored in the current directory and named secdep.pub
|
# The public key is stored in the current directory and named secdep.pub
|
||||||
# The passphrase is an empty string
|
# The passphrase is an empty string
|
||||||
# The key is a 4096 bit RSA key
|
# The key is a 4096 bit RSA key
|
||||||
|
# The key's comment is secdep@hostname
|
||||||
|
|
||||||
key = paramiko.RSAKey.generate(4096)
|
key = paramiko.RSAKey.generate(4096)
|
||||||
key.write_private_key_file(SECDEP_SSH_PRIVATE_KEY)
|
key.write_private_key_file(SECDEP_SSH_PRIVATE_KEY)
|
||||||
with open(SECDEP_SSH_PUBLIC_KEY, 'w') as f:
|
with open(SECDEP_SSH_PUBLIC_KEY, 'w') as f:
|
||||||
f.write("%s %s" % (key.get_name(), key.get_base64()))
|
f.write("%s %s secdep@%s" % (key.get_name(), key.get_base64(), socket.gethostname()))
|
||||||
|
|
||||||
# We first check if it exists already in order to avoid overwriting it
|
# We first check if it exists already in order to avoid overwriting it
|
||||||
# and if it doesn't exist, we create it by inserting an empty string
|
# and if it doesn't exist, we create it by inserting an empty string
|
||||||
@@ -715,8 +718,8 @@ def choose_from_list(listFromlistFunction,listName):
|
|||||||
printFormat = "{}) {}\n\n{}\n"
|
printFormat = "{}) {}\n\n{}\n"
|
||||||
printstring = "print(printFormat.format(count, item.name, item.extra['description']))"
|
printstring = "print(printFormat.format(count, item.name, item.extra['description']))"
|
||||||
elif listName == "node":
|
elif listName == "node":
|
||||||
printFormat = "{}) {}\n\nState: {}\nPublic IPs: {}\nPrivate IPs: {}\nDriver: {}\nSize: {}\nImage: {}\nCreation Date: {}\n"
|
printFormat = "{}) {}\n\nState: {}\nPublic IPs: {}\nPrivate IPs: {}\nDriver: {}\nSize: {}\nImage: {}\nCreation Date: {}\nExtra: {}\n"
|
||||||
printstring = "print(printFormat.format(count, item.name, item.state, item.public_ips, item.private_ips, item.driver, item.size, item.image, item.created_at))"
|
printstring = "print(printFormat.format(count, item.name, item.state, item.public_ips, item.private_ips, item.driver, item.size, item.image, item.created_at, item.extra))"
|
||||||
|
|
||||||
compiled_code = compile(printstring,"<string>","exec")
|
compiled_code = compile(printstring,"<string>","exec")
|
||||||
print("Choosing 0 will exit")
|
print("Choosing 0 will exit")
|
||||||
@@ -801,17 +804,19 @@ def create_node(provider, name=None, location=None, size=None, image=None, confi
|
|||||||
# Get public ssh key value
|
# Get public ssh key value
|
||||||
with open(SECDEP_SSH_PUBLIC_KEY, 'r') as f:
|
with open(SECDEP_SSH_PUBLIC_KEY, 'r') as f:
|
||||||
pubkey = f.read()
|
pubkey = f.read()
|
||||||
if provider != "gce":
|
if provider == "azure":
|
||||||
auth = NodeAuthSSHKey(pubkey)
|
auth = NodeAuthSSHKey(pubkey)
|
||||||
# Check if name was given and if not prompt the user to give one
|
# Check if name was given and if not prompt the user to give one
|
||||||
if name is None:
|
if name is None:
|
||||||
name = input("Enter the name of the node: ")
|
name = input("Enter the name of the node: ")
|
||||||
assert name != "", "Name is empty"
|
assert name != "", "Name is empty"
|
||||||
name = "provider_"+name
|
name = provider+"_"+name
|
||||||
|
else:
|
||||||
|
name = provider+"_"+name
|
||||||
# In the case of aws location has to be None because it is actually derived from the ami (image)
|
# In the case of aws location has to be None because it is actually derived from the ami (image)
|
||||||
if provider == "aws":
|
if provider == "aws":
|
||||||
location = None
|
location = None
|
||||||
print("in aws you first have to choose an image before the location")
|
# print("in aws you first have to choose an image before the location")
|
||||||
else:
|
else:
|
||||||
# In other cases
|
# In other cases
|
||||||
# Check if location was given and if not prompt the user to choose
|
# Check if location was given and if not prompt the user to choose
|
||||||
@@ -859,6 +864,12 @@ def create_node(provider, name=None, location=None, size=None, image=None, confi
|
|||||||
if image is None:
|
if image is None:
|
||||||
image = get_provider_image(provider)
|
image = get_provider_image(provider)
|
||||||
assert image is not None, "Image is None"
|
assert image is not None, "Image is None"
|
||||||
|
if provider == "aws":
|
||||||
|
ami = image.id
|
||||||
|
region = getAWSRegionFromAmi(ami)
|
||||||
|
dr = get_corresponding_driver(provider)
|
||||||
|
assert dr is not None, "Driver is not set up correctly"
|
||||||
|
image = get_driver(Provider.EC2)(SECDEP_AWS_ACCESS_KEY, SECDEP_AWS_SECRET_KEY,region=region).get_image(ami)
|
||||||
else:
|
else:
|
||||||
blockPrint()
|
blockPrint()
|
||||||
# If provider was aws we must get the list of amis
|
# If provider was aws we must get the list of amis
|
||||||
@@ -939,8 +950,20 @@ def create_node(provider, name=None, location=None, size=None, image=None, confi
|
|||||||
# step = ScriptDeployment(SCRIPT)
|
# step = ScriptDeployment(SCRIPT)
|
||||||
node = driver.create_node(name=name, image=image, size=size, location=location, ex_service_accounts=sa_scopes, ex_metadata=metadata)
|
node = driver.create_node(name=name, image=image, size=size, location=location, ex_service_accounts=sa_scopes, ex_metadata=metadata)
|
||||||
# node = driver.deploy_node(name=name, image=image, size=size, location=location, deploy=step, ex_service_accounts=sa_scopes, ex_metadata=metadata, ssh_key=SECDEP_SSH_PRIVATE_KEY)
|
# node = driver.deploy_node(name=name, image=image, size=size, location=location, deploy=step, ex_service_accounts=sa_scopes, ex_metadata=metadata, ssh_key=SECDEP_SSH_PRIVATE_KEY)
|
||||||
else:
|
elif provider == "azure":
|
||||||
node = driver.create_node(name, size, image, location, auth=auth)
|
node = driver.create_node(name, size, image, location, auth=auth)
|
||||||
|
else:
|
||||||
|
# driver.import_key_pair_from_string("secdep@"+socket.gethostname(), pubkey)
|
||||||
|
SCRIPT = '''#!/usr/bin/env bash
|
||||||
|
useradd -G sudo -m secdep
|
||||||
|
echo "secdep:secdeppass" | chpasswd
|
||||||
|
echo "%sudo ALL=(ALL:ALL) ALL" >> /etc/sudoers
|
||||||
|
mkdir -p /home/secdep/.ssh
|
||||||
|
cp /root/.ssh/authorized_keys /home/secdep/.ssh/authorized_keys'''
|
||||||
|
step_1 = SSHKeyDeployment(pubkey)
|
||||||
|
step_2 = ScriptDeployment(SCRIPT)
|
||||||
|
msd = MultiStepDeployment([step_1, step_2])
|
||||||
|
node = driver.deploy_node(name=name, image=image, size=size, deploy=msd, ssh_key=SECDEP_SSH_PRIVATE_KEY)
|
||||||
else:
|
else:
|
||||||
# When the -y or --yes parameter is passed we go straight to the node creation
|
# When the -y or --yes parameter is passed we go straight to the node creation
|
||||||
if provider == "gce":
|
if provider == "gce":
|
||||||
@@ -952,14 +975,43 @@ def create_node(provider, name=None, location=None, size=None, image=None, confi
|
|||||||
# step = ScriptDeployment(SCRIPT)
|
# step = ScriptDeployment(SCRIPT)
|
||||||
node = driver.create_node(name=name, image=image, size=size, location=location, ex_service_accounts=sa_scopes, ex_metadata=metadata)
|
node = driver.create_node(name=name, image=image, size=size, location=location, ex_service_accounts=sa_scopes, ex_metadata=metadata)
|
||||||
# node = driver.deploy_node(name=name, image=image, size=size, location=location, deploy=step, ex_service_accounts=sa_scopes, ex_metadata=metadata, ssh_key=SECDEP_SSH_PRIVATE_KEY)
|
# node = driver.deploy_node(name=name, image=image, size=size, location=location, deploy=step, ex_service_accounts=sa_scopes, ex_metadata=metadata, ssh_key=SECDEP_SSH_PRIVATE_KEY)
|
||||||
else:
|
# if provider == "aws":
|
||||||
|
# SCRIPT = '''#!/usr/bin/env bash
|
||||||
|
# useradd -G sudo -m secdep
|
||||||
|
# echo "secdep:secdeppass" | chpasswd
|
||||||
|
# echo "%sudo ALL=(ALL:ALL) ALL" >> /etc/sudoers
|
||||||
|
# mkdir -p /home/secdep/.ssh'''
|
||||||
|
# step = ScriptDeployment(SCRIPT)
|
||||||
|
#
|
||||||
|
elif provider == "azure":
|
||||||
node = driver.create_node(name, size, image, location, auth=auth)
|
node = driver.create_node(name, size, image, location, auth=auth)
|
||||||
|
else:
|
||||||
|
# driver.import_key_pair_from_string("secdep@"+socket.gethostname(), pubkey)
|
||||||
|
SCRIPT = '''#!/usr/bin/env bash
|
||||||
|
useradd -G sudo -m secdep
|
||||||
|
echo "secdep:secdeppass" | chpasswd
|
||||||
|
echo "%sudo ALL=(ALL:ALL) ALL" >> /etc/sudoers
|
||||||
|
mkdir -p /home/secdep/.ssh
|
||||||
|
cp /root/.ssh/authorized_keys /home/secdep/.ssh/authorized_keys'''
|
||||||
|
step_1 = SSHKeyDeployment(pubkey)
|
||||||
|
step_2 = ScriptDeployment(SCRIPT)
|
||||||
|
msd = MultiStepDeployment([step_1, step_2])
|
||||||
|
node = driver.deploy_node(name=name, image=image, size=size, deploy=msd, ssh_key=SECDEP_SSH_PRIVATE_KEY)
|
||||||
|
print('stdout: %s' % (step_1.stdout))
|
||||||
|
print('stderr: %s' % (step_1.stderr))
|
||||||
|
print('exit_code: %s' % (step_1.exit_status))
|
||||||
|
print('stdout: %s' % (step_2.stdout))
|
||||||
|
print('stderr: %s' % (step_2.stderr))
|
||||||
|
print('exit_code: %s' % (step_2.exit_status))
|
||||||
print(node.name + " created successfully")
|
print(node.name + " created successfully")
|
||||||
|
print("Node is initializing")
|
||||||
|
time.sleep(30)
|
||||||
print("ip to connect to")
|
print("ip to connect to")
|
||||||
print(node.public_ips)
|
print("\nIP: %s\n" % (node.public_ips))
|
||||||
return node
|
return node
|
||||||
|
## aws node does not return ip
|
||||||
|
|
||||||
def list_all_nodes():
|
def list_all_nodes(filterOut=None):
|
||||||
print("Getting all nodes...")
|
print("Getting all nodes...")
|
||||||
nodes = []
|
nodes = []
|
||||||
if SECDEP_GCE_CLIENT_ID != "":
|
if SECDEP_GCE_CLIENT_ID != "":
|
||||||
@@ -987,9 +1039,11 @@ def list_all_nodes():
|
|||||||
if len(nodes) == 0:
|
if len(nodes) == 0:
|
||||||
print("No nodes")
|
print("No nodes")
|
||||||
exit(0)
|
exit(0)
|
||||||
|
if filterOut == "terminated":
|
||||||
|
nodes = list(filter(lambda x: 'terminated' not in x.state.lower(), nodes))
|
||||||
for node in nodes:
|
for node in nodes:
|
||||||
count += 1
|
count += 1
|
||||||
print("{}) {}\n\nState: {}\nPublic IPs: {}\nPrivate IPs: {}\nDriver: {}\nSize: {}\nImage: {}\nCreation Date: {}\n".format(count, node.name, node.state, node.public_ips, node.private_ips, node.driver, node.size, node.image, node.created_at))
|
print("{}) {}\n\nState: {}\nPublic IPs: {}\nPrivate IPs: {}\nDriver: {}\nSize: {}\nImage: {}\nCreation Date: {}\nExtra: {}\n".format(count, node.name, node.state, node.public_ips, node.private_ips, node.driver, node.size, node.image, node.created_at, node.extra))
|
||||||
return nodes
|
return nodes
|
||||||
|
|
||||||
def get_node():
|
def get_node():
|
||||||
@@ -997,7 +1051,7 @@ def get_node():
|
|||||||
return node
|
return node
|
||||||
|
|
||||||
def delete_node():
|
def delete_node():
|
||||||
node = choose_from_list(list_all_nodes(), "node")
|
node = choose_from_list(list_all_nodes("terminated"), "node")
|
||||||
providerName = node.name.split("_")[0]
|
providerName = node.name.split("_")[0]
|
||||||
if providerName == "gce":
|
if providerName == "gce":
|
||||||
driver = get_corresponding_driver("gce")
|
driver = get_corresponding_driver("gce")
|
||||||
@@ -1005,10 +1059,15 @@ def delete_node():
|
|||||||
driver = get_corresponding_driver("azure")
|
driver = get_corresponding_driver("azure")
|
||||||
elif providerName == "aws":
|
elif providerName == "aws":
|
||||||
driver = get_corresponding_driver("aws")
|
driver = get_corresponding_driver("aws")
|
||||||
|
assert driver is not None, "Driver is not set up correctly"
|
||||||
|
region = getAWSRegionFromAmi(node.extra['image_id'])
|
||||||
|
driver = get_driver(Provider.EC2)(SECDEP_AWS_ACCESS_KEY, SECDEP_AWS_SECRET_KEY,region=region)
|
||||||
if(driver.destroy_node(node)):
|
if(driver.destroy_node(node)):
|
||||||
print("% node deleted successfully" % (providerName.upper()))
|
print("%s node deleted successfully" % (providerName.upper()))
|
||||||
else:
|
else:
|
||||||
print("% node could not be deleted" % (providerName.upper()))
|
print("%s node could not be deleted" % (providerName.upper()))
|
||||||
|
|
||||||
|
#elif node.state == "running":
|
||||||
|
|
||||||
# def get_provider_features(provider):
|
# def get_provider_features(provider):
|
||||||
# driver = get_corresponding_driver(provider);
|
# driver = get_corresponding_driver(provider);
|
||||||
|
|||||||
Reference in New Issue
Block a user