Example #1
0
        def __init__(self, config):
            """
            Swift client wrapper

            :param config: global configuration dict
            """
            self.config = SwiftConfig(config)
            self.vault = Vault(config)
            user_pass = self.vault.get(self.config.password_prefix)
            self.swift = swiftclient.service.SwiftService(options={
                    "auth_version": user_pass.get('auth_version', '3'),
                    "os_username": user_pass.get('os_username'),
                    "os_user_domain_name": user_pass.get(
                        'os_user_domain_name', 'default'
                        ),
                    "os_password": user_pass.get('os_password'),
                    "os_project_name": user_pass.get('os_project_name'),
                    "os_project_domain_name": user_pass.get(
                        'os_project_domain_name', 'default'
                        ),
                    "os_auth_url": user_pass.get('os_auth_url'),
                    "insecure": user_pass.get('insecure')
                })
            self.temporary_url_key = user_pass.get('temp_url_key')
            self.project = user_pass
            stats = self.swift.stat()
            self.account = dict(stats.get('items', {})).get('Account')
            if not self.account:
                LOGGER.warn("Unable to get Account from swift stats")
            temp_url_key = stats['headers'].get('x-account-meta-temp-url-key')
            if temp_url_key:
                if not self.temporary_url_key or\
                        (str(self.temporary_url_key) != str(temp_url_key)):
                    self.temporary_url_key = temp_url_key
Example #2
0
class S3Storage(BaseStorate):

    def __init__(self, config):
        self.config = Config(config)
        self.client = boto3.client
        self.vault = Vault(config)
        user_pass = self.vault.get(self.config.password_prefix)
        self.storage = boto3.client(
            's3',
            aws_access_key_id=user_pass.get(
                'AWS_ACCESS_KEY_ID',
                str(user_pass.get('user', 'AWS_ACCESS_KEY_ID'))
                ),
            aws_secret_access_key=user_pass.get(
                'AWS_SECRET_ACCESS_KEY',
                str(user_pass.get('password', 'AWS_SECRET_ACCESS_KEY'))
                ),
            region_name=user_pass.get(
                'AWS_DEFAULT_REGION',
                str(user_pass.get('region', 'eu-west-2'))
                )
            )

    def generate_presigned_url(self, key):
        return self.client.generate_presigned_url(
                    'get_object',
                    Params={'Bucket': self.config.bucket, 'Key': key},
                    ExpiresIn=self.config.expires,
                    )

    @retry(wait_exponential_multiplier=1000, stop_max_attempt_number=5)
    def upload_file(self, file, timestamp):
        # timestamp aka full path prefix
        # accepts only full system path to the file
        assert timestamp
        key = '/'.join((timestamp, os.path.basename(file)))
        try:
            self.storage.upload_file(
                file,
                self.config.bucket,
                key
                )
        except ClientError as e:
            LOGGER.fatal(
                "Falied to upload file {}. Error {}".format(file, e)
                )
            return ""
        try:
            return self.generate_presigned_url(key)
        except Exception as e:
            LOGGER.fatal(
                'Falied to sign url for file {}. Error: {}'.format(key, e)
                )
            return ""

    def list_objects(self, prefix):
        return self.client.list_objects(
                Bucket=self.config.bucket,
                Prefix=prefix
                )['Contents']
Example #3
0
class MemoryStorage(BaseStorate):
    storage = {}

    def __init__(self, config):
        self.config = Config(config)
        self.vault = Vault(config)
        user_pass = self.vault.get(self.config.password_prefix)
        LOGGER.debug("Inited memory storage with user: {} password: {}".format(
            user_pass.get("user"),
            user_pass.get('password')
            ))

    def generate_presigned_url(self, key):
        return "file://{}".format(self.storage[key])

    @retry(wait_exponential_multiplier=1000, stop_max_attempt_number=5)
    def upload_file(self, file, timestamp):
        key = '/'.join((timestamp, os.path.basename(file)))
        with NamedTemporaryFile(mode='w+') as tmp_file:
            with open(file, 'r') as in_file:
                shutil.copyfileobj(in_file, tmp_file)
            self.storage[key] = tmp_file.name
        return self.generate_presigned_url(key)

    def list_objects(self, prefix):
        for k, v in self.storage.items():
            if k.startswith(prefix):
                yield k
