def test_create_new_machine_images_with_windows_image(self): """Test that new windows machine images are marked appropriately.""" aws_account_id = util_helper.generate_dummy_aws_account_id() arn = util_helper.generate_dummy_arn(aws_account_id) api_helper.generate_cloud_account(arn=arn, aws_account_id=aws_account_id) region = util_helper.get_random_region() instances_data = { region: [ util_helper.generate_dummy_describe_instance( state=aws.InstanceState.running) ] } instances_data[region][0]["Platform"] = "Windows" ami_id = instances_data[region][0]["ImageId"] mock_session = Mock() described_amis = util_helper.generate_dummy_describe_image( image_id=ami_id, owner_id=aws_account_id) with patch.object(util.aws, "describe_images") as mock_describe_images: mock_describe_images.return_value = [described_amis] result = util.create_new_machine_images(mock_session, instances_data) mock_describe_images.assert_called_with(mock_session, {ami_id}, region) self.assertEqual(result, [ami_id]) images = list(AwsMachineImage.objects.all()) self.assertEqual(len(images), 1) self.assertEqual(images[0].ec2_ami_id, ami_id) self.assertEqual(images[0].platform, AwsMachineImage.WINDOWS)
def test_enabled_task_missing(self): """Enabled clounts get a task.""" account_helper.generate_cloud_account(generate_verify_task=False) self.assertEqual(AwsCloudAccount.objects.all().count(), 1) self.assertEqual( PeriodicTask.objects.filter( task="api.clouds.aws.tasks.verify_account_permissions").count( ), 0, ) with self.assertLogs("api.clouds.aws.tasks", level="INFO") as cm: verify_verify_tasks() self.assertEqual(len(cm.records), 1) self.assertEqual(cm.records[0].levelname, "ERROR") self.assertIn( "enabled, but missing verification task. Creating.", cm.records[0].message, ) self.assertEqual(AwsCloudAccount.objects.all().count(), 1) self.assertEqual( PeriodicTask.objects.filter( task="api.clouds.aws.tasks.verify_account_permissions").count( ), 1, ) self.assertEqual( AwsCloudAccount.objects.all().first().verify_task_id, PeriodicTask.objects.filter( task="api.clouds.aws.tasks.verify_account_permissions").first( ).id, )
def setUp(self): """Set up a bunch of test data.""" self.user1 = util_helper.generate_test_user() self.user2 = util_helper.generate_test_user() self.account1 = api_helper.generate_cloud_account(user=self.user1) self.account2 = api_helper.generate_cloud_account(user=self.user2) self.image_plain = api_helper.generate_image() self.image_windows = api_helper.generate_image(is_windows=True) self.image_rhel = api_helper.generate_image(rhel_detected=True) self.image_ocp = api_helper.generate_image(openshift_detected=True) self.instance1 = api_helper.generate_instance( cloud_account=self.account1, image=self.image_plain ) self.instance2 = api_helper.generate_instance( cloud_account=self.account1, image=self.image_windows ) self.instance3 = api_helper.generate_instance( cloud_account=self.account1, image=self.image_rhel ) self.instance4 = api_helper.generate_instance( cloud_account=self.account1, image=self.image_ocp )
def setUp(self): """ Set up a bunch of test data. This gets very noisy very quickly because we need users who have accounts that have instances that have events that used various image types. """ # Users self.user1 = util_helper.generate_test_user() self.user2 = util_helper.generate_test_user() # Accounts for the users self.account_u1_1 = api_helper.generate_cloud_account(user=self.user1) self.account_u1_2 = api_helper.generate_cloud_account(user=self.user1) self.account_u2_1 = api_helper.generate_cloud_account(user=self.user2) self.account_u2_2 = api_helper.generate_cloud_account(user=self.user2) # Images with various contents self.image_plain = api_helper.generate_image() self.image_windows = api_helper.generate_image(is_windows=True) self.image_rhel = api_helper.generate_image(rhel_detected=True) self.image_ocp = api_helper.generate_image(openshift_detected=True, architecture="arm64") self.image_rhel_ocp = api_helper.generate_image( rhel_detected=True, openshift_detected=True, status=MachineImage.UNAVAILABLE) self.inspected_image = api_helper.generate_image( status=MachineImage.INSPECTED) # Instances for the accounts self.instance_u1_1 = api_helper.generate_instance( cloud_account=self.account_u1_1, image=self.image_plain) self.instance_u1_2 = api_helper.generate_instance( cloud_account=self.account_u1_2, image=self.image_rhel) self.instance_u2_1 = api_helper.generate_instance( cloud_account=self.account_u2_1, image=self.image_ocp) self.instance_u2_2 = api_helper.generate_instance( cloud_account=self.account_u2_2, image=self.image_rhel_ocp) # Some initial event activity spread across the accounts powered_times = (( util_helper.utc_dt(2018, 1, 9, 0, 0, 0), util_helper.utc_dt(2018, 1, 10, 0, 0, 0), ), ) instance_images = ( (self.instance_u1_1, self.image_plain), (self.instance_u1_2, self.image_rhel), (self.instance_u2_1, self.image_ocp), (self.instance_u2_2, self.image_rhel_ocp), ) for instance, image in instance_images: self.generate_events(powered_times, instance, image) self.factory = APIRequestFactory()
def test_delete_inactive_users_ignores_users_with_cloudaccount(self): """Test delete_inactive_users ignores Users having any CloudAccount.""" age = settings.DELETE_INACTIVE_USERS_MIN_AGE + 10 old_date = misc.get_now() - timedelta(seconds=age) for account_number in range(1, USERS_COUNT + 1): user = User.objects.create_user(account_number, date_joined=old_date) api_helper.generate_cloud_account(user=user) self.assertEqual(User.objects.count(), USERS_COUNT) self.assertEqual(CloudAccount.objects.count(), USERS_COUNT) tasks.delete_inactive_users() self.assertEqual(User.objects.count(), USERS_COUNT)
def test_save_with_concurrent_usages(self): """Test that save deletes the related concurrent_usages.""" user = util_helper.generate_test_user() aws_account_id = util_helper.generate_dummy_aws_account_id() account = api_helper.generate_cloud_account( aws_account_id=aws_account_id, user=user, ) image = api_helper.generate_image( owner_aws_account_id=aws_account_id, rhel_detected=True, ) instance = api_helper.generate_instance(account, image=image) api_helper.generate_single_run( instance, ( util_helper.utc_dt(2019, 5, 1, 1, 0, 0), util_helper.utc_dt(2019, 5, 1, 2, 0, 0), ), image=instance.machine_image, ) request_date = datetime.date(2019, 5, 1) calculate_max_concurrent_usage(request_date, user_id=user.id) self.assertEquals(1, ConcurrentUsage.objects.count()) image.rhel_detected_by_tag = True image.save() self.assertEquals(0, ConcurrentUsage.objects.count())
def setUp(self): """Set up shared variables.""" self.authentication_id = _faker.pyint() self.account_id = util_helper.generate_dummy_aws_account_id() self.arn = util_helper.generate_dummy_arn(account_id=self.account_id) self.clount = api_helper.generate_cloud_account( arn=self.arn, platform_authentication_id=self.authentication_id) self.username = _faker.user_name() self.application_id = _faker.pyint() self.source_id = _faker.pyint() self.account_number = str(_faker.pyint()) self.auth_return_value = { "username": self.arn, "resource_type": settings.SOURCES_RESOURCE_TYPE, "resource_id": self.application_id, "id": self.authentication_id, "authtype": settings.SOURCES_CLOUDMETER_ARN_AUTHTYPE, } self.app_return_value = { "source_id": self.source_id, "id": self.application_id, }
def setUp(self): """Set up test models.""" aws_account_id = util_helper.generate_dummy_aws_account_id() arn = util_helper.generate_dummy_arn(account_id=aws_account_id) self.role = util_helper.generate_dummy_role() self.account = helper.generate_cloud_account( arn=arn, aws_account_id=aws_account_id, name="test")
def test_generate_aws_events_with_args_and_some_times(self): """Assert generation of InstanceEvents with all specified args.""" account = helper.generate_cloud_account() ec2_ami_id = util_helper.generate_dummy_image_id() image = helper.generate_image(ec2_ami_id=ec2_ami_id) instance = helper.generate_instance(account, image=image) powered_times = ( (None, util_helper.utc_dt(2017, 1, 1)), (util_helper.utc_dt(2017, 1, 2), util_helper.utc_dt(2017, 1, 3)), (util_helper.utc_dt(2017, 1, 4), None), ) instance_type = util_helper.get_random_instance_type() subnet = str(uuid.uuid4()) events = helper.generate_instance_events( instance, powered_times, instance_type=instance_type, subnet=subnet, ) self.assertEqual(len(events), 4) # We don't care to check *everything* in the events since that should # already be covered by ``test_generate_events_with_some_times``. # Here we only care that argument values were set correctly. for event in events: if event.event_type != event.TYPE.power_off: self.assertEqual( event.instance.machine_image.content_object.ec2_ami_id, ec2_ami_id ) self.assertEqual(event.content_object.instance_type, instance_type) self.assertEqual(event.content_object.subnet, subnet)
def setUp(self): """Set up commonly used data for each test.""" # various images not belonging to any particular cloud account self.image_plain = api_helper.generate_image() self.image_rhel = api_helper.generate_image(rhel_detected=True) self.image_ocp = api_helper.generate_image(openshift_detected=True) # define users self.user_1 = util_helper.generate_test_user() self.user_2 = util_helper.generate_test_user() self.user_super = util_helper.generate_test_user(is_superuser=True) # define users' cloud accounts self.account_1 = api_helper.generate_cloud_account(user=self.user_1, name=_faker.bs()) # define instances that belong to user_1 account_1 self.instance_plain = api_helper.generate_instance( cloud_account=self.account_1, image=self.image_plain) self.instance_rhel = api_helper.generate_instance( cloud_account=self.account_1, image=self.image_rhel) self.instance_ocp = api_helper.generate_instance( cloud_account=self.account_1, image=self.image_ocp) self.instance_noimage = api_helper.generate_instance( cloud_account=self.account_1, no_image=True) api_helper.generate_instance_type_definitions()
def test_save_instance_with_available_image(self): """Test that save instance events also writes image on instance.""" aws_account_id = util_helper.generate_dummy_aws_account_id() arn = util_helper.generate_dummy_arn(aws_account_id) account = api_helper.generate_cloud_account( arn=arn, aws_account_id=aws_account_id) region = util_helper.get_random_region() instances_data = { region: [ util_helper.generate_dummy_describe_instance( state=aws.InstanceState.running) ] } ami_id = instances_data[region][0]["ImageId"] mock_session = Mock() described_amis = util_helper.generate_dummy_describe_image( image_id=ami_id, owner_id=aws_account_id) with patch.object(util.aws, "describe_images") as mock_describe_images: mock_describe_images.return_value = [described_amis] util.create_new_machine_images(mock_session, instances_data) mock_describe_images.assert_called_with(mock_session, {ami_id}, region) awsinstance = util.save_instance(account, instances_data[region][0], region) instance = awsinstance.instance.get() self.assertEqual(instance.machine_image.content_object.ec2_ami_id, ami_id) self.assertEqual(instance.machine_image.status, MachineImage.PENDING)
def setUp(self): """Set up common variables for tests.""" self.user = util_helper.generate_test_user() self.aws_account_id = util_helper.generate_dummy_aws_account_id() self.account = api_helper.generate_cloud_account( aws_account_id=self.aws_account_id, user=self.user) self.arn = util_helper.generate_dummy_arn( account_id=self.aws_account_id)
def test_delete_clount_doesnt_delete_user_for_two_clounts( self, mock_notify_source): """Test User is not deleted if it has more clounts left.""" user = util_helper.generate_test_user() username = user.username aws_account_id = util_helper.generate_dummy_aws_account_id() account = api_helper.generate_cloud_account( aws_account_id=aws_account_id, user=user, ) aws_account_id2 = util_helper.generate_dummy_aws_account_id() api_helper.generate_cloud_account( aws_account_id=aws_account_id2, user=user, ) account.delete() self.assertTrue(User.objects.filter(username=username).exists())
def test_generate_azure_events_default_and_no_times(self): """Assert generation of an azure InstanceEvent.""" account = helper.generate_cloud_account(cloud_type="azure") instance = helper.generate_instance(account, cloud_type="azure") events = helper.generate_instance_events(instance, tuple(), cloud_type="azure") self.assertEqual(len(events), 0)
def test_get_noun(self): """Assert "get" requests work.""" client = helper.SandboxedRestClient() client._force_authenticate(self.user) account = helper.generate_cloud_account(user=self.user) response = client.get_accounts(account.id) self.assertEqual(response.status_code, http.HTTPStatus.OK) response_json = response.json() self.assertEqual(response_json["account_id"], account.id)
def setUp(self): """Set up an AwsCloudAccount for relevant events.""" self.user = util_helper.generate_test_user() self.aws_account_id = util_helper.generate_dummy_aws_account_id() self.account = api_helper.generate_cloud_account( aws_account_id=self.aws_account_id, user=self.user, created_at=util_helper.utc_dt(2017, 12, 1, 0, 0, 0), )
def test_generate_azure_instance_default(self): """Assert generation of an Instance with minimal args.""" account = helper.generate_cloud_account(cloud_type="azure") instance = helper.generate_instance(account, cloud_type="azure") self.assertIsInstance(instance, Instance) self.assertEqual(instance.cloud_account, account) self.assertIsNotNone(instance.content_object.resource_id) self.assertIsNotNone(instance.content_object.region) self.assertGreater(len(instance.content_object.region), 0)
def test_copy_ami_snapshot_success_with_reference(self, mock_aws): """Assert the snapshot copy task succeeds using a reference AMI ID.""" mock_session = mock_aws.boto3.Session.return_value mock_account_id = mock_aws.get_session_account_id.return_value account = account_helper.generate_cloud_account() arn = account.content_object.account_arn region = util_helper.get_random_region() new_image_id = util_helper.generate_dummy_image_id() # unlike non-reference calls to copy_ami_snapshot, we do NOT want to # call "account_helper.generate_aws_image(ec2_ami_id=new_image_id)" # here because cloudigrade has only seen the reference, not the new. mock_image = util_helper.generate_mock_image(new_image_id) block_mapping = mock_image.block_device_mappings mock_snapshot_id = block_mapping[0]["Ebs"]["SnapshotId"] mock_snapshot = util_helper.generate_mock_snapshot( mock_snapshot_id, owner_id=mock_account_id) mock_new_snapshot_id = util_helper.generate_dummy_snapshot_id() # This is the original ID of a private/shared image. # It would have been saved to our DB upon initial discovery. reference_image = account_helper.generate_image() reference_image_id = reference_image.content_object.ec2_ami_id mock_aws.get_session.return_value = mock_session mock_aws.get_ami.return_value = mock_image mock_aws.get_ami_snapshot_id.return_value = mock_snapshot_id mock_aws.get_snapshot.return_value = mock_snapshot mock_aws.copy_snapshot.return_value = mock_new_snapshot_id with patch.object(tasks.imageprep, "create_volume") as mock_create_volume, patch.object( tasks.imageprep, "remove_snapshot_ownership" ) as mock_remove_snapshot_ownership: tasks.copy_ami_snapshot(arn, new_image_id, region, reference_image_id) # arn, customer_snapshot_id, snapshot_region, snapshot_copy_id mock_remove_snapshot_ownership.delay.assert_called_with( arn, mock_snapshot_id, region, mock_new_snapshot_id) mock_create_volume.delay.assert_called_with( reference_image_id, mock_new_snapshot_id) mock_aws.get_session.assert_called_with(arn) mock_aws.get_ami.assert_called_with(mock_session, new_image_id, region) mock_aws.get_ami_snapshot_id.assert_called_with(mock_image) mock_aws.add_snapshot_ownership.assert_called_with(mock_snapshot) mock_aws.copy_snapshot.assert_called_with(mock_snapshot_id, region) # Verify that the copy object was stored correctly to reference later. copied_image = AwsMachineImageCopy.objects.get(ec2_ami_id=new_image_id) self.assertIsNotNone(copied_image) self.assertEqual( copied_image.reference_awsmachineimage.ec2_ami_id, reference_image_id, )
def setUp(self): """Set up common variables for tests.""" self.user = util_helper.generate_test_user() self.aws_account_id = util_helper.generate_dummy_aws_account_id() self.account = api_helper.generate_cloud_account( aws_account_id=self.aws_account_id, user=self.user, created_at=util_helper.utc_dt(2017, 12, 1, 0, 0, 0), ) api_helper.generate_instance_type_definitions()
def test_generate_aws_account_with_args(self): """Assert generation of an AwsAccount with all specified args.""" aws_account_id = util_helper.generate_dummy_aws_account_id() arn = util_helper.generate_dummy_arn(account_id=aws_account_id) user = util_helper.generate_test_user() name = _faker.name() created_at = util_helper.utc_dt(2017, 1, 1, 0, 0, 0) platform_authentication_id = _faker.pyint() platform_application_id = _faker.pyint() platform_source_id = _faker.pyint() is_enabled = False enabled_at = util_helper.utc_dt(2017, 1, 2, 0, 0, 0) schedule, _ = IntervalSchedule.objects.get_or_create( every=settings.SCHEDULE_VERIFY_VERIFY_TASKS_INTERVAL, period=IntervalSchedule.SECONDS, ) verify_task, _ = PeriodicTask.objects.get_or_create( interval=schedule, name=f"Verify {arn}.", task="api.clouds.aws.tasks.verify_account_permissions", kwargs=json.dumps( { "account_arn": arn, } ), defaults={"start_time": created_at}, ) account = helper.generate_cloud_account( arn, aws_account_id, user, name, created_at, platform_authentication_id, platform_application_id, platform_source_id, is_enabled, enabled_at, verify_task, ) self.assertIsInstance(account, CloudAccount) self.assertEqual(account.content_object.account_arn, arn) self.assertEqual(account.content_object.aws_account_id, aws_account_id) self.assertEqual(account.platform_authentication_id, platform_authentication_id) self.assertEqual(account.platform_application_id, platform_application_id) self.assertEqual(account.platform_source_id, platform_source_id) self.assertEqual(account.user, user) self.assertEqual(account.name, name) self.assertEqual(account.created_at, created_at) self.assertFalse(account.is_enabled) self.assertEqual(account.enabled_at, enabled_at) self.assertEqual(account.content_object.verify_task, verify_task)
def setUp(self): """Set up a bunch of test data.""" self.user1 = util_helper.generate_test_user() self.user1.date_joined = util_helper.utc_dt(2019, 1, 1, 0, 0, 0) self.user1.save() self.account1 = api_helper.generate_cloud_account(user=self.user1) self.account2 = api_helper.generate_cloud_account(user=self.user1) self.image1_rhel = api_helper.generate_image( rhel_detected=True, rhel_version="7.7", syspurpose={"role": "potato"}, ) self.image2_rhel = api_helper.generate_image(rhel_detected=True) self.instance1 = api_helper.generate_instance(self.account1, image=self.image1_rhel) self.instance2 = api_helper.generate_instance(self.account1, image=self.image2_rhel) self.instance_type1 = "c5.xlarge" # 4 vcpu and 8.0 memory self.factory = APIRequestFactory() self.faker = faker.Faker()
def setUp(self): """Set up a bunch shared test data.""" self.user = util_helper.generate_test_user() source_id = _faker.pyint() self.account = api_helper.generate_cloud_account( user=self.user, platform_authentication_id=_faker.pyint(), platform_application_id=_faker.pyint(), platform_source_id=source_id, is_enabled=False, ) self.account2 = api_helper.generate_cloud_account( user=self.user, platform_authentication_id=_faker.pyint(), platform_application_id=_faker.pyint(), platform_source_id=source_id, is_enabled=False, ) self.factory = APIRequestFactory()
def test_update_aws_clount_different_aws_account_id_fails_arn_already_exists( self, mock_enable, mock_disable, mock_notify_sources, mock_notify_error, ): """Test update_aws_cloud_account fails for duplicate arn.""" aws_account_id2 = util_helper.generate_dummy_aws_account_id() arn2 = util_helper.generate_dummy_arn(account_id=aws_account_id2) api_helper.generate_cloud_account( arn=arn2, aws_account_id=aws_account_id2, ) util.update_aws_cloud_account(self.clount, arn2, self.account_number, self.auth_id, self.source_id) mock_notify_error.assert_called()
def setUp(self): """Set up basic aws account.""" self.account = helper.generate_cloud_account() self.image = helper.generate_image() self.instance = helper.generate_instance(cloud_account=self.account, image=self.image) self.instance_without_image = helper.generate_instance( cloud_account=self.account, no_image=True, )
def test_delete_clount_deletes_user(self, mock_notify_sources): """Test User is deleted if last clount is deleted.""" user = util_helper.generate_test_user() username = user.username aws_account_id = util_helper.generate_dummy_aws_account_id() account = api_helper.generate_cloud_account( aws_account_id=aws_account_id, user=user, ) account.delete() self.assertFalse(User.objects.filter(username=username).exists())
def setUp(self): """Set up data for an account with a running instance.""" self.account = account_helper.generate_cloud_account() self.instance = account_helper.generate_instance(self.account) self.aws_instance = self.instance.content_object self.region = self.aws_instance.region self.power_on_time = util_helper.utc_dt(2018, 1, 1, 0, 0, 0) self.power_off_time = util_helper.utc_dt(2019, 1, 1, 0, 0, 0) event = account_helper.generate_single_instance_event( self.instance, self.power_on_time, event_type=InstanceEvent.TYPE.power_on) self.process_event(event)
def setUp(self): """Set up common variables for tests.""" self.application_id = _faker.pyint() self.application_authentication_id = _faker.pyint() self.authentication_id = _faker.pyint() self.source_id = _faker.pyint() self.account = api_helper.generate_cloud_account( platform_authentication_id=self.authentication_id, platform_application_id=self.application_id, platform_source_id=self.source_id, ) self.user = self.account.user
def setUp(self): """Set up basic aws account.""" self.created_at = util_helper.utc_dt(2019, 1, 1, 0, 0, 0) aws_account_id = util_helper.generate_dummy_aws_account_id() arn = util_helper.generate_dummy_arn(account_id=aws_account_id) self.role = util_helper.generate_dummy_role() self.account = helper.generate_cloud_account( arn=arn, aws_account_id=aws_account_id, name="test", created_at=self.created_at, generate_verify_task=False, )
def test_noop(self): """No tasks need creation or cleaning up.""" account_helper.generate_cloud_account(generate_verify_task=True) aws_clount_before_count = AwsCloudAccount.objects.filter( verify_task_id__isnull=False).count() verify_task_before_count = PeriodicTask.objects.filter( task="api.clouds.aws.tasks.verify_account_permissions").count() verify_verify_tasks() self.assertEqual( aws_clount_before_count, AwsCloudAccount.objects.filter( verify_task_id__isnull=False).count(), ) self.assertEqual( verify_task_before_count, PeriodicTask.objects.filter( task="api.clouds.aws.tasks.verify_account_permissions").count( ), )
def test_inspect_pending_images(self): """ Test that only old "pending" images are found and reinspected. Note that we effectively time-travel here to points in the past to create the account, images, and instances. This is necessary because updated_at is automatically set by Django and cannot be manually set, but we need things with specific older updated_at times. """ real_now = get_now() yesterday = real_now - datetime.timedelta(days=1) with clouditardis(yesterday): account = account_helper.generate_cloud_account() image_old_inspected = account_helper.generate_image() image_old_pending = account_helper.generate_image( status=MachineImage.PENDING) # an instance exists using old inspected image. account_helper.generate_instance(cloud_account=account, image=image_old_inspected) # an instance exists using old pending image. instance_old_pending = account_helper.generate_instance( cloud_account=account, image=image_old_pending) # another instance exists using the same old pending image, but the # image should still only be reinspected once regardless of how # many instances used it. account_helper.generate_instance(cloud_account=account, image=image_old_pending) one_hour_ago = real_now - datetime.timedelta(seconds=60 * 60) with clouditardis(one_hour_ago): image_new_inspected = account_helper.generate_image() image_new_pending = account_helper.generate_image( status=MachineImage.PENDING) # an instance exists using new inspected image. account_helper.generate_instance(cloud_account=account, image=image_new_inspected) # an instance exists using new pending image, but it should not # trigger inspection because the image is not old enough. account_helper.generate_instance(cloud_account=account, image=image_new_pending) expected_calls = [ call( account.content_object.account_arn, image_old_pending.content_object.ec2_ami_id, instance_old_pending.content_object.region, ) ] with patch.object(tasks, "start_image_inspection") as mock_start: tasks.inspect_pending_images() mock_start.assert_has_calls(expected_calls, any_order=True)