Пример #1
0
def _query_cost_native(scope: Union[AzureBillingAccount,
                                    AzureSubscriptionHandle],
                       query: QueryDefinition,
                       max_pages: int) -> List[QueryResult]:
    client = default_sdk_client(CostManagementClient)
    raw_result: ClientRawResponse = client.query.usage(scope.resource_id(),
                                                       query,
                                                       raw=True)
    result = raw_result.output
    results = [result]
    next_link = result.next_link

    if next_link:
        pages = 1
        headers = raw_result.response.request.headers
        body = json.loads(raw_result.response.request.body)
        service_client = client._client
        while next_link:
            if pages == max_pages:
                raise Exception(
                    "More results remain after max pages of cost query.")
            request = service_client.post(next_link,
                                          headers=headers,
                                          content=body)
            response = service_client.send(request, stream=False)
            if response.status_code != 200:
                raise Exception("Failed to get next page of cost query.")
            result = client.query._deserialize('QueryResult', response)
            next_link = result.next_link
            results.append(result)
            pages += 1

    return results
Пример #2
0
def _query_native(subscriptions: Iterable[str], query: str,
                  max_pages) -> List[QueryResponse]:
    client = default_sdk_client(ResourceGraphClient)
    query_options = QueryRequestOptions()
    query_request = QueryRequest(subscriptions=realize_sequence(subscriptions),
                                 query=query,
                                 options=query_options)
    query_response: QueryResponse = client.resources(query_request)

    if query_response.result_truncated is ResultTruncated.true:
        raise RuntimeError(
            "results are truncated. project id to enable paging.")

    if query_response.skip_token:
        page_size = query_response.count
        if query_response.total_records > page_size * max_pages:
            raise RuntimeError("too many results. increase max pages.")

    responses = [query_response]
    while query_response.skip_token:
        query_options = QueryRequestOptions(
            skip_token=query_response.skip_token)
        query_request = QueryRequest(subscriptions=subscriptions,
                                     query=query,
                                     options=query_options)
        query_response = client.resources(query_request)
        responses.append(query_response)

    return responses
Пример #3
0
def _reservations_native() -> List[ReservationResponse]:
    api = default_sdk_client(AzureReservationAPI)

    try:
        original_url = ReservationOperations.list.metadata['url']
        # Monkey Patch the Python SDK. A wrapper for this functionality is missing.
        ReservationOperations.list.metadata[
            'url'] = '/providers/Microsoft.Capacity/reservations'
        # list() input is ignored due to patch above.
        all_results = list(api.reservation.list('*'))
    finally:
        ReservationOperations.list.metadata['url'] = original_url

    return all_results
Пример #4
0
def get_billing_accounts() -> List[AzureBillingAccount]:
    billing_client = default_sdk_client(BillingManagementClient)
    service_client = billing_client._client
    url = service_client.format_url(
        "/providers/Microsoft.Billing/billingAccounts")
    query_parameters = {"api-version": "2019-10-01-preview"}
    request = service_client.get(url, query_parameters)
    response = service_client.send(request, stream=False)
    if response.status_code != 200:
        raise Exception("Failed to enumerate billing accounts.")
    raw_accounts = json.loads(response.content)["value"]
    return [
        AzureBillingAccount(a["name"],
                            a["properties"]["displayName"],
                            is_default=True) for a in raw_accounts if
        a.get("properties", {}).get("agreementType") == "EnterpriseAgreement"
    ]
Пример #5
0
def get_billing_periods(limit: int = 12) -> List[BillingPeriod]:
    billing_client = default_sdk_client(BillingManagementClient)
    return list(
        itertools.islice(billing_client.billing_periods.list(top=limit),
                         limit))
