Example #1
0
    def show_step_inner_messaage(self, message, status, error_msg=None):
        dot_len = self.column_length - len(message) - 30
        print_message = "\t%s %s [%s]" % (
            message, self._get_line_dots_in_color(dot_len),
            self._get_status_in_color(status))
        SysLog().write_debug_log(print_message)
        print(print_message)

        if error_msg:
            print("\t\t%s" % self._get_error_msg_in_color(error_msg))
            SysLog().write_error_log(error_msg)
Example #2
0
 def run(self, sys_args):
     self.show_loading_messsage()
     Settings.set('running_command', ' '.join(sys_args))
     try:
         SysLog().debug_started(Settings.running_command)
         if self.do_pre_requisite_check():
             command_class_instance = self.get_command_class_instance(
                 sys_args)  # Get the command list and optional commands
             self.execute(command_class_instance)
     except Exception as e:
         self.show_step_inner_error(
             "Error occured, please check error log for more details")
         SysLog().write_error_log(str(e))
Example #3
0
    def display_op_msg(self, display_op_list):
        """
        Display output message at the end of process execution

        Args:
            display_op_list (list): List of key, value pairs to be displayed
        """
        if display_op_list:
            result_title = "OUTPUT"
            column_length = self.column_length - 10
            pre_star_count = math.ceil(
                int(column_length - len(result_title) - 2) / 2)
            post_star_count = math.floor(
                int(column_length - len(result_title) - 2) / 2)

            heading = "\n\t%s %s %s" % ("*" * pre_star_count, result_title,
                                        "*" * post_star_count)
            print(self._get_heading_message_in_color(heading, self.BCYAN_ANSI))

            debug_log_msg = ""
            for op in display_op_list:
                for key, val in op.items():
                    key_value_msg = "\t%20s: %s" % (key, val)
                    debug_log_msg += key_value_msg + "\n"
                    print(self.GREEN_ANSI + key_value_msg + self.RESET_ANSI)

            SysLog().write_debug_log(heading + "\n" + debug_log_msg)

            end = "\t" + "*" * column_length
            print(self._get_heading_message_in_color(end, self.BCYAN_ANSI))
        print("\n")
Example #4
0
    def pre_terraform_apply(self):
        status, msg = create_iam_service_linked_role(
            "rds.amazonaws.com",
            Settings.RESOURCE_DESCRIPTION,
            Settings.AWS_AUTH_CRED)

        SysLog().write_debug_log("RDS IAM Service Linked role creation: Status:%s, Message: %s" % (str(status), msg))
Example #5
0
    def show_step_inner_messaage(self, message, status, error_msg=None):
        """
        Show an inner message

        Args:
            message (str): Message to be displayed on the line
        """
        dot_len = self.column_length - len(message) - 30
        print_message = "\t%s %s [%s]" % (
            message, self._get_line_dots_in_color(dot_len),
            self._get_status_in_color(status))
        SysLog().write_debug_log(print_message)
        print(print_message)

        if error_msg:
            print("\t\t%s" % self._get_error_msg_in_color(error_msg))
            SysLog().write_error_log(error_msg)
Example #6
0
    def pre_terraform_apply(self):
        status, msg = create_iam_service_linked_role(
            Settings.AWS_ACCESS_KEY, Settings.AWS_SECRET_KEY,
            "ecs.amazonaws.com", Settings.RESOURCE_DESCRIPTION)

        SysLog().write_debug_log(
            "ECS IAM Service Linked role creation: Status:%s, Message: %s" %
            (str(status), msg))
Example #7
0
 def show_step_heading(self, heading, write_log=True):
     if write_log:
         SysLog().write_debug_log(heading)
     step_count_num = Settings.get('step_count_num', 1)
     print(
         self._get_heading_message_in_color(
             "\nStep %s: %s" % (str(step_count_num), heading),
             self.BCYAN_ANSI))
     step_count_num = Settings.set('step_count_num', step_count_num + 1)
Example #8
0
    def show_step_inner_warning(self, message):
        """
        Show message as sep message i.e with a tab prefix to display warning

        Args:
            message (str): Message to be displayed on the line
        """
        print_message = "\t%s" % message
        SysLog().write_debug_log(print_message)
        print(self.WARN_ANSI + print_message + self.RESET_ANSI)
Example #9
0
    def show_step_inner_error(self, message):
        """
        Show message as sep message i.e with a tab prefix to display error

        Args:
            message (str): Message to be displayed on the line
        """
        print_message = "\t%s" % self._get_error_msg_in_color(message)
        SysLog().write_error_log(print_message)
        print(print_message)
