def test_get_or_create_vpc(self):
        cidr = Mock()
        vpc = Mock()
        vpc_service = Mock()
        vpc_service.find_vpc_for_reservation = Mock(return_value=None)
        vpc_service.create_vpc_for_reservation = Mock(return_value=vpc)

        prepare_conn = PrepareSandboxInfraOperation(
            vpc_service,
            self.sg_serv,
            self.key_pair_serv,
            self.tag_service,
            self.route_table_service,
            self.cancellation_service,
            self.subnet_service,
            self.subnet_waiter,
        )

        result = prepare_conn._get_or_create_vpc(
            cidr=cidr, ec2_session=self.ec2_session, reservation=self.reservation
        )

        vpc_service.find_vpc_for_reservation.assert_called_once_with(
            ec2_session=self.ec2_session, reservation_id=self.reservation.reservation_id
        )

        vpc_service.create_vpc_for_reservation.assert_called_once_with(
            ec2_session=self.ec2_session, reservation=self.reservation, cidr=cidr
        )

        self.assertEqual(vpc, result)
    def test_create_key_pair(self):
        key_pair_service = Mock()
        key_pair_service.load_key_pair_by_name = Mock(return_value=None)
        prepare_conn = PrepareSandboxInfraOperation(
            self.vpc_serv,
            self.sg_serv,
            key_pair_service,
            self.tag_service,
            self.route_table_service,
            self.cancellation_service,
            self.subnet_service,
            self.subnet_waiter,
        )
        key_pair = Mock()
        key_pair_service.create_key_pair = Mock(return_value=key_pair)

        access_key = prepare_conn._get_or_create_key_pair(
            self.ec2_session, self.s3_session, "bucket", "res_id"
        )

        key_pair_service.load_key_pair_by_name.assert_called_once_with(
            s3_session=self.s3_session, bucket_name="bucket", reservation_id="res_id"
        )
        key_pair_service.create_key_pair.assert_called_once_with(
            ec2_session=self.ec2_session,
            s3_session=self.s3_session,
            bucket="bucket",
            reservation_id="res_id",
        )
        self.assertEquals(access_key, key_pair.key_material)
Esempio n. 3
0
    def test_get_or_create_isolated_security_group(self):
        sg_name = Mock()
        sg = Mock()
        vpc = Mock()
        management_sg_id = Mock()
        security_group_service = Mock()
        isolated_sg_name = 'all alone in the watch tower'
        security_group_service.get_security_group_by_name = Mock(
            return_value=None)
        security_group_service.create_security_group = Mock(return_value=sg)
        security_group_service.sandbox_default_sg_name = Mock(
            return_value=sg_name)
        security_group_service.sandbox_isolated_sg_name = Mock(
            return_value=isolated_sg_name)

        prepare_conn = PrepareSandboxInfraOperation(
            self.vpc_serv, security_group_service, self.key_pair_serv,
            self.tag_service, self.route_table_service,
            self.cancellation_service, self.subnet_service, self.subnet_waiter)

        res = prepare_conn._get_or_create_sandbox_isolated_security_group(
            ec2_session=self.ec2_session,
            management_sg_id=management_sg_id,
            reservation=self.reservation,
            vpc=vpc)
        security_group_service.get_security_group_by_name.assert_called_once_with(
            vpc=vpc, name=isolated_sg_name)

        security_group_service.create_security_group.assert_called_once_with(
            ec2_session=self.ec2_session,
            vpc_id=vpc.id,
            security_group_name=isolated_sg_name)
        security_group_service.sandbox_isolated_sg_name.assert_called_once_with(
            self.reservation.reservation_id)
        self.assertEqual(sg, res)
    def setUp(self):
        self.vpc_serv = Mock()
        self.vpc_serv.get_all_internet_gateways = Mock(return_value=[])

        self.sg_serv = Mock()
        self.key_pair_serv = Mock()
        self.ec2_session = Mock()
        self.ec2_client = Mock()
        self.s3_session = Mock()
        self.aws_dm = Mock()
        self.aws_dm.vpc_mode = VpcMode.DYNAMIC
        self.tag_service = Mock()
        self.reservation = Mock()
        self.route_table_service = Mock()
        self.cancellation_service = Mock()
        self.cancellation_context = Mock()
        self.subnet_service = Mock()
        self.subnet_waiter = Mock()
        self.prepare_conn = PrepareSandboxInfraOperation(
            self.vpc_serv,
            self.sg_serv,
            self.key_pair_serv,
            self.tag_service,
            self.route_table_service,
            self.cancellation_service,
            self.subnet_service,
            self.subnet_waiter,
        )
    def test_get_or_create_isolated_security_group(self):
        sg_name = Mock()
        sg = Mock()
        vpc = Mock()
        management_sg_id = Mock()
        security_group_service = Mock()
        isolated_sg_name = 'all alone in the watch tower'
        security_group_service.get_security_group_by_name = Mock(return_value=None)
        security_group_service.create_security_group = Mock(return_value=sg)
        security_group_service.sandbox_default_sg_name = Mock(return_value=sg_name)
        security_group_service.sandbox_isolated_sg_name = Mock(return_value=isolated_sg_name)

        prepare_conn = PrepareSandboxInfraOperation(self.vpc_serv, security_group_service, self.key_pair_serv,
                                                    self.tag_service, self.route_table_service,
                                                    self.cancellation_service,
                                                    self.subnet_service, self.subnet_waiter)

        res = prepare_conn._get_or_create_sandbox_isolated_security_group(ec2_session=self.ec2_session,
                                                                          management_sg_id=management_sg_id,
                                                                          reservation=self.reservation,
                                                                          vpc=vpc)
        security_group_service.get_security_group_by_name.assert_called_once_with(vpc=vpc, name=isolated_sg_name)

        security_group_service.create_security_group.assert_called_once_with(ec2_session=self.ec2_session,
                                                                             vpc_id=vpc.id,
                                                                             security_group_name=isolated_sg_name)
        security_group_service.sandbox_isolated_sg_name.assert_called_once_with(self.reservation.reservation_id)
        self.assertEqual(sg, res)
    def test_get_or_create_default_sandbox_security_group(self):
        sg_name = Mock()
        sg = Mock()
        vpc = Mock()
        management_sg_id = Mock()
        isolated_sg = Mock()
        security_group_service = Mock()
        security_group_service.sandbox_default_sg_name = Mock(return_value=sg_name)
        security_group_service.get_security_group_by_name = Mock(return_value=None)
        security_group_service.create_security_group = Mock(return_value=sg)
        security_group_service.set_shared_reservation_security_group_rules = Mock()

        tags = Mock()
        self.tag_service.get_sandbox_default_security_group_tags = Mock(
            return_value=tags
        )

        prepare_conn = PrepareSandboxInfraOperation(
            self.vpc_serv,
            security_group_service,
            self.key_pair_serv,
            self.tag_service,
            self.route_table_service,
            self.cancellation_service,
            self.subnet_service,
            self.subnet_waiter,
        )

        res = prepare_conn._get_or_create_sandbox_default_security_group(
            ec2_session=self.ec2_session,
            management_sg_id=management_sg_id,
            reservation=self.reservation,
            vpc=vpc,
            isolated_sg=isolated_sg,
            need_management_access=True,
        )

        security_group_service.get_security_group_by_name.assert_called_once_with(
            vpc=vpc, name=sg_name
        )
        security_group_service.create_security_group.assert_called_once_with(
            ec2_session=self.ec2_session, vpc_id=vpc.id, security_group_name=sg_name
        )
        self.tag_service.get_sandbox_default_security_group_tags.assert_called_once_with(  # noqa: E501
            name=sg_name, reservation=self.reservation
        )
        self.tag_service.set_ec2_resource_tags.assert_called_once_with(sg, tags)

        security_group_service.set_shared_reservation_security_group_rules.assert_called_once_with(  # noqa: E501
            security_group=sg,
            management_sg_id=management_sg_id,
            isolated_sg=isolated_sg,
            need_management_sg=True,
        )
        self.assertEqual(sg, res)
    def test_create_key_pair(self):
        key_pair_service = Mock()
        key_pair_service.load_key_pair_by_name = Mock(return_value=None)
        prepare_conn = PrepareSandboxInfraOperation(self.vpc_serv, self.sg_serv, key_pair_service, self.tag_service,
                                                    self.route_table_service,
                                                    self.cancellation_service,
                                                    self.subnet_service, self.subnet_waiter)
        key_pair = Mock()
        key_pair_service.create_key_pair = Mock(return_value=key_pair)

        access_key = prepare_conn._get_or_create_key_pair(self.ec2_session, self.s3_session, 'bucket', 'res_id')

        key_pair_service.load_key_pair_by_name.assert_called_once_with(s3_session=self.s3_session, bucket_name='bucket', reservation_id='res_id')
        key_pair_service.create_key_pair.assert_called_once_with(ec2_session=self.ec2_session, s3_session=self.s3_session, bucket='bucket', reservation_id='res_id')
        self.assertEquals(access_key, key_pair.key_material)
Esempio n. 8
0
    def test_get_or_create_security_groups(self):
        sg = Mock()
        vpc = Mock()
        sg_name = Mock()
        isolated_sg = Mock()
        management_sg_id = Mock()
        security_group_service = Mock()
        security_group_service.get_security_group_name = Mock(
            return_value=sg_name)
        security_group_service.get_security_group_by_name = Mock(
            return_value=None)
        security_group_service.create_security_group = Mock(return_value=sg)

        prepare_conn = PrepareSandboxInfraOperation(
            self.vpc_serv, security_group_service, self.key_pair_serv,
            self.tag_service, self.route_table_service,
            self.cancellation_service, self.subnet_service, self.subnet_waiter)

        prepare_conn._get_or_create_sandbox_isolated_security_group = Mock(
            return_value=isolated_sg)

        res = prepare_conn._get_or_create_default_security_groups(
            self.ec2_session, self.reservation, vpc, management_sg_id)

        security_group_service.get_security_group_by_name.assert_called_with(
            vpc=vpc, name=security_group_service.sandbox_default_sg_name())

        security_group_service.create_security_group.assert_called_with(
            ec2_session=self.ec2_session,
            vpc_id=vpc.id,
            security_group_name=security_group_service.sandbox_default_sg_name(
            ))

        self.tag_service.get_sandbox_default_security_group_tags.assert_called_once_with(
            name=security_group_service.sandbox_default_sg_name(),
            reservation=self.reservation)

        security_group_service.set_shared_reservation_security_group_rules.assert_called_once_with(
            security_group=sg,
            management_sg_id=management_sg_id,
            isolated_sg=isolated_sg)
        self.assertEqual(
            [isolated_sg, sg],
            res)  # create two security groups, default and isolated
    def test_get_or_create_default_sandbox_security_group(self):
        sg_name = Mock()
        sg = Mock()
        vpc = Mock()
        management_sg_id = Mock()
        isolated_sg = Mock()
        security_group_service = Mock()
        security_group_service.sandbox_default_sg_name = Mock(return_value=sg_name)
        security_group_service.get_security_group_by_name = Mock(return_value=None)
        security_group_service.create_security_group = Mock(return_value=sg)
        security_group_service.set_shared_reservation_security_group_rules = Mock()

        tags = Mock()
        self.tag_service.get_sandbox_default_security_group_tags = Mock(return_value=tags)

        prepare_conn = PrepareSandboxInfraOperation(self.vpc_serv, security_group_service, self.key_pair_serv,
                                                    self.tag_service, self.route_table_service,
                                                    self.cancellation_service,
                                                    self.subnet_service, self.subnet_waiter)

        res = prepare_conn._get_or_create_sandbox_default_security_group(ec2_session=self.ec2_session,
                                                                         management_sg_id=management_sg_id,
                                                                         reservation=self.reservation,
                                                                         vpc=vpc,
                                                                         isolated_sg=isolated_sg)

        security_group_service.get_security_group_by_name.assert_called_once_with(vpc=vpc, name=sg_name)
        security_group_service.create_security_group.assert_called_once_with(ec2_session=self.ec2_session,
                                                                             vpc_id=vpc.id,
                                                                             security_group_name=sg_name)
        self.tag_service.get_sandbox_default_security_group_tags.assert_called_once_with(name=sg_name,
                                                                                         reservation=self.reservation)
        self.tag_service.set_ec2_resource_tags.assert_called_once_with(sg, tags)

        security_group_service.set_shared_reservation_security_group_rules.assert_called_once_with(security_group=sg,
                                                                                                   management_sg_id=management_sg_id,
                                                                                                   isolated_sg=isolated_sg)
        self.assertEqual(sg, res)
    def test_get_or_create_vpc(self):
        cidr = Mock()
        vpc = Mock()
        vpc_service = Mock()
        vpc_service.find_vpc_for_reservation = Mock(return_value=None)
        vpc_service.create_vpc_for_reservation = Mock(return_value=vpc)

        prepare_conn = PrepareSandboxInfraOperation(vpc_service, self.sg_serv, self.key_pair_serv, self.tag_service,
                                                    self.route_table_service,
                                                    self.cancellation_service,
                                                    self.subnet_service, self.subnet_waiter)

        result = prepare_conn._get_or_create_vpc(cidr=cidr,
                                              ec2_session=self.ec2_session,
                                              reservation=self.reservation)

        vpc_service.find_vpc_for_reservation.assert_called_once_with(ec2_session=self.ec2_session,
                                                                     reservation_id=self.reservation.reservation_id)

        vpc_service.create_vpc_for_reservation.assert_called_once_with(ec2_session=self.ec2_session,
                                                                       reservation=self.reservation,
                                                                       cidr=cidr)

        self.assertEqual(vpc, result)
    def setUp(self):
        self.vpc_serv = Mock()
        self.vpc_serv.get_all_internet_gateways = Mock(return_value=[])

        self.sg_serv = Mock()
        self.key_pair_serv = Mock()
        self.ec2_session = Mock()
        self.ec2_client = Mock()
        self.s3_session = Mock()
        self.aws_dm = Mock()
        self.tag_service = Mock()
        self.reservation = Mock()
        self.route_table_service = Mock()
        self.cancellation_service = Mock()
        self.cancellation_context = Mock()
        self.subnet_service = Mock()
        self.subnet_waiter = Mock()
        self.prepare_conn = PrepareSandboxInfraOperation(self.vpc_serv, self.sg_serv, self.key_pair_serv,
                                                         self.tag_service, self.route_table_service,
                                                         self.cancellation_service,
                                                         self.subnet_service, self.subnet_waiter)