Example #4
0
 def __init__(self, config):
     self.config = Config(config)
     self.client = boto3.client
     self.vault = Vault(config)
     user_pass = self.vault.get(self.config.password_prefix)
     self.storage = boto3.client(
         's3',
         aws_access_key_id=user_pass.get(
             'AWS_ACCESS_KEY_ID',
             str(user_pass.get('user', 'AWS_ACCESS_KEY_ID'))),
         aws_secret_access_key=user_pass.get(
             'AWS_SECRET_ACCESS_KEY',
             str(user_pass.get('password', 'AWS_SECRET_ACCESS_KEY'))),
         region_name=user_pass.get(
             'AWS_DEFAULT_REGION', str(user_pass.get('region',
                                                     'eu-west-2'))))
Example #5
0
class MemoryStorage(BaseStorate):
    storage = {}

    def __init__(self, config):
        self.config = Config(config)
        self.vault = Vault(config)
        user_pass = self.vault.get(self.config.password_prefix)
        LOGGER.debug("Inited memory storage with user: {} password: {}".format(
            user_pass.get("user"), user_pass.get('password')))

    def generate_presigned_url(self, key):
        return "file://{}".format(self.storage[key])

    @retry(wait_exponential_multiplier=1000, stop_max_attempt_number=5)
    def upload_file(self, file, timestamp):
        key = '/'.join((timestamp, os.path.basename(file)))
        with NamedTemporaryFile(mode='w+') as tmp_file:
            with open(file, 'r') as in_file:
                shutil.copyfileobj(in_file, tmp_file)
            self.storage[key] = tmp_file.name
        return self.generate_presigned_url(key)

    def list_objects(self, prefix):
        for k, v in self.storage.items():
            if k.startswith(prefix):
                yield k
Example #6
0
 def __init__(self, config):
     self.config = Config(config)
     self.vault = Vault(config)
     user_pass = self.vault.get(self.config.password_prefix)
     LOGGER.debug("Inited memory storage with user: {} password: {}".format(
         user_pass.get("user"),
         user_pass.get('password')
         ))
Example #7
0
        def __init__(self, config):
            """
            Swift client wrapper

            :param config: global configuration dict
            """
            self.config = SwiftConfig(config)
            self.vault = Vault(config)
            user_pass = self.vault.get(self.config.password_prefix)
            self.swift = swiftclient.service.SwiftService(
                options={
                    "auth_version":
                    user_pass.get('auth_version', '3'),
                    "os_username":
                    user_pass.get('os_username'),
                    "os_user_domain_name":
                    user_pass.get('os_user_domain_name', 'default'),
                    "os_password":
                    user_pass.get('os_password'),
                    "os_project_name":
                    user_pass.get('os_project_name'),
                    "os_project_domain_name":
                    user_pass.get('os_project_domain_name', 'default'),
                    "os_auth_url":
                    user_pass.get('os_auth_url'),
                    "insecure":
                    user_pass.get('insecure')
                })
            self.temporary_url_key = user_pass.get('temp_url_key')
            self.project = user_pass
            stats = self.swift.stat()
            self.account = dict(stats.get('items', {})).get('Account')
            if not self.account:
                LOGGER.warn("Unable to get Account from swift stats")
            temp_url_key = stats['headers'].get('x-account-meta-temp-url-key')
            if temp_url_key:
                if not self.temporary_url_key or\
                        (str(self.temporary_url_key) != str(temp_url_key)):
                    self.temporary_url_key = temp_url_key
