Example #1
0
    def _process_job_status(self, service, job_doc):
        """
        Send job status to DB service.

        Include info on prev and next service which DB service
        does not know about.
        """
        job_doc['current_service'] = self._get_next_service(service)
        job_doc['prev_service'] = service
        last_service = job_doc.pop('last_service')
        notification_email = job_doc.pop('notification_email')

        try:
            handle_request(
                self.database_api_url,
                'jobs/',
                'put',
                job_data=job_doc
            )
        except Exception as error:
            self.log.error('Job status update failed: {}'.format(error))

        if notification_email and (last_service == service):
            self.send_notification(
                job_doc['id'],
                notification_email,
                job_doc['status'],
                job_doc.get('cloud_image_name'),
                job_doc['errors']
            )
Example #2
0
def delete_aliyun_account_for_user(name, user_id):
    """
    Delete Aliyun account for user.
    """
    data = {
        'cloud': 'aliyun',
        'account_name': name,
        'requesting_user': user_id
    }

    aliyun_account = get_aliyun_account_for_user(name, user_id)

    if aliyun_account:
        try:
            db.session.delete(aliyun_account)
            db.session.commit()
            handle_request(
                current_app.config['CREDENTIALS_URL'],
                'credentials/',
                'delete',
                job_data=data
            )
        except Exception:
            db.session.rollback()
            raise
        else:
            return 1
    else:
        return 0
Example #3
0
def test_handle_request_failed(mock_requests):
    response = MagicMock()
    response.status_code = 400
    response.reason = 'Not Found'
    response.json.return_value = {}
    mock_requests.get.return_value = response

    with raises(MashException):
        handle_request('localhost', '/jobs', 'get')
Example #4
0
def update_azure_account_for_user(
    account_name,
    user_id,
    region=None,
    credentials=None,
    source_container=None,
    source_resource_group=None,
    source_storage_account=None
):
    """
    Update Azure account for user.
    """
    account = get_azure_account_by_user(account_name, user_id)

    if not account:
        return None

    if credentials:
        data = {
            'cloud': 'azure',
            'account_name': account_name,
            'requesting_user': user_id,
            'credentials': credentials
        }

        try:
            handle_request(
                current_app.config['CREDENTIALS_URL'],
                'credentials/',
                'post',
                job_data=data
            )
        except Exception:
            raise

    if region:
        account.region = region

    if source_container:
        account.source_container = source_container

    if source_resource_group:
        account.source_resource_group = source_resource_group

    if source_storage_account:
        account.source_storage_account = source_storage_account

    try:
        db.session.add(account)
        db.session.commit()
    except Exception:
        db.session.rollback()
        raise

    return account
Example #5
0
def update_aliyun_account_for_user(
    account_name,
    user_id,
    bucket=None,
    region=None,
    credentials=None,
    security_group_id=None,
    vswitch_id=None
):
    """
    Update an existing Aliyun account.
    """
    aliyun_account = get_aliyun_account_for_user(account_name, user_id)

    if not aliyun_account:
        return None

    if credentials:
        data = {
            'cloud': 'aliyun',
            'account_name': account_name,
            'requesting_user': user_id,
            'credentials': credentials
        }

        try:
            handle_request(
                current_app.config['CREDENTIALS_URL'],
                'credentials/',
                'post',
                job_data=data
            )
        except Exception:
            raise

    if region:
        aliyun_account.region = region

    if bucket:
        aliyun_account.bucket = bucket

    if security_group_id:
        aliyun_account.security_group_id = security_group_id

    if vswitch_id:
        aliyun_account.vswitch_id = vswitch_id

    try:
        db.session.add(aliyun_account)
        db.session.commit()
    except Exception:
        db.session.rollback()
        raise

    return aliyun_account
Example #6
0
def create_job(data):
    """
    Create a new job for user.
    """
    if data.get('dry_run'):
        return None

    job_id = get_new_job_id()
    data['job_id'] = job_id

    user_id = data['requesting_user']

    kwargs = {
        'job_id': job_id,
        'last_service': data['last_service'],
        'utctime': data['utctime'],
        'image': data['image'],
        'download_url': data['download_url'],
        'user_id': user_id,
        'state': RUNNING,
        'current_service': current_app.config['SERVICE_NAMES'][0]
    }

    if data['utctime'] != 'now':
        kwargs['start_time'] = parser.parse(data['utctime'])

    if data.get('cloud_architecture'):
        kwargs['cloud_architecture'] = data['cloud_architecture']

    if data.get('profile'):
        kwargs['profile'] = data['profile']

    response = handle_request(current_app.config['DATABASE_API_URL'],
                              'jobs/',
                              'post',
                              job_data=kwargs)

    try:
        publish('jobcreator', 'job_document', json.dumps(data, sort_keys=True))
    except Exception:
        try:
            handle_request(current_app.config['DATABASE_API_URL'],
                           'jobs/',
                           'delete',
                           job_data={
                               'job_id': job_id,
                               'user_id': user_id
                           })
        except Exception:
            pass  # Attempt to cleanup job in database

        raise MashJobException('Failed to initialize job.')

    return response.json()