class TestPrepareSandboxInfra(TestCase):
    def setUp(self):
        self.vpc_serv = Mock()
        self.vpc_serv.get_all_internet_gateways = Mock(return_value=[])

        self.sg_serv = Mock()
        self.key_pair_serv = Mock()
        self.ec2_session = Mock()
        self.ec2_client = Mock()
        self.s3_session = Mock()
        self.aws_dm = Mock()
        self.aws_dm.vpc_mode = VpcMode.DYNAMIC
        self.tag_service = Mock()
        self.reservation = Mock()
        self.route_table_service = Mock()
        self.cancellation_service = Mock()
        self.cancellation_context = Mock()
        self.subnet_service = Mock()
        self.subnet_waiter = Mock()
        self.prepare_conn = PrepareSandboxInfraOperation(
            self.vpc_serv,
            self.sg_serv,
            self.key_pair_serv,
            self.tag_service,
            self.route_table_service,
            self.cancellation_service,
            self.subnet_service,
            self.subnet_waiter,
        )

    def test_prepare_conn_must_receive_network_action(self):
        with self.assertRaises(
            Exception, msg="Actions list must contain a PrepareCloudInfraAction."
        ):
            self.prepare_conn.prepare_connectivity(
                ec2_client=self.ec2_client,
                ec2_session=self.ec2_session,
                s3_session=self.s3_session,
                reservation=self.reservation,
                aws_ec2_datamodel=self.aws_dm,
                actions=[PrepareSubnet()],
                cancellation_context=self.cancellation_context,
                logger=Mock(),
            )

    @pytest.mark.skip(reason="skip for now")
    def test_prepare_conn_execute_the_network_action_first(self):
        # Arrage
        actions = []
        prepare_subnet_sub_a = PrepareSubnet()
        prepare_subnet_sub_a.actionId = "SubA"
        prepare_subnet_sub_a.actionParams = PrepareSubnetParams()
        actions.append(prepare_subnet_sub_a)
        prepare_cloud_infra = PrepareCloudInfra()
        prepare_cloud_infra.actionId = "Net"
        prepare_cloud_infra.actionParams = PrepareCloudInfraParams()
        actions.append(prepare_cloud_infra)
        prepare_subnet_sub_b = PrepareSubnet()
        prepare_subnet_sub_b.actionId = "SubB"
        prepare_subnet_sub_b.actionParams = PrepareSubnetParams()
        actions.append(prepare_subnet_sub_b)
        prepare_create_key = CreateKeys()
        prepare_create_key.actionId = "CreateKeys"
        actions.append(prepare_create_key)
        # Act
        results = self.prepare_conn.prepare_connectivity(
            ec2_client=self.ec2_client,
            ec2_session=self.ec2_session,
            s3_session=self.s3_session,
            reservation=self.reservation,
            aws_ec2_datamodel=self.aws_dm,
            actions=actions,
            cancellation_context=self.cancellation_context,
            logger=Mock(),
        )
        # Assert
        self.assertEqual(len(results), 4)
        self.assertEqual(results[0].actionId, "Net")
        self.assertEqual(results[1].actionId, "CreateKeys")
        self.assertEqual(results[2].actionId, "SubA")
        self.assertEqual(results[3].actionId, "SubB")

    @pytest.mark.skip(reason="skip for now")
    def test_prepare_conn_execute_the_subnet_actions(self):
        # Arrage
        actions = []
        prepare_subnet_sub_a = PrepareSubnet()
        prepare_subnet_sub_a.actionId = "SubA"
        prepare_subnet_sub_a.actionParams = PrepareSubnetParams()
        actions.append(prepare_subnet_sub_a)
        prepare_cloud_infra = PrepareCloudInfra()
        prepare_cloud_infra.actionId = "Net"
        prepare_cloud_infra.actionParams = PrepareCloudInfraParams()
        actions.append(prepare_cloud_infra)
        prepare_subnet_sub_b = PrepareSubnet()
        prepare_subnet_sub_b.actionId = "SubB"
        prepare_subnet_sub_b.actionParams = PrepareSubnetParams()
        actions.append(prepare_subnet_sub_b)
        prepare_create_key = CreateKeys()
        prepare_create_key.actionId = "CreateKeys"
        actions.append(prepare_create_key)
        # Act
        with patch(
            "cloudshell.cp.aws.domain.conncetivity.operations.prepare."
            "PrepareSubnetExecutor"
        ) as ctor:
            obj = Mock()
            obj.execute = Mock(return_value=["ResA", "ResB"])
            ctor.return_value = obj
            results = self.prepare_conn.prepare_connectivity(
                ec2_client=self.ec2_client,
                ec2_session=self.ec2_session,
                s3_session=self.s3_session,
                reservation=self.reservation,
                aws_ec2_datamodel=self.aws_dm,
                actions=actions,
                cancellation_context=self.cancellation_context,
                logger=Mock(),
            )
        # Assert
        self.assertEqual(len(results), 4)
        self.assertEqual(results[2], "ResA")
        self.assertEqual(results[3], "ResB")

    @pytest.mark.skip(reason="skip for now")
    def test_prepare_conn_command(self):
        # Arrange
        action = PrepareCloudInfra()
        action.actionId = "1234"
        action.actionParams = PrepareCloudInfraParams()

        action2 = CreateKeys()
        action2.actionId = "123"

        self.vpc_serv.get_peering_connection_by_reservation_id = Mock(return_value=None)
        access_key = Mock()
        self.prepare_conn._get_or_create_key_pair = Mock(return_value=access_key)
        self.route_table_service.get_all_route_tables = Mock(return_value=MagicMock())

        results = self.prepare_conn.prepare_connectivity(
            ec2_client=self.ec2_client,
            ec2_session=self.ec2_session,
            s3_session=self.s3_session,
            reservation=self.reservation,
            aws_ec2_datamodel=self.aws_dm,
            actions=[action, action2],
            cancellation_context=self.cancellation_context,
            logger=Mock(),
        )

        self.assertEqual(results[0].actionId, action.actionId)
        self.assertTrue(results[0].success)
        self.assertEqual(
            results[0].infoMessage, "PrepareCloudInfra finished successfully"
        )
        self.assertEqual(results[0].errorMessage, "")
        self.assertEqual(results[1].actionId, action2.actionId)
        self.assertTrue(results[1].success)
        self.assertEqual(
            results[1].infoMessage, "PrepareCreateKeys finished successfully"
        )
        self.assertEqual(results[1].errorMessage, "")
        self.assertEqual(results[1].accessKey, access_key)
        self.cancellation_service.check_if_cancelled.assert_called()

    @pytest.mark.skip(reason="skip for now")
    def test_prepare_conn_command_no_management_vpc(self):
        request = Mock()
        aws_dm = Mock()
        cancellation_context = Mock()
        aws_dm.aws_management_vpc_id = None
        self.assertRaises(
            ValueError,
            self.prepare_conn.prepare_connectivity,
            self.ec2_client,
            self.ec2_session,
            self.s3_session,
            self.reservation,
            aws_dm,
            request,
            cancellation_context,
            Mock(),
        )

    @pytest.mark.skip(reason="skip for now")
    def test_prepare_conn_error_no_vpc_with_vpc_count(self):
        self.vpc_serv.find_vpc_for_reservation = Mock(return_value=None)

        vpc_count = 50
        self.vpc_serv.get_active_vpcs_count = Mock(return_value=vpc_count)

        # Arrage
        actions = []
        prepare_subnet_sub_a = PrepareSubnet()
        prepare_subnet_sub_a.actionId = "SubA"
        prepare_subnet_sub_a.actionParams = PrepareSubnetParams()
        actions.append(prepare_subnet_sub_a)
        prepare_cloud_infra = PrepareCloudInfra()
        prepare_cloud_infra.actionId = "Net"
        prepare_cloud_infra.actionParams = PrepareCloudInfraParams()
        actions.append(prepare_cloud_infra)
        prepare_subnet_sub_b = PrepareSubnet()
        prepare_subnet_sub_b.actionId = "SubB"
        prepare_subnet_sub_b.actionParams = PrepareSubnetParams()
        actions.append(prepare_subnet_sub_b)
        prepare_create_key = CreateKeys()
        prepare_create_key.actionId = "CreateKeys"
        actions.append(prepare_create_key)

        # Assert
        self.assertRaisesRegexp(
            ValueError,
            f"(/{vpc_count}/)|(limit.$)",
            self.prepare_conn.prepare_connectivity,
            ec2_client=self.ec2_client,
            ec2_session=self.ec2_session,
            s3_session=self.s3_session,
            reservation=self.reservation,
            aws_ec2_datamodel=self.aws_dm,
            actions=actions,
            cancellation_context=self.cancellation_context,
            logger=Mock(),
        )

    @pytest.mark.skip(reason="skip for now")
    def test_prepare_conn_error_no_vpc(self):
        self.vpc_serv.find_vpc_for_reservation = Mock(return_value=None)
        self.vpc_serv.get_active_vpcs_count = Mock(return_value=None)

        # Arrage
        actions = []
        prepare_subnet_sub_a = PrepareSubnet()
        prepare_subnet_sub_a.actionId = "SubA"
        prepare_subnet_sub_a.actionParams = PrepareSubnetParams()
        actions.append(prepare_subnet_sub_a)
        prepare_cloud_infra = PrepareCloudInfra()
        prepare_cloud_infra.actionId = "Net"
        prepare_cloud_infra.actionParams = PrepareCloudInfraParams()
        actions.append(prepare_cloud_infra)
        prepare_subnet_sub_b = PrepareSubnet()
        prepare_subnet_sub_b.actionId = "SubB"
        prepare_subnet_sub_b.actionParams = PrepareSubnetParams()
        actions.append(prepare_subnet_sub_b)

        # Assert
        self.assertRaisesRegexp(
            ValueError,
            "^((?!limit).)*$",
            self.prepare_conn.prepare_connectivity,
            ec2_client=self.ec2_client,
            ec2_session=self.ec2_session,
            s3_session=self.s3_session,
            reservation=self.reservation,
            aws_ec2_datamodel=self.aws_dm,
            actions=actions,
            cancellation_context=self.cancellation_context,
            logger=Mock(),
        )

    @pytest.mark.skip(reason="skip for now")
    def test_prepare_conn_command_fault_res(self):
        self.aws_dm.is_static_vpc_mode = False

        action = PrepareCloudInfra()
        action.actionId = "1234"
        action.actionParams = PrepareCloudInfraParams()
        action.actionParams.cidr = "1.2.3.4/24"
        action2 = CreateKeys()
        action2.actionId = "123"
        cancellation_context = Mock()

        results = self.prepare_conn.prepare_connectivity(
            ec2_client=self.ec2_client,
            ec2_session=self.ec2_session,
            s3_session=self.s3_session,
            reservation=self.reservation,
            aws_ec2_datamodel=self.aws_dm,
            actions=[action, action2],
            cancellation_context=cancellation_context,
            logger=Mock(),
        )

        self.assertFalse(results[0].success)
        self.assertEqual(results[0].infoMessage, "")
        self.assertIsNotNone(results[0].errorMessage)

    def test_create_key_pair(self):
        key_pair_service = Mock()
        key_pair_service.load_key_pair_by_name = Mock(return_value=None)
        prepare_conn = PrepareSandboxInfraOperation(
            self.vpc_serv,
            self.sg_serv,
            key_pair_service,
            self.tag_service,
            self.route_table_service,
            self.cancellation_service,
            self.subnet_service,
            self.subnet_waiter,
        )
        key_pair = Mock()
        key_pair_service.create_key_pair = Mock(return_value=key_pair)

        access_key = prepare_conn._get_or_create_key_pair(
            self.ec2_session, self.s3_session, "bucket", "res_id"
        )

        key_pair_service.load_key_pair_by_name.assert_called_once_with(
            s3_session=self.s3_session, bucket_name="bucket", reservation_id="res_id"
        )
        key_pair_service.create_key_pair.assert_called_once_with(
            ec2_session=self.ec2_session,
            s3_session=self.s3_session,
            bucket="bucket",
            reservation_id="res_id",
        )
        self.assertEquals(access_key, key_pair.key_material)

    def test_get_or_create_security_groups(self):
        sg = Mock()
        vpc = Mock()
        sg_name = Mock()
        isolated_sg = Mock()
        management_sg_id = Mock()
        security_group_service = Mock()
        security_group_service.get_security_group_name = Mock(return_value=sg_name)
        security_group_service.get_security_group_by_name = Mock(return_value=None)
        security_group_service.create_security_group = Mock(return_value=sg)

        prepare_conn = PrepareSandboxInfraOperation(
            self.vpc_serv,
            security_group_service,
            self.key_pair_serv,
            self.tag_service,
            self.route_table_service,
            self.cancellation_service,
            self.subnet_service,
            self.subnet_waiter,
        )

        prepare_conn._get_or_create_sandbox_isolated_security_group = Mock(
            return_value=isolated_sg
        )

        res = prepare_conn._get_or_create_default_security_groups(
            self.ec2_session, self.reservation, vpc, management_sg_id, True
        )

        security_group_service.get_security_group_by_name.assert_called_with(
            vpc=vpc, name=security_group_service.sandbox_default_sg_name()
        )

        security_group_service.create_security_group.assert_called_with(
            ec2_session=self.ec2_session,
            vpc_id=vpc.id,
            security_group_name=security_group_service.sandbox_default_sg_name(),
        )

        self.tag_service.get_sandbox_default_security_group_tags.assert_called_once_with(  # noqa: E501
            name=security_group_service.sandbox_default_sg_name(),
            reservation=self.reservation,
        )

        security_group_service.set_shared_reservation_security_group_rules.assert_called_once_with(  # noqa: E501
            security_group=sg,
            management_sg_id=management_sg_id,
            isolated_sg=isolated_sg,
            need_management_sg=True,
        )
        self.assertEqual(
            [isolated_sg, sg], res
        )  # create two security groups, default and isolated

    def test_get_or_create_default_sandbox_security_group(self):
        sg_name = Mock()
        sg = Mock()
        vpc = Mock()
        management_sg_id = Mock()
        isolated_sg = Mock()
        security_group_service = Mock()
        security_group_service.sandbox_default_sg_name = Mock(return_value=sg_name)
        security_group_service.get_security_group_by_name = Mock(return_value=None)
        security_group_service.create_security_group = Mock(return_value=sg)
        security_group_service.set_shared_reservation_security_group_rules = Mock()

        tags = Mock()
        self.tag_service.get_sandbox_default_security_group_tags = Mock(
            return_value=tags
        )

        prepare_conn = PrepareSandboxInfraOperation(
            self.vpc_serv,
            security_group_service,
            self.key_pair_serv,
            self.tag_service,
            self.route_table_service,
            self.cancellation_service,
            self.subnet_service,
            self.subnet_waiter,
        )

        res = prepare_conn._get_or_create_sandbox_default_security_group(
            ec2_session=self.ec2_session,
            management_sg_id=management_sg_id,
            reservation=self.reservation,
            vpc=vpc,
            isolated_sg=isolated_sg,
            need_management_access=True,
        )

        security_group_service.get_security_group_by_name.assert_called_once_with(
            vpc=vpc, name=sg_name
        )
        security_group_service.create_security_group.assert_called_once_with(
            ec2_session=self.ec2_session, vpc_id=vpc.id, security_group_name=sg_name
        )
        self.tag_service.get_sandbox_default_security_group_tags.assert_called_once_with(  # noqa: E501
            name=sg_name, reservation=self.reservation
        )
        self.tag_service.set_ec2_resource_tags.assert_called_once_with(sg, tags)

        security_group_service.set_shared_reservation_security_group_rules.assert_called_once_with(  # noqa: E501
            security_group=sg,
            management_sg_id=management_sg_id,
            isolated_sg=isolated_sg,
            need_management_sg=True,
        )
        self.assertEqual(sg, res)

    def test_get_or_create_isolated_security_group(self):
        sg_name = Mock()
        sg = Mock()
        vpc = Mock()
        management_sg_id = Mock()
        security_group_service = Mock()
        isolated_sg_name = "all alone in the watch tower"
        security_group_service.get_security_group_by_name = Mock(return_value=None)
        security_group_service.create_security_group = Mock(return_value=sg)
        security_group_service.sandbox_default_sg_name = Mock(return_value=sg_name)
        security_group_service.sandbox_isolated_sg_name = Mock(
            return_value=isolated_sg_name
        )

        prepare_conn = PrepareSandboxInfraOperation(
            self.vpc_serv,
            security_group_service,
            self.key_pair_serv,
            self.tag_service,
            self.route_table_service,
            self.cancellation_service,
            self.subnet_service,
            self.subnet_waiter,
        )

        res = prepare_conn._get_or_create_sandbox_isolated_security_group(
            ec2_session=self.ec2_session,
            management_sg_id=management_sg_id,
            reservation=self.reservation,
            vpc=vpc,
            need_management_access=True,
        )
        security_group_service.get_security_group_by_name.assert_called_once_with(
            vpc=vpc, name=isolated_sg_name
        )

        security_group_service.create_security_group.assert_called_once_with(
            ec2_session=self.ec2_session,
            vpc_id=vpc.id,
            security_group_name=isolated_sg_name,
        )
        security_group_service.sandbox_isolated_sg_name.assert_called_once_with(
            self.reservation.reservation_id
        )
        self.assertEqual(sg, res)

    @pytest.mark.skip(reason="skip for now")
    def test_get_or_create_vpc(self):
        cidr = Mock()
        vpc = Mock()
        vpc_service = Mock()
        vpc_service.find_vpc_for_reservation = Mock(return_value=None)
        vpc_service.create_vpc_for_reservation = Mock(return_value=vpc)

        prepare_conn = PrepareSandboxInfraOperation(
            vpc_service,
            self.sg_serv,
            self.key_pair_serv,
            self.tag_service,
            self.route_table_service,
            self.cancellation_service,
            self.subnet_service,
            self.subnet_waiter,
        )

        result = prepare_conn._get_or_create_vpc(
            cidr=cidr, ec2_session=self.ec2_session, reservation=self.reservation
        )

        vpc_service.find_vpc_for_reservation.assert_called_once_with(
            ec2_session=self.ec2_session, reservation_id=self.reservation.reservation_id
        )

        vpc_service.create_vpc_for_reservation.assert_called_once_with(
            ec2_session=self.ec2_session, reservation=self.reservation, cidr=cidr
        )

        self.assertEqual(vpc, result)