Example #8
0
class S3Storage(BaseStorate):
    def __init__(self, config):
        self.config = Config(config)
        self.client = boto3.client
        self.vault = Vault(config)
        user_pass = self.vault.get(self.config.password_prefix)
        self.storage = boto3.client(
            's3',
            aws_access_key_id=user_pass.get(
                'AWS_ACCESS_KEY_ID',
                str(user_pass.get('user', 'AWS_ACCESS_KEY_ID'))),
            aws_secret_access_key=user_pass.get(
                'AWS_SECRET_ACCESS_KEY',
                str(user_pass.get('password', 'AWS_SECRET_ACCESS_KEY'))),
            region_name=user_pass.get(
                'AWS_DEFAULT_REGION', str(user_pass.get('region',
                                                        'eu-west-2'))))

    def generate_presigned_url(self, key):
        return self.client.generate_presigned_url(
            'get_object',
            Params={
                'Bucket': self.config.bucket,
                'Key': key
            },
            ExpiresIn=self.config.expires,
        )

    @retry(wait_exponential_multiplier=1000, stop_max_attempt_number=5)
    def upload_file(self, file, timestamp):
        # timestamp aka full path prefix
        # accepts only full system path to the file
        assert timestamp
        key = '/'.join((timestamp, os.path.basename(file)))
        try:
            self.storage.upload_file(file, self.config.bucket, key)
        except ClientError as e:
            LOGGER.fatal("Falied to upload file {}. Error {}".format(file, e))
            return ""
        try:
            return self.generate_presigned_url(key)
        except Exception as e:
            LOGGER.fatal('Falied to sign url for file {}. Error: {}'.format(
                key, e))
            return ""

    def list_objects(self, prefix):
        return self.client.list_objects(Bucket=self.config.bucket,
                                        Prefix=prefix)['Contents']
Example #9
0
 def __init__(self, config):
     self.config = Config(config)
     self.client = boto3.client
     self.vault = Vault(config)
     user_pass = self.vault.get(self.config.password_prefix)
     self.storage = boto3.client(
         's3',
         aws_access_key_id=user_pass.get(
             'AWS_ACCESS_KEY_ID',
             str(user_pass.get('user', 'AWS_ACCESS_KEY_ID'))
             ),
         aws_secret_access_key=user_pass.get(
             'AWS_SECRET_ACCESS_KEY',
             str(user_pass.get('password', 'AWS_SECRET_ACCESS_KEY'))
             ),
         region_name=user_pass.get(
             'AWS_DEFAULT_REGION',
             str(user_pass.get('region', 'eu-west-2'))
             )
         )
Example #10
0
parser.add_argument('--mode', default=DEFAULT_MODE, choices=MODES)
parser.add_argument('--clean', action='store', default=YES[0], choices=YES+NO)
parser.add_argument('--sentry_dsn')
ARGS = parser.parse_args()

with open(ARGS.config) as _in:
    CONFIG = load(_in)

dictConfig(CONFIG)
WORKDIR = CONFIG['out']['out_dir']
INCLUDE = [op.strip() for op in ARGS.include.split(",")]
TIMESTAMP = ARGS.timestamp or datetime.now().strftime("%Y-%m-%d/%H-%M-%S-%f")

LOGGER = getLogger('BILLING')
PORTER = Porter(CONFIG, TIMESTAMP, ARGS.notify_brokers)
VAULT = Vault(CONFIG)


def upload_and_notify(files):
    ctx = PORTER.upload_files(files)
    if ARGS.notify and (ARGS.notify in YES):
        PORTER.postman.send_emails(ctx)
    return ctx


def send_emails_from_existing_files():
    ctx = PORTER.create_emails_context_from_existing_prefix()
    if ARGS.notify and (ARGS.notify in YES):
        PORTER.postman.send_emails(ctx)
    return [entry['broker'] for entry in ctx]