Example #7
0
def update_ec2_account_for_user(account_name,
                                user_id,
                                additional_regions=None,
                                credentials=None,
                                group=None,
                                region=None,
                                subnet=None):
    """
    Update an existing EC2 account.
    """
    ec2_account = get_ec2_account_for_user(account_name, user_id)

    if not ec2_account:
        return None

    if credentials:
        data = {
            'cloud': 'ec2',
            'account_name': account_name,
            'requesting_user': user_id,
            'credentials': credentials
        }

        try:
            handle_request(current_app.config['CREDENTIALS_URL'],
                           'credentials/',
                           'post',
                           job_data=data)
        except Exception:
            raise

    if group:
        ec2_account.group = _get_or_create_ec2_group(group, user_id)

    if additional_regions:
        for additional_region in additional_regions:
            create_new_ec2_region(additional_region['name'],
                                  additional_region['helper_image'],
                                  ec2_account)

    if region:
        ec2_account.region = region

    if subnet:
        ec2_account.subnet = subnet

    try:
        db.session.add(ec2_account)
        db.session.commit()
    except Exception:
        db.session.rollback()
        raise

    return ec2_account
Example #8
0
def delete_user(user_id):
    """
    Delete user by id.

    If user does not exist return 0.
    """
    try:
        handle_request(current_app.config['DATABASE_API_URL'],
                       'users/{user}'.format(user=user_id), 'delete')
    except Exception:
        return 0

    return 1
Example #9
0
def update_gce_account_for_user(
    account_name,
    user_id,
    bucket=None,
    region=None,
    credentials=None,
    testing_account=None
):
    """
    Update an existing GCE account.
    """
    gce_account = get_gce_account_for_user(account_name, user_id)

    if not gce_account:
        return None

    if credentials:
        data = {
            'cloud': 'gce',
            'account_name': account_name,
            'requesting_user': user_id,
            'credentials': credentials
        }

        try:
            handle_request(
                current_app.config['CREDENTIALS_URL'],
                'credentials/',
                'post',
                job_data=data
            )
        except Exception:
            raise

    if bucket:
        gce_account.bucket = bucket

    if region:
        gce_account.region = region

    if testing_account and gce_account.is_publishing_account:
        gce_account.testing_account = testing_account

    try:
        db.session.add(gce_account)
        db.session.commit()
    except Exception:
        db.session.rollback()
        raise

    return gce_account
Example #10
0
def create_new_aliyun_account(
    user_id,
    account_name,
    bucket_name,
    region_name,
    credentials,
    security_group_id=None,
    vswitch_id=None
):
    """
    Create a new Aliyun account for user.
    """
    data = {
        'cloud': 'aliyun',
        'account_name': account_name,
        'requesting_user': user_id,
        'credentials': credentials
    }

    aliyun_account = AliyunAccount(
        name=account_name,
        region=region_name,
        bucket=bucket_name,
        security_group_id=security_group_id,
        vswitch_id=vswitch_id,
        user_id=user_id
    )

    if security_group_id:
        aliyun_account.security_group_id = security_group_id

    if vswitch_id:
        aliyun_account.vswitch_id = vswitch_id

    try:
        handle_request(
            current_app.config['CREDENTIALS_URL'],
            'credentials/',
            'post',
            job_data=data
        )
        db.session.add(aliyun_account)
        db.session.commit()
    except Exception:
        db.session.rollback()
        raise

    return aliyun_account