Esempio n. 13
0
    def __init__(self):
        self.command_result_parser = CommandResultsParser()
        self.cancellation_service = CommandCancellationService()
        self.client_err_wrapper = ClientErrorWrapper()
        self.tag_service = TagService(client_err_wrapper=self.client_err_wrapper)
        self.ec2_instance_waiter = InstanceWaiter(cancellation_service=self.cancellation_service)
        self.instance_service = InstanceService(self.tag_service, self.ec2_instance_waiter)
        self.ec2_storage_service = EC2StorageService()
        self.model_parser = AWSModelsParser()
        self.cloudshell_session_helper = CloudshellDriverHelper()
        self.aws_session_manager = AWSSessionProvider()
        self.password_waiter = PasswordWaiter(self.cancellation_service)
        self.vm_custom_params_extractor = VmCustomParamsExtractor()
        self.ami_credentials_service = InstanceCredentialsService(self.password_waiter)
        self.security_group_service = SecurityGroupService(self.tag_service)
        self.subnet_waiter = SubnetWaiter()
        self.subnet_service = SubnetService(self.tag_service, self.subnet_waiter)
        self.s3_service = S3BucketService()
        self.vpc_peering_waiter = VpcPeeringConnectionWaiter()
        self.key_pair_service = KeyPairService(self.s3_service)
        self.vpc_waiter = VPCWaiter()
        self.route_tables_service = RouteTablesService(self.tag_service)
        self.network_interface_service = NetworkInterfaceService(subnet_service=self.subnet_service)
        self.elastic_ip_service = ElasticIpService()
        self.vm_details_provider = VmDetailsProvider()

        self.vpc_service = VPCService(tag_service=self.tag_service,
                                      subnet_service=self.subnet_service,
                                      instance_service=self.instance_service,
                                      vpc_waiter=self.vpc_waiter,
                                      vpc_peering_waiter=self.vpc_peering_waiter,
                                      sg_service=self.security_group_service,
                                      route_table_service=self.route_tables_service)
        self.prepare_connectivity_operation = \
            PrepareSandboxInfraOperation(vpc_service=self.vpc_service,
                                         security_group_service=self.security_group_service,
                                         key_pair_service=self.key_pair_service,
                                         tag_service=self.tag_service,
                                         route_table_service=self.route_tables_service,
                                         cancellation_service=self.cancellation_service,
                                         subnet_service=self.subnet_service,
                                         subnet_waiter=self.subnet_waiter)

        self.deploy_ami_operation = DeployAMIOperation(instance_service=self.instance_service,
                                                       ami_credential_service=self.ami_credentials_service,
                                                       security_group_service=self.security_group_service,
                                                       tag_service=self.tag_service,
                                                       vpc_service=self.vpc_service,
                                                       key_pair_service=self.key_pair_service,
                                                       subnet_service=self.subnet_service,
                                                       elastic_ip_service=self.elastic_ip_service,
                                                       network_interface_service=self.network_interface_service,
                                                       cancellation_service=self.cancellation_service,
                                                       device_index_strategy=AllocateMissingValuesDeviceIndexStrategy(),
                                                       vm_details_provider=self.vm_details_provider)

        self.refresh_ip_operation = RefreshIpOperation(instance_service=self.instance_service)

        self.power_management_operation = PowerOperation(instance_service=self.instance_service,
                                                         instance_waiter=self.ec2_instance_waiter)

        self.delete_ami_operation = DeleteAMIOperation(instance_service=self.instance_service,
                                                       ec2_storage_service=self.ec2_storage_service,
                                                       security_group_service=self.security_group_service,
                                                       tag_service=self.tag_service,
                                                       elastic_ip_service=self.elastic_ip_service)

        self.clean_up_operation = CleanupSandboxInfraOperation(vpc_service=self.vpc_service,
                                                               key_pair_service=self.key_pair_service,
                                                               route_table_service=self.route_tables_service)

        self.deployed_app_ports_operation = DeployedAppPortsOperation(self.vm_custom_params_extractor,
                                                                      security_group_service=self.security_group_service,
                                                                      instance_service=self.instance_service)

        self.access_key_operation = GetAccessKeyOperation(key_pair_service=self.key_pair_service)

        self.set_app_security_groups_operation = SetAppSecurityGroupsOperation(instance_service=self.instance_service,
                                                                               tag_service=self.tag_service,
                                                                               security_group_service=self.security_group_service)

        self.vm_details_operation = VmDetailsOperation(instance_service=self.instance_service,
                                                       vm_details_provider=self.vm_details_provider)