Example #11
0
    class SwiftStorage(BaseStorate):

        def __init__(self, config):
            """
            Swift client wrapper

            :param config: global configuration dict
            """
            self.config = SwiftConfig(config)
            self.vault = Vault(config)
            user_pass = self.vault.get(self.config.password_prefix)
            self.swift = swiftclient.service.SwiftService(options={
                    "auth_version": user_pass.get('auth_version', '3'),
                    "os_username": user_pass.get('os_username'),
                    "os_user_domain_name": user_pass.get(
                        'os_user_domain_name', 'default'
                        ),
                    "os_password": user_pass.get('os_password'),
                    "os_project_name": user_pass.get('os_project_name'),
                    "os_project_domain_name": user_pass.get(
                        'os_project_domain_name', 'default'
                        ),
                    "os_auth_url": user_pass.get('os_auth_url'),
                    "insecure": user_pass.get('insecure')
                })
            self.temporary_url_key = user_pass.get('temp_url_key')
            self.project = user_pass
            stats = self.swift.stat()
            self.account = dict(stats.get('items', {})).get('Account')
            if not self.account:
                LOGGER.warn("Unable to get Account from swift stats")
            temp_url_key = stats['headers'].get('x-account-meta-temp-url-key')
            if temp_url_key:
                if not self.temporary_url_key or\
                        (str(self.temporary_url_key) != str(temp_url_key)):
                    self.temporary_url_key = temp_url_key

        def generate_presigned_url(self, key):
            """
            Generates temporary public URL from given full key
            to swift object

            :param key: Full path to the object.
            :return: Full URL to the object for unauthenticated used to
                     being able to download object.
            """
            full_path = "/v1/{}/{}/{}".format(
                    self.account,
                    self.config.bucket,
                    key
                    )
            url = generate_temp_url(
                        full_path,
                        self.config.expires,
                        self.temporary_url_key,
                        'GET'
                    ).split(self.config.bucket)[1]
            if not self.config.swift_url_prefix.endswith('/'):
                if url.startswith('/'):
                    return "{}{}".format(self.config.swift_url_prefix, url)
                else:
                    return "{}/{}".format(self.config.swift_url_prefix, url)
            return self.config.swift_url_prefix[:-1] + url

        @retry(wait_exponential_multiplier=1000, stop_max_attempt_number=5)
        def upload_file(self, file, timestamp):
            with open(file, 'r') as upload_stream:
                try:
                    key = '/'.join((timestamp, os.path.basename(file)))
                    upload_obj = swiftclient.service.SwiftUploadObject(
                        upload_stream,
                        object_name=key
                        )
                    results = self.swift.upload(
                                container=self.config.bucket,
                                objects=[upload_obj]
                                )
                    for result in results:
                        if result['success']:
                            if 'object' in result:
                                LOGGER.info(
                                    "Action {} with object {} success: {}. :"
                                    "Reason: {}. x-trans-id: {}".format(
                                        result['action'], result['object'],
                                        result['success'],
                                        result['response_dict']['reason'],
                                        result['response_dict']['headers'].get(
                                            'x-trans-id'
                                            )
                                        ))
                            else:
                                LOGGER.info(
                                    "Operation {} successfull. "
                                    "Reason: {}. x-trans-id {}".format(
                                        result['action'],
                                        result['response_dict']['reason'],
                                        result['response_dict']['headers'].get(
                                            'x-trans-id'
                                            ))
                                    )
                        else:
                            LOGGER.fatal(
                                "Operation {} falied with error {}".format(
                                    result['action'],
                                    result['error']
                                ))
                            LOGGER.fatal("Error traceback {}".format(
                                result.get('traceback'))
                                )
                    if all((res['success'] for res in results)):
                        return self.generate_presigned_url(key)
                    else:
                        return ""

                except swiftclient.service.SwiftError as error:
                    LOGGER.fatal(
                        "Falied to upload file to swift with error {}".format(
                            error
                            )
                        )
                    return ""

        def list_objects(self, prefix):
            try:
                result = next(self.swift.list(
                        container=self.config.bucket,
                        options={"prefix": prefix}
                        ))
                if result['success']:
                    LOGGER.info(
                        'Action `{}` on container {} success: {}'.format(
                            result.get('action'),
                            result.get('container'),
                            result['success']
                        ))
                    return [item['name'] for item in result['listing']]
                LOGGER.fatal(
                        "Request  status {} with error {}".format(
                            result['success'], result['error']
                            )
                        )
                return []
            except swiftclient.service.SwiftError as e:
                LOGGER.fatal(
                        "Error {} on getting listint of "
                        "objects of {} with prefix {}".format(
                            e, self.container, prefix)
                        )
                return []
