def test_batch_network_configuration(self, **kwargs):
        client = self.create_aad_client(**kwargs)
        # Test Create Pool with Network Config
        network_config = models.NetworkConfiguration(
            endpoint_configuration=models.PoolEndpointConfiguration(
                inbound_nat_pools=[
                    models.InboundNATPool(
                        name="TestEndpointConfig",
                        protocol=models.InboundEndpointProtocol.udp,
                        backend_port=64444,
                        frontend_port_range_start=60000,
                        frontend_port_range_end=61000,
                        network_security_group_rules=[
                            models.NetworkSecurityGroupRule(
                                priority=150,
                                access=models.NetworkSecurityGroupRuleAccess.allow,
                                source_address_prefix='*'
                            )
                        ]
                    )
                ]
            )
        )
        virtual_machine_config = models.VirtualMachineConfiguration(
            node_agent_sku_id="batch.node.ubuntu 16.04",
            image_reference=models.ImageReference(
                publisher="Canonical",
                offer="UbuntuServer",
                sku="16.04-LTS")
        )
        pool = models.PoolAddParameter(
            id=self.get_resource_name('batch_network_'),
            target_dedicated_nodes=1,
            vm_size='Standard_A1',
            virtual_machine_configuration=virtual_machine_config,
            network_configuration=network_config
        )

        client.pool.add(pool)
        network_pool = client.pool.get(pool.id)
        while self.is_live and network_pool.allocation_state != models.AllocationState.steady:
            time.sleep(10)
            network_pool = client.pool.get(pool.id)

        # Test Compute Node Config
        nodes = list(client.compute_node.list(pool.id))
        self.assertEqual(len(nodes), 1)
        self.assertIsInstance(nodes[0], models.ComputeNode)
        self.assertEqual(len(nodes[0].endpoint_configuration.inbound_endpoints), 2)
        self.assertEqual(nodes[0].endpoint_configuration.inbound_endpoints[0].name, 'TestEndpointConfig.0')
        self.assertEqual(nodes[0].endpoint_configuration.inbound_endpoints[0].protocol.value, 'udp')
    def check_or_create_pool(self, id=None):
        if id is None:
            id = self.config.get('POOL', 'id')

        self.pool_id = id

        if self.client.pool.exists(id):
            found_job = False
            # Update the Job ID here
            for job in self.client.job.list():
                if job.pool_info.pool_id == self.pool_id:
                    self.job_id = job.id
                    found_job = True
                    break
            if not found_job:
                self.start_mc_server_job_pool(
                )  # Restart Jobs for this pool - this is necessary!
            return self.client.pool.get(id)

        api_port = self.config.get('POOL', 'api_port')
        min_count = self.config.get('POOL', 'mincount')

        image_reference = batchmodels.ImageReference(
            virtual_machine_image_id=
            "/subscriptions/889566d5-6e5d-4d31-a82d-b60603b3e50b/resourceGroups/polycraft-game/providers/Microsoft.Compute/galleries/polycraftImgGallery/images/polycraftBestGameServerV1/versions/1.0.0"
        )

        vmc = batchmodels.VirtualMachineConfiguration(
            image_reference=image_reference,
            node_agent_sku_id="batch.node.ubuntu 18.04")

        users = [
            batchmodels.UserAccount(
                name='azureuser',
                password='******',
                elevation_level=batchmodels.ElevationLevel.admin),
            # batchmodels.UserAccount(
            #     name='pool-nonadmin',
            #     password='******',
            #     elevation_level=batchmodels.ElevationLevel.non_admin)
        ]

        # Thank you Ask Ubuntu https://askubuntu.com/a/373478
        wait_for_locks = 'while sudo fuser /var/lib/dpkg/lock /var/lib/apt/lists/lock /var/cache/apt/archives/lock /var/lib/dpkg/lock-frontend >/dev/null 2>&1; do echo "Waiting for release of apt locks"; sleep 2; done; '

        # NOTE: Always use DOUBLE QUOTES within commands as azure prepends the entire string with a single quote.
        start_task = batchmodels.StartTask(
            command_line=helpers.wrap_commands_in_shell(
                'linux',
                [
                    'whoami',
                    'printenv',
                    'usermod -aG sudo azureuser',
                    'sudo systemctl disable --now apt-daily.timer',
                    'sudo systemctl disable --now apt-daily-upgrade.timer',
                    'sudo systemctl daemon-reload',
                    'cd /home/polycraft',
                    'chmod -R 777 *',
                    'rm /home/polycraft/oxygen/mods/*.jar',
                    'cd /home/polycraft/oxygen/',
                    'echo "[DEBUG] removing helium..."',
                    'ls -l',
                    f'sudo rm -rf /home/polycraft/oxygen/{self.config.get("SERVER","worldName")}',
                    'sudo rm -f *.zip',
                    'echo "[DEBUG] removed helium?"',
                    'ls -l',
                    # Stop the crontabs from running
                    'sudo rm /var/spool/cron/crontabs/*',
                    # Taken from: https://stackoverflow.com/questions/45269225/ansible-playbook-fails-to-lock-apt/51919678#51919678
                    'sudo systemd-run --property="After=apt-daily.service apt-daily-upgrade.service" --wait /bin/true',
                    'sudo apt-get -y purge unattended-upgrades',
                    'sudo apt-get -y update',
                    wait_for_locks +
                    'sudo apt-get install software-properties-common -y',
                    # 'while fuser /var/lib/dpkg/lock >/dev/null 2>&1; do sleep 1; done; sudo apt-add-repository universe',
                    wait_for_locks + 'sudo apt-add-repository universe',
                    # Mount the Polycraft Game FileShare
                    wait_for_locks +
                    'sudo apt-get install cifs-utils -y && sudo mkdir -p /mnt/PolycraftGame/',
                    f'mount -t cifs //polycraftbestbatch.file.core.windows.net/best-batch-round-1-test /mnt/PolycraftGame -o vers=3.0,username={self.credentials.get("Storage", "storageaccountname")},password={self.credentials.get("Storage", "storageaccountkey")},dir_mode=0777,file_mode=0777,serverino && ls /mnt/PolycraftGame',
                    # Copy the default world file to the right folder
                    f'cp /mnt/PolycraftGame/{self.config.get("SERVER","fileShareFolder")}/worlds/{self.config.get("SERVER","worldZipName")}.tar.gz /home/polycraft/oxygen/',
                    'cd /home/polycraft/oxygen/',
                    # 'sudo rm -r helium',
                    f'gzip -d /home/polycraft/oxygen/{self.config.get("SERVER","worldZipName")}.tar.gz',
                    'echo "[DEBUG] extracting the tar"',
                    'ls -l',
                    f'sudo tar -xf {self.config.get("SERVER","worldZipName")}.tar',
                    'echo "[DEBUG] extracted the tar"',
                    'ls -l',
                    # 'sudo mv helium-backup-0924 helium',
                    f'sudo mv helium {self.config.get("SERVER","worldName")}',  # TODO Remove this once we finalize the server name?
                    f'chmod -R 777 {self.config.get("SERVER","worldName")}/',  #  NOTE: The folder inside here is called helium!
                    'echo "[DEBUG] Adjusted permissions for helium?"',
                    'ls -l',
                ]),
            wait_for_success=True,
            # user_accounts=users,
            user_identity=batchmodels.UserIdentity(
                # user_name='azureuser',
                auto_user=batchmodels.AutoUserSpecification(
                    scope=batchmodels.AutoUserScope.pool,
                    elevation_level=batchmodels.ElevationLevel.admin)
                # ),
            ),
        )

        net_config = batchmodels.NetworkConfiguration(
            # subnet_id="/subscriptions/889566d5-6e5d-4d31-a82d-b60603b3e50b/resourceGroups/vnet-eastus-azurebatch/providers/Microsoft.Network/virtualNetworks/vnet-eastus-azurebatch/subnets/main-batch-subnet",
            endpoint_configuration=batchmodels.
            PoolEndpointConfiguration(inbound_nat_pools=[
                batchmodels.InboundNATPool(
                    name='minecraftServer',
                    protocol='tcp',
                    backend_port=25565,
                    frontend_port_range_start=44000,
                    frontend_port_range_end=44099,
                    network_security_group_rules=[
                        batchmodels.NetworkSecurityGroupRule(
                            priority=199,
                            access='allow',
                            source_address_prefix='*'),
                    ]),
                batchmodels.InboundNATPool(
                    name='api_port',
                    protocol='tcp',
                    backend_port=int(api_port)
                    if api_port and api_port.isdecimal() else 9007,
                    frontend_port_range_start=44500,
                    frontend_port_range_end=44599,
                    network_security_group_rules=[
                        # batchmodels.NetworkSecurityGroupRule(
                        #     priority=170,
                        #     access='allow',
                        #     source_address_prefix='192.168.1.0/24'      # TODO: is this the right subnet?
                        # ),
                        batchmodels.NetworkSecurityGroupRule(
                            priority=198,
                            access='allow',  # 'deny'
                            source_address_prefix=
                            '*'  # TODO: only allow access to the right ports
                        )
                    ]),
            ]))

        pool = batchmodels.PoolAddParameter(
            id=id,
            vm_size=self.config.get('POOL', 'vm_size'),
            target_dedicated_nodes=int(min_count)
            if min_count and min_count.isdecimal() else 1,
            virtual_machine_configuration=vmc,
            start_task=start_task,
            user_accounts=users,
            network_configuration=net_config)

        helpers.create_pool_if_not_exist(self.client, pool)
        self.start_mc_server_job_pool(pool.target_dedicated_nodes)