class TestPrepareSandboxInfra(TestCase):
    def setUp(self):
        self.vpc_serv = Mock()
        self.vpc_serv.get_all_internet_gateways = Mock(return_value=[])

        self.sg_serv = Mock()
        self.key_pair_serv = Mock()
        self.ec2_session = Mock()
        self.ec2_client = Mock()
        self.s3_session = Mock()
        self.aws_dm = Mock()
        self.tag_service = Mock()
        self.reservation = Mock()
        self.route_table_service = Mock()
        self.cancellation_service = Mock()
        self.cancellation_context = Mock()
        self.subnet_service = Mock()
        self.subnet_waiter = Mock()
        self.prepare_conn = PrepareSandboxInfraOperation(self.vpc_serv, self.sg_serv, self.key_pair_serv,
                                                         self.tag_service, self.route_table_service,
                                                         self.cancellation_service,
                                                         self.subnet_service, self.subnet_waiter)

    def test_prepare_conn_must_receive_network_action(self):
        with self.assertRaises(Exception) as error:
            self.prepare_conn.prepare_connectivity(ec2_client=self.ec2_client,
                                                   ec2_session=self.ec2_session,
                                                   s3_session=self.s3_session,
                                                   reservation=self.reservation,
                                                   aws_ec2_datamodel=self.aws_dm,
                                                   actions=[PrepareSubnet()],
                                                   cancellation_context=self.cancellation_context,
                                                   logger=Mock())
        self.assertEqual(error.exception.message, "Actions list must contain a PrepareCloudInfraAction.")

    def test_prepare_conn_execute_the_network_action_first(self):
        # Arrage
        actions = []
        prepare_subnet_sub_a = PrepareSubnet();
        prepare_subnet_sub_a.actionId = "SubA"
        prepare_subnet_sub_a.actionParams = PrepareSubnetParams()
        actions.append(prepare_subnet_sub_a)
        prepare_cloud_infra = PrepareCloudInfra()
        prepare_cloud_infra.actionId = "Net"
        prepare_cloud_infra.actionParams = PrepareCloudInfraParams()
        actions.append(prepare_cloud_infra)
        prepare_subnet_sub_b = PrepareSubnet();
        prepare_subnet_sub_b.actionId = "SubB"
        prepare_subnet_sub_b.actionParams = PrepareSubnetParams()
        actions.append(prepare_subnet_sub_b)
        prepare_create_key = CreateKeys();
        prepare_create_key.actionId = "CreateKeys"
        actions.append(prepare_create_key)
        # Act
        results = self.prepare_conn.prepare_connectivity(ec2_client=self.ec2_client,
                                                         ec2_session=self.ec2_session,
                                                         s3_session=self.s3_session,
                                                         reservation=self.reservation,
                                                         aws_ec2_datamodel=self.aws_dm,
                                                         actions=actions,
                                                         cancellation_context=self.cancellation_context,
                                                         logger=Mock())
        # Assert
        self.assertEqual(len(results), 4)
        self.assertEqual(results[0].actionId, "Net")
        self.assertEqual(results[1].actionId, "CreateKeys")
        self.assertEqual(results[2].actionId, "SubA")
        self.assertEqual(results[3].actionId, "SubB")

    def test_prepare_conn_execute_the_subnet_actions(self):
        # Arrage
        actions = []
        prepare_subnet_sub_a = PrepareSubnet();
        prepare_subnet_sub_a.actionId = "SubA"
        prepare_subnet_sub_a.actionParams = PrepareSubnetParams()
        actions.append(prepare_subnet_sub_a)
        prepare_cloud_infra = PrepareCloudInfra()
        prepare_cloud_infra.actionId = "Net"
        prepare_cloud_infra.actionParams = PrepareCloudInfraParams()
        actions.append(prepare_cloud_infra)
        prepare_subnet_sub_b = PrepareSubnet();
        prepare_subnet_sub_b.actionId = "SubB"
        prepare_subnet_sub_b.actionParams = PrepareSubnetParams()
        actions.append(prepare_subnet_sub_b)
        prepare_create_key = CreateKeys();
        prepare_create_key.actionId = "CreateKeys"
        actions.append(prepare_create_key)
        # Act
        with patch('cloudshell.cp.aws.domain.conncetivity.operations.prepare.PrepareSubnetExecutor') as ctor:
            obj = Mock()
            obj.execute = Mock(return_value=["ResA", "ResB"])
            ctor.return_value = obj
            results = self.prepare_conn.prepare_connectivity(ec2_client=self.ec2_client,
                                                             ec2_session=self.ec2_session,
                                                             s3_session=self.s3_session,
                                                             reservation=self.reservation,
                                                             aws_ec2_datamodel=self.aws_dm,
                                                             actions=actions,
                                                             cancellation_context=self.cancellation_context,
                                                             logger=Mock())
        # Assert
        self.assertEqual(len(results), 4)
        self.assertEqual(results[2], "ResA")
        self.assertEqual(results[3], "ResB")

    def test_prepare_conn_command(self):
        # Arrange
        action = PrepareCloudInfra()
        action.actionId = "1234"
        action.actionParams = PrepareCloudInfraParams()

        action2 = CreateKeys()
        action2.actionId = "123"

        self.vpc_serv.get_peering_connection_by_reservation_id = Mock(return_value=None)
        access_key = Mock()
        self.prepare_conn._get_or_create_key_pair = Mock(return_value=access_key)
        self.route_table_service.get_all_route_tables = Mock(return_value=MagicMock())

        results = self.prepare_conn.prepare_connectivity(ec2_client=self.ec2_client,
                                                         ec2_session=self.ec2_session,
                                                         s3_session=self.s3_session,
                                                         reservation=self.reservation,
                                                         aws_ec2_datamodel=self.aws_dm,
                                                         actions=[action,action2],
                                                         cancellation_context=self.cancellation_context,
                                                         logger=Mock())


        self.assertEqual(results[0].actionId, action.actionId)
        self.assertTrue(results[0].success)
        self.assertEqual(results[0].infoMessage, 'PrepareCloudInfra finished successfully')
        self.assertEqual(results[0].errorMessage, '')
        self.assertEqual(results[1].actionId, action2.actionId)
        self.assertTrue(results[1].success)
        self.assertEqual(results[1].infoMessage, 'PrepareCreateKeys finished successfully')
        self.assertEqual(results[1].errorMessage, '')
        self.assertEqual(results[1].accessKey, access_key)
        self.cancellation_service.check_if_cancelled.assert_called()

    def test_prepare_conn_command_no_management_vpc(self):
        request = Mock()
        aws_dm = Mock()
        cancellation_context = Mock()
        aws_dm.aws_management_vpc_id = None
        self.assertRaises(ValueError,
                          self.prepare_conn.prepare_connectivity,
                          self.ec2_client,
                          self.ec2_session,
                          self.s3_session,
                          self.reservation,
                          aws_dm,
                          request,
                          cancellation_context,
                          Mock())

    def test_prepare_conn_error_no_vpc_with_vpc_count(self):
        self.vpc_serv.find_vpc_for_reservation = Mock(return_value=None)

        vpc_count = 50
        self.vpc_serv.get_active_vpcs_count = Mock(return_value=vpc_count)

        # Arrage
        actions = []
        prepare_subnet_sub_a = PrepareSubnet();
        prepare_subnet_sub_a.actionId = "SubA"
        prepare_subnet_sub_a.actionParams = PrepareSubnetParams()
        actions.append(prepare_subnet_sub_a)
        prepare_cloud_infra = PrepareCloudInfra()
        prepare_cloud_infra.actionId = "Net"
        prepare_cloud_infra.actionParams = PrepareCloudInfraParams()
        actions.append(prepare_cloud_infra)
        prepare_subnet_sub_b = PrepareSubnet();
        prepare_subnet_sub_b.actionId = "SubB"
        prepare_subnet_sub_b.actionParams = PrepareSubnetParams()
        actions.append(prepare_subnet_sub_b)
        prepare_create_key = CreateKeys();
        prepare_create_key.actionId = "CreateKeys"
        actions.append(prepare_create_key)

        # Assert
        self.assertRaisesRegexp(ValueError,
                                '(/{0}/)|(limit.$)'.format(vpc_count),
                                self.prepare_conn.prepare_connectivity,
                                ec2_client=self.ec2_client,
                                ec2_session=self.ec2_session,
                                s3_session=self.s3_session,
                                reservation=self.reservation,
                                aws_ec2_datamodel=self.aws_dm,
                                actions=actions,
                                cancellation_context=self.cancellation_context,
                                logger=Mock())

    def test_prepare_conn_error_no_vpc(self):
        self.vpc_serv.find_vpc_for_reservation = Mock(return_value=None)
        self.vpc_serv.get_active_vpcs_count = Mock(return_value=None)

        # Arrage
        actions = []
        prepare_subnet_sub_a = PrepareSubnet();
        prepare_subnet_sub_a.actionId = "SubA"
        prepare_subnet_sub_a.actionParams = PrepareSubnetParams()
        actions.append(prepare_subnet_sub_a)
        prepare_cloud_infra = PrepareCloudInfra()
        prepare_cloud_infra.actionId = "Net"
        prepare_cloud_infra.actionParams = PrepareCloudInfraParams()
        actions.append(prepare_cloud_infra)
        prepare_subnet_sub_b = PrepareSubnet();
        prepare_subnet_sub_b.actionId = "SubB"
        prepare_subnet_sub_b.actionParams = PrepareSubnetParams()
        actions.append(prepare_subnet_sub_b)

        # Assert
        self.assertRaisesRegexp(ValueError,
                                '^((?!limit).)*$',
                                self.prepare_conn.prepare_connectivity,
                                ec2_client=self.ec2_client,
                                ec2_session=self.ec2_session,
                                s3_session=self.s3_session,
                                reservation=self.reservation,
                                aws_ec2_datamodel=self.aws_dm,
                                actions=actions,
                                cancellation_context=self.cancellation_context,
                                logger=Mock())

    def test_prepare_conn_command_fault_res(self):
        action = PrepareCloudInfra()
        action.actionId="1234"
        action.actionParams = PrepareCloudInfraParams()
        action.actionParams.cidr = "1.2.3.4/24"
        action2 = CreateKeys()
        action2.actionId="123"
        cancellation_context = Mock()

        results = self.prepare_conn.prepare_connectivity(ec2_client=self.ec2_client,
                                                         ec2_session=self.ec2_session,
                                                         s3_session=self.s3_session,
                                                         reservation=self.reservation,
                                                         aws_ec2_datamodel=self.aws_dm,
                                                         actions=[action, action2],
                                                         cancellation_context=cancellation_context,
                                                         logger=Mock())

        self.assertFalse(results[0].success)
        self.assertEqual(results[0].infoMessage, '')
        self.assertIsNotNone(results[0].errorMessage)

    def test_create_key_pair(self):
        key_pair_service = Mock()
        key_pair_service.load_key_pair_by_name = Mock(return_value=None)
        prepare_conn = PrepareSandboxInfraOperation(self.vpc_serv, self.sg_serv, key_pair_service, self.tag_service,
                                                    self.route_table_service,
                                                    self.cancellation_service,
                                                    self.subnet_service, self.subnet_waiter)
        key_pair = Mock()
        key_pair_service.create_key_pair = Mock(return_value=key_pair)

        access_key = prepare_conn._get_or_create_key_pair(self.ec2_session, self.s3_session, 'bucket', 'res_id')

        key_pair_service.load_key_pair_by_name.assert_called_once_with(s3_session=self.s3_session, bucket_name='bucket', reservation_id='res_id')
        key_pair_service.create_key_pair.assert_called_once_with(ec2_session=self.ec2_session, s3_session=self.s3_session, bucket='bucket', reservation_id='res_id')
        self.assertEquals(access_key, key_pair.key_material)

    def test_get_or_create_security_groups(self):
        sg = Mock()
        vpc = Mock()
        sg_name = Mock()
        isolated_sg = Mock()
        management_sg_id = Mock()
        security_group_service = Mock()
        security_group_service.get_security_group_name = Mock(return_value=sg_name)
        security_group_service.get_security_group_by_name = Mock(return_value=None)
        security_group_service.create_security_group = Mock(return_value=sg)


        prepare_conn = PrepareSandboxInfraOperation(self.vpc_serv, security_group_service, self.key_pair_serv,
                                                    self.tag_service, self.route_table_service,
                                                    self.cancellation_service,
                                                    self.subnet_service, self.subnet_waiter)

        prepare_conn._get_or_create_sandbox_isolated_security_group = Mock(return_value=isolated_sg)

        res = prepare_conn._get_or_create_default_security_groups(self.ec2_session, self.reservation, vpc,
                                                                  management_sg_id)

        security_group_service.get_security_group_by_name.assert_called_with(vpc=vpc,
                                                                             name=security_group_service.sandbox_default_sg_name())

        security_group_service.create_security_group.assert_called_with(ec2_session=self.ec2_session,
                                                                             vpc_id=vpc.id,
                                                                             security_group_name=security_group_service.sandbox_default_sg_name())

        self.tag_service.get_sandbox_default_security_group_tags.assert_called_once_with(name=security_group_service.sandbox_default_sg_name(),
                                                                                         reservation=self.reservation)

        security_group_service.set_shared_reservation_security_group_rules.assert_called_once_with(security_group=sg,
                                                                                                   management_sg_id=management_sg_id,
                                                                                                   isolated_sg=isolated_sg)
        self.assertEqual([isolated_sg, sg], res)  # create two security groups, default and isolated

    def test_get_or_create_default_sandbox_security_group(self):
        sg_name = Mock()
        sg = Mock()
        vpc = Mock()
        management_sg_id = Mock()
        isolated_sg = Mock()
        security_group_service = Mock()
        security_group_service.sandbox_default_sg_name = Mock(return_value=sg_name)
        security_group_service.get_security_group_by_name = Mock(return_value=None)
        security_group_service.create_security_group = Mock(return_value=sg)
        security_group_service.set_shared_reservation_security_group_rules = Mock()

        tags = Mock()
        self.tag_service.get_sandbox_default_security_group_tags = Mock(return_value=tags)

        prepare_conn = PrepareSandboxInfraOperation(self.vpc_serv, security_group_service, self.key_pair_serv,
                                                    self.tag_service, self.route_table_service,
                                                    self.cancellation_service,
                                                    self.subnet_service, self.subnet_waiter)

        res = prepare_conn._get_or_create_sandbox_default_security_group(ec2_session=self.ec2_session,
                                                                         management_sg_id=management_sg_id,
                                                                         reservation=self.reservation,
                                                                         vpc=vpc,
                                                                         isolated_sg=isolated_sg)

        security_group_service.get_security_group_by_name.assert_called_once_with(vpc=vpc, name=sg_name)
        security_group_service.create_security_group.assert_called_once_with(ec2_session=self.ec2_session,
                                                                             vpc_id=vpc.id,
                                                                             security_group_name=sg_name)
        self.tag_service.get_sandbox_default_security_group_tags.assert_called_once_with(name=sg_name,
                                                                                         reservation=self.reservation)
        self.tag_service.set_ec2_resource_tags.assert_called_once_with(sg, tags)

        security_group_service.set_shared_reservation_security_group_rules.assert_called_once_with(security_group=sg,
                                                                                                   management_sg_id=management_sg_id,
                                                                                                   isolated_sg=isolated_sg)
        self.assertEqual(sg, res)

    def test_get_or_create_isolated_security_group(self):
        sg_name = Mock()
        sg = Mock()
        vpc = Mock()
        management_sg_id = Mock()
        security_group_service = Mock()
        isolated_sg_name = 'all alone in the watch tower'
        security_group_service.get_security_group_by_name = Mock(return_value=None)
        security_group_service.create_security_group = Mock(return_value=sg)
        security_group_service.sandbox_default_sg_name = Mock(return_value=sg_name)
        security_group_service.sandbox_isolated_sg_name = Mock(return_value=isolated_sg_name)

        prepare_conn = PrepareSandboxInfraOperation(self.vpc_serv, security_group_service, self.key_pair_serv,
                                                    self.tag_service, self.route_table_service,
                                                    self.cancellation_service,
                                                    self.subnet_service, self.subnet_waiter)

        res = prepare_conn._get_or_create_sandbox_isolated_security_group(ec2_session=self.ec2_session,
                                                                          management_sg_id=management_sg_id,
                                                                          reservation=self.reservation,
                                                                          vpc=vpc)
        security_group_service.get_security_group_by_name.assert_called_once_with(vpc=vpc, name=isolated_sg_name)

        security_group_service.create_security_group.assert_called_once_with(ec2_session=self.ec2_session,
                                                                             vpc_id=vpc.id,
                                                                             security_group_name=isolated_sg_name)
        security_group_service.sandbox_isolated_sg_name.assert_called_once_with(self.reservation.reservation_id)
        self.assertEqual(sg, res)

    def test_get_or_create_vpc(self):
        cidr = Mock()
        vpc = Mock()
        vpc_service = Mock()
        vpc_service.find_vpc_for_reservation = Mock(return_value=None)
        vpc_service.create_vpc_for_reservation = Mock(return_value=vpc)

        prepare_conn = PrepareSandboxInfraOperation(vpc_service, self.sg_serv, self.key_pair_serv, self.tag_service,
                                                    self.route_table_service,
                                                    self.cancellation_service,
                                                    self.subnet_service, self.subnet_waiter)

        result = prepare_conn._get_or_create_vpc(cidr=cidr,
                                              ec2_session=self.ec2_session,
                                              reservation=self.reservation)

        vpc_service.find_vpc_for_reservation.assert_called_once_with(ec2_session=self.ec2_session,
                                                                     reservation_id=self.reservation.reservation_id)

        vpc_service.create_vpc_for_reservation.assert_called_once_with(ec2_session=self.ec2_session,
                                                                       reservation=self.reservation,
                                                                       cidr=cidr)

        self.assertEqual(vpc, result)