Example #12
0
 def __init__(self, config):
     self.config = config
     self.brokers = []
     self.emails_to = self.config.get('brokers_emails')
     self.vault = Vault(self.config)
Example #13
0
class Postman(object):
    def __init__(self, config):
        self.config = config
        self.brokers = []
        self.emails_to = self.config.get('brokers_emails')
        self.vault = Vault(self.config)

    def render_email(self, context):
        return ENV.get_template(TEMPLATE).render(context)

    def construct_mime_message(self, context):
        recipients = self.emails_to[context['broker']]
        msg = MIMEText(self.render_email(context), 'html', 'utf-8')
        msg['Subject'] = SUBJECT.format(**dict(broker=context['broker'],
                                               type=context['type'],
                                               period=context['period']))
        msg['From'] = self.config.get('email', {}).get('verified_email')
        msg['To'] = COMMASPACE.join(recipients)
        return (recipients, msg)

    @retry(wait_exponential_multiplier=1000, stop_max_attempt_number=5)
    def send_emails(self, msgs):
        try:
            self.server = smtplib.SMTP(
                self.config.get('email', {}).get('smtp_server'),
                self.config.get('email', {}).get('smtp_port'))
            user_pass = self.vault.get(
                self.config.get('email', {}).get('password_prefix'))
            self.server.ehlo()
            if self.config.get('use_tls', True):
                self.server.starttls()
                self.server.ehlo()
            if self.config.get('email', {}).get('use_auth'):
                self.server.login(
                    user_pass.get('AWS_ACCESS_KEY_ID', user_pass.get('user')),
                    user_pass.get('AWS_SECRET_ACCESS_KEY',
                                  user_pass.get('password')))
        except smtplib.SMTPException as e:
            LOGGER.fatal("SMTP connection failed with error: {}. :"
                         "Generation will ran without notifications".format(e))
            self.server = None
        except Exception as e:
            LOGGER.fatal("Uncaught error while connecting to SMTP: Error: {}."
                         "Generation will ran without notifications".format(e))
            self.server = None

        try:
            for context in msgs:
                recipients, msg = self.construct_mime_message(context)
                if (not self.brokers) or (self.brokers and context['broker']
                                          in self.brokers):
                    if self.server:
                        self.server.sendmail(
                            self.config.get('email', {}).get('verified_email'),
                            recipients, msg.as_string())
                        LOGGER.info('Sent mail to {}'.format(recipients))
        except smtplib.SMTPException as e:
            LOGGER.fatal("Falied to send mails. Error: {}".format(e))
        finally:
            try:
                self.server.close()
            except Exception as e:
                LOGGER.fatal("Unable to close connection "
                             "to SMTP server. Error: {}".format(e))
Example #14
0
 def __init__(self, config):
     self.config = Config(config)
     self.vault = Vault(config)
     user_pass = self.vault.get(self.config.password_prefix)
     LOGGER.debug("Inited memory storage with user: {} password: {}".format(
         user_pass.get("user"), user_pass.get('password')))