Example #10
0
 def generate_terraform(self):
     if self.PROCESS:  # Generate the resource terraform file only if the resource is to be processed
         try:
             terraform_args_dict = self.get_terraform_resource_args_dict()
             self.create_terraform_resource_file(terraform_args_dict)
         except Exception as e:
             msg = 'Error occured in Terraform file generation. Resource: %s' % self.__class__.__name__
             print(msg)
             SysLog().write_error_log(str(e) + '\n' + msg)
             sys.exit()
    def post_terraform_apply(self):
        archive_type = "zip"
        s3_client = s3.get_s3_client(Settings.AWS_AUTH_CRED)

        zip_file_name = Settings.RESOURCE_NAME_PREFIX + "-terraform-installer-backup"
        zip_file_abs_path = os.path.join(Settings.BASE_APP_DIR, zip_file_name)
        dir_to_archive = Settings.DATA_DIR
        SysLog().write_debug_log("Started Archiving Terraform Directory")
        shutil.make_archive(zip_file_abs_path, archive_type, dir_to_archive)
        SysLog().write_debug_log("Completed Archiving")

        bucket_name = BucketStorage.get_input_attr('bucket')
        zip_file_name = zip_file_name + ".zip"
        zip_file_abs_path = zip_file_abs_path + ".zip"
        SysLog().write_debug_log("Started Uploading Archived Terraform(Zip File: %s) into S3 Bucket(Name: %s)" % (zip_file_abs_path, bucket_name))
        s3_client.upload_file(
            zip_file_abs_path,
            bucket_name,
            zip_file_name)

        os.remove(zip_file_abs_path)
Example #12
0
 def exit_with_validation_errors(self, errors):
     for key, error_list in errors.items():
         msg = '\nValidation Error. Resource %s\n' % key
         msg = msg + '\n'.join(error_list)
         print(msg)
         SysLog().write_error_log(msg, with_trace=False)
Example #13
0
 def show_step_inner_warning(self, message):
     print_message = "\t%s" % message
     SysLog().write_debug_log(print_message)
     print(self.WARN_ANSI + print_message + self.RESET_ANSI)