Example #11
0
def create_new_gce_account(
    user_id,
    account_name,
    bucket,
    region_name,
    credentials,
    testing_account,
    is_publishing_account
):
    """
    Create a new GCE account for user.
    """
    if is_publishing_account and not testing_account:
        raise MashDBException(
            'Jobs using a GCE publishing account require'
            ' the use of a test account.'
        )

    data = {
        'cloud': 'gce',
        'account_name': account_name,
        'requesting_user': user_id,
        'credentials': credentials
    }

    account = GCEAccount(
        name=account_name,
        bucket=bucket,
        region=region_name,
        testing_account=testing_account,
        is_publishing_account=is_publishing_account,
        user_id=user_id
    )

    try:
        handle_request(
            current_app.config['CREDENTIALS_URL'],
            'credentials/',
            'post',
            job_data=data
        )
        db.session.add(account)
        db.session.commit()
    except Exception:
        db.session.rollback()
        raise

    return account
Example #12
0
def add_user(email, password=None):
    """
    Add new user to database and set password hash.

    If the user or email exists return None.
    If password is None, a random password is created, in effect creating
    an account that can only be used with oidc authentication.
    """
    if password and len(password) < 8:
        raise MashException(
            'Password too short. Minimum length is 8 characters.')

    if not email_in_whitelist(email):
        raise MashException(
            'Cannot create a user with the provided email. Access denied.')

    response = handle_request(current_app.config['DATABASE_API_URL'],
                              'users/',
                              'post',
                              job_data={
                                  'email': email,
                                  'password': password
                              })

    return response.json()
Example #13
0
def test_handle_request(mock_requests):
    response = MagicMock()
    response.status_code = 200
    mock_requests.get.return_value = response

    result = handle_request('localhost', '/jobs', 'get')
    assert result == response
Example #14
0
    def request_credentials(self, accounts, cloud=None):
        """
        Request credentials from credential service.

        Only send request if credentials not already populated.
        """
        if self.credentials:
            return

        data = {
            'cloud': cloud or self.cloud,
            'cloud_accounts': accounts,
            'requesting_user': self.requesting_user
        }

        try:
            response = handle_request(
                self.config.get_credentials_url(),
                'credentials/',
                'get',
                job_data=data
            )
            self.credentials = response.json()
        except Exception:
            raise MashJobException(
                'Credentials request failed for accounts: {accounts}'.format(
                    accounts=', '.join(accounts)
                )
            )
Example #15
0
def get_user_tokens(user_id):
    """
    Returns all of the tokens for given user.
    """
    response = handle_request(current_app.config['DATABASE_API_URL'],
                              'tokens/list/{user}'.format(user=user_id), 'get')

    return response.json()
Example #16
0
def revoke_tokens(user_id):
    """
    Revokes (deletes) all tokens for given user.
    """
    response = handle_request(current_app.config['DATABASE_API_URL'],
                              'tokens/list/{user}'.format(user=user_id),
                              'delete')
    return response.json().get('rows_deleted', 0)
Example #17
0
def add_token_to_database(encoded_token, user_id):
    """
    Add a new token to the database.
    """
    decoded_token = decode_token(encoded_token)
    jti = decoded_token['jti']
    token_type = decoded_token['type']
    expires = decoded_token['exp']

    handle_request(current_app.config['DATABASE_API_URL'],
                   'tokens/',
                   'post',
                   job_data={
                       'jti': jti,
                       'token_type': token_type,
                       'user_id': user_id,
                       'expires': expires
                   })
Example #18
0
def get_user_by_id(user_id):
    """
    Retrieve user from database if a match exists.

    If user does not exist return None.
    """
    response = handle_request(current_app.config['DATABASE_API_URL'],
                              'users/{user}'.format(user=user_id), 'get')
    return response.json()
Example #19
0
def get_gce_accounts(user_id):
    """
    Retrieve all GCE accounts for user.
    """
    response = handle_request(current_app.config['DATABASE_API_URL'],
                              'gce_accounts/list/{user}'.format(user=user_id),
                              'get')

    return response.json()
Example #20
0
def create_new_azure_account(
    user_id,
    account_name,
    region_name,
    credentials,
    source_container,
    source_resource_group,
    source_storage_account
):
    """
    Create a new Azure account for user.
    """
    data = {
        'cloud': 'azure',
        'account_name': account_name,
        'requesting_user': user_id,
        'credentials': credentials
    }

    account = AzureAccount(
        name=account_name,
        region=region_name,
        source_container=source_container,
        source_resource_group=source_resource_group,
        source_storage_account=source_storage_account,
        user_id=user_id
    )

    try:
        handle_request(
            current_app.config['CREDENTIALS_URL'],
            'credentials/',
            'post',
            job_data=data
        )
        db.session.add(account)
        db.session.commit()
    except Exception:
        db.session.rollback()
        raise

    return account