Example #15
0
    class SwiftStorage(BaseStorate):
        def __init__(self, config):
            """
            Swift client wrapper

            :param config: global configuration dict
            """
            self.config = SwiftConfig(config)
            self.vault = Vault(config)
            user_pass = self.vault.get(self.config.password_prefix)
            self.swift = swiftclient.service.SwiftService(
                options={
                    "auth_version":
                    user_pass.get('auth_version', '3'),
                    "os_username":
                    user_pass.get('os_username'),
                    "os_user_domain_name":
                    user_pass.get('os_user_domain_name', 'default'),
                    "os_password":
                    user_pass.get('os_password'),
                    "os_project_name":
                    user_pass.get('os_project_name'),
                    "os_project_domain_name":
                    user_pass.get('os_project_domain_name', 'default'),
                    "os_auth_url":
                    user_pass.get('os_auth_url'),
                    "insecure":
                    user_pass.get('insecure')
                })
            self.temporary_url_key = user_pass.get('temp_url_key')
            self.project = user_pass
            stats = self.swift.stat()
            self.account = dict(stats.get('items', {})).get('Account')
            if not self.account:
                LOGGER.warn("Unable to get Account from swift stats")
            temp_url_key = stats['headers'].get('x-account-meta-temp-url-key')
            if temp_url_key:
                if not self.temporary_url_key or\
                        (str(self.temporary_url_key) != str(temp_url_key)):
                    self.temporary_url_key = temp_url_key

        def generate_presigned_url(self, key):
            """
            Generates temporary public URL from given full key
            to swift object

            :param key: Full path to the object.
            :return: Full URL to the object for unauthenticated used to
                     being able to download object.
            """
            full_path = "/v1/{}/{}/{}".format(self.account, self.config.bucket,
                                              key)
            url = generate_temp_url(full_path,
                                    int(time() + int(self.config.expires)),
                                    self.temporary_url_key,
                                    'GET').split(self.config.bucket)[1]
            if not self.config.swift_url_prefix.endswith('/'):
                if url.startswith('/'):
                    return "{}{}".format(self.config.swift_url_prefix, url)
                else:
                    return "{}/{}".format(self.config.swift_url_prefix, url)
            return self.config.swift_url_prefix[:-1] + url

        @retry(wait_exponential_multiplier=1000, stop_max_attempt_number=5)
        def upload_file(self, file, timestamp):
            with open(file, 'r') as upload_stream:
                try:
                    key = '/'.join((timestamp, os.path.basename(file)))
                    upload_obj = swiftclient.service.SwiftUploadObject(
                        upload_stream, object_name=key)
                    results = self.swift.upload(container=self.config.bucket,
                                                objects=[upload_obj])
                    for result in results:
                        if result['success']:
                            if 'object' in result:
                                LOGGER.info(
                                    "Action {} with object {} success: {}. :"
                                    "Reason: {}. x-trans-id: {}".format(
                                        result['action'], result['object'],
                                        result['success'],
                                        result['response_dict']['reason'],
                                        result['response_dict']['headers'].get(
                                            'x-trans-id')))
                            else:
                                LOGGER.info(
                                    "Operation {} successfull. "
                                    "Reason: {}. x-trans-id {}".format(
                                        result['action'],
                                        result['response_dict']['reason'],
                                        result['response_dict']['headers'].get(
                                            'x-trans-id')))
                        else:
                            LOGGER.fatal(
                                "Operation {} falied with error {}".format(
                                    result['action'], result['error']))
                            LOGGER.fatal("Error traceback {}".format(
                                result.get('traceback')))
                    if all((res['success'] for res in results)):
                        return self.generate_presigned_url(key)
                    else:
                        return ""

                except swiftclient.service.SwiftError as error:
                    LOGGER.fatal(
                        "Falied to upload file to swift with error {}".format(
                            error))
                    return ""

        def list_objects(self, prefix):
            try:
                result = next(
                    self.swift.list(container=self.config.bucket,
                                    options={"prefix": prefix}))
                if result['success']:
                    LOGGER.info(
                        'Action `{}` on container {} success: {}'.format(
                            result.get('action'), result.get('container'),
                            result['success']))
                    return [item['name'] for item in result['listing']]
                LOGGER.fatal("Request  status {} with error {}".format(
                    result['success'], result['error']))
                return []
            except swiftclient.service.SwiftError as e:
                LOGGER.fatal("Error {} on getting listint of "
                             "objects of {} with prefix {}".format(
                                 e, self.container, prefix))
                return []