Esempio n. 15
0
class AWSShell(object):
    def __init__(self):
        self.command_result_parser = CommandResultsParser()
        self.cancellation_service = CommandCancellationService()
        self.client_err_wrapper = ClientErrorWrapper()
        self.tag_service = TagService(
            client_err_wrapper=self.client_err_wrapper)
        self.ec2_instance_waiter = InstanceWaiter(
            cancellation_service=self.cancellation_service)
        self.instance_service = InstanceService(self.tag_service,
                                                self.ec2_instance_waiter)
        self.ec2_storage_service = EC2StorageService()
        self.model_parser = AWSModelsParser()
        self.cloudshell_session_helper = CloudshellDriverHelper()
        self.aws_session_manager = AWSSessionProvider()
        self.password_waiter = PasswordWaiter(self.cancellation_service)
        self.vm_custom_params_extractor = VmCustomParamsExtractor()
        self.ami_credentials_service = InstanceCredentialsService(
            self.password_waiter)
        self.security_group_service = SecurityGroupService(self.tag_service)
        self.subnet_waiter = SubnetWaiter()
        self.subnet_service = SubnetService(self.tag_service,
                                            self.subnet_waiter)
        self.s3_service = S3BucketService()
        self.vpc_peering_waiter = VpcPeeringConnectionWaiter()
        self.key_pair_service = KeyPairService(self.s3_service)
        self.vpc_waiter = VPCWaiter()
        self.route_tables_service = RouteTablesService(self.tag_service)
        self.network_interface_service = NetworkInterfaceService(
            subnet_service=self.subnet_service)
        self.elastic_ip_service = ElasticIpService()
        self.vm_details_provider = VmDetailsProvider()

        self.vpc_service = VPCService(
            tag_service=self.tag_service,
            subnet_service=self.subnet_service,
            instance_service=self.instance_service,
            vpc_waiter=self.vpc_waiter,
            vpc_peering_waiter=self.vpc_peering_waiter,
            sg_service=self.security_group_service,
            route_table_service=self.route_tables_service)
        self.prepare_connectivity_operation = \
            PrepareSandboxInfraOperation(vpc_service=self.vpc_service,
                                         security_group_service=self.security_group_service,
                                         key_pair_service=self.key_pair_service,
                                         tag_service=self.tag_service,
                                         route_table_service=self.route_tables_service,
                                         cancellation_service=self.cancellation_service,
                                         subnet_service=self.subnet_service,
                                         subnet_waiter=self.subnet_waiter)

        self.deploy_ami_operation = DeployAMIOperation(
            instance_service=self.instance_service,
            ami_credential_service=self.ami_credentials_service,
            security_group_service=self.security_group_service,
            tag_service=self.tag_service,
            vpc_service=self.vpc_service,
            key_pair_service=self.key_pair_service,
            subnet_service=self.subnet_service,
            elastic_ip_service=self.elastic_ip_service,
            network_interface_service=self.network_interface_service,
            cancellation_service=self.cancellation_service,
            device_index_strategy=AllocateMissingValuesDeviceIndexStrategy(),
            vm_details_provider=self.vm_details_provider)

        self.refresh_ip_operation = RefreshIpOperation(
            instance_service=self.instance_service)

        self.power_management_operation = PowerOperation(
            instance_service=self.instance_service,
            instance_waiter=self.ec2_instance_waiter)

        self.delete_ami_operation = DeleteAMIOperation(
            instance_service=self.instance_service,
            ec2_storage_service=self.ec2_storage_service,
            security_group_service=self.security_group_service,
            tag_service=self.tag_service,
            elastic_ip_service=self.elastic_ip_service)

        self.clean_up_operation = CleanupSandboxInfraOperation(
            vpc_service=self.vpc_service,
            key_pair_service=self.key_pair_service,
            route_table_service=self.route_tables_service)

        self.deployed_app_ports_operation = DeployedAppPortsOperation(
            self.vm_custom_params_extractor,
            security_group_service=self.security_group_service,
            instance_service=self.instance_service)

        self.access_key_operation = GetAccessKeyOperation(
            key_pair_service=self.key_pair_service)

        self.set_app_security_groups_operation = SetAppSecurityGroupsOperation(
            instance_service=self.instance_service,
            tag_service=self.tag_service,
            security_group_service=self.security_group_service)

        self.vm_details_operation = VmDetailsOperation(
            instance_service=self.instance_service,
            vm_details_provider=self.vm_details_provider)

    def cleanup_connectivity(self, command_context, actions):
        """
        Will delete the reservation vpc and all related resources including all remaining instances
        :param ResourceCommandContext command_context:
        :param list[RequestActionBase] actions::
        :return: json string response
        :rtype: str
        """

        with AwsShellContext(
                context=command_context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            with ErrorHandlingContext(shell_context.logger):
                shell_context.logger.info('Cleanup Connectivity')

                result = self.clean_up_operation \
                    .cleanup(ec2_client=shell_context.aws_api.ec2_client,
                             ec2_session=shell_context.aws_api.ec2_session,
                             s3_session=shell_context.aws_api.s3_session,
                             aws_ec2_data_model=shell_context.aws_ec2_resource_model,
                             reservation_id=command_context.reservation.reservation_id,
                             actions=actions,
                             logger=shell_context.logger)
                return self.command_result_parser.set_command_result(
                    {'driverResponse': {
                        'actionResults': [result]
                    }})

    def prepare_connectivity(self, command_context, actions,
                             cancellation_context):
        """
        Will create a vpc for the reservation and will peer it with the management vpc
        :param ResourceCommandContext command_context: The Command Context
        :param list[RequestActionBase] actions:
        :return: json string response
        :param CancellationContext cancellation_context:
        :rtype: list[ActionResultBase]
        """
        with AwsShellContext(
                context=command_context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            with ErrorHandlingContext(shell_context.logger):
                shell_context.logger.info('Prepare Connectivity')

                results = self.prepare_connectivity_operation.prepare_connectivity(
                    ec2_client=shell_context.aws_api.ec2_client,
                    ec2_session=shell_context.aws_api.ec2_session,
                    s3_session=shell_context.aws_api.s3_session,
                    reservation=self.model_parser.convert_to_reservation_model(
                        command_context.reservation),
                    aws_ec2_datamodel=shell_context.aws_ec2_resource_model,
                    actions=actions,
                    cancellation_context=cancellation_context,
                    logger=shell_context.logger)

                return results

    def power_on_ami(self, command_context):
        """
        Will power on the ami
        :param ResourceRemoteCommandContext command_context:
        """
        with AwsShellContext(
                context=command_context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            with ErrorHandlingContext(shell_context.logger):
                shell_context.logger.info('Power On')

                resource = command_context.remote_endpoints[0]
                data_holder = self.model_parser.convert_app_resource_to_deployed_app(
                    resource)

                self.power_management_operation.power_on(
                    ec2_session=shell_context.aws_api.ec2_session,
                    ami_id=data_holder.vmdetails.uid)

    def power_off_ami(self, command_context):
        """
        Will power on the ami
        :param ResourceRemoteCommandContext command_context:
        """
        with AwsShellContext(
                context=command_context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            with ErrorHandlingContext(shell_context.logger):
                shell_context.logger.info('Power Off')

                resource = command_context.remote_endpoints[0]
                data_holder = self.model_parser.convert_app_resource_to_deployed_app(
                    resource)

                self.power_management_operation.power_off(
                    ec2_session=shell_context.aws_api.ec2_session,
                    ami_id=data_holder.vmdetails.uid)

    def delete_instance(self, command_context):
        """
        Will delete the ami instance
        :param ResourceRemoteCommandContext command_context:
        """
        with AwsShellContext(
                context=command_context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            with ErrorHandlingContext(shell_context.logger):
                shell_context.logger.info('Delete instance')

                resource = command_context.remote_endpoints[0]
                data_holder = self.model_parser.convert_app_resource_to_deployed_app(
                    resource)

                self.delete_ami_operation.delete_instance(
                    logger=shell_context.logger,
                    ec2_session=shell_context.aws_api.ec2_session,
                    instance_id=data_holder.vmdetails.uid)

    def get_application_ports(self, command_context):
        """
        Will return the application ports in a nicely formated manner
        :param ResourceRemoteCommandContext command_context:
        :rtype: str
        """
        with AwsShellContext(
                context=command_context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            with ErrorHandlingContext(shell_context.logger):
                shell_context.logger.info('Get Application Ports')
                resource = command_context.remote_endpoints[0]

                # Get instance id
                deployed_instance_id = self.model_parser.try_get_deployed_connected_resource_instance_id(
                    command_context)

                # Get Allow all Storage Traffic on deployed resource
                allow_all_storage_traffic = self.model_parser.get_allow_all_storage_traffic_from_connected_resource_details(
                    command_context)

                return self.deployed_app_ports_operation.get_app_ports_from_cloud_provider(
                    ec2_session=shell_context.aws_api.ec2_session,
                    instance_id=deployed_instance_id,
                    resource=resource,
                    allow_all_storage_traffic=allow_all_storage_traffic)

    def deploy_ami(self, command_context, actions, cancellation_context):
        """
        Will deploy Amazon Image on the cloud provider
        :param ResourceCommandContext command_context:
        :param list[RequestActionBase] actions::
        :param CancellationContext cancellation_context:
        """
        with AwsShellContext(
                context=command_context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            with ErrorHandlingContext(shell_context.logger):
                shell_context.logger.info('Deploying AMI')

                deploy_action = single(actions,
                                       lambda x: isinstance(x, DeployApp))
                network_actions = [
                    a for a in actions if isinstance(a, ConnectSubnet)
                ]

                deploy_data = self.deploy_ami_operation \
                    .deploy(ec2_session=shell_context.aws_api.ec2_session,
                            s3_session=shell_context.aws_api.s3_session,
                            name=deploy_action.actionParams.appName,
                            reservation=self.model_parser.convert_to_reservation_model(command_context.reservation),
                            aws_ec2_cp_resource_model=shell_context.aws_ec2_resource_model,
                            ami_deploy_action=deploy_action,
                            network_actions=network_actions,
                            ec2_client=shell_context.aws_api.ec2_client,
                            cancellation_context=cancellation_context,
                            logger=shell_context.logger)

                return deploy_data

    def refresh_ip(self, command_context):
        """
        :param ResourceRemoteCommandContext command_context:
        """
        with AwsShellContext(
                context=command_context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            with ErrorHandlingContext(shell_context.logger):
                shell_context.logger.info('Refresh IP')

                # Get Private Ip on deployed resource
                private_ip_on_resource = self.model_parser.get_private_ip_from_connected_resource_details(
                    command_context)
                # Get Public IP on deployed resource
                public_ip_on_resource = self.model_parser.get_public_ip_from_connected_resource_details(
                    command_context)
                # Get instance id
                deployed_instance_id = self.model_parser.try_get_deployed_connected_resource_instance_id(
                    command_context)
                # Get connected resource name
                resource_fullname = self.model_parser.get_connectd_resource_fullname(
                    command_context)

                self.refresh_ip_operation.refresh_ip(
                    cloudshell_session=shell_context.cloudshell_session,
                    ec2_session=shell_context.aws_api.ec2_session,
                    deployed_instance_id=deployed_instance_id,
                    private_ip_on_resource=private_ip_on_resource,
                    public_ip_on_resource=public_ip_on_resource,
                    resource_fullname=resource_fullname)

    def get_access_key(self, command_context):
        """
        Returns the pem file for the connected resource
        :param ResourceRemoteCommandContext command_context:
        :rtype str:
        """
        with AwsShellContext(
                context=command_context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            with ErrorHandlingContext(shell_context.logger):
                shell_context.logger.info('GetAccessKey')
                reservation_id = self._get_reservation_id(command_context)
                return self.access_key_operation.get_access_key(
                    s3_session=shell_context.aws_api.s3_session,
                    aws_ec2_resource_model=shell_context.
                    aws_ec2_resource_model,
                    reservation_id=reservation_id)

    def set_app_security_groups(self, context, request):
        """
        Set security groups (inbound rules only)
        :param context: todo - set the type of the parameter
        :param request: The json request
        :return:
        """
        with AwsShellContext(
                context=context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            with ErrorHandlingContext(shell_context.logger):
                shell_context.logger.info('Set App Security Groups')

                reservation = self.model_parser.convert_to_reservation_model(
                    context.reservation)
                app_security_group_models = self.model_parser.convert_to_app_security_group_models(
                    request)

                result = self.set_app_security_groups_operation.set_apps_security_groups(
                    app_security_group_models=app_security_group_models,
                    reservation=reservation,
                    ec2_session=shell_context.aws_api.ec2_session,
                    logger=shell_context.logger)

                json_result = SetAppSecurityGroupActionResult.to_json(result)

                return json_result

    def get_vm_details(self, context, cancellation_context, requests_json):
        """
        Get vm details for specific deployed app
        :type context: ResourceCommandContext
        :rtype str
        """
        results = []
        vm_details_requests = [
            VmDetailsRequest(item) for item in DeployDataHolder(
                jsonpickle.decode(requests_json)).items
        ]

        for request in vm_details_requests:
            if cancellation_context.is_cancelled:
                break

            try:
                with AwsShellContext(context=context,
                                     aws_session_manager=self.
                                     aws_session_manager) as shell_context:
                    with ErrorHandlingContext(shell_context.logger):
                        shell_context.logger.info('Get VmDetails')
                        vm_details = self.vm_details_operation.get_vm_details(
                            request.uuid, shell_context.aws_api.ec2_session)
                        vm_details.appName = request.app_name
                        results.append(vm_details)
            except Exception as e:
                result = VmDetailsData()
                result.appName = request.app_name
                result.error = e.message
                results.append(result)

        return self.command_result_parser.set_command_result(results)

    @staticmethod
    def _get_reservation_id(context):
        reservation_id = None
        reservation = getattr(context, 'reservation',
                              getattr(context, 'remote_reservation', None))
        if reservation:
            reservation_id = reservation.reservation_id
        return reservation_id
Esempio n. 16
0
class AWSShell:
    CREDENTIALS_ERROR_MESSAGE = ("Oops, looks like there was a problem with "
                                 "your cloud provider credentials. "
                                 "Please check AWS Secret Access Key "
                                 "and AWS Access Key ID")

    def __init__(self):
        self.image_waiter = AMIWaiter()
        self.command_result_parser = CommandResultsParser()
        self.cancellation_service = CommandCancellationService()
        self.client_err_wrapper = ClientErrorWrapper()
        self.tag_service = TagService(
            client_err_wrapper=self.client_err_wrapper)
        self.ec2_instance_waiter = InstanceWaiter(
            cancellation_service=self.cancellation_service)
        self.instance_service = InstanceService(self.tag_service,
                                                self.ec2_instance_waiter)
        self.ec2_storage_service = EC2StorageService()
        self.model_parser = AWSModelsParser()
        self.cloudshell_session_helper = CloudshellDriverHelper()
        self.aws_session_manager = AWSSessionProvider()
        self.password_waiter = PasswordWaiter(self.cancellation_service)
        self.vm_custom_params_extractor = VmCustomParamsExtractor()
        self.ami_credentials_service = InstanceCredentialsService(
            self.password_waiter)
        self.security_group_service = SecurityGroupService(self.tag_service)
        self.subnet_waiter = SubnetWaiter()
        self.subnet_service = SubnetService(self.tag_service,
                                            self.subnet_waiter)
        self.s3_service = S3BucketService()
        self.vpc_peering_waiter = VpcPeeringConnectionWaiter()
        self.key_pair_service = KeyPairService(self.s3_service)
        self.vpc_waiter = VPCWaiter()
        self.route_tables_service = RouteTablesService(self.tag_service)
        self.network_interface_service = NetworkInterfaceService(
            subnet_service=self.subnet_service,
            security_group_service=self.security_group_service,
        )
        self.elastic_ip_service = ElasticIpService()
        self.vm_details_provider = VmDetailsProvider()
        self.session_number_service = SessionNumberService()
        self.traffic_mirror_service = TrafficMirrorService()
        self.request_parser = DriverRequestParser()

        self.vpc_service = VPCService(
            tag_service=self.tag_service,
            subnet_service=self.subnet_service,
            instance_service=self.instance_service,
            vpc_waiter=self.vpc_waiter,
            vpc_peering_waiter=self.vpc_peering_waiter,
            sg_service=self.security_group_service,
            route_table_service=self.route_tables_service,
            traffic_mirror_service=self.traffic_mirror_service,
        )
        self.prepare_connectivity_operation = PrepareSandboxInfraOperation(
            vpc_service=self.vpc_service,
            security_group_service=self.security_group_service,
            key_pair_service=self.key_pair_service,
            tag_service=self.tag_service,
            route_table_service=self.route_tables_service,
            cancellation_service=self.cancellation_service,
            subnet_service=self.subnet_service,
            subnet_waiter=self.subnet_waiter,
        )

        self.deploy_ami_operation = DeployAMIOperation(
            instance_service=self.instance_service,
            ami_credential_service=self.ami_credentials_service,
            security_group_service=self.security_group_service,
            tag_service=self.tag_service,
            vpc_service=self.vpc_service,
            key_pair_service=self.key_pair_service,
            subnet_service=self.subnet_service,
            elastic_ip_service=self.elastic_ip_service,
            network_interface_service=self.network_interface_service,
            cancellation_service=self.cancellation_service,
            device_index_strategy=AllocateMissingValuesDeviceIndexStrategy(),
            vm_details_provider=self.vm_details_provider,
        )

        self.refresh_ip_operation = RefreshIpOperation(
            instance_service=self.instance_service)

        self.power_management_operation = PowerOperation(
            instance_service=self.instance_service,
            instance_waiter=self.ec2_instance_waiter,
        )

        self.delete_ami_operation = DeleteAMIOperation(
            instance_service=self.instance_service,
            ec2_storage_service=self.ec2_storage_service,
            security_group_service=self.security_group_service,
            tag_service=self.tag_service,
            elastic_ip_service=self.elastic_ip_service,
        )

        self.clean_up_operation = CleanupSandboxInfraOperation(
            vpc_service=self.vpc_service,
            key_pair_service=self.key_pair_service,
            route_table_service=self.route_tables_service,
            traffic_mirror_service=self.traffic_mirror_service,
        )

        self.deployed_app_ports_operation = DeployedAppPortsOperation(
            self.vm_custom_params_extractor,
            security_group_service=self.security_group_service,
            instance_service=self.instance_service,
        )

        self.access_key_operation = GetAccessKeyOperation(
            key_pair_service=self.key_pair_service)

        self.set_app_security_groups_operation = SetAppSecurityGroupsOperation(
            instance_service=self.instance_service,
            tag_service=self.tag_service,
            security_group_service=self.security_group_service,
        )

        self.vm_details_operation = VmDetailsOperation(
            instance_service=self.instance_service,
            vm_details_provider=self.vm_details_provider,
        )

        self.autoload_operation = AutoloadOperation()

        self.snapshot_operation = SnapshotOperation(self.instance_service,
                                                    self.image_waiter)

        self.traffic_mirroring_operation = TrafficMirrorOperation(
            tag_service=self.tag_service,
            session_number_service=self.session_number_service,
            traffic_mirror_service=self.traffic_mirror_service,
            cancellation_service=self.cancellation_service,
        )

    def cleanup_connectivity(self, command_context, actions):
        """# noqa
        Will delete the reservation vpc and all related resources including all remaining instances
        :param ResourceCommandContext command_context:
        :param list[RequestActionBase] actions::
        :return: json string response
        :rtype: str
        """
        with AwsShellContext(
                context=command_context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            shell_context.logger.info("Cleanup Connectivity")

            result = self.clean_up_operation.cleanup(
                ec2_client=shell_context.aws_api.ec2_client,
                ec2_session=shell_context.aws_api.ec2_session,
                s3_session=shell_context.aws_api.s3_session,
                aws_ec2_data_model=shell_context.aws_ec2_resource_model,
                reservation_id=command_context.reservation.reservation_id,
                actions=actions,
                logger=shell_context.logger,
            )
            return self.command_result_parser.set_command_result(
                {"driverResponse": {
                    "actionResults": [result]
                }})

    def prepare_connectivity(self, command_context, actions,
                             cancellation_context):
        """# noqa
        Will create a vpc for the reservation and will peer it with the management vpc
        :param ResourceCommandContext command_context: The Command Context
        :param list[RequestActionBase] actions:
        :return: json string response
        :param CancellationContext cancellation_context:
        :rtype: list[ActionResultBase]
        """
        with AwsShellContext(
                context=command_context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            shell_context.logger.info("Prepare Connectivity")
            reservation = self.model_parser.convert_to_reservation_model(
                command_context.reservation)
            cs_subnet_service = CsSubnetService(
                shell_context.cloudshell_session, reservation.reservation_id)

            results = self.prepare_connectivity_operation.prepare_connectivity(
                ec2_client=shell_context.aws_api.ec2_client,
                ec2_session=shell_context.aws_api.ec2_session,
                s3_session=shell_context.aws_api.s3_session,
                reservation=reservation,
                aws_ec2_datamodel=shell_context.aws_ec2_resource_model,
                actions=actions,
                cancellation_context=cancellation_context,
                cs_subnet_service=cs_subnet_service,
                logger=shell_context.logger,
            )

            return results

    def get_inventory(self, command_context):
        """Validate Cloud Provider.

        :param command_context: ResourceCommandContext
        """
        try:
            with AwsShellContext(context=command_context,
                                 aws_session_manager=self.aws_session_manager
                                 ) as shell_context:
                shell_context.logger.info("Starting Autoload Operation...")
                result = self.autoload_operation.get_inventory(
                    cloud_provider_model=shell_context.aws_ec2_resource_model,
                    logger=shell_context.logger,
                    ec2_client=shell_context.aws_api.ec2_client,
                    ec2_session=shell_context.aws_api.ec2_session,
                    s3_session=shell_context.aws_api.s3_session,
                )
                shell_context.logger.info("End Autoload Operation...")
                return result

        except ClientError as ce:
            if "AuthorizationHeaderMalformed" in str(ce):
                raise Exception(self.CREDENTIALS_ERROR_MESSAGE)
            raise ce

        except NoCredentialsError:
            raise Exception(self.CREDENTIALS_ERROR_MESSAGE)

        except ValueError as ve:
            if "Invalid endpoint" in str(ve):
                raise Exception(
                    "Oops, like you didnt configure Region correctly. Please select "
                    "Region and try again ")
            else:
                raise ve

    def power_on_ami(self, command_context):
        """# noqa
        Will power on the ami
        :param ResourceRemoteCommandContext command_context:
        """
        with AwsShellContext(
                context=command_context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            shell_context.logger.info("Power On")

            resource = command_context.remote_endpoints[0]
            data_holder = self.model_parser.convert_app_resource_to_deployed_app(
                resource)

            self.power_management_operation.power_on(
                ec2_session=shell_context.aws_api.ec2_session,
                ami_id=data_holder.vmdetails.uid,
            )

    def power_off_ami(self, command_context):
        """# noqa
        Will power on the ami
        :param ResourceRemoteCommandContext command_context:
        """
        with AwsShellContext(
                context=command_context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            shell_context.logger.info("Power Off")

            resource = command_context.remote_endpoints[0]
            data_holder = self.model_parser.convert_app_resource_to_deployed_app(
                resource)

            self.power_management_operation.power_off(
                ec2_session=shell_context.aws_api.ec2_session,
                ami_id=data_holder.vmdetails.uid,
            )

    def delete_instance(self, command_context):
        """# noqa
        Will delete the ami instance
        :param ResourceRemoteCommandContext command_context:
        """
        with AwsShellContext(
                context=command_context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            shell_context.logger.info("Delete instance")

            resource = command_context.remote_endpoints[0]
            data_holder = self.model_parser.convert_app_resource_to_deployed_app(
                resource)

            self.delete_ami_operation.delete_instance(
                logger=shell_context.logger,
                ec2_session=shell_context.aws_api.ec2_session,
                instance_id=data_holder.vmdetails.uid,
            )

    def get_application_ports(self, command_context):
        """# noqa
        Will return the application ports in a nicely formated manner
        :param ResourceRemoteCommandContext command_context:
        :rtype: str
        """
        with AwsShellContext(
                context=command_context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            shell_context.logger.info("Get Application Ports")
            resource = command_context.remote_endpoints[0]

            # Get instance id
            deployed_instance_id = (
                self.model_parser.
                try_get_deployed_connected_resource_instance_id(
                    command_context))

            # Get Allow all Storage Traffic on deployed resource
            allow_all_storage_traffic = self.model_parser.get_allow_all_storage_traffic_from_connected_resource_details(  # noqa
                command_context)

            return self.deployed_app_ports_operation.get_app_ports_from_cloud_provider(
                ec2_session=shell_context.aws_api.ec2_session,
                instance_id=deployed_instance_id,
                resource=resource,
                allow_all_storage_traffic=allow_all_storage_traffic,
            )

    def deploy_ami(self, command_context, actions, cancellation_context):
        """# noqa
        Will deploy Amazon Image on the cloud provider
        :param ResourceCommandContext command_context:
        :param list[RequestActionBase] actions::
        :param CancellationContext cancellation_context:
        """
        with AwsShellContext(
                context=command_context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            shell_context.logger.info("Deploying AMI")

            deploy_action = single(actions, lambda x: isinstance(x, DeployApp))
            network_actions = [
                a for a in actions if isinstance(a, ConnectSubnet)
            ]

            deploy_data = self.deploy_ami_operation.deploy(
                ec2_session=shell_context.aws_api.ec2_session,
                s3_session=shell_context.aws_api.s3_session,
                name=deploy_action.actionParams.appName,
                reservation=self.model_parser.convert_to_reservation_model(
                    command_context.reservation),
                aws_ec2_cp_resource_model=shell_context.aws_ec2_resource_model,
                ami_deploy_action=deploy_action,
                network_actions=network_actions,
                ec2_client=shell_context.aws_api.ec2_client,
                cancellation_context=cancellation_context,
                logger=shell_context.logger,
            )

            return deploy_data

    def refresh_ip(self, command_context):
        """# noqa
        :param ResourceRemoteCommandContext command_context:
        """
        with AwsShellContext(
                context=command_context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            shell_context.logger.info("Refresh IP")

            # Get Private Ip on deployed resource
            private_ip_on_resource = (
                self.model_parser.
                get_private_ip_from_connected_resource_details(command_context)
            )
            # Get Public IP on deployed resource

            (
                public_ip_attr_name,
                public_ip_on_resource,
            ) = self.model_parser.get_public_ip_attr_from_connected_resource_details(
                command_context)
            # Get instance id
            deployed_instance_id = (
                self.model_parser.
                try_get_deployed_connected_resource_instance_id(
                    command_context))
            # Get connected resource name
            resource_fullname = self.model_parser.get_connectd_resource_fullname(
                command_context)

            self.refresh_ip_operation.refresh_ip(
                cloudshell_session=shell_context.cloudshell_session,
                ec2_session=shell_context.aws_api.ec2_session,
                deployed_instance_id=deployed_instance_id,
                private_ip_on_resource=private_ip_on_resource,
                public_ip_on_resource=public_ip_on_resource,
                public_ip_attribute_name=public_ip_attr_name,
                resource_fullname=resource_fullname,
            )

    def get_access_key(self, command_context):
        """# noqa
        Returns the pem file for the connected resource
        :param ResourceRemoteCommandContext command_context:
        :rtype str:
        """
        with AwsShellContext(
                context=command_context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            shell_context.logger.info("GetAccessKey")
            reservation_id = self._get_reservation_id(command_context)
            return self.access_key_operation.get_access_key(
                s3_session=shell_context.aws_api.s3_session,
                aws_ec2_resource_model=shell_context.aws_ec2_resource_model,
                reservation_id=reservation_id,
            )

    def set_app_security_groups(self, context, request):
        """# noqa
        Set security groups (inbound rules only)
        :param context: todo - set the type of the parameter
        :param request: The json request
        :return:
        """
        with AwsShellContext(
                context=context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            shell_context.logger.info("Set App Security Groups")

            reservation = self.model_parser.convert_to_reservation_model(
                context.reservation)
            app_security_group_models = (
                self.model_parser.convert_to_app_security_group_models(request)
            )

            result = self.set_app_security_groups_operation.set_apps_security_groups(
                app_security_group_models=app_security_group_models,
                reservation=reservation,
                ec2_session=shell_context.aws_api.ec2_session,
                logger=shell_context.logger,
            )

            json_result = SetAppSecurityGroupActionResult.to_json(result)

            return json_result

    def get_vm_details(self, context, cancellation_context, requests_json):
        """# noqa
        Get vm details for specific deployed app
        :type context: ResourceCommandContext
        :rtype str
        """
        results = []
        vm_details_requests = [
            VmDetailsRequest(item) for item in DeployDataHolder(
                jsonpickle.decode(requests_json)).items
        ]

        for request in vm_details_requests:
            if cancellation_context.is_cancelled:
                break

            try:
                with AwsShellContext(context=context,
                                     aws_session_manager=self.
                                     aws_session_manager) as shell_context:
                    shell_context.logger.info("Get VmDetails")
                    vm_details = self.vm_details_operation.get_vm_details(
                        request.uuid, shell_context.aws_api.ec2_session)
                    vm_details.appName = request.app_name
                    results.append(vm_details)
            except Exception as e:
                result = VmDetailsData()
                result.appName = request.app_name
                result.error = str(e)
                results.append(result)

        return self.command_result_parser.set_command_result(results)

    # def remote_get_snapshots(self, context):  # noqa
    #     with AwsShellContext(context=context, aws_session_manager=self.aws_session_manager) as shell_context:  # noqa
    #         with ErrorHandlingContext(shell_context.logger):  # noqa
    #             shell_context.logger.info('Get Snapshots')  # noqa
    #
    #             resource = context.remote_endpoints[0]  # noqa
    #             resource_fullname = self.model_parser.get_connectd_resource_fullname(context)  # noqa
    #             reservation_id = self._get_reservation_id(context)  # noqa
    #
    #             return self.snapshot_operation.get(shell_context.aws_api.ec2_client,  # noqa
    #                                                reservation_id, resource_fullname)  # noqa

    def remote_get_snapshots(self, context):
        with AwsShellContext(
                context=context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            shell_context.logger.info("Get Snapshots")

            resource = context.remote_endpoints[0]
            data_holder = self.model_parser.convert_app_resource_to_deployed_app(
                resource)

            return self.snapshot_operation.get_snapshots(
                shell_context.aws_api.ec2_client,
                instance_id=data_holder.vmdetails.uid)

    def remote_save_snapshot(self, context, snapshot_name):
        with AwsShellContext(
                context=context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            shell_context.logger.info("Save Snapshot")
            resource = context.remote_endpoints[0]
            reservation = ReservationModel(context.remote_reservation)
            tags = self.tag_service.get_default_tags(snapshot_name,
                                                     reservation)
            data_holder = self.model_parser.convert_app_resource_to_deployed_app(
                resource)
            self.snapshot_operation.save_snapshot(
                ec2_client=shell_context.aws_api.ec2_client,
                ec2_session=shell_context.aws_api.ec2_session,
                instance_id=data_holder.vmdetails.uid,
                snapshot_name=snapshot_name,
                tags=tags,
            )

    def remote_restore_snapshot(self, context, snapshot_name):
        with AwsShellContext(
                context=context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            shell_context.logger.info("Save Snapshot")
            resource = context.remote_endpoints[0]
            reservation = ReservationModel(context.remote_reservation)
            tags = self.tag_service.get_default_tags(snapshot_name,
                                                     reservation)
            data_holder = self.model_parser.convert_app_resource_to_deployed_app(
                resource)
            self.snapshot_operation.save_snapshot(
                ec2_client=shell_context.aws_api.ec2_client,
                ec2_session=shell_context.aws_api.ec2_session,
                instance_id=data_holder.vmdetails.uid,
                snapshot_name=snapshot_name,
                tags=tags,
            )

    def save_app(self, context, cancellation_context):
        """# noqa
        :param context:
        :param cancellation_context:
        :return:
        """
        with AwsShellContext(
                context=context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            shell_context.logger.info("Save Snapshot")

            resource = context.remote_endpoints[0]

            data_holder = self.model_parser.convert_app_resource_to_deployed_app(
                resource)
            resource_fullname = self.model_parser.get_connectd_resource_fullname(
                context)

            image_id = self.snapshot_operation.save(
                logger=shell_context.logger,
                ec2_session=shell_context.aws_api.ec2_session,
                instance_id=data_holder.vmdetails.uid,
                deployed_app_name=resource_fullname,
                snapshot_prefix="",
                no_reboot=True,
            )

            return json.dumps({"AWS EC2 Instance.AWS AMI Id": image_id})

    def add_custom_tags(self, context, request):
        """# noqa
        :param ResourceCommandContext context:
        :param str request:
        :return:
        """
        with AwsShellContext(
                context=context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            shell_context.logger.info("Add custom tags")

            # Get instance id
            deployed_instance_id = (
                self.model_parser.
                try_get_deployed_connected_resource_instance_id(context))

            # Expected request syntax:
            # [{  # noqa
            #     'Key': 'string',  # noqa
            #     'Value': 'string'  # noqa
            # }]  # noqa
            tags = json.loads(request)

            instance = self.instance_service.get_instance_by_id(
                shell_context.aws_api.ec2_session, deployed_instance_id)
            instance.create_tags(Tags=tags)

    def create_traffic_mirroring(self, context, cancellation_context, request):
        """# noqa
        Will create a vpc for the reservation and will peer it with the management vpc
        :param request:
        :param ResourceCommandContext context:

        :return: json string response
        :param CancellationContext cancellation_context:
        :rtype: list[ActionResultBase]
        """
        with AwsShellContext(
                context=context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            shell_context.logger.info("Create traffic mirroring")
            actions = self._parse_request(request, shell_context)
            self.traffic_mirroring_operation.validate_create_actions(
                actions, request, shell_context.logger)
            results = self.traffic_mirroring_operation.create(
                ec2_client=shell_context.aws_api.ec2_client,
                reservation=self.model_parser.convert_to_reservation_model(
                    context.reservation),
                actions=actions,
                cancellation_context=cancellation_context,
                logger=shell_context.logger,
                cloudshell=shell_context.cloudshell_session,
            )

            return results

    def _parse_request(self, request, shell_context):
        try:
            actions = self.request_parser.convert_driver_request_to_actions(
                request)
            if not actions:
                raise Exception("Invalid request: " + request)
        except Exception as e:
            shell_context.logger.exception("Invalid request " + request)
            raise e
        return actions

    @staticmethod
    def _get_reservation_id(context):
        reservation_id = None
        reservation = getattr(context, "reservation",
                              getattr(context, "remote_reservation", None))
        if reservation:
            reservation_id = reservation.reservation_id
        return reservation_id

    def remove_traffic_mirroring(self, context, request):
        """# noqa
        Can remove traffic mirroring sessions by session id, or all sessions associated with a traffic mirror target (by target nic id)
        :param str request:
        :param ResourceCommandContext context:
        :param ResourceCommandContext context:

        :return: json string response
        :rtype: list[ActionResultBase]
        """
        with AwsShellContext(
                context=context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            shell_context.logger.info("Create traffic mirroring")

            self.traffic_mirroring_operation.validate_remove_request(
                request, shell_context.logger)

            actions = self._parse_request(request, shell_context)

            results = self.traffic_mirroring_operation.remove(
                ec2_client=shell_context.aws_api.ec2_client,
                reservation=self.model_parser.convert_to_reservation_model(
                    context.reservation),
                actions=actions,
                logger=shell_context.logger,
                cloudshell=shell_context.cloudshell_session,
            )

            return results

    def assign_additional_private_ipv4s(self, context, vnic_id, new_ips):
        with AwsShellContext(
                context=context,
                aws_session_manager=self.aws_session_manager) as shell_context:
            shell_context.logger.info("Assign additional IP Addresses")

            ips = map(str.strip, new_ips.split(";"))
            try:
                response = shell_context.aws_api.ec2_client.assign_private_ip_addresses(
                    AllowReassignment=True,
                    NetworkInterfaceId=vnic_id,
                    PrivateIpAddresses=ips,
                )
                assigned_ips_response = response.get(
                    "AssignedPrivateIpAddresses", [])
                return ";".join([
                    ip.get("PrivateIpAddress") for ip in assigned_ips_response
                    if ip.get("PrivateIpAddress")
                ])
            except Exception:
                shell_context.logger.error("Failed to add ips", exc_info=1)
                return None
Esempio n. 17
0
    def __init__(self):
        self.image_waiter = AMIWaiter()
        self.command_result_parser = CommandResultsParser()
        self.cancellation_service = CommandCancellationService()
        self.client_err_wrapper = ClientErrorWrapper()
        self.tag_service = TagService(
            client_err_wrapper=self.client_err_wrapper)
        self.ec2_instance_waiter = InstanceWaiter(
            cancellation_service=self.cancellation_service)
        self.instance_service = InstanceService(self.tag_service,
                                                self.ec2_instance_waiter)
        self.ec2_storage_service = EC2StorageService()
        self.model_parser = AWSModelsParser()
        self.cloudshell_session_helper = CloudshellDriverHelper()
        self.aws_session_manager = AWSSessionProvider()
        self.password_waiter = PasswordWaiter(self.cancellation_service)
        self.vm_custom_params_extractor = VmCustomParamsExtractor()
        self.ami_credentials_service = InstanceCredentialsService(
            self.password_waiter)
        self.security_group_service = SecurityGroupService(self.tag_service)
        self.subnet_waiter = SubnetWaiter()
        self.subnet_service = SubnetService(self.tag_service,
                                            self.subnet_waiter)
        self.s3_service = S3BucketService()
        self.vpc_peering_waiter = VpcPeeringConnectionWaiter()
        self.key_pair_service = KeyPairService(self.s3_service)
        self.vpc_waiter = VPCWaiter()
        self.route_tables_service = RouteTablesService(self.tag_service)
        self.network_interface_service = NetworkInterfaceService(
            subnet_service=self.subnet_service,
            security_group_service=self.security_group_service,
        )
        self.elastic_ip_service = ElasticIpService()
        self.vm_details_provider = VmDetailsProvider()
        self.session_number_service = SessionNumberService()
        self.traffic_mirror_service = TrafficMirrorService()
        self.request_parser = DriverRequestParser()

        self.vpc_service = VPCService(
            tag_service=self.tag_service,
            subnet_service=self.subnet_service,
            instance_service=self.instance_service,
            vpc_waiter=self.vpc_waiter,
            vpc_peering_waiter=self.vpc_peering_waiter,
            sg_service=self.security_group_service,
            route_table_service=self.route_tables_service,
            traffic_mirror_service=self.traffic_mirror_service,
        )
        self.prepare_connectivity_operation = PrepareSandboxInfraOperation(
            vpc_service=self.vpc_service,
            security_group_service=self.security_group_service,
            key_pair_service=self.key_pair_service,
            tag_service=self.tag_service,
            route_table_service=self.route_tables_service,
            cancellation_service=self.cancellation_service,
            subnet_service=self.subnet_service,
            subnet_waiter=self.subnet_waiter,
        )

        self.deploy_ami_operation = DeployAMIOperation(
            instance_service=self.instance_service,
            ami_credential_service=self.ami_credentials_service,
            security_group_service=self.security_group_service,
            tag_service=self.tag_service,
            vpc_service=self.vpc_service,
            key_pair_service=self.key_pair_service,
            subnet_service=self.subnet_service,
            elastic_ip_service=self.elastic_ip_service,
            network_interface_service=self.network_interface_service,
            cancellation_service=self.cancellation_service,
            device_index_strategy=AllocateMissingValuesDeviceIndexStrategy(),
            vm_details_provider=self.vm_details_provider,
        )

        self.refresh_ip_operation = RefreshIpOperation(
            instance_service=self.instance_service)

        self.power_management_operation = PowerOperation(
            instance_service=self.instance_service,
            instance_waiter=self.ec2_instance_waiter,
        )

        self.delete_ami_operation = DeleteAMIOperation(
            instance_service=self.instance_service,
            ec2_storage_service=self.ec2_storage_service,
            security_group_service=self.security_group_service,
            tag_service=self.tag_service,
            elastic_ip_service=self.elastic_ip_service,
        )

        self.clean_up_operation = CleanupSandboxInfraOperation(
            vpc_service=self.vpc_service,
            key_pair_service=self.key_pair_service,
            route_table_service=self.route_tables_service,
            traffic_mirror_service=self.traffic_mirror_service,
        )

        self.deployed_app_ports_operation = DeployedAppPortsOperation(
            self.vm_custom_params_extractor,
            security_group_service=self.security_group_service,
            instance_service=self.instance_service,
        )

        self.access_key_operation = GetAccessKeyOperation(
            key_pair_service=self.key_pair_service)

        self.set_app_security_groups_operation = SetAppSecurityGroupsOperation(
            instance_service=self.instance_service,
            tag_service=self.tag_service,
            security_group_service=self.security_group_service,
        )

        self.vm_details_operation = VmDetailsOperation(
            instance_service=self.instance_service,
            vm_details_provider=self.vm_details_provider,
        )

        self.autoload_operation = AutoloadOperation()

        self.snapshot_operation = SnapshotOperation(self.instance_service,
                                                    self.image_waiter)

        self.traffic_mirroring_operation = TrafficMirrorOperation(
            tag_service=self.tag_service,
            session_number_service=self.session_number_service,
            traffic_mirror_service=self.traffic_mirror_service,
            cancellation_service=self.cancellation_service,
        )
Esempio n. 18
0
class AWSShell(object):
    def __init__(self):
        self.command_result_parser = CommandResultsParser()
        self.cancellation_service = CommandCancellationService()
        self.client_err_wrapper = ClientErrorWrapper()
        self.tag_service = TagService(client_err_wrapper=self.client_err_wrapper)
        self.ec2_instance_waiter = InstanceWaiter(cancellation_service=self.cancellation_service)
        self.instance_service = InstanceService(self.tag_service, self.ec2_instance_waiter)
        self.ec2_storage_service = EC2StorageService()
        self.model_parser = AWSModelsParser()
        self.cloudshell_session_helper = CloudshellDriverHelper()
        self.aws_session_manager = AWSSessionProvider()
        self.password_waiter = PasswordWaiter(self.cancellation_service)
        self.vm_custom_params_extractor = VmCustomParamsExtractor()
        self.ami_credentials_service = InstanceCredentialsService(self.password_waiter)
        self.security_group_service = SecurityGroupService(self.tag_service)
        self.subnet_waiter = SubnetWaiter()
        self.subnet_service = SubnetService(self.tag_service, self.subnet_waiter)
        self.s3_service = S3BucketService()
        self.vpc_peering_waiter = VpcPeeringConnectionWaiter()
        self.key_pair_service = KeyPairService(self.s3_service)
        self.vpc_waiter = VPCWaiter()
        self.route_tables_service = RouteTablesService(self.tag_service)
        self.network_interface_service = NetworkInterfaceService(subnet_service=self.subnet_service)
        self.elastic_ip_service = ElasticIpService()
        self.vm_details_provider = VmDetailsProvider()

        self.vpc_service = VPCService(tag_service=self.tag_service,
                                      subnet_service=self.subnet_service,
                                      instance_service=self.instance_service,
                                      vpc_waiter=self.vpc_waiter,
                                      vpc_peering_waiter=self.vpc_peering_waiter,
                                      sg_service=self.security_group_service,
                                      route_table_service=self.route_tables_service)
        self.prepare_connectivity_operation = \
            PrepareSandboxInfraOperation(vpc_service=self.vpc_service,
                                         security_group_service=self.security_group_service,
                                         key_pair_service=self.key_pair_service,
                                         tag_service=self.tag_service,
                                         route_table_service=self.route_tables_service,
                                         cancellation_service=self.cancellation_service,
                                         subnet_service=self.subnet_service,
                                         subnet_waiter=self.subnet_waiter)

        self.deploy_ami_operation = DeployAMIOperation(instance_service=self.instance_service,
                                                       ami_credential_service=self.ami_credentials_service,
                                                       security_group_service=self.security_group_service,
                                                       tag_service=self.tag_service,
                                                       vpc_service=self.vpc_service,
                                                       key_pair_service=self.key_pair_service,
                                                       subnet_service=self.subnet_service,
                                                       elastic_ip_service=self.elastic_ip_service,
                                                       network_interface_service=self.network_interface_service,
                                                       cancellation_service=self.cancellation_service,
                                                       device_index_strategy=AllocateMissingValuesDeviceIndexStrategy(),
                                                       vm_details_provider=self.vm_details_provider)

        self.refresh_ip_operation = RefreshIpOperation(instance_service=self.instance_service)

        self.power_management_operation = PowerOperation(instance_service=self.instance_service,
                                                         instance_waiter=self.ec2_instance_waiter)

        self.delete_ami_operation = DeleteAMIOperation(instance_service=self.instance_service,
                                                       ec2_storage_service=self.ec2_storage_service,
                                                       security_group_service=self.security_group_service,
                                                       tag_service=self.tag_service,
                                                       elastic_ip_service=self.elastic_ip_service)

        self.clean_up_operation = CleanupSandboxInfraOperation(vpc_service=self.vpc_service,
                                                               key_pair_service=self.key_pair_service,
                                                               route_table_service=self.route_tables_service)

        self.deployed_app_ports_operation = DeployedAppPortsOperation(self.vm_custom_params_extractor,
                                                                      security_group_service=self.security_group_service,
                                                                      instance_service=self.instance_service)

        self.access_key_operation = GetAccessKeyOperation(key_pair_service=self.key_pair_service)

        self.set_app_security_groups_operation = SetAppSecurityGroupsOperation(instance_service=self.instance_service,
                                                                               tag_service=self.tag_service,
                                                                               security_group_service=self.security_group_service)

        self.vm_details_operation = VmDetailsOperation(instance_service=self.instance_service,
                                                       vm_details_provider=self.vm_details_provider)

    def cleanup_connectivity(self, command_context, actions):
        """
        Will delete the reservation vpc and all related resources including all remaining instances
        :param ResourceCommandContext command_context:
        :param list[RequestActionBase] actions::
        :return: json string response
        :rtype: str
        """

        with AwsShellContext(context=command_context, aws_session_manager=self.aws_session_manager) as shell_context:
            with ErrorHandlingContext(shell_context.logger):
                shell_context.logger.info('Cleanup Connectivity')

                result = self.clean_up_operation \
                    .cleanup(ec2_client=shell_context.aws_api.ec2_client,
                             ec2_session=shell_context.aws_api.ec2_session,
                             s3_session=shell_context.aws_api.s3_session,
                             aws_ec2_data_model=shell_context.aws_ec2_resource_model,
                             reservation_id=command_context.reservation.reservation_id,
                             actions=actions,
                             logger=shell_context.logger)
                return self.command_result_parser.set_command_result(
                    {'driverResponse': {'actionResults': [result]}})

    def prepare_connectivity(self, command_context, actions, cancellation_context):
        """
        Will create a vpc for the reservation and will peer it with the management vpc
        :param ResourceCommandContext command_context: The Command Context
        :param list[RequestActionBase] actions:
        :return: json string response
        :param CancellationContext cancellation_context:
        :rtype: list[ActionResultBase]
        """
        with AwsShellContext(context=command_context, aws_session_manager=self.aws_session_manager) as shell_context:
            with ErrorHandlingContext(shell_context.logger):
                shell_context.logger.info('Prepare Connectivity')

                results = self.prepare_connectivity_operation.prepare_connectivity(
                    ec2_client=shell_context.aws_api.ec2_client,
                    ec2_session=shell_context.aws_api.ec2_session,
                    s3_session=shell_context.aws_api.s3_session,
                    reservation=self.model_parser.convert_to_reservation_model(command_context.reservation),
                    aws_ec2_datamodel=shell_context.aws_ec2_resource_model,
                    actions=actions,
                    cancellation_context=cancellation_context,
                    logger=shell_context.logger)

                return results

    def power_on_ami(self, command_context):
        """
        Will power on the ami
        :param ResourceRemoteCommandContext command_context:
        """
        with AwsShellContext(context=command_context, aws_session_manager=self.aws_session_manager) as shell_context:
            with ErrorHandlingContext(shell_context.logger):
                shell_context.logger.info('Power On')

                resource = command_context.remote_endpoints[0]
                data_holder = self.model_parser.convert_app_resource_to_deployed_app(resource)

                self.power_management_operation.power_on(ec2_session=shell_context.aws_api.ec2_session,
                                                         ami_id=data_holder.vmdetails.uid)

    def power_off_ami(self, command_context):
        """
        Will power on the ami
        :param ResourceRemoteCommandContext command_context:
        """
        with AwsShellContext(context=command_context, aws_session_manager=self.aws_session_manager) as shell_context:
            with ErrorHandlingContext(shell_context.logger):
                shell_context.logger.info('Power Off')

                resource = command_context.remote_endpoints[0]
                data_holder = self.model_parser.convert_app_resource_to_deployed_app(resource)

                self.power_management_operation.power_off(ec2_session=shell_context.aws_api.ec2_session,
                                                          ami_id=data_holder.vmdetails.uid)

    def delete_instance(self, command_context):
        """
        Will delete the ami instance
        :param ResourceRemoteCommandContext command_context:
        """
        with AwsShellContext(context=command_context, aws_session_manager=self.aws_session_manager) as shell_context:
            with ErrorHandlingContext(shell_context.logger):
                shell_context.logger.info('Delete instance')

                resource = command_context.remote_endpoints[0]
                data_holder = self.model_parser.convert_app_resource_to_deployed_app(resource)

                self.delete_ami_operation.delete_instance(logger=shell_context.logger,
                                                          ec2_session=shell_context.aws_api.ec2_session,
                                                          instance_id=data_holder.vmdetails.uid)

    def get_application_ports(self, command_context):
        """
        Will return the application ports in a nicely formated manner
        :param ResourceRemoteCommandContext command_context:
        :rtype: str
        """
        with AwsShellContext(context=command_context, aws_session_manager=self.aws_session_manager) as shell_context:
            with ErrorHandlingContext(shell_context.logger):
                shell_context.logger.info('Get Application Ports')
                resource = command_context.remote_endpoints[0]

                # Get instance id
                deployed_instance_id = self.model_parser.try_get_deployed_connected_resource_instance_id(
                    command_context)

                # Get Allow all Storage Traffic on deployed resource
                allow_all_storage_traffic = self.model_parser.get_allow_all_storage_traffic_from_connected_resource_details(
                    command_context)

                return self.deployed_app_ports_operation.get_app_ports_from_cloud_provider(
                    ec2_session=shell_context.aws_api.ec2_session,
                    instance_id=deployed_instance_id,
                    resource=resource,
                    allow_all_storage_traffic=allow_all_storage_traffic)

    def deploy_ami(self, command_context, actions, cancellation_context):
        """
        Will deploy Amazon Image on the cloud provider
        :param ResourceCommandContext command_context:
        :param list[RequestActionBase] actions::
        :param CancellationContext cancellation_context:
        """
        with AwsShellContext(context=command_context, aws_session_manager=self.aws_session_manager) as shell_context:
            with ErrorHandlingContext(shell_context.logger):
                shell_context.logger.info('Deploying AMI')

                deploy_action = single(actions, lambda x: isinstance(x, DeployApp))
                network_actions = [a for a in actions if isinstance(a, ConnectSubnet)]

                deploy_data = self.deploy_ami_operation \
                    .deploy(ec2_session=shell_context.aws_api.ec2_session,
                            s3_session=shell_context.aws_api.s3_session,
                            name=deploy_action.actionParams.appName,
                            reservation=self.model_parser.convert_to_reservation_model(command_context.reservation),
                            aws_ec2_cp_resource_model=shell_context.aws_ec2_resource_model,
                            ami_deploy_action=deploy_action,
                            network_actions=network_actions,
                            ec2_client=shell_context.aws_api.ec2_client,
                            cancellation_context=cancellation_context,
                            logger=shell_context.logger)

                return deploy_data

    def refresh_ip(self, command_context):
        """
        :param ResourceRemoteCommandContext command_context:
        """
        with AwsShellContext(context=command_context, aws_session_manager=self.aws_session_manager) as shell_context:
            with ErrorHandlingContext(shell_context.logger):
                shell_context.logger.info('Refresh IP')

                # Get Private Ip on deployed resource
                private_ip_on_resource = self.model_parser.get_private_ip_from_connected_resource_details(
                    command_context)
                # Get Public IP on deployed resource
                public_ip_on_resource = self.model_parser.get_public_ip_from_connected_resource_details(
                    command_context)
                # Get instance id
                deployed_instance_id = self.model_parser.try_get_deployed_connected_resource_instance_id(
                    command_context)
                # Get connected resource name
                resource_fullname = self.model_parser.get_connectd_resource_fullname(command_context)

                self.refresh_ip_operation.refresh_ip(cloudshell_session=shell_context.cloudshell_session,
                                                     ec2_session=shell_context.aws_api.ec2_session,
                                                     deployed_instance_id=deployed_instance_id,
                                                     private_ip_on_resource=private_ip_on_resource,
                                                     public_ip_on_resource=public_ip_on_resource,
                                                     resource_fullname=resource_fullname)

    def get_access_key(self, command_context):
        """
        Returns the pem file for the connected resource
        :param ResourceRemoteCommandContext command_context:
        :rtype str:
        """
        with AwsShellContext(context=command_context, aws_session_manager=self.aws_session_manager) as shell_context:
            with ErrorHandlingContext(shell_context.logger):
                shell_context.logger.info('GetAccessKey')
                reservation_id = self._get_reservation_id(command_context)
                return self.access_key_operation.get_access_key(s3_session=shell_context.aws_api.s3_session,
                                                                aws_ec2_resource_model=shell_context.aws_ec2_resource_model,
                                                                reservation_id=reservation_id)

    def set_app_security_groups(self, context, request):
        """
        Set security groups (inbound rules only)
        :param context: todo - set the type of the parameter
        :param request: The json request
        :return:
        """
        with AwsShellContext(context=context, aws_session_manager=self.aws_session_manager) as shell_context:
            with ErrorHandlingContext(shell_context.logger):
                shell_context.logger.info('Set App Security Groups')

                reservation = self.model_parser.convert_to_reservation_model(context.reservation)
                app_security_group_models = self.model_parser.convert_to_app_security_group_models(request)

                result = self.set_app_security_groups_operation.set_apps_security_groups(
                    app_security_group_models=app_security_group_models,
                    reservation=reservation,
                    ec2_session=shell_context.aws_api.ec2_session,
                    logger=shell_context.logger)

                json_result = SetAppSecurityGroupActionResult.to_json(result)

                return json_result

    def get_vm_details(self, context, cancellation_context, requests_json):
        """
        Get vm details for specific deployed app
        :type context: ResourceCommandContext
        :rtype str
        """
        results = []
        vm_details_requests = [VmDetailsRequest(item) for item in
                               DeployDataHolder(jsonpickle.decode(requests_json)).items]

        for request in vm_details_requests:
            if cancellation_context.is_cancelled:
                break

            try:
                with AwsShellContext(context=context, aws_session_manager=self.aws_session_manager) as shell_context:
                    with ErrorHandlingContext(shell_context.logger):
                        shell_context.logger.info('Get VmDetails')
                        vm_details = self.vm_details_operation.get_vm_details(request.uuid,
                                                                              shell_context.aws_api.ec2_session)
                        vm_details.appName = request.app_name
                        results.append(vm_details)
            except Exception as e:
                result = VmDetailsData()
                result.appName = request.app_name
                result.error = e.message
                results.append(result)

        return self.command_result_parser.set_command_result(results)

    @staticmethod
    def _get_reservation_id(context):
        reservation_id = None
        reservation = getattr(context, 'reservation', getattr(context, 'remote_reservation', None))
        if reservation:
            reservation_id = reservation.reservation_id
        return reservation_id