diff --git a/.idea/.name b/.idea/.name index 7491e6b..30c8dea 100644 --- a/.idea/.name +++ b/.idea/.name @@ -1 +1 @@ -SecureCloudInit \ No newline at end of file +Cloudefigo \ No newline at end of file diff --git a/.idea/SecureCloudInit.iml b/.idea/Cloudefigo.iml similarity index 100% rename from .idea/SecureCloudInit.iml rename to .idea/Cloudefigo.iml diff --git a/.idea/modules.xml b/.idea/modules.xml index 23f98ed..34885a2 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,8 +2,7 @@ - + - - + \ No newline at end of file diff --git a/AWS/EC2.py b/AWS/EC2.py deleted file mode 100644 index 5115d49..0000000 --- a/AWS/EC2.py +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/python - -__author__ = 'nirv' - -import boto.ec2 -import time -from Common.AppConfigMgr import ConfigMgr -from Common.Exceptions import GenericException -from AWS.EnvironmentVarialbes import EnvronmentVarialbes -from Common.Logger import Logger -from AWS.IAM import IAM - - -class EC2: - - def __init__(self, is_executed_by_cloud_init = True, region = None): - self.__cfg = ConfigMgr() - if is_executed_by_cloud_init: - credentials = EnvronmentVarialbes.get_instance_credentials().split(" ") - self.__conn = boto.ec2.EC2Connection(aws_access_key_id=credentials[0], aws_secret_access_key=credentials[1], security_token=credentials[2]) - self.__conn.region = EnvronmentVarialbes.get_current_instance_region() - self.__current_instance_name = EnvronmentVarialbes.get_current_instance_name() - else: - self.__conn = boto.ec2.connect_to_region(region) - - - # - - def create_volume(self): - inst = self.__get_instance_object_by_instance_id(self.__current_instance_name) - vol = self.__conn.create_volume(1,self.__conn.region) - time.sleep(30) - curr_vol = self.__conn.get_all_volumes([vol.id])[0] - while curr_vol.status != 'available': - time.sleep(10) - Logger.logger("info", "pending to make volume available") - self.__conn.attach_volume (vol.id, inst.id, "/dev/sdf") - Logger.log("info", "The volume {} attached to this instance".format(vol.id)) - - def move_current_instance_to_production_group(self): - production_group_id = self.__cfg.getParameter("AWS", "ProductionSecurityGroupId") - instance = self.__get_instance_object_by_instance_id(self.__current_instance_name) - self.__conn.modify_instance_attribute(self.__current_instance_name, - "groupSet", [production_group_id]) - Logger.log("info", "This instance moved to the production subnet {}".format(production_group_id)) - - def post_validation_action(self): - iam = IAM(True) - current_role_name = EnvronmentVarialbes.get_current_instance_profile() - iam.strict_dynamic_role(current_role_name) - Logger.log("info", "Changed the IAM role to be more strict") - - # - - # - - def create_secure_instance(self, ami_id, instance_type, instance_name): - script_path = self.__cfg.getParameter("AWS", "CloudInitScriptPath") - production_security_group_id = self.__cfg.getParameter("AWS", "RemediationSecurityGroupId") - production_subnet_id = self.__cfg.getParameter("AWS", "ProductionSubnetId") - key_name = self.__cfg.getParameter("AWS", "EC2KeyName") - with open(script_path, "r") as script_file: - cloud_init_script = script_file.read() - iam_role = IAM(False) - instance_profile = iam_role.create_dynamic_role() - new_reservation = self.__try_create_instance(ami_id, key_name, instance_profile, instance_type, - production_subnet_id, production_security_group_id, - cloud_init_script) - instance = new_reservation.instances[0] - self.__conn.create_tags([instance.id], {"Name": instance_name}) - Logger.log("info", "An instance created with id {}".format(instance.id)) - - def get_all_running_instance_names(self): - instances_list = [] - instances = self.__conn.get_all_instances() - for instance in instances: - if instance.instances[0].state == "running": - instance_hostname = instance.instances[0].private_dns_name.split('.')[0] - instances_list.append(instance_hostname) - return instances_list - - # - - # TODO remove after testing of new method in EnvironmentVarialbes - def __get_current_instance_iam_role(self): - instance = self.__get_instance_object_by_instance_id(self.__current_instance_name) - iam_arn = instance.instance_profile['arn'] - iam_arn_list = iam_arn.split("/") - return iam_arn_list[len(iam_arn_list) - 1] - - def __get_instance_object_by_instance_id(self, instance_id): - reservations = self.__conn.get_all_instances(instance_ids=[instance_id]) - for instance in reservations[0].instances: - if instance.id == self.__current_instance_name: - return instance - return None - - def __try_create_instance(self, ami_id, key_name, profile_name, instance_type, subnet_id, - security_group_id, user_data): - try: - new_reservation = self.__conn.run_instances(ami_id, key_name=key_name, - instance_profile_name=profile_name, instance_type=instance_type, - subnet_id=subnet_id, security_group_ids=[security_group_id], - user_data=user_data) - return new_reservation - except: - Logger.log("warning", "Could not create instance first time. Waiting another few seconds before retrying") - time.sleep(30) - Logger.log("warning", "Retrying to create instance") - try: - new_reservation = self.__conn.run_instances(ami_id, key_name=key_name, - instance_profile_name=profile_name, - instance_type=instance_type, - subnet_id=subnet_id, security_group_ids=[security_group_id], - user_data=user_data) - return new_reservation - except Exception as ex: - message = "Cannot create new instance: {}".format(ex.message) - raise GenericException(message) diff --git a/AWS/IAM.py b/AWS/IAM.py deleted file mode 100644 index a78181e..0000000 --- a/AWS/IAM.py +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/python - -__author__ = 'nirv' - - -import boto -import uuid -from Common.AppConfigMgr import ConfigMgr -from AWS.EnvironmentVarialbes import EnvronmentVarialbes -from Common.Logger import Logger -from boto.iam import IAMConnection - - - -class IAM: - def __init__(self, is_initiated_by_cloud_init = True): - self.__cfg = ConfigMgr() - self.__iam_basic_policy_path = self.__cfg.getParameter("AWS", "IAMBasicPolicyPath") - self.__iam__strict_policy_path = self.__cfg.getParameter("AWS", "IAMStrictPolicyPath") - self.__prefix_name = self.__cfg.getParameter("AWS", "NamingPrefix") - if is_initiated_by_cloud_init: - credentials = EnvronmentVarialbes.get_instance_credentials().split(" ") - self.__conn = IAMConnection(aws_access_key_id=credentials[0], aws_secret_access_key=credentials[1], security_token=credentials[2]) - else: - self.__conn = boto.connect_iam() - self.__iam_policy_name = "cloud-sec-policy" - - # - - def create_dynamic_role(self): - random_id = uuid.uuid4().get_hex() - with open(self.__iam_basic_policy_path, "r") as policy_file: - iam_role_name = "{}-{}".format(self.__prefix_name, random_id) - iam_policy_document = policy_file.read().replace("BUCKETNAME", "{}*".format(self.__prefix_name)) - self.__conn.create_role(iam_role_name) - self.__conn.create_instance_profile(iam_role_name) - self.__conn.add_role_to_instance_profile(iam_role_name, iam_role_name) - self.__conn.put_role_policy(iam_role_name, self.__iam_policy_name, iam_policy_document) - Logger.log("info", "Created a dynamic role named {}".format(iam_role_name)) - return iam_role_name - - # - - def strict_dynamic_role(self, iam_role_name): - with open(self.__iam__strict_policy_path, "r") as policy_file: - bucket_unique_id = EnvronmentVarialbes.get_bucket_unique_id(self.__prefix_name) - iam_policy_document = policy_file.read().replace("BUCKETNAME", bucket_unique_id) - self.__conn.put_role_policy(iam_role_name, self.__iam_policy_name, iam_policy_document) \ No newline at end of file diff --git a/Chef/ConfigurationManagement.py b/Chef/ConfigurationManagement.py index 83fd362..9983af7 100644 --- a/Chef/ConfigurationManagement.py +++ b/Chef/ConfigurationManagement.py @@ -3,18 +3,18 @@ __author__ = 'nirv' from chef import Node, ChefAPI -from Common.AppConfigMgr import ConfigMgr -from Common.Logger import Logger -from Common.Exceptions import RemediationException +from CloudServices.Common.AppConfigMgr import ConfigMgr +from CloudServices.Common.Logger import Logger +from CloudServices.Common.Exceptions import RemediationException class ChefClient: def __init__(self): cfg = ConfigMgr() - url = cfg.getParameter("Chef","ServerURL") - key_path = cfg.getParameter("Chef","KeyFilePath") - client_name = cfg.getParameter("Chef","ValidationClientName") + url = cfg.get_parameter("Chef","ServerURL") + key_path = cfg.get_parameter("Chef","KeyFilePath") + client_name = cfg.get_parameter("Chef","ValidationClientName") self.__chef_client = ChefAPI(url,key_path,client_name) def verify_management(self): diff --git a/CloudServices/Admin/CloudTrail.py b/CloudServices/Admin/CloudTrail.py new file mode 100644 index 0000000..1c44322 --- /dev/null +++ b/CloudServices/Admin/CloudTrail.py @@ -0,0 +1,67 @@ +#!/usr/bin/python +from abc import ABCMeta, abstractmethod + +__author__ = 'nirv' + +from boto.cloudtrail import layer1 +from chef.utils import json +from CloudServices.Admin.Storage import S3StorageAdmin +from CloudServices.Common.AppConfigMgr import ConfigMgr + +class AbstractBaseAudit(): + __metaclass__ = ABCMeta + + @abstractmethod + def get_logs(self): + pass + + +class Audit(AbstractBaseAudit): + + def __init__(self): + self.__cfg = ConfigMgr() + self.__conn = layer1.CloudTrailConnection(); + self.__storage = S3StorageAdmin() + + def get_logs(self): + trails_list = self.__conn.describe_trails()["trailList"] + logs_list = [] + for trail in trails_list: + bucket_name = trail["S3BucketName"] + bucket_prefix = trail["S3KeyPrefix"] + file_contents_list = self.__storage.get_all_files(bucket_name, bucket_prefix) + for file_content in file_contents_list: + json_content = json.loads(file_content) + for event in json_content["Records"]: + log_entry = self.__get_log_entry_from_json(event) + logs_list.append(log_entry) + return logs_list + + def reset_files_extensions(self): + trails_list = self.__conn.describe_trails()["trailList"] + for trail in trails_list: + bucket_name = trail["S3BucketName"] + bucket_prefix = trail["S3KeyPrefix"] + self.__storage.reset_files_extension(bucket_name, bucket_prefix) + + @staticmethod + def __get_log_entry_from_json(event): + log_entry = {'timestamp': event["eventTime"]} + try: + log_entry['username'] = event["userIdentity"]["userName"] + except: + log_entry['username'] = "" + try: + log_entry['access_key'] = event["userIdentity"]["accessKeyId"] + except: + log_entry['access_key'] = "" + log_entry['event_name'] = event["eventName"] + log_entry['event_source'] = event["eventSource"] + log_entry['source_ip'] = event["sourceIPAddress"] + log_entry['user_agent'] = event["userAgent"] + log_entry['region'] = event["awsRegion"] + log_entry['request_parameters'] = json.dumps(event["requestParameters"]) + log_entry['response'] = json.dumps(event["responseElements"]) + return log_entry + + diff --git a/CloudServices/Admin/IdentityManagement.py b/CloudServices/Admin/IdentityManagement.py new file mode 100644 index 0000000..38e6e2d --- /dev/null +++ b/CloudServices/Admin/IdentityManagement.py @@ -0,0 +1,38 @@ +#!/usr/bin/python +from abc import abstractmethod, ABCMeta + +__author__ = 'nirv' + +import boto +import uuid +from CloudServices.Common.AppConfigMgr import ConfigMgr +from CloudServices.Common.Logger import Logger + + +class AbstractBaseIDMAdmin(): + __metaclass__ = ABCMeta + + @abstractmethod + def create_dynamic_role(self): + pass + + +class IAMAdmin(AbstractBaseIDMAdmin): + def __init__(self): + self.__cfg = ConfigMgr() + self.__iam_basic_policy_path = self.__cfg.get_parameter("Instances", "IAMBasicPolicyPath") + self.__prefix_name = self.__cfg.get_parameter("Instances", "NamingPrefix") + self.__iam_policy_name = "cloud-sec-policy" + self.__conn = boto.connect_iam() + + def create_dynamic_role(self): + random_id = uuid.uuid4().get_hex() + with open(self.__iam_basic_policy_path, "r") as policy_file: + iam_role_name = "{}-{}".format(self.__prefix_name, random_id) + iam_policy_document = policy_file.read().replace("BUCKETNAME", "{}*".format(self.__prefix_name)) + self.__conn.create_role(iam_role_name) + self.__conn.create_instance_profile(iam_role_name) + self.__conn.add_role_to_instance_profile(iam_role_name, iam_role_name) + self.__conn.put_role_policy(iam_role_name, self.__iam_policy_name, iam_policy_document) + Logger.log("info", "Created a dynamic role named {}".format(iam_role_name)) + return iam_role_name diff --git a/CloudServices/Admin/Instances.py b/CloudServices/Admin/Instances.py new file mode 100644 index 0000000..9f07f91 --- /dev/null +++ b/CloudServices/Admin/Instances.py @@ -0,0 +1,82 @@ +#!/usr/bin/python + +__author__ = 'nirv' + +import time +from abc import abstractmethod, ABCMeta + +import boto.ec2 + +from CloudServices.Common.AppConfigMgr import ConfigMgr +from CloudServices.Common.Exceptions import GenericException +from CloudServices.Admin.IdentityManagement import IAMAdmin +from CloudServices.Common.Logger import Logger + + +class AbstractBaseInstanceAdmin(): + __metaclass__ = ABCMeta + + @abstractmethod + def create_secure_instance(self, image_id, instance_type, instance_name): + pass + + @abstractmethod + def get_all_running_instance_names(self): + pass + + +class EC2InstanceAdmin(AbstractBaseInstanceAdmin): + + def __init__(self, region = None): + self.__cfg = ConfigMgr() + self.__conn = boto.ec2.connect_to_region(region) + + def create_secure_instance(self, image_id, instance_type, instance_name): + script_path = self.__cfg.get_parameter("Instances", "CloudInitScriptPath") + production_security_group_id = self.__cfg.get_parameter("Instances", "RemediationSecurityGroupId") + production_subnet_id = self.__cfg.get_parameter("Instances", "ProductionSubnetId") + key_name = self.__cfg.get_parameter("Instances", "EC2KeyName") + with open(script_path, "r") as script_file: + cloud_init_script = script_file.read() + iam_role = IAMAdmin() + instance_profile = iam_role.create_dynamic_role() + new_reservation = self.__try_create_instance(image_id, key_name, instance_profile, instance_type, + production_subnet_id, production_security_group_id, + cloud_init_script) + instance = new_reservation.instances[0] + self.__conn.create_tags([instance.id], {"Name": instance_name}) + message = "An instance created with id {}".format(instance.id) + Logger.log("info", message) + return message + + def get_all_running_instance_names(self): + instances_list = [] + instances = self.__conn.get_all_instances() + for instance in instances: + if instance.instances[0].state == "running": + instance_hostname = instance.instances[0].private_dns_name.split('.')[0] + instances_list.append(instance_hostname) + return instances_list + + def __try_create_instance(self, ami_id, key_name, profile_name, instance_type, subnet_id, + security_group_id, user_data): + try: + new_reservation = self.__conn.run_instances(ami_id, key_name=key_name, + instance_profile_name=profile_name, instance_type=instance_type, + subnet_id=subnet_id, security_group_ids=[security_group_id], + user_data=user_data) + return new_reservation + except: + Logger.log("warning", "Could not create instance first time. Waiting another few seconds before retrying") + time.sleep(30) + Logger.log("warning", "Retrying to create instance") + try: + new_reservation = self.__conn.run_instances(ami_id, key_name=key_name, + instance_profile_name=profile_name, + instance_type=instance_type, + subnet_id=subnet_id, security_group_ids=[security_group_id], + user_data=user_data) + return new_reservation + except Exception as ex: + message = "Cannot create new instance: {}".format(ex.message) + raise GenericException(message) diff --git a/AWS/CloudConfig.config b/CloudServices/Admin/RuntimeConfig/CloudConfig.config similarity index 92% rename from AWS/CloudConfig.config rename to CloudServices/Admin/RuntimeConfig/CloudConfig.config index 38ca1ab..1f85950 100644 --- a/AWS/CloudConfig.config +++ b/CloudServices/Admin/RuntimeConfig/CloudConfig.config @@ -21,12 +21,13 @@ runcmd: - pip install StringGenerator - wget https://s3.amazonaws.com/config-cloudsec/CloudInit.tar.gz -O CloudInit.tar.gz - tar -zxvf CloudInit.tar.gz - - cd /SecureCloudInit + - cd /Cloudefigo - python Prepare.py generate - wget https://www.opscode.com/chef/install.sh -O install.sh - bash install.sh - mkdir /etc/chef - - wget https://s3.amazonaws.com/config-cloudsec/validation.pem -O /etc/chef/validation.pem + - wget https://s3.amazonaws.com/config-cloudsec/validation.pem -O validation.pem + - cp validation.pem /etc/chef/validation.pem - wget https://s3.amazonaws.com/config-cloudsec/client.rb -O /etc/chef/client.rb - chef-client -r encryption - python Init.py diff --git a/AWS/IAMBasicPolicy.config b/CloudServices/Admin/RuntimeConfig/IAMBasicPolicy.config similarity index 100% rename from AWS/IAMBasicPolicy.config rename to CloudServices/Admin/RuntimeConfig/IAMBasicPolicy.config diff --git a/CloudServices/Admin/Storage.py b/CloudServices/Admin/Storage.py new file mode 100644 index 0000000..3e81668 --- /dev/null +++ b/CloudServices/Admin/Storage.py @@ -0,0 +1,68 @@ +#!/usr/bin/python + +__author__ = 'nirv' + +import gzip +import os +from abc import abstractmethod, ABCMeta + +import boto.s3 +import boto.s3.bucket +from boto.s3.connection import S3Connection + +from CloudServices.Common.Logger import Logger + + +class AbstractBaseStorageAdmin(): + __metaclass__ = ABCMeta + + @abstractmethod + def get_all_files(self, storage_name, prefix): + pass + + @abstractmethod + def reset_files_extension(self, storage_name, prefix): + pass + + +class S3StorageAdmin(AbstractBaseStorageAdmin): + + def __init__(self, region = "us-east-1"): + self.__s3 = boto.s3.connect_to_region(region) + + def get_all_files(self, storage_name, prefix): + bucket = self.__s3.get_bucket(storage_name) + return self.__get_file_contents_list_from_bucket(bucket, prefix, storage_name) + + def reset_files_extension(self, storage_name, prefix): + bucket = self.__s3.get_bucket(storage_name) + for key in bucket.list(prefix=prefix): + if key.name.endswith('-done'): + new_key_name = key.name.replace('-done','') + bucket.copy_key(new_key_name=new_key_name, src_bucket_name=storage_name, src_key_name=key.name) + bucket.delete_key(key.name) + + @staticmethod + def __get_file_contents_list_from_bucket(bucket, prefix, bucket_name): + json_files_list = [] + for key in bucket.list(prefix=prefix): + if key.name.endswith('/') or key.name.endswith('-done'): + continue + try: + new_key_name = "{}-done".format(key.name) + bucket.copy_key(new_key_name=new_key_name, src_bucket_name=bucket_name, src_key_name=key.name) + bucket.delete_key(key.name) + new_key = bucket.get_key(new_key_name) + new_key.get_contents_to_filename(filename="tmp.json.gz") + f = gzip.open('tmp.json.gz', 'rb') + json_files_list.append(f.read()) + f.close() + except Exception as ex: + Logger.log("warning", "{} FAILED: {}".format(key.name, ex.message)) + return json_files_list + + def __del__(self): + try: + os.remove("tmp.json.gz") + except: + pass \ No newline at end of file diff --git a/AWS/__init__.py b/CloudServices/Admin/__init__.py similarity index 100% rename from AWS/__init__.py rename to CloudServices/Admin/__init__.py diff --git a/CloudServices/Common/AppConfigMgr.py b/CloudServices/Common/AppConfigMgr.py new file mode 100644 index 0000000..86a7e2b --- /dev/null +++ b/CloudServices/Common/AppConfigMgr.py @@ -0,0 +1,40 @@ +#!/usr/bin/python +import os + +from CloudServices.Common.Logger import Logger + +__author__ = 'nirv' + +import sys, os +from CloudServices.Common.Exceptions import GenericException + + +class ConfigMgr: + + def __init__(self,): + path = self.__get_path() + import xml.etree.ElementTree as ET + try: + self.cfg_tree = ET.parse(path) + except: + error_message = "Cannot find the configuration file {}".format(path) + Logger.log("error", error_message) + raise GenericException(error_message) + + return + + def get_parameter(self, scope, param): + if self.cfg_tree is not None: + try: + scopeNode = self.cfg_tree.find(scope) + return scopeNode.find(param).text + except: + error_message = "Cannot find the configuration for the scope {} and parameter {}".format(scope, param) + Logger.log("error", error_message) + raise GenericException(error_message) + return "" + + def __get_path(self): + config_file_name = "Init.config" + config_folder_name = os.path.dirname(sys.modules[ConfigMgr.__module__].__file__) + return config_folder_name + "/" + config_file_name diff --git a/Common/Exceptions.py b/CloudServices/Common/Exceptions.py similarity index 88% rename from Common/Exceptions.py rename to CloudServices/Common/Exceptions.py index 966c8a5..56ee8bd 100644 --- a/Common/Exceptions.py +++ b/CloudServices/Common/Exceptions.py @@ -2,7 +2,8 @@ # __author__ = 'nirv' -from Common.Logger import Logger +from CloudServices.Common.Logger import Logger + class RemediationException(Exception): diff --git a/CloudServices/Common/Init.config b/CloudServices/Common/Init.config new file mode 100644 index 0000000..853d459 --- /dev/null +++ b/CloudServices/Common/Init.config @@ -0,0 +1,28 @@ + + + + CloudServices/IaaS/RuntimeConfig/BucketPolicy.config + CloudServices/Admin/RuntimeConfig/IAMBasicPolicy.config + CloudServices/IaaS/RuntimeConfig/IAMStrictPolicy.config + CloudServices/Admin/RuntimeConfig/CloudConfig.config + cloudsec + sg-7befd21e + subnet-59e2f871 + sg-e6323583 + mykey + ebe6799346d8527955740c643faeb405a27ab195a29e5f20f326082fc5abdfb8 + + + validation.pem + cloudsecdemo-validator + https://api.opscode.com/organizations/cloudsecdemo + + + https + 54.173.5.2 + 8834 + cloudinit + yourpass + 1 + + \ No newline at end of file diff --git a/Common/Logger.py b/CloudServices/Common/Logger.py similarity index 99% rename from Common/Logger.py rename to CloudServices/Common/Logger.py index d2bb002..b66374f 100644 --- a/Common/Logger.py +++ b/CloudServices/Common/Logger.py @@ -4,6 +4,7 @@ import logging + class Logger: logger_initiated = False diff --git a/Common/__init__.py b/CloudServices/Common/__init__.py similarity index 100% rename from Common/__init__.py rename to CloudServices/Common/__init__.py diff --git a/AWS/EnvironmentVarialbes.py b/CloudServices/IaaS/EnvironmentVarialbes.py similarity index 66% rename from AWS/EnvironmentVarialbes.py rename to CloudServices/IaaS/EnvironmentVarialbes.py index f8754dc..e878566 100644 --- a/AWS/EnvironmentVarialbes.py +++ b/CloudServices/IaaS/EnvironmentVarialbes.py @@ -1,14 +1,44 @@ #!/usr/bin/python -from Common import Logger __author__ = 'nirv' import urllib2 import hashlib import json -from Common.Logger import Logger +from abc import ABCMeta, abstractmethod -class EnvronmentVarialbes: +from CloudServices.Common.Logger import Logger + + +class AbstractBaseEnvironmentVariables(): + __metaclass__ = ABCMeta + + @abstractmethod + def get_current_instance_region(self): + pass + + @abstractmethod + def get_current_instance_name(self): + pass + + @abstractmethod + def get_current_instance_mac(self): + pass + + @abstractmethod + def get_storage_unique_id(prefix): + pass + + @abstractmethod + def get_current_instance_profile(self): + pass + + @abstractmethod + def get_instance_credentials(self): + pass + + +class EnvironmentVariables(AbstractBaseEnvironmentVariables): @staticmethod def get_current_instance_region(): @@ -23,8 +53,8 @@ def get_current_instance_mac(): return urllib2.urlopen("http://169.254.169.254/latest/meta-data/mac").read() @staticmethod - def get_bucket_unique_id(prefix): - unique_string_hash = hashlib.sha1(EnvronmentVarialbes.get_current_instance_name()).hexdigest() + def get_storage_unique_id(prefix): + unique_string_hash = hashlib.sha1(EnvironmentVariables.get_current_instance_name()).hexdigest() uppercase_result = "{}-{}".format(prefix, unique_string_hash) return uppercase_result.lower() @@ -39,7 +69,7 @@ def get_current_instance_profile(): @staticmethod def get_instance_credentials(): try: - role_name = EnvronmentVarialbes.get_current_instance_profile(); + role_name = EnvironmentVariables.get_current_instance_profile(); creds_url = "http://169.254.169.254/latest/meta-data/iam/security-credentials/{}".format(role_name) response = urllib2.urlopen(creds_url).read() parsed_response = json.loads(response) diff --git a/CloudServices/IaaS/IdentityManagement.py b/CloudServices/IaaS/IdentityManagement.py new file mode 100644 index 0000000..f6a994f --- /dev/null +++ b/CloudServices/IaaS/IdentityManagement.py @@ -0,0 +1,33 @@ +#!/usr/bin/python +from abc import abstractmethod, ABCMeta + +__author__ = 'nirv' + +import boto +from CloudServices.Common.AppConfigMgr import ConfigMgr +from CloudServices.IaaS.EnvironmentVarialbes import EnvironmentVariables +from boto.iam import IAMConnection + + +class AbstractBaseIDM(): + __metaclass__ = ABCMeta + + @abstractmethod + def strict_dynamic_role(self): + pass + + +class IAM(AbstractBaseIDM): + def __init__(self): + self.__cfg = ConfigMgr() + self.__iam_strict_policy_path = self.__cfg.get_parameter("Instances", "IAMStrictPolicyPath") + self.__prefix_name = self.__cfg.get_parameter("Instances", "NamingPrefix") + credentials = EnvironmentVariables.get_instance_credentials().split(" ") + self.__conn = IAMConnection(aws_access_key_id=credentials[0], aws_secret_access_key=credentials[1], security_token=credentials[2]) + self.__iam_policy_name = "cloud-sec-policy" + + def strict_dynamic_role(self, iam_role_name): + with open(self.__iam_strict_policy_path, "r") as policy_file: + bucket_unique_id = EnvironmentVariables.get_storage_unique_id(self.__prefix_name) + iam_policy_document = policy_file.read().replace("BUCKETNAME", bucket_unique_id) + self.__conn.put_role_policy(iam_role_name, self.__iam_policy_name, iam_policy_document) \ No newline at end of file diff --git a/CloudServices/IaaS/Instances.py b/CloudServices/IaaS/Instances.py new file mode 100644 index 0000000..a196cb9 --- /dev/null +++ b/CloudServices/IaaS/Instances.py @@ -0,0 +1,71 @@ +#!/usr/bin/python + +__author__ = 'nirv' + +import time +from abc import abstractmethod, ABCMeta + +import boto.ec2 + +from CloudServices.Common.AppConfigMgr import ConfigMgr +from CloudServices.IaaS.EnvironmentVarialbes import EnvironmentVariables +from CloudServices.Common.Logger import Logger +from CloudServices.IaaS.IdentityManagement import IAM + + +class AbstractBaseInstance(): + __metaclass__ = ABCMeta + + @abstractmethod + def attach_new_storage_to_current_instance(self): + pass + + @abstractmethod + def move_current_instance_to_production_group(self): + pass + + @abstractmethod + def strict_current_instance_role_permissions(self): + pass + + +class EC2Instance(AbstractBaseInstance): + + def __init__(self): + self.__cfg = ConfigMgr() + credentials = EnvironmentVariables.get_instance_credentials().split(" ") + self.__conn = boto.ec2.EC2Connection(aws_access_key_id=credentials[0], aws_secret_access_key=credentials[1], security_token=credentials[2]) + self.__conn.region = EnvironmentVariables.get_current_instance_region() + self.__current_instance_name = EnvironmentVariables.get_current_instance_name() + + def attach_new_storage_to_current_instance(self): + inst = self.get_instance_object_by_instance_id(self.__current_instance_name) + vol = self.__conn.create_volume(1,self.__conn.region) + time.sleep(30) + curr_vol = self.__conn.get_all_volumes([vol.id])[0] + while curr_vol.status != 'available': + time.sleep(10) + Logger.logger("info", "pending to make volume available") + self.__conn.attach_volume (vol.id, inst.id, "/dev/sdf") + Logger.log("info", "The volume {} attached to this instance".format(vol.id)) + + def move_current_instance_to_production_group(self): + production_group_id = self.__cfg.get_parameter("Instances", "ProductionSecurityGroupId") + instance = self.get_instance_object_by_instance_id(self.__current_instance_name) + self.__conn.modify_instance_attribute(self.__current_instance_name, + "groupSet", [production_group_id]) + Logger.log("info", "This instance moved to the production subnet {}".format(production_group_id)) + + def strict_current_instance_role_permissions(self): + iam = IAM() + current_role_name = EnvironmentVariables.get_current_instance_profile() + iam.strict_dynamic_role(current_role_name) + Logger.log("info", "Changed the IAM role to be more strict") + + def get_instance_object_by_instance_id(self, instance_id): + reservations = self.__conn.get_all_instances(instance_ids=[instance_id]) + for instance in reservations[0].instances: + if instance.id == self.__current_instance_name: + return instance + return None + diff --git a/AWS/BucketPolicy.config b/CloudServices/IaaS/RuntimeConfig/BucketPolicy.config similarity index 100% rename from AWS/BucketPolicy.config rename to CloudServices/IaaS/RuntimeConfig/BucketPolicy.config diff --git a/AWS/IAMStrictPolicy.config b/CloudServices/IaaS/RuntimeConfig/IAMStrictPolicy.config similarity index 100% rename from AWS/IAMStrictPolicy.config rename to CloudServices/IaaS/RuntimeConfig/IAMStrictPolicy.config diff --git a/AWS/S3.py b/CloudServices/IaaS/Storage.py similarity index 60% rename from AWS/S3.py rename to CloudServices/IaaS/Storage.py index 9470596..641674d 100644 --- a/AWS/S3.py +++ b/CloudServices/IaaS/Storage.py @@ -2,25 +2,40 @@ __author__ = 'nirv' -import boto import hashlib -from Common.AppConfigMgr import ConfigMgr -from AWS.EnvironmentVarialbes import EnvronmentVarialbes -from Common.Logger import Logger +from abc import ABCMeta, abstractmethod + from boto.s3.connection import S3Connection -class S3: +from CloudServices.Common.AppConfigMgr import ConfigMgr +from CloudServices.IaaS.EnvironmentVarialbes import EnvironmentVariables +from CloudServices.Common.Logger import Logger + + +class AbstractBaseStorage(): + __metaclass__ = ABCMeta + + @abstractmethod + def generate_and_store_encryption_key(self): + pass + + @abstractmethod + def get_encryption_key(self): + pass + + +class S3Storage(AbstractBaseStorage): + def __init__(self): self.__cfg = ConfigMgr() - self.__bucket_name = self.__cfg.getParameter("AWS", "NamingPrefix") - self.__bucket_unique_id = EnvronmentVarialbes.get_bucket_unique_id(self.__bucket_name) - self.__bucket_policy_path = self.__cfg.getParameter("AWS", "BucketPolicyPath") - self.__current_instance_name = EnvronmentVarialbes.get_current_instance_name() - credentials = EnvronmentVarialbes.get_instance_credentials().split(" ") + self.__bucket_name = self.__cfg.get_parameter("Instances", "NamingPrefix") + self.__bucket_unique_id = EnvironmentVariables.get_storage_unique_id(self.__bucket_name) + self.__bucket_policy_path = self.__cfg.get_parameter("Instances", "BucketPolicyPath") + self.__current_instance_name = EnvironmentVariables.get_current_instance_name() + credentials = EnvironmentVariables.get_instance_credentials().split(" ") self.__s3 = S3Connection(aws_access_key_id=credentials[0], aws_secret_access_key=credentials[1], security_token=credentials[2]) - - def set_encryption_key(self): + def generate_and_store_encryption_key(self): bucket = self.__s3.create_bucket(self.__bucket_unique_id) bucket.set_policy(self.__get_bucket_policy) from boto.s3.key import Key @@ -40,7 +55,7 @@ def get_encryption_key(self): return response def __get_referer_unique_id(self): - unique_string = "{}{}".format(EnvronmentVarialbes.get_current_instance_mac(), self.__current_instance_name) + unique_string = "{}{}".format(EnvironmentVariables.get_current_instance_mac(), self.__current_instance_name) uppercase_result = hashlib.sha512(unique_string).hexdigest() return uppercase_result.lower() @@ -48,12 +63,11 @@ def __generate_encryption_key(self): from strgen import StringGenerator as SG return SG("[\l\d]{100}&[\p]").render() - @property def __get_bucket_policy(self): referer_name = self.__get_referer_unique_id() - bucket_name = EnvronmentVarialbes.get_bucket_unique_id(self.__bucket_name) - canonical_user = self.__cfg.getParameter("AWS", "CanonicalUserId") + bucket_name = EnvironmentVariables.get_storage_unique_id(self.__bucket_name) + canonical_user = self.__cfg.get_parameter("Instances", "CanonicalUserId") with open(self.__bucket_policy_path, "r") as policy_file: bucket_policy = policy_file.read().replace('\n', '').replace('\t', '').replace('BUCKETNAME', bucket_name).replace('REFERERNAME', referer_name).replace("CANONICALUSER",canonical_user) diff --git a/CloudServices/IaaS/__init__.py b/CloudServices/IaaS/__init__.py new file mode 100644 index 0000000..1546b97 --- /dev/null +++ b/CloudServices/IaaS/__init__.py @@ -0,0 +1 @@ +__author__ = 'nirv' diff --git a/CloudServices/Test.py b/CloudServices/Test.py new file mode 100644 index 0000000..4990e79 --- /dev/null +++ b/CloudServices/Test.py @@ -0,0 +1,6 @@ +__author__ = 'nirv' + +from CloudServices.Admin.CloudTrail import Audit + +audit = Audit() +print audit.get_logs() \ No newline at end of file diff --git a/CloudServices/__init__.py b/CloudServices/__init__.py new file mode 100644 index 0000000..1546b97 --- /dev/null +++ b/CloudServices/__init__.py @@ -0,0 +1 @@ +__author__ = 'nirv' diff --git a/Cloudefigo/__init__.py b/Cloudefigo/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Cloudefigo/settings.py b/Cloudefigo/settings.py new file mode 100644 index 0000000..61af5af --- /dev/null +++ b/Cloudefigo/settings.py @@ -0,0 +1,87 @@ +""" +Django settings for Cloudefigo project. + +For more information on this file, see +https://docs.djangoproject.com/en/1.7/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/1.7/ref/settings/ +""" + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +import os +BASE_DIR = os.path.dirname(os.path.dirname(__file__)) +TEMPLATE_DIRS = [os.path.join(BASE_DIR, 'templates')] + + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'd-xs_cqkqbhi)k)lo_v^ksxd8zl2v*pxtcgp*%5hr^l#fann$9' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +TEMPLATE_DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = ( + 'Manager', + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + +) + +MIDDLEWARE_CLASSES = ( + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +) + +ROOT_URLCONF = 'Cloudefigo.urls' + +WSGI_APPLICATION = 'Cloudefigo.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/1.7/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} + +# Internationalization +# https://docs.djangoproject.com/en/1.7/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.7/howto/static-files/ + +STATIC_URL = '/static/' \ No newline at end of file diff --git a/Cloudefigo/urls.py b/Cloudefigo/urls.py new file mode 100644 index 0000000..bd8ccad --- /dev/null +++ b/Cloudefigo/urls.py @@ -0,0 +1,11 @@ +from django.conf.urls import patterns, include, url +from django.contrib import admin + +urlpatterns = patterns('', + # Examples: + # url(r'^$', 'Cloudefigo.views.home', name='home'), + # url(r'^blog/', include('blog.urls')), + + url(r'^admin/', include(admin.site.urls)), + url(r'^manager/', include('Manager.urls')), +) diff --git a/Cloudefigo/wsgi.py b/Cloudefigo/wsgi.py new file mode 100644 index 0000000..736a382 --- /dev/null +++ b/Cloudefigo/wsgi.py @@ -0,0 +1,14 @@ +""" +WSGI config for Cloudefigo project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/ +""" + +import os +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Cloudefigo.settings") + +from django.core.wsgi import get_wsgi_application +application = get_wsgi_application() diff --git a/Common/AppConfigMgr.py b/Common/AppConfigMgr.py deleted file mode 100644 index 76475d4..0000000 --- a/Common/AppConfigMgr.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/python -from Common.Logger import Logger -import os - -__author__ = 'nirv' - -from Common.Exceptions import GenericException - -# This class handles the configuration management for this program. -# The configurations taken from a standard XML file -class ConfigMgr: - - config_file_name = "Init.config" - - def __init__(self,): - import xml.etree.ElementTree as ET - try: - self.cfgTree = ET.parse(ConfigMgr.config_file_name) - except: - path = os.getcwd() - raise GenericException("Cannot find the configuration file {} in path {}".format(self.config_file_name, path)) - - return - - def getParameter(self, scope, param): - if self.cfgTree is not None: - try: - scopeNode = self.cfgTree.find(scope) - return scopeNode.find(param).text - except: - raise GenericException("Cannot find the configuration for the scope {} and parameter {}".format(scope, param)) - return "" \ No newline at end of file diff --git a/Init.py b/Init.py index f454e5e..47c187a 100644 --- a/Init.py +++ b/Init.py @@ -4,11 +4,11 @@ from Chef.ConfigurationManagement import ChefClient from NessusScanner.VulnerabilityAssessment import Scanner -from Common.Exceptions import RemediationException,GenericException -from AWS.EC2 import EC2 -from Common.Logger import Logger +from CloudServices.Common.Exceptions import RemediationException,GenericException +from CloudServices.IaaS.Instances import EC2Instance +from CloudServices.Common.Logger import Logger -ec2 = EC2() +ec2 = EC2Instance() try: chef_client = ChefClient() @@ -18,10 +18,10 @@ nessus.run_scan() ec2.move_current_instance_to_production_group() - ec2.post_validation_action() + ec2.strict_current_instance_role_permissions() except RemediationException as re: - ec2.post_validation_action() + ## ec2.strict_current_instance_role_permissions() ## Depends on the business, it can be added. exit() except GenericException as ge: diff --git a/Manage-cmd.py b/Manage-cmd.py new file mode 100644 index 0000000..41cee02 --- /dev/null +++ b/Manage-cmd.py @@ -0,0 +1,30 @@ +#!/usr/bin/python + +__author__ = 'nirv' + +from Chef.ConfigurationManagement import ChefClient +from AWS.EC2 import EC2 + +def get_menu(): + return ("\n----- Secure Cloud Management Console -----\n" + "1. Launch secure instance\n" + "2. Locate not managed instances\n" + "3. Exit\n" + "Your choise: ") + +ec2 = EC2(False, "us-east-1") +chef = ChefClient() + +while True: + response = raw_input(get_menu()) + if response == '1': + ec2.create_secure_instance("ami-c65be9ae","t1.micro","Secure Instance") # ami-c65be9ae is Ubuntu 14 + elif response == '2': + ec2_instances = ec2.get_all_running_instance_names() + chef_nodes = chef.get_all_nodes() + print "Not managed nodes list: " + for ec2_instance in ec2_instances: + if ec2_instance not in chef_nodes: + print ec2_instance + else: + exit() \ No newline at end of file diff --git a/Manage.py b/Manage.py old mode 100644 new mode 100755 index 41cee02..59b0ef8 --- a/Manage.py +++ b/Manage.py @@ -1,30 +1,10 @@ -#!/usr/bin/python +#!/usr/bin/env python +import os +import sys -__author__ = 'nirv' +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Cloudefigo.settings") -from Chef.ConfigurationManagement import ChefClient -from AWS.EC2 import EC2 + from django.core.management import execute_from_command_line -def get_menu(): - return ("\n----- Secure Cloud Management Console -----\n" - "1. Launch secure instance\n" - "2. Locate not managed instances\n" - "3. Exit\n" - "Your choise: ") - -ec2 = EC2(False, "us-east-1") -chef = ChefClient() - -while True: - response = raw_input(get_menu()) - if response == '1': - ec2.create_secure_instance("ami-c65be9ae","t1.micro","Secure Instance") # ami-c65be9ae is Ubuntu 14 - elif response == '2': - ec2_instances = ec2.get_all_running_instance_names() - chef_nodes = chef.get_all_nodes() - print "Not managed nodes list: " - for ec2_instance in ec2_instances: - if ec2_instance not in chef_nodes: - print ec2_instance - else: - exit() \ No newline at end of file + execute_from_command_line(sys.argv) diff --git a/Manager/__init__.py b/Manager/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Manager/admin.py b/Manager/admin.py new file mode 100644 index 0000000..2205e4c --- /dev/null +++ b/Manager/admin.py @@ -0,0 +1,12 @@ +from django.contrib import admin +from Manager.models import Event + + +class EventAdmin(admin.ModelAdmin): + list_display = ('timestamp', 'username', 'access_key', 'event_name', 'event_source', 'source_ip', 'user_agent', + 'region', 'request_parameters', 'response') + search_fields = ['username', 'access_key', 'event_name', 'event_source', 'source_ip', 'user_agent', + 'region', 'request_parameters', 'response'] + + +admin.site.register(Event, EventAdmin) \ No newline at end of file diff --git a/Manager/migrations/0001_initial.py b/Manager/migrations/0001_initial.py new file mode 100644 index 0000000..01a5609 --- /dev/null +++ b/Manager/migrations/0001_initial.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Event', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('timestamp', models.CharField(max_length=20)), + ('username', models.CharField(max_length=200)), + ('access_key', models.CharField(max_length=50)), + ('event_name', models.CharField(max_length=50)), + ('event_source', models.CharField(max_length=50)), + ('source_ip', models.CharField(max_length=15)), + ('user_agent', models.CharField(max_length=70)), + ('region', models.CharField(max_length=15)), + ('request_parameters', models.CharField(max_length=800)), + ('response', models.CharField(max_length=800)), + ], + options={ + }, + bases=(models.Model,), + ), + ] diff --git a/Manager/migrations/__init__.py b/Manager/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Manager/models.py b/Manager/models.py new file mode 100644 index 0000000..0077040 --- /dev/null +++ b/Manager/models.py @@ -0,0 +1,43 @@ +from django.db import models +import json + + +class Event(models.Model): + timestamp = models.CharField(max_length=20) + username = models.CharField(max_length=200) + access_key = models.CharField(max_length=50) + event_name = models.CharField(max_length=50) + event_source = models.CharField(max_length=50) + source_ip = models.CharField(max_length=15) + user_agent = models.CharField(max_length=70) + region = models.CharField(max_length=15) + request_parameters = models.CharField(max_length=800) + response = models.CharField(max_length=800) + + def set_by_key_value_list(self, key_value_list = None): + if key_value_list is not None: + self.timestamp = key_value_list['timestamp'] + self.username = key_value_list['username'] + self.access_key = key_value_list['access_key'] + self.event_name = key_value_list['event_name'] + self.event_source = key_value_list['event_source'] + self.source_ip = key_value_list['source_ip'] + self.user_agent = key_value_list['user_agent'] + self.region = key_value_list['region'] + self.request_parameters = key_value_list['request_parameters'] + self.response = key_value_list['response'] + + def __unicode__(self): + return json.dumps(self.get_key_value_list()) + + + def get_key_value_list(self): + key_value_list = {'timestamp': self.timestamp, 'username': self.username, 'access_key': self.access_key, + 'event_name': self.event_name, 'event_source': self.event_source, 'source_ip': self.source_ip, + 'user_agent': self.user_agent, 'region': self.region, + 'request_parameters': self.request_parameters, 'response': self.response} + return key_value_list + + + + diff --git a/Manager/tests.py b/Manager/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/Manager/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/Manager/urls.py b/Manager/urls.py new file mode 100644 index 0000000..b820e28 --- /dev/null +++ b/Manager/urls.py @@ -0,0 +1,10 @@ +from django.conf.urls import patterns, url +from Manager import views + +urlpatterns = patterns('', + url(r'^$',views.index , name='index'), + url(r'^events/sync/$', views.sync_events, name='sync'), + url(r'^events/sync/reset$', views.reset_sync_events, name='sync'), + url(r'^events/all/$', views.all_events, name='all'), + url(r'^instances/launch$', views.launch_instance, name='all'), +) \ No newline at end of file diff --git a/Manager/views.py b/Manager/views.py new file mode 100644 index 0000000..87eefc8 --- /dev/null +++ b/Manager/views.py @@ -0,0 +1,52 @@ +import json +from django.http import HttpResponse +from Manager.models import Event +from CloudServices.Admin.Instances import EC2InstanceAdmin +from CloudServices.Admin.CloudTrail import Audit +from Chef.ConfigurationManagement import ChefClient + + +def index(request): + return HttpResponse('{"Status": "Management API is Alive!"}', content_type="application/json") + + +def sync_events(request): + audit = Audit() + logs_list = audit.get_logs() + for log_entry in logs_list: + log = Event() + log.set_by_key_value_list(log_entry) + log.save() + return HttpResponse('{"Status": "Done"}', content_type="application/json") + + +def reset_sync_events(request): + audit = Audit() + audit.reset_files_extensions() + return HttpResponse('{"Status": "Done"}', content_type="application/json") + + +def all_events(request): + all_events_in_db = Event.objects.order_by('-timestamp') + events_json_list = [] + for event in all_events_in_db: + events_json_list.append(event.get_key_value_list()) + json_element = {'logs': events_json_list} + return HttpResponse(json.dumps(json_element), content_type="application/json") + +def launch_instance(request): + launcher = EC2InstanceAdmin(region = "us-east-1") + status = launcher.create_secure_instance("ami-c65be9ae","t1.micro","Secure Instance") # ami-c65be9ae is Ubuntu 14 + return HttpResponse('{"Status": "OK"}', content_type="application/json") + + +def get_unmanaged_servers(request): + launcher = EC2InstanceAdmin(region = "us-east-1") + iaas_instance_names = launcher.get_all_running_instance_names() + chef_nodes = ChefClient.get_all_nodes() + unmanaged_nodes = [] + for ec2_instance in iaas_instance_names: + if ec2_instance not in chef_nodes: + unmanaged_nodes.append(ec2_instance) + response_key_value = {"Unmanaged" : unmanaged_nodes} + return HttpResponse(json.dumps(response_key_value), content_type="application/json") diff --git a/Prepare.py b/Prepare.py index 9ed3603..be060d7 100644 --- a/Prepare.py +++ b/Prepare.py @@ -2,16 +2,16 @@ __author__ = 'nirv' -from AWS.S3 import S3 -from AWS.EC2 import EC2 -from Common.Logger import Logger +from CloudServices.IaaS.Storage import S3Storage +from CloudServices.IaaS.Instances import EC2Instance +from CloudServices.Common.Logger import Logger import sys try: - ec2 = EC2() + ec2 = EC2Instance() ec2.create_volume() - bucket = S3() + bucket = S3Storage() if len(sys.argv) > 1: bucket.set_encryption_key() diff --git a/db.sqlite3 b/db.sqlite3 new file mode 100644 index 0000000..8b0814a Binary files /dev/null and b/db.sqlite3 differ diff --git a/templates/admin/base.html b/templates/admin/base.html new file mode 100755 index 0000000..17ac334 --- /dev/null +++ b/templates/admin/base.html @@ -0,0 +1,82 @@ +{% load admin_static %}{% load firstof from future %} + + +{% block title %}{% endblock %} + +{% block extrastyle %}{% endblock %} + +{% if LANGUAGE_BIDI %}{% endif %} + + +{% block extrahead %}{% endblock %} +{% block blockbots %}{% endblock %} + +{% load i18n %} + + + + +
+ + {% if not is_popup %} + + + + {% block breadcrumbs %} + + {% endblock %} + {% endif %} + + {% block messages %} + {% if messages %} + + {% endif %} + {% endblock messages %} + + +
+ {% block pretitle %}{% endblock %} + {% block content_title %}{% if title %}

{{ title }}

{% endif %}{% endblock %} + {% block content %} + {% block object-tools %}{% endblock %} + {{ content }} + {% endblock %} + {% block sidebar %}{% endblock %} +
+
+ + + {% block footer %}{% endblock %} +
+ + + + diff --git a/templates/admin/base_site.html b/templates/admin/base_site.html new file mode 100755 index 0000000..31a3123 --- /dev/null +++ b/templates/admin/base_site.html @@ -0,0 +1,9 @@ +{% extends "admin/base.html" %} + +{% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %} + +{% block branding %} +

Embedded ImageCloudefigo administration

+{% endblock %} + +{% block nav-global %}{% endblock %}