def test_cloudi_create_account(): """Ensure that Cloudigrade responds appropriately to Sources trigger. :id: 8DA8D12F-A6FE-426E-BF87-33DFBE2E65D0 :description: Ensure that Cloudigrade recognizes when a user initiates an event via Sources. :steps: 1) Add a source with AWS credentials. 2) Watch Cloudigrade to see that a new cloud account with the appropriate arn is created. :expectedresults: 1) Account is created in Cloudigrade with a name matching the pattern 'aws-account-<ACCOUNT_NUMBER_OF_TEMP_AWS_ACCOUNT>'. 2) Said account has expected arn for same temp account in AWS. """ client = api.ClientV2() arn = 'arn:aws:iam::439727791560:role/cloudigrade-role-for-743187646576' # Make sure that there isn't already an account using this arn. aws_profile = config.get_config()['aws_profiles'][0] delete_preexisting_accounts(aws_profile) # delete_current_cloud_accounts(arn) # Trigger Sources authentication create_auth_obj_in_sources() time = 30 params = ('get', 'accounts/') cloudi_response = wait_for_response_with_timeout(client, params, arn, time) assert cloudi_response['name'] == 'aws-account-439727791560' assert cloudi_response['content_object']['account_arn'] == arn
def fetch_api_accounts(): """Return account data for available accounts.""" client = api.ClientV2() response = client.request('get', 'accounts/') assert response.status_code == 200, \ 'Could not retrieve any account information' \ ' (check credentials?)' accounts = response.json()['data'] return accounts
def test_sysconfig(): """Ensure API v2 sysconfig returns expected configuration information. :id: 437E5632-60AD-43F6-A121-AE57A9A07F9A :description: Ensure sysconfig returns expected configuration information. :steps: Do a GET request to /api/v2/sysconfig/ with correct headers and check the response. :expectedresults: The server returns a 200 response with the expected configuration information. """ client = api.ClientV2() response = client.request('get', 'sysconfig/') assert response.status_code == 200, response.text
def create_auth_obj_in_sources(): """Get authentication object from Sources. Add a source with AWS credentials. You must have a Source object first. Then get the Endpoint object and whth you can create an Authentication object. Once this is done, Cloudigrade should notice the authentication and from there, create a cloud account for the user to monitor the newly triggered activity. """ creds = get_credentials() client = api.ClientV2(SOURCES_URL, auth=creds) now = datetime.now() unique_name = now.strftime('%m_%d_%Y-%H:%M:%S') name = f'integrade_test_source_{unique_name}' # Get Source object id. source_data = json.dumps({'name': name, 'source_type_id': '2'}) source_r = client.request('post', 'sources', data=source_data) source_response = json.loads(source_r.content) source_id = source_response['id'] # Get Endpoint object id. endpoint_data = json.dumps({'role': 'aws', 'source_id': source_id}) endpoint_r = client.request('post', 'endpoints', data=endpoint_data) endpoint_response = json.loads(endpoint_r.content) endpoint_id = endpoint_response['id'] # Get Authentication object id. 'aws_username' and 'aws_password' should # be from temp/throw-away AWS account. See TODO in # 'delete_current_cloud_accounts'. aws_username = '******' aws_password = '******' auth_data = json.dumps({ 'resource_id': endpoint_id, 'resource_type': 'Endpoint', 'username': aws_username, 'password': aws_password }) auth_r = client.request('post', 'authentications', data=auth_data) auth_response = json.loads(auth_r.content) auth_id = auth_response['id'] auth_id_response = client.request('get', f'authentications/{auth_id}') auth_id = auth_id_response.json()['id'] print(f'Source response: {source_response}') print(f'Endpoint response: {endpoint_response}') print(f'Auth id response: {auth_id_response.text}') print(f'Auth id: {auth_id}')
def delete_preexisting_accounts(aws_profile): """Delete any pre-existing accounts to start fresh. In case something went wrong last time this test ran, check to be sure that the account doesn't exist and delete it if it does. TODO: move this to an 'addfinalizer' to delete accounts """ arn = aws_profile['arn'] aws_id = '743187646576' arn_text = 'arn:aws:iam::439727791560:role/cloudigrade-role-for' sources_arn = f'{arn_text}-{aws_id}' accounts = fetch_api_accounts() client = api.ClientV2() for acct in accounts: acct_arn = acct['content_object']['account_arn'] if acct_arn == arn or acct_arn == sources_arn: account_id = acct['account_id'] endpoint = f'accounts/{account_id}/' client.request('delete', endpoint)
def test_inspection(test_case, request): """Ensure instances are inspected. :id: 45BBB27E-F38D-415F-B64F-B2543D1132DE :description: Ensure images are inspected for all running instances. :steps: 1) Create a cloud account 2) Run instances based off of a non-windows image 3) Send a GET to '/api/cloudigrade/v2/instances/' with a timeout and expect to get the instances we created 4) Send a GET to '/api/cloudigrade/v2/images/' and expect to get the image that the instances were based off of. 5) Keep checking to see that the images progress from "pending", "preparing", "inspecting", to "inspected" :expectedresults: 1) We get 200 responses for our GET requests and information about the images includes inspection state information. 2) The images are eventually inspected. """ aws_profile = config.get_config()['aws_profiles'][0] aws_profile_name = aws_profile['name'] # Purge leftover sqs messages in _ready_volumes queue aws_utils.purge_queue_messages() # Make sure clusters are scaled down at start of inspection aws_utils.scale_down_houndigrade() # Delete any preexisting accounts in cloudigrade delete_preexisting_accounts(aws_profile) # Add AWS account to cloudigrade arn = aws_profile['arn'] client = api.ClientV2() acct_data_params = { 'account_arn': arn, 'name': uuid4(), 'cloud_type': 'aws', } # Create an account add_acct_response = client.request('post', 'accounts/', data=acct_data_params) assert add_acct_response.status_code == 201 # Start an instance for initial discovery image_type, image_name, expected_state = test_case ec2_ami_id = '' for image in aws_profile['images'][image_type]: if image_name == image['name']: ec2_ami_id = image['image_id'] instance_id = aws_utils.run_instances_by_name(aws_profile_name, image_type, image_name, count=1)[0] request.addfinalizer( functools.partial(aws_utils.terminate_instance, (aws_profile_name, instance_id))) instances = _get_object_with_timeout(client, 'instances/', MEDIUM_TIMEOUT) images = _get_object_with_timeout(client, 'images/', MEDIUM_TIMEOUT) # Check that images and instances show up in Cloudigrade account assert _get_instance_id_with_ec2_instance_id(instance_id, instances) is \ not None image_id = _image_id_with_ec2_image_id(ec2_ami_id, images) assert image_id is not None # Check that Cloudigrade eventually inspects images. inspection_results = _wait_for_inspection_with_timeout( client, image_id, LONG_TIMEOUT, expected_state) assert inspection_results is True
def test_discovery(test_case, request): """Ensure instances are discovered on account creation. :id: 509260DA-9980-4F9D-85D9-54C30B99DA56 :description: Ensure running instances are discovered. :steps: 1) Run an image in AWS 2) Create an account in Cloudigrade - send a POST with the cloud account information to '/api/cloudigrade/v2/' 4) Send a GET to '/api/cloudigrade/v2/instances/' and expect to get the instances we created 5) Send a GET to '/api/cloudigrade/v2/images/' and expect to get the image that the instances were based off of. :expectedresults: 1) The server returns a 201 response with the information of the created account. 2) We get 200 responses for our GET requests and information about the images includes inspection state information. """ aws_profile = config.get_config()['aws_profiles'][0] aws_profile_name = aws_profile['name'] # Delete any preexisting accounts in cloudigrade delete_preexisting_accounts(aws_profile) # Purge leftover sqs messages in _ready_volumes queue aws_utils.purge_queue_messages() # Run an instance image_type, image_name, expected_state = test_case ec2_ami_id = '' for image in aws_profile['images'][image_type]: if image_name == image['name']: ec2_ami_id = image['image_id'] # Start an instance for initial discovery instance_id = aws_utils.run_instances_by_name(aws_profile_name, image_type, image_name, count=1)[0] print(f'Instance id: {instance_id}') print(f'Image_id: {ec2_ami_id}') request.addfinalizer( functools.partial(aws_utils.terminate_instance, (aws_profile_name, instance_id))) # Add AWS account to cloudigrade arn = aws_profile['arn'] client = api.ClientV2() acct_data_params = { 'account_arn': arn, 'name': uuid4(), 'cloud_type': 'aws', } # Create an account add_acct_response = client.request('post', 'accounts/', data=acct_data_params) assert add_acct_response.status_code == 201 # Validate that started instance is in cloudigrade acct_id = add_acct_response.json()['account_id'] acct_image = client.request('get', f'accounts/{acct_id}/') arn = acct_image.json()['content_object']['account_arn'] instances = _get_object_with_timeout( client, 'instances/', MEDIUM_TIMEOUT, ) assert _get_instance_id_with_ec2_instance_id(instance_id, instances) is \ not None images = _get_object_with_timeout(client, 'images/', MEDIUM_TIMEOUT) assert _image_id_with_ec2_image_id(ec2_ami_id, images) is not None
def test_create_cloud_account(cloudtrails_to_delete, aws_profile, request): """Ensure cloud accounts can be registered to a user. :id: bb8fa2a4-7ff7-43e6-affb-7a2dedaaab74 :description: Ensure a user can create a cloud account. :steps: 1) Log in as a user. 2) Send POST with the cloud account's information to 'api/v2/account/' 3) Send a GET to 'api/v2/account/' to get a list of the cloud accounts 4) Run an instance in that account 5) Check that Cloudigrade and AWS both show same instance_id 6) Delete account 7) Check instance in AWS :expectedresults: The server returns a 201 response with the information of the created account. Cloudigrade and AWS both show same instance_id. Delete account response returns status 204. After deletion, AWS instance_id.state is 'terminated'. """ account_id = 0 arn = aws_profile['arn'] client = api.ClientV2() acct_data_params = { 'account_arn': arn, 'name': uuid4(), 'cloud_type': 'aws', } delete_preexisting_accounts(aws_profile) # POST # Create an account add_acct_response = client.request('post', 'accounts/', data=acct_data_params) assert add_acct_response.status_code == 201 # Check AWS permissions acct_details = add_acct_response.json() permission = acct_details['content_object']['account_arn'] assert 'allow-dev11-cloudigrade-metering' in permission # Start AWS session and cloudtrail client session = aws_utils.aws_session('DEV07CUSTOMER') env_bucket_name = config.get_config()['openshift_prefix'].strip( 'c-review-') aws_cloudtrails = session.client( 'cloudtrail').describe_trails()['trailList'] aws_cloudtrail_found = False aws_cloudtrail_arn = '' cloudtrails_client = session.client('cloudtrail') # Find the cloudtrail for this particular account and check that # it's enabled. for trail in aws_cloudtrails: if env_bucket_name in trail['S3BucketName']: aws_cloudtrail_found = True aws_cloudtrail_arn = trail['TrailARN'] assert aws_cloudtrail_found is True trail_status = cloudtrails_client.get_trail_status(Name=aws_cloudtrail_arn) assert trail_status['IsLogging'] is True # Find the recently added account so we can delete it accounts = fetch_api_accounts() for acct in accounts: if acct['content_object']['account_arn'] == arn: account_id = acct['account_id'] # DELETE # Delete that account endpoint = f'accounts/{account_id}/' delete_acct_response = client.request('delete', endpoint) assert delete_acct_response.status_code == 204 # Check that deleted account is no longer present in cloudigrade accounts = fetch_api_accounts() assert account_id not in accounts # Check that the cloudtrail has been disabled trail_status = cloudtrails_client.get_trail_status(Name=aws_cloudtrail_arn) assert trail_status['IsLogging'] is False # Cleanup: Remove cloudtrail from AWS cloudtrails_to_delete.append( (aws_profile['name'], aws_profile['cloudtrail_name']))