Пример #6
0
def load_compute_specifications(logger: Logger) -> AzureComputeSpecifications:
    client = default_sdk_client(ComputeManagementClient)
    sku_pages: Iterable[ResourceSku] = client.resource_skus.list(
        filter="location eq 'eastus2'")
    specifications = AzureComputeSpecifications()
    for sku in sku_pages:
        if sku.resource_type not in ('virtualMachines', 'disks'):
            continue
        capabilities: Mapping[str, str] = {
            c.name: c.value
            for c in sku.capabilities
        }
        if sku.resource_type == 'virtualMachines':
            if sku.family == 'standardBSFamily' and 'ACUs' not in capabilities:
                capabilities['ACUs'] = 160

            # Bugs in data
            if sku.family in ('standardBSFamily', 'standardHBSFamily',
                              'standardHBrsv2Family', 'standardDCSv2Family',
                              'standardNCSv2Family', 'standardNCSv3Family',
                              'standardHCSFamily', 'standardNVSv3Family',
                              'standardNVSv4Family', 'standardNDSFamily',
                              'standardMSv2Family'):
                capabilities['EphemeralOSDiskSupported'] = 'False'
            elif sku.family in ('standardDSv2PromoFamily', 'standardMSFamily'):
                capabilities['EphemeralOSDiskSupported'] = 'True'

            match_constrained = re.search(r'-(\d+)', sku.name)
            if match_constrained is not None:
                constraint = float(match_constrained[1])
                vcpus = map_if_not_none(capabilities.get('vCPUs'), float)
                vcpus_available = map_if_not_none(
                    capabilities.get('vCPUsAvailable'), float)
                if vcpus == vcpus_available or vcpus_available != constraint:
                    logger.warning(
                        f'Auto-corrected likely incorrect data from ARM from SKU {sku.name}. vcpus: {vcpus} avail: {vcpus_available}'
                    )
                    capabilities['vCPUsAvailable'] = constraint

            if sku.name == 'Standard_E20_v3':
                capabilities['HyperVGenerations'] = 'V1,V2'

            if map_if_not_none(capabilities.get('PremiumIO'),
                               _parse_bool) is False:
                if 'UncachedDiskBytesPerSecond' not in capabilities:
                    capabilities['UncachedDiskBytesPerSecond'] = 60 * 1024**2
                if 'UncachedDiskIOPS' not in capabilities:
                    capabilities['UncachedDiskIOPS'] = 500

            vm_capability_tuple = VirtualMachineCapabilities(
                acus=map_if_not_none(capabilities.get('ACUs'), float),
                accelerated_networking_enabled=map_if_not_none(
                    capabilities.get('AcceleratedNetworkingEnabled'),
                    _parse_bool),
                cached_disk_bytes=map_if_not_none(
                    capabilities.get('CachedDiskBytes'), float),
                combined_temp_disk_and_cached_iops=map_if_not_none(
                    capabilities.get('CombinedTempDiskAndCachedIOPS'), float),
                combined_temp_disk_and_cached_read_bytes_per_second=
                map_if_not_none(
                    capabilities.get(
                        'CombinedTempDiskAndCachedReadBytesPerSecond'), float),
                combined_temp_disk_and_cached_write_bytes_per_second=
                map_if_not_none(
                    capabilities.get(
                        'CombinedTempDiskAndCachedWriteBytesPerSecond'),
                    float),
                ephemeral_os_disk_supported=map_if_not_none(
                    capabilities.get('EphemeralOSDiskSupported'), _parse_bool),
                gpus=map_if_not_none(capabilities.get('GPUs'), float),
                hyperv_generations=capabilities.get(
                    'HyperVGenerations'),  # type: ignore
                low_priority_capable=map_if_not_none(
                    capabilities.get('LowPriorityCapable'), _parse_bool),
                max_data_disk_count=map_if_not_none(
                    capabilities.get('MaxDataDiskCount'), float),
                max_network_interfaces=map_if_not_none(
                    capabilities.get('MaxNetworkInterfaces'), float),
                max_resource_volume_mb=map_if_not_none(
                    capabilities.get('MaxResourceVolumeMB'), float),
                max_write_accelerator_disks_allowed=map_if_not_none(
                    capabilities.get('MaxWriteAcceleratorDisksAllowed'),
                    float),
                memory_gb=map_if_not_none(capabilities.get('MemoryGB'), float),
                os_vhd_size_mb=map_if_not_none(capabilities.get('OSVhdSizeMB'),
                                               float),
                parent_size=capabilities.get('ParentSize'),  # type: ignore
                premium_io=map_if_not_none(capabilities.get('PremiumIO'),
                                           _parse_bool),
                rdma_enabled=map_if_not_none(capabilities.get('RdmaEnabled'),
                                             _parse_bool),
                uncached_disk_bytes_per_second=map_if_not_none(
                    capabilities.get('UncachedDiskBytesPerSecond'), float),
                uncached_disk_iops=map_if_not_none(
                    capabilities.get('UncachedDiskIOPS'), float),
                vcpus=map_if_not_none(capabilities.get('vCPUs'), float),
                vcpus_available=map_if_not_none(
                    capabilities.get('vCPUsAvailable'), float),
                vcpus_per_core=map_if_not_none(
                    capabilities.get('vCPUsPerCore'), float))
            key = sku.name.lower()
            existing_vm = specifications._virtual_machine_skus.get(key)
            if existing_vm is not None:
                assert existing_vm.capabilities == vm_capability_tuple
                #if not (existing_vm.capabilities == vm_capability_tuple):
                #    print(f"** OMG: {sku.name} - {sku.family} mistmatch")
                continue
            specifications._virtual_machine_skus[key] = VirtualMachineSku(
                sku.tier, sku.family, sku.name, sku.size, vm_capability_tuple)
        elif sku.resource_type == 'disks':
            disk_capability_tuple = ManagedDiskCapabilities(
                billing_partition_sizes=capabilities.get(
                    'BillingPartitionSizes'),  # type: ignore
                max_bandwidth_mbps=map_if_not_none(
                    capabilities.get('MaxBandwidthMBps'), float),
                max_bandwidth_mbps_read_only=map_if_not_none(
                    capabilities.get('MaxBandwidthMBpsReadOnly'), float),
                max_bandwidth_mbps_read_write=map_if_not_none(
                    capabilities.get('MaxBandwidthMBpsReadWrite'), float),
                max_io_size_kibps=map_if_not_none(
                    capabilities.get('MaxIOSizeKiBps'), float),
                max_iops=map_if_not_none(capabilities.get('MaxIOps'), float),
                max_iops_read_write=map_if_not_none(
                    capabilities.get('MaxIOpsReadWrite'), float),
                max_iops_per_gib_read_only=map_if_not_none(
                    capabilities.get('MaxIopsPerGiBReadOnly'), float),
                max_iops_per_gib_read_write=map_if_not_none(
                    capabilities.get('MaxIopsPerGiBReadWrite'), float),
                max_iops_read_only=map_if_not_none(
                    capabilities.get('MaxIopsReadOnly'), float),
                max_size_gib=map_if_not_none(capabilities.get('MaxSizeGiB'),
                                             float),
                min_bandwidth_mbps=map_if_not_none(
                    capabilities.get('MinBandwidthMBps'), float),
                min_bandwidth_mbps_read_only=map_if_not_none(
                    capabilities.get('MinBandwidthMBpsReadOnly'), float),
                min_bandwidth_mbps_read_write=map_if_not_none(
                    capabilities.get('MinBandwidthMBpsReadWrite'), float),
                min_io_size_kibps=map_if_not_none(
                    capabilities.get('MinIOSizeKiBps'), float),
                min_iops=map_if_not_none(capabilities.get('MinIOps'), float),
                min_iops_read_write=map_if_not_none(
                    capabilities.get('MinIOpsReadWrite'), float),
                min_iops_per_gib_read_only=map_if_not_none(
                    capabilities.get('MinIopsPerGiBReadOnly'), float),
                min_iops_per_gib_read_write=map_if_not_none(
                    capabilities.get('MinIopsPerGiBReadWrite'), float),
                min_iops_read_only=map_if_not_none(
                    capabilities.get('MinIopsReadOnly'), float),
                min_size_gib=map_if_not_none(capabilities.get('MinSizeGiB'),
                                             float))
            key = sku.size.lower()
            existing_disk = specifications._managed_disk_skus.get(key)
            if existing_disk is not None:
                if sku.size not in (
                        'E4', 'P4'
                ):  # these skus vary in their min size across locations for some reason.
                    assert existing_disk.capabilities == disk_capability_tuple
                continue
            specifications._managed_disk_skus[key] = ManagedDiskSku(
                sku.tier, sku.name, sku.size, disk_capability_tuple)

    return specifications
Пример #7
0
 def get_iter_for_sub(subscription: str) ->  Iterable[ResourceRecommendationBase]:
     client = default_sdk_client(AdvisorManagementClient, subscription_id=subscription)
     return client.recommendations.list(filter="Category eq 'Cost'")