Example #14
0
class PyTerraform():
    """
    This is the main class which bridges between the python_terraform class and framework system

    Attributes:
        log_obj (obj): SysLog object used to write logs
    """
    log_obj = SysLog()

    def terraform_init(self):
        """
        Run terraform init and raise excpetion if there is any error or response of the command

        Returns:
            response (dict): Response after terraform init
        """
        if exists_teraform_lock():
            raise Exception(K.ANOTHER_PROCESS_RUNNING)

        terraform = Terraform(
            working_dir=Settings.TERRAFORM_DIR,
        )
        self.log_obj.write_debug_log(K.TERRAFORM_INIT_STARTED)
        response = terraform.init()

        if response[0] == 1:
            self.log_obj.write_debug_log(K.TERRAFORM_INIT_ERROR)
            raise Exception(response[2])

        self.log_obj.write_terraform_init_log(response)

        return response

    def terraform_plan(self, resources=None):
        """
        Run terraform plan and raise excpetion if there is any error or response of the command

        Args:
            resources (list): List of resources if there are targets else None

        Returns:
            response (dict): Response after terraform plan
        """
        if exists_teraform_lock():
            raise Exception(K.ANOTHER_PROCESS_RUNNING)

        terraform = Terraform(
            working_dir=Settings.TERRAFORM_DIR,
            targets=self.get_target_resources(resources)
        )

        self.log_obj.write_debug_log(K.TERRAFORM_PLAN_STARTED)
        response = terraform.plan()

        if response[0] == 1:
            self.log_obj.write_debug_log(K.TERRAFORM_PLAN_ERROR)
            raise Exception(response[2])

        self.log_obj.write_terraform_plan_log(response)

        return response

    def terraform_apply(self, resources=None):
        """
        Run terraform apply and raise excpetion if there is any error or response of the command

        Args:
            resources (list): List of resources if there are targets else None

        Returns:
            response (dict): Response after terraform apply
        """
        if exists_teraform_lock():
            raise Exception(K.ANOTHER_PROCESS_RUNNING)

        CMD = Settings.get('running_command', "Terraform Apply")
        terraform = Terraform(
            working_dir=Settings.TERRAFORM_DIR,
            targets=self.get_target_resources(resources),
            stdout_log_file=self.log_obj.get_terraform_install_log_file()
        )

        self.log_obj.write_terraform_apply_log_header()
        # In order to -auto-approve we need to pass skip_plan=True for python3
        response = terraform.apply(skip_plan=True)

        if response[0] == 1:
            self.log_obj.write_debug_log(K.TERRAFORM_APPLY_ERROR)
            self.write_current_status(CMD, K.APPLY_STATUS_ERROR, response[2])
            raise Exception(response[2])

        self.write_current_status(CMD, K.APPLY_STATUS_COMPLETED, K.TERRAFORM_APPLY_COMPLETED)
        return response

    def terraform_destroy(self, resources=None):
        """
        Run terraform destroy and raise excpetion if there is any error or response of the command

        Args:
            resources (list): List of resources if there are targets else None

        Returns:
            response (dict): Response after terraform destroy
        """
        if exists_teraform_lock():
            raise Exception(K.ANOTHER_PROCESS_RUNNING)

        CMD = Settings.get('running_command', "Terraform Destroy")
        terraform = Terraform(
            working_dir=Settings.TERRAFORM_DIR,
            targets=self.get_target_resources(resources),
            stdout_log_file=self.log_obj.get_terraform_destroy_log_file()
        )

        self.log_obj.write_terraform_destroy_log_header()
        kwargs = {"auto_approve": True}
        response = terraform.destroy(**kwargs)

        if response[0] == 1:
            self.log_obj.write_debug_log(K.TERRAFORM_DESTROY_ERROR)
            self.write_current_status(CMD, K.DESTROY_STATUS_ERROR, response[2])
            raise Exception(response[2])

        self.write_current_status(CMD, K.DESTROY_STATUS_COMPLETED, K.TERRAFORM_DESTROY_COMPLETED)
        return response

    def process_destroy_result(self, p):
        """
        Store the destroy response and riase exception if there is any

        Args:
            p (process obj): process obj of the terraform destroy
        """
        response = Terraform().return_process_result(p)
        CMD = Settings.get('running_command', "Terraform Destroy")

        if response[0] == 1:
            self.log_obj.write_debug_log(K.TERRAFORM_DESTROY_ERROR)
            self.write_current_status(CMD, K.DESTROY_STATUS_ERROR, response[2])
            raise Exception(response[2])

        self.write_current_status(CMD, K.DESTROY_STATUS_COMPLETED, K.TERRAFORM_DESTROY_COMPLETED)

    def terraform_taint(self, resources):
        """
        Run terraform taint on the mentioned resources

        Args:
            resources (list): List of resources if there are targets else None

        Returns:
            response (dict): Response after terraform taint
        """
        if exists_teraform_lock():
            raise Exception(K.ANOTHER_PROCESS_RUNNING)

        terraform = Terraform(
            working_dir=Settings.TERRAFORM_DIR,
        )

        taint_resources = self.get_taint_resources(resources)

        self.log_obj.write_debug_log(K.TERRAFORM_TAINT_STARTED)

        for resource_name in taint_resources:
            response = terraform.cmd("taint", resource_name)
            if response[0] == 1:
                self.log_obj.write_debug_log(K.TERRAFORM_TAINT_ERROR)
                raise Exception(response[2])

        self.log_obj.write_debug_log(K.TERRAFORM_TAINT_COMPLETED)

        return response

    def get_target_resources(self, resources):
        """
        Get list of terraform targets arguments to be supplied to terraform command

        Args:
            resources (list): List of resources if there are targets else None

        Returns:
            targets (list / none): list of resources to be added as targets if there is any else None
        """
        if resources:
            targets = []
            for resource in resources:
                # DO NOT process this resource as its definiiton asked to skip
                if resource.PROCESS is False:
                    continue

                if BaseTerraformVariable not in inspect.getmro(resource.__class__) and TerraformData not in inspect.getmro(resource.__class__):
                    targets.append(get_terraform_resource_path(resource))

            return targets

        return None

    def get_taint_resources(self, resources):
        """
        Get list of terraform resources to be tainted

        Args:
            resources (list): List of resources

        Returns:
            taint_resources (list): List of resources to be tainted
        """
        taint_resources = []
        for resource in resources:
            if TerraformResource in inspect.getmro(resource.__class__):
                taint_resources.append(get_terraform_resource_path(resource))

        return taint_resources

    @classmethod
    def save_terraform_output(cls):
        """
        Save terraform output to the output file

        Returns:
            output_dict (dict): Terraform output
        """
        tf_output_file = get_terraform_latest_output_file()
        output_dict = cls.load_terraform_output()

        with open(tf_output_file, 'w') as jsonfile:
            json.dump(output_dict, jsonfile, indent=4)
        cls.log_obj.write_debug_log(K.TERRAFORM_OUTPUT_STORED)

        return output_dict

    @classmethod
    def load_terraform_output(cls):
        """
        Load terraform output form the output command

        Returns:
            output_dict (dict): Terraform output
        """
        output_dict = {}

        terraform = Terraform(
            working_dir=Settings.TERRAFORM_DIR,
        )
        response = terraform.output()
        if response:
            for key, item in response.items():
                key_splitted = key.split('-')
                resource_key = '-'.join(key_splitted[0:-1])

                if resource_key in output_dict:
                    output_dict[resource_key][key_splitted[-1]] = item['value']
                else:
                    output_dict[resource_key] = {key_splitted[-1]: item['value']}

        return output_dict

    @classmethod
    def load_terraform_output_from_json_file(cls):
        """
        Load terraform output form the output file

        Returns:
            output_dict (dict): Terraform output
        """
        tf_output_file = get_terraform_latest_output_file()
        output_dict = {}
        if os.path.exists(tf_output_file):
            with open(tf_output_file) as jsonfile:
                output_dict = json.load(jsonfile)

        return output_dict

    def write_current_status(self, command, status_code, description=""):
        """
        Write current status for the executed comamnd to status file

        Args:
            command (str): Command name
            status_code (str): Status of the current execution
            description (str): Description of the current command
        """
        current_status = self.get_current_status()
        prev_status = None

        if current_status:
            prev_status = {
                'status_code': current_status['status_code'],
                'description': current_status['description'],
                'last_exec_command': current_status['last_exec_command'],
                'executed_time': current_status['executed_time']
            }

        current_status['status_code'] = status_code
        current_status['description'] = description
        current_status['last_exec_command'] = command
        current_status['executed_time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')

        if prev_status:  # FIrst time previous status won't be available
            current_status[prev_status['executed_time']] = prev_status

        status_file = get_terraform_status_file()
        with open(status_file, 'w') as jsonfile:
            json.dump(current_status, jsonfile, indent=4)

    @classmethod
    def get_current_status(self):
        """
        Write current status for the executed comamnd to status file

        Returns:
            status_dict (dict): Status dict to be written
        """
        status_file = get_terraform_status_file()
        status_dict = {}
        if os.path.exists(status_file):
            with open(status_file) as jsonfile:
                status_dict = json.load(jsonfile)

        return status_dict
