def post(self):
""" POST API code """
# validate parameters
#print "start time = ",datetime.now().time()
schema = api_input.ClientPostSchema()
args, errors = schema.load(request.get_json())
if errors:
abort(400, message="Validation errors : {0}".format(errors))
app.logger.info("Client POST start - {0}".format(args['client_id']))
argument_list = args.items()
if errors:
abort(400, message="Validation errors : {0}".format(errors))
# dictionary for storing aws master details i.e details come from service input
try:
task = self.init_clients.apply_async(argument_list)
msg = 'Clients Initialzation request has been posted successfully. ' \
'Use the task ID to get the status with GET request '
# task_id = task.id
# msg += 'task_id =%s' % task.id
app.logger.info(msg)
app.logger.info(task.id)
returnmsg = {'message': msg, 'task_id': task.id}
return returnmsg, 201
except Exception as e:
print traceback.format_exc()
msg = 'Celery task did not execute properly.Task ID is not returned.'
app.logger.error(msg)
abort(400, message=msg)
def deletegcp(self, backend, item, src_namespace):
"""Delete GCP Service Account """
# get master credentials details from vault
data = config.get_cloud_init_data()
namespace = backend.return_namespace(src_namespace + item, 'master')
creds = backend.get_namespace_data(namespace)
if creds is None:
msg = 'GCP master details not present in vault. Kindly contact service provider'
app.logger.error(msg)
abort(400, message=msg)
wanted_keys = ['type', 'project_id', 'private_key_id', 'private_key', 'client_email',
'client_id',
'auth_uri', 'token_uri', 'auth_provider_x509_cert_url',
'client_x509_cert_url']
newdict = {}
newdict = dict((k, creds[k]) for k in wanted_keys if k in creds)
# login gcp account using service account
credentials = self.gcplogin(newdict)
try:
service = discovery.build('iam', 'v1', credentials=credentials)
except Exception as obj:
app.logger.error(obj)
msg = "SSL certificate error.Kindly make sure private key is correct & retry"
app.logger.error(msg)
abort(400, message=msg)
for credential_type, value in data['gcp']['credential_name'].iteritems():
username = value['user_name']
if username == 'master':
continue
else:
namespace = backend.return_namespace(src_namespace + item, username)
vdata = backend.get_namespace_data(namespace)
if vdata is not None:
self.deletegcpserviceaccount(service, vdata['project_id'], vdata['client_email'])
def deleteazure(self, backend, item, src_namespace):
"""Delete AZURE Service Principle"""
# print "Azure Delete start time = ", datetime.now().time()
data = config.get_cloud_init_data()
namespace = backend.return_namespace(src_namespace + item, 'master')
creds = backend.get_namespace_data(namespace)
if creds is None:
msg = 'GCP master details not present in vault. Kindly contact service provider'
app.logger.error(msg)
abort(400, message=msg)
if platform == "linux" or platform == "linux2":
makecmd = "az login -u " + creds['username'] + " -p " + creds['password']
cmd = [makecmd]
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
stdin=subprocess.PIPE)
out, err = p.communicate()
if p.returncode != 0:
msg = "user Unable to login azure cloud.Kindly verify username & password"
app.logger.error(err)
abort(400, message=msg)
elif platform == "win32":
makecmd = "az login -u " + creds['username'] + " -p " + creds['password']
cmd = ["powershell.exe", makecmd]
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
stdin=subprocess.PIPE)
out, err = p.communicate()
if p.returncode != 0:
msg = "user Unable to login azure cloud.Kindly verify username & password"
app.logger.error(err)
abort(400, message=msg)
for credential_type, value in data['azure']['credential_name'].iteritems():
username = value['user_name']
if username == 'master':
continue
else:
namespace = backend.return_namespace(src_namespace + item, username)
vdata = backend.get_namespace_data(namespace)
if vdata is not None:
if platform == "linux" or platform == "linux2":
makecmd = "az ad sp delete --id http://{0}".format(username)
cmd = [makecmd]
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE)
out, err = p.communicate()
p.wait()
if p.returncode != 0:
msg = "Error While Deleting Service Principle for " + username + \
".Kindly contact service provider"
app.logger.error(err)
abort(400, message=msg)
elif platform == "win32":
makecmd = "az ad sp delete --id http://{0}".format(username)
# print "delete command = ",makecmd
cmd = ["powershell.exe", makecmd]
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE)
out, err = p.communicate()
p.wait()
if p.returncode != 0:
msg = "Error While Deleting Service Principle for " + username + \
".Kindly contact service provider"
app.logger.error(msg)
abort(400, message=msg)
# print "Azure End time = ", datetime.now().time()
def deleteaws(self, backend, item, src_namespace):
"""Delete AWS users """
master_access_key = ''
master_secret_key = ''
master_region = ''
app.logger.info("Delete AWS Start")
data = config.get_cloud_init_data()
namespace = backend.return_namespace(src_namespace + item, 'master')
vdata = backend.get_namespace_data(namespace)
if vdata is None:
msg = 'Aws master details not present in vault. Kindly contact service provider'
app.logger.error(msg)
abort(400, message=msg)
master_access_key = vdata['access_key']
master_secret_key = vdata['secret_key']
master_region = vdata['region']
account_id = ""
iam_client = None
try:
aws_session = boto3.Session(aws_access_key_id=master_access_key,
aws_secret_access_key=master_secret_key,
region_name=master_region)
account_id = (aws_session.client("sts").get_caller_identity()['Account'])
iam_client = aws_session.client('iam')
except Exception as obj:
#print traceback.format_exc()
msg = "error while creating AWS session, check, master keys validity and correct region"
app.logger.error(msg)
app.logger.error(obj)
abort(400, message=msg)
for credential_type, value in data['aws']['credential_name'].iteritems():
username = value['user_name']
if username == 'master':
continue
else:
namespace = backend.return_namespace(src_namespace + item, username)
vdata = backend.get_namespace_data(namespace)
if vdata is not None:
# detach aws policy
arnpolicy = 'arn:aws:iam::'+account_id+':policy/' + "vault-"+username
status_code = self.deleteuserpolicy(iam_client, username, arnpolicy)
if status_code != 200:
msg = "error while detaching " + arnpolicy + " for the " + username
app.logger.error(msg)
abort(400, message=msg)
app.logger.info("aws policy detached and deleted {0}".format(arnpolicy))
# delete aws access key
status_code = self.deleteaccesskeys(iam_client, username)
if status_code != 200:
msg = "error while Deleting access key(s)"
app.logger.error(msg)
abort(400, message=msg)
# delete aws user
status_code = self.deleteuser(iam_client, username)
if status_code != 200:
msg = "Error Occur While deleting " + username + \
".Kindly Contact Service Provider"
app.logger.error(msg)
abort(400, message=msg)
app.logger.info("Delete AWS End")
def delete(self, client_id):
""" delete API code """
# validate parameters
#print "start time = ", datetime.now().time()
service_secret_key = request.headers.get('service-secret-key')
service_access_key = request.headers.get('service-access-key')
schema = api_input.ClientDeleteSchema()
args, errors = schema.load(dict(client_id=client_id, service_secret_key=service_secret_key,
service_access_key=service_access_key))
if errors:
abort(400, message="Validation errors : {0}".format(errors))
app.logger.info("Delete Start CLIENT ID {0} ".format(client_id))
try:
backend = vault.Vault()
#login in vault
backend.login(args['service_access_key'], args['service_secret_key'])
src_namespace = 'secret/clients/{0}/'.format(client_id)
dest_namespace = 'archive/clients/{0}/'.format(client_id)
vault_keys = backend.list_namespace(src_namespace)
if vault_keys is None:
msg = "Cloud Details Not Present In Vault"
app.logger.error(msg)
abort(400, message=msg)
for i, item in enumerate(vault_keys):
if item == 'metadata':
continue
if item[:-1] == 'aws':
self.deleteaws(backend, item, src_namespace)
if item[:-1] == 'gcp':
self.deletegcp(backend, item, src_namespace)
if item[:-1] == 'azure':
self.deleteazure(backend, item, src_namespace)
backend.recursive_copy(src_namespace, dest_namespace)
env_src_namespace = 'secret/environments/{0}/'
env_dest_namespace = 'archive/environments/{0}/'
backend.scan_env_metadata_delete_env_details('secret/environments/', client_id, env_src_namespace,
env_dest_namespace)
backend.recursive_delete(src_namespace)
#print "End time = ", datetime.now().time()
app.logger.info("Delete End CLIENT ID {0} ".format(client_id))
return "Successfully deleted.", 200
except hvac.exceptions.InvalidRequest as obj:
# when vault keys error.
print traceback.format_exc()
app.logger.error(obj.message)
abort(400, message="Error : {}".format(obj.message))
except KeyError as kobj:
print traceback.format_exc()
app.logger.error(kobj.message)
abort(400, message="Invalid Parameters : {}".format(kobj.message))
class AllClients(Resource):
""" Get client endpoint resource class"""
def get(self, client_id):
""" get endpoint API function"""
input_params = reqparse.RequestParser()
input_params.add_argument('service-access-key', required=True,
help="Vault Access Key cannot be blank!",
location='headers', dest='service_access_key')
input_params.add_argument('service-secret-key', required=True,
help="Vault Secret ID cannot be blank!",
location='headers', dest='service_secret_key')
args = input_params.parse_args(strict=True)
backend = vault.Vault()
backend.login(args['service_access_key'], args['service_secret_key'])
# checking payload/namespace already exists or not
if not backend.client_exists(client_id):
abort(404, message="Client does not exist")
app.logger.info("Client metadata exist")
return {'message': 'Client present'}