Example #21
0
def create_new_ec2_account(user_id, account_name, partition, region_name,
                           credentials, subnet, group_name,
                           additional_regions):
    """
    Create a new EC2 account for user.

    Create a new group and additional regions if necessary.
    """
    data = {
        'cloud': 'ec2',
        'account_name': account_name,
        'requesting_user': user_id,
        'credentials': credentials
    }

    account = EC2Account(name=account_name,
                         partition=partition,
                         region=region_name,
                         subnet=subnet,
                         user_id=user_id)

    if group_name:
        group = _get_or_create_ec2_group(group_name, user_id)
        account.group = group

    if additional_regions:
        for additional_region in additional_regions:
            create_new_ec2_region(additional_region['name'],
                                  additional_region['helper_image'], account)

    try:
        handle_request(current_app.config['CREDENTIALS_URL'],
                       'credentials/',
                       'post',
                       job_data=data)
        db.session.add(account)
        db.session.commit()
    except Exception:
        db.session.rollback()
        raise

    return account
Example #22
0
def change_user_password(email, current_password, new_password):
    """
    Change password for user if user exists and existing password matches.

    And reset the password to clean so the user can login again.
    """
    if len(new_password) < 8:
        raise MashException(
            'Password too short. Minimum length is 8 characters.')

    handle_request(current_app.config['DATABASE_API_URL'],
                   'users/password/change/{email}'.format(email=email),
                   'post',
                   job_data={
                       'current_password': current_password,
                       'new_password': new_password
                   })

    current_app.notification_class.send_notification(
        password_change_msg_template, '[MASH] Password Changed', email)
Example #23
0
def revoke_token_by_jti(jti, user_id):
    """
    Revoke token by jti identifier.
    """
    response = handle_request(current_app.config['DATABASE_API_URL'],
                              'tokens/',
                              'delete',
                              job_data={
                                  'jti': jti,
                                  'user_id': user_id
                              })
    return response.json()['rows_deleted']
Example #24
0
def get_user_by_email(email, create=False):
    """
    Retrieve user from database if a match exists.

    If the user does not exist and create is True, the user
    is created on the fly. Otherwise None is returned.
    """
    response = handle_request(current_app.config['DATABASE_API_URL'],
                              'users/get_user/{email}'.format(email=email),
                              'get',
                              job_data={'create': create})
    return response.json()
Example #25
0
def create_gce_account(user_id, data):
    """
    Create a new GCE account for user.
    """
    data['user_id'] = user_id

    response = handle_request(current_app.config['DATABASE_API_URL'],
                              'gce_accounts/',
                              'post',
                              job_data=data)

    return response.json()
Example #26
0
def get_jobs(user_id, page=None, per_page=None):
    """
    Retrieve all jobs for user.
    """
    response = handle_request(current_app.config['DATABASE_API_URL'],
                              'jobs/list/{user}'.format(user=user_id),
                              'get',
                              job_data={
                                  'page': page,
                                  'per_page': per_page
                              })

    return response.json()
Example #27
0
def get_token_by_jti(token_jti, user_id):
    """
    Get token by jti identifier.
    """
    response = handle_request(current_app.config['DATABASE_API_URL'],
                              'tokens/',
                              'get',
                              job_data={
                                  'jti': token_jti,
                                  'user_id': user_id
                              })

    return response.json()
Example #28
0
def get_accounts_in_ec2_group(group_name, user_id):
    """
    Get an EC2 group for user.
    """
    response = handle_request(current_app.config['DATABASE_API_URL'],
                              'ec2_accounts/group_accounts',
                              'get',
                              job_data={
                                  'user_id': user_id,
                                  'group_name': group_name
                              })

    return response.json()
Example #29
0
def update_gce_account(account_name, user_id, data):
    """
    Update GCE account for user.
    """
    data['account_name'] = account_name
    data['user_id'] = user_id

    response = handle_request(current_app.config['DATABASE_API_URL'],
                              'gce_accounts/',
                              'put',
                              job_data=data)

    return response.json()
Example #30
0
def delete_gce_account(name, user_id):
    """
    Delete GCE account for user.
    """
    response = handle_request(current_app.config['DATABASE_API_URL'],
                              'gce_accounts/',
                              'delete',
                              job_data={
                                  'name': name,
                                  'user_id': user_id
                              })

    return response.json()['rows_deleted']