Example #15
0
    def show_step_finish(self, end_heading, write_log=True, color=""):
        if write_log:
            SysLog().write_debug_log(end_heading)

        end_heading = "\t%s" % end_heading
        print(color + end_heading + self.RESET_ANSI)
Example #16
0
class PyTerraform():
    log_obj = SysLog()

    def terraform_init(self):
        if exists_teraform_lock():
            raise Exception(K.ANOTHER_PROCESS_RUNNING)

        terraform = Terraform(
            working_dir=Settings.TERRAFORM_DIR,
        )
        self.log_obj.write_debug_log(K.TERRAFORM_INIT_STARTED)
        response = terraform.init()

        if response[0] == 1:
            self.log_obj.write_debug_log(K.TERRAFORM_INIT_ERROR)
            raise Exception(response[2])

        self.log_obj.write_terraform_init_log(response)

        return response

    def terraform_plan(self, resources=None):
        if exists_teraform_lock():
            raise Exception(K.ANOTHER_PROCESS_RUNNING)

        terraform = Terraform(
            working_dir=Settings.TERRAFORM_DIR,
            targets=self.get_target_resources(resources)
        )

        self.log_obj.write_debug_log(K.TERRAFORM_PLAN_STARTED)
        response = terraform.plan()

        if response[0] == 1:
            self.log_obj.write_debug_log(K.TERRAFORM_PLAN_ERROR)
            raise Exception(response[2])

        self.log_obj.write_terraform_plan_log(response)

        return response

    def terraform_apply(self, resources=None):
        if exists_teraform_lock():
            raise Exception(K.ANOTHER_PROCESS_RUNNING)

        CMD = Settings.get('running_command', "Terraform Apply")
        terraform = Terraform(
            working_dir=Settings.TERRAFORM_DIR,
            targets=self.get_target_resources(resources),
            stdout_log_file=self.log_obj.get_terraform_install_log_file()
        )

        self.log_obj.write_terraform_apply_log_header()
        # In order to -auto-approve we need to pass skip_plan=True for python3
        response = terraform.apply(skip_plan=True)

        if response[0] == 1:
            self.log_obj.write_debug_log(K.TERRAFORM_APPLY_ERROR)
            self.write_current_status(CMD, K.APPLY_STATUS_ERROR, response[2])
            raise Exception(response[2])

        self.write_current_status(CMD, K.APPLY_STATUS_COMPLETED, K.TERRAFORM_APPLY_COMPLETED)
        return response

    def terraform_destroy(self, resources=None):
        if exists_teraform_lock():
            raise Exception(K.ANOTHER_PROCESS_RUNNING)

        CMD = Settings.get('running_command', "Terraform Destroy")
        terraform = Terraform(
            working_dir=Settings.TERRAFORM_DIR,
            targets=self.get_target_resources(resources),
            stdout_log_file=self.log_obj.get_terraform_destroy_log_file()
        )

        self.log_obj.write_terraform_destroy_log_header()
        kwargs = {"auto_approve": True}
        response = terraform.destroy(**kwargs)

        if response[0] == 1:
            self.log_obj.write_debug_log(K.TERRAFORM_DESTROY_ERROR)
            self.write_current_status(CMD, K.DESTROY_STATUS_ERROR, response[2])
            raise Exception(response[2])

        self.write_current_status(CMD, K.DESTROY_STATUS_COMPLETED, K.TERRAFORM_DESTROY_COMPLETED)
        return response

    def terraform_taint(self, resources):
        if exists_teraform_lock():
            raise Exception(K.ANOTHER_PROCESS_RUNNING)

        terraform = Terraform(
            working_dir=Settings.TERRAFORM_DIR,
        )

        taint_resources = self.get_taint_resources(resources)

        self.log_obj.write_debug_log(K.TERRAFORM_TAINT_STARTED)

        for resource_name in taint_resources:
            response = terraform.cmd("taint", resource_name)
            if response[0] == 1:
                self.log_obj.write_debug_log(K.TERRAFORM_TAINT_ERROR)
                raise Exception(response[2])

        self.log_obj.write_debug_log(K.TERRAFORM_TAINT_COMPLETED)

        return response

    def get_target_resources(self, resources):
        if resources:
            targets = []
            for resource in resources:
                # DO NOT process this resource as its definiiton asked to skip
                if resource.PROCESS is False:
                    continue

                if BaseTerraformVariable not in inspect.getmro(resource.__class__) and TerraformData not in inspect.getmro(resource.__class__):
                    targets.append(get_terraform_resource_path(resource))

            return targets

        return None

    def get_taint_resources(self, resources):
        taint_resources = []
        for resource in resources:
            if TerraformResource in inspect.getmro(resource.__class__):
                taint_resources.append(get_terraform_resource_path(resource))

        return taint_resources

    @classmethod
    def save_terraform_output(cls):
        tf_output_file = get_terraform_latest_output_file()
        output_dict = cls.load_terraform_output()

        with open(tf_output_file, 'w') as jsonfile:
            json.dump(output_dict, jsonfile, indent=4)
        cls.log_obj.write_debug_log(K.TERRAFORM_OUTPUT_STORED)

        return output_dict

    @classmethod
    def load_terraform_output(cls):
        output_dict = {}

        terraform = Terraform(
            working_dir=Settings.TERRAFORM_DIR,
        )
        response = terraform.output()
        if response:
            for key, item in response.items():
                key_splitted = key.split('-')
                resource_key = '-'.join(key_splitted[0:-1])

                if resource_key in output_dict:
                    output_dict[resource_key][key_splitted[-1]] = item['value']
                else:
                    output_dict[resource_key] = {key_splitted[-1]: item['value']}

        return output_dict

    @classmethod
    def load_terraform_output_from_json_file(cls):
        tf_output_file = get_terraform_latest_output_file()
        output_dict = {}
        if os.path.exists(tf_output_file):
            with open(tf_output_file) as jsonfile:
                output_dict = json.load(jsonfile)

        return output_dict

    def write_current_status(self, command, status_code, description=""):
        current_status = self.get_current_status()
        prev_status = None

        if current_status:
            prev_status = {
                'status_code': current_status['status_code'],
                'description': current_status['description'],
                'last_exec_command': current_status['last_exec_command'],
                'executed_time': current_status['executed_time']
            }

        current_status['status_code'] = status_code
        current_status['description'] = description
        current_status['last_exec_command'] = command
        current_status['executed_time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')

        if prev_status:  # FIrst time previous status won't be available
            current_status[prev_status['executed_time']] = prev_status

        status_file = get_terraform_status_file()
        with open(status_file, 'w') as jsonfile:
            json.dump(current_status, jsonfile, indent=4)

    @classmethod
    def get_current_status(self):
        status_file = get_terraform_status_file()
        status_dict = {}
        if os.path.exists(status_file):
            with open(status_file) as jsonfile:
                status_dict = json.load(jsonfile)

        return status_dict
Example #17
0
 def show_step_inner_error(self, message):
     print_message = "\t%s" % self._get_error_msg_in_color(message)
     SysLog().write_error_log(print_message)
     print(print_message)