예제 #3
0
    def create_pool(self,
                    pool_id,
                    vm_size,
                    target_dedicated,
                    target_low_priority,
                    batch_image_spec,
                    starttask_cmd,
                    starttask_url,
                    starttask_script,
                    sp_cert_thumb,
                    app_licenses=None,
                    disable_remote_access=True,
                    app_pkgs=None,
                    subnet_id=None,
                    app_insights_app_key=None,
                    app_insights_instrumentation_key=None):

        pool = batchmodels.PoolAddParameter(
            id=pool_id,
            display_name=pool_id,
            vm_size=vm_size,
            target_dedicated_nodes=target_dedicated,
            target_low_priority_nodes=target_low_priority,
            virtual_machine_configuration=batch_image_spec.
            get_virtual_machine_configuration(),
            application_package_references=app_pkgs,
            certificate_references=[
                batchmodels.CertificateReference(sp_cert_thumb, 'sha1')
            ])

        if app_licenses:
            pool.application_licenses = app_licenses

        pool.start_task = batchmodels.StartTask(
            command_line=starttask_cmd,
            max_task_retry_count=3,
            user_identity=batchmodels.UserIdentity(
                auto_user=batchmodels.AutoUserSpecification(
                    scope=batchmodels.AutoUserScope.pool,
                    elevation_level=batchmodels.ElevationLevel.admin)),
            wait_for_success=True,
            resource_files=[
                batchmodels.ResourceFile(starttask_url, starttask_script)
            ])

        if app_insights_app_key and app_insights_instrumentation_key:
            pool.start_task.environment_settings = [
                batchmodels.EnvironmentSetting('APP_INSIGHTS_APP_ID',
                                               app_insights_app_key),
                batchmodels.EnvironmentSetting(
                    'APP_INSIGHTS_INSTRUMENTATION_KEY',
                    app_insights_instrumentation_key)
            ]

        if subnet_id:
            pool.network_configuration = batchmodels.NetworkConfiguration(
                subnet_id=subnet_id)

        if disable_remote_access:
            if pool.network_configuration is None:
                pool.network_configuration = batchmodels.NetworkConfiguration()
            endpoint_config = batchmodels.PoolEndpointConfiguration(
                inbound_nat_pools=[
                    batchmodels.InboundNATPool(
                        'DisableRDP',
                        batchmodels.InboundEndpointProtocol.tcp,
                        3389,
                        60000,
                        60099,
                        network_security_group_rules=[
                            batchmodels.NetworkSecurityGroupRule(
                                150, batchmodels.
                                NetworkSecurityGroupRuleAccess.deny, '*')
                        ]),
                    batchmodels.InboundNATPool(
                        'DisableSSH',
                        batchmodels.InboundEndpointProtocol.tcp,
                        22,
                        61000,
                        61099,
                        network_security_group_rules=[
                            batchmodels.NetworkSecurityGroupRule(
                                151, batchmodels.
                                NetworkSecurityGroupRuleAccess.deny, '*')
                        ])
                ])
            pool.network_configuration.endpoint_configuration = endpoint_config

        try:
            client = self._get_batch_client()
            client.pool.add(pool)
        except batchmodels.BatchErrorException as be:
            if be.error:
                print('Error creating pool, code={}, message={}'.format(
                    be.error.code, be.error.message))
                if be.error.values:
                    for e in be.error.values:
                        print('Key={}, Value={}'.format(e.key, e.value))
            raise