diff --git a/CHANGELOG.md b/CHANGELOG.md index fc955eb8..88caedf8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [2.3.0] - 2023-11-25 +### Added +- Added support for Azure Stateful Node APIs: `swap_os_disk_to_stateful_node`, `get_all_stateful_node_costs`, +`get_all_stateful_node_aggregated_daily_costs`, `get_stateful_node_size_usage`. + +### Fixed +- Updated fields in all Azure Stateful Node model classes as per latest schema. + ## [2.2.2] - 2023-11-20 ### Fixed - Passing query parameters in `delete_virtual_node_group` API for AWS Ocean. @@ -37,7 +45,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [2.1.40] - 2023-07-31 ### Added - Add support for GCP Eastigroup APIs: `get_elastilog`, `get_cost_per_account`, `get_instance_status`, -- `lock_instance`, `unlock_instance` +`lock_instance`, `unlock_instance` ## [2.1.39] - 2023-07-17 ### Added diff --git a/docs/clients/stateful_node/stateful_node_azure_client.md b/docs/clients/stateful_node/stateful_node_azure_client.md index c5779d36..d3a09e3d 100644 --- a/docs/clients/stateful_node/stateful_node_azure_client.md +++ b/docs/clients/stateful_node/stateful_node_azure_client.md @@ -83,7 +83,8 @@ __Returns__

get_all_stateful_nodes

```python -StatefulNodeAzureClient.get_all_stateful_nodes() +StatefulNodeAzureClient.get_all_stateful_nodes(name: str = None, + region: str = None) ``` Get all Stateful Nodes @@ -267,3 +268,78 @@ __Returns__ `(Object)`: Stateful Node API response +

swap_os_disk_to_stateful_node

+ +```python +StatefulNodeAzureClient.swap_os_disk_to_stateful_node( + node_id: str, swap_osdisk_configuration: SwapOsDiskConfiguration) +``` + +Configure a new managed OS disk for an OS persisted paused Stateful Node + +__Arguments__ + +- __node_id (String)__: Stateful Node ID +- __swap_osdisk_configuration (SwapOsDiskConfiguration)__: Configuration of OS Disk + +__Returns__ + +`(Object)`: StatefulNode API response + +

get_all_stateful_node_costs

+ +```python +StatefulNodeAzureClient.get_all_stateful_node_costs( + from_date: str, to_date: str, owner_id: str = None) +``` + +Get the total costs of a single stateful node/all stateful nodes and for a specific time period. + +__Arguments__ + +- __to_date (String)__: On or Before this date +- __from_date (String)__: On or After this date +- __ownerId (String) (Optional)__: Log level severity + +__Returns__ + +`(Object)`: Stateful Node API response + +

get_all_stateful_node_aggregated_daily_costs

+ +```python +StatefulNodeAzureClient.get_all_stateful_node_aggregated_daily_costs( + from_date: str, to_date: str, owner_id: str = None) +``` + +Get the total costs per day of a single stateful node/all stateful nodes and for a specific time period. + +__Arguments__ + +- __to_date (String)__: On or Before this date +- __from_date (String)__: On or After this date +- __ownerId (String) (Optional)__: Log level severity + +__Returns__ + +`(Object)`: Stateful Node API response + +

get_stateful_node_size_usage

+ +```python +StatefulNodeAzureClient.get_stateful_node_size_usage( + from_date: str, to_date: str, owner_id: str = None) +``` + +Get the daily costs per VM size of a single stateful node/all stateful nodes and for a specific time period. + +__Arguments__ + +- __to_date (String)__: On or Before this date +- __from_date (String)__: On or After this date +- __ownerId (String) (Optional)__: Log level severity + +__Returns__ + +`(Object)`: Stateful Node API response + diff --git a/docs/models/stateful_node.md b/docs/models/stateful_node.md index 8f677edc..5c387698 100644 --- a/docs/models/stateful_node.md +++ b/docs/models/stateful_node.md @@ -1,13 +1,34 @@

spotinst_sdk2.models.stateful_node

+

PersistenceMode

+ +```python +PersistenceMode(cls, + value, + names=None, + *, + module, + qualname, + type, + start) +``` +An enumeration. +

on_launch

+ + +

reattach

+ +

Persistence

```python Persistence( self, - data_disks_persistence_mode: str = 'd3043820717d74d9a17694c176d39733', - os_disk_persistence_mode: str = 'd3043820717d74d9a17694c176d39733', + data_disks_persistence_mode: + PersistenceMode = 'd3043820717d74d9a17694c176d39733', + os_disk_persistence_mode: + PersistenceMode = 'd3043820717d74d9a17694c176d39733', should_persist_data_disks: bool = 'd3043820717d74d9a17694c176d39733', should_persist_network: bool = 'd3043820717d74d9a17694c176d39733', should_persist_os_disk: bool = 'd3043820717d74d9a17694c176d39733') @@ -15,44 +36,87 @@ Persistence( __Arguments__ -- __data_disks_persistence_mode__: str -- __os_disk_persistence_mode__: str +- __data_disks_persistence_mode__: PersistenceMode +- __os_disk_persistence_mode__: PersistenceMode - __should_persist_data_disks__: bool - __should_persist_network__: bool - __should_persist_os_disk__: bool +

HealthCheckTypes

+ +```python +HealthCheckTypes(cls, + value, + names=None, + *, + module, + qualname, + type, + start) +``` +An enumeration. +

application_gateway

+ + +

vm_state

+ +

Health

```python -Health(self, - health_check_types: - typing.List[str] = 'd3043820717d74d9a17694c176d39733', - auto_healing: bool = 'd3043820717d74d9a17694c176d39733', - grace_period: int = 'd3043820717d74d9a17694c176d39733', - unhealthy_duration: int = 'd3043820717d74d9a17694c176d39733') +Health( + self, + health_check_types: + typing.List[spotinst_sdk2.models.stateful_node.HealthCheckTypes] = 'd3043820717d74d9a17694c176d39733', + auto_healing: bool = 'd3043820717d74d9a17694c176d39733', + grace_period: int = 'd3043820717d74d9a17694c176d39733', + unhealthy_duration: int = 'd3043820717d74d9a17694c176d39733') ``` __Arguments__ -- __health_check_types__: List[str] +- __health_check_types__: List[HealthCheckTypes] - __auto_healing__: bool - __grace_period__: int - __unhealthy_duration__: int +

SchedulingTaskType

+ +```python +SchedulingTaskType(cls, + value, + names=None, + *, + module, + qualname, + type, + start) +``` +An enumeration. +

pause

+ + +

recycle

+ + +

resume

+ +

SchedulingTask

```python -SchedulingTask(self, - is_enabled: bool = 'd3043820717d74d9a17694c176d39733', - cron_expression: str = 'd3043820717d74d9a17694c176d39733', - type: str = 'd3043820717d74d9a17694c176d39733') +SchedulingTask( + self, + is_enabled: bool = 'd3043820717d74d9a17694c176d39733', + cron_expression: str = 'd3043820717d74d9a17694c176d39733', + type: SchedulingTaskType = 'd3043820717d74d9a17694c176d39733') ``` __Arguments__ - __is_enabled__: bool - __cron_expression__: str -- __type__: str +- __type__: SchedulingTaskType

Scheduling

@@ -68,39 +132,143 @@ __Arguments__ - __tasks__: List[SchedulingTask] +

PerformAt

+ +```python +PerformAt(cls, value, names=None, *, module, qualname, type, start) +``` +An enumeration. +

always

+ + +

never

+ + +

time_window

+ +

RevertToSpot

```python -RevertToSpot(self, perform_at: str = 'd3043820717d74d9a17694c176d39733') +RevertToSpot(self, + perform_at: PerformAt = 'd3043820717d74d9a17694c176d39733') ``` __Arguments__ -- __perform_at__: str +- __perform_at__: PerformAt + +

SignalType

+ +```python +SignalType(cls, value, names=None, *, module, qualname, type, start) +``` +An enumeration. +

vm_ready

+ + +

vm_ready_to_shutdown

+

Signal

```python Signal(self, timeout: int = 'd3043820717d74d9a17694c176d39733', - type: str = 'd3043820717d74d9a17694c176d39733') + type: SignalType = 'd3043820717d74d9a17694c176d39733') ``` __Arguments__ - __timeout__: int -- __type__: str +- __type__: SignalType + +

CapacityReservationGroups

+ +```python +CapacityReservationGroups( + self, + name: str = 'd3043820717d74d9a17694c176d39733', + resource_group_name: str = 'd3043820717d74d9a17694c176d39733', + should_prioritize: bool = 'd3043820717d74d9a17694c176d39733') +``` + +__Arguments__ + +- __name__: str +- __resource_group_name__: str +- __should_prioritize__: bool + +

UtilizationStrategy

+ +```python +UtilizationStrategy(cls, + value, + names=None, + *, + module, + qualname, + type, + start) +``` +An enumeration. +

utilize_over_od

+ + +

utilize_over_spot

+ + +

CapacityReservation

+ +```python +CapacityReservation( + self, + capacity_reservation_groups: + typing.List[spotinst_sdk2.models.stateful_node.CapacityReservationGroups] = 'd3043820717d74d9a17694c176d39733', + should_utilize: bool = 'd3043820717d74d9a17694c176d39733', + utilization_strategy: + UtilizationStrategy = 'd3043820717d74d9a17694c176d39733') +``` + +__Arguments__ + +- __capacity_reservation_groups__: List[CapacityReservationGroups] +- __should_utilize__: bool +- __utilization_strategy__: UtilizationStrategy + +

PreferredLifeCycle

+ +```python +PreferredLifeCycle(cls, + value, + names=None, + *, + module, + qualname, + type, + start) +``` +An enumeration. +

od

+ + +

spot

+

Strategy

```python Strategy( self, + availability_vs_cost: int = 'd3043820717d74d9a17694c176d39733', + capacity_reservation: + CapacityReservation = 'd3043820717d74d9a17694c176d39733', draining_timeout: int = 'd3043820717d74d9a17694c176d39733', fallback_to_od: bool = 'd3043820717d74d9a17694c176d39733', od_windows: typing.List[str] = 'd3043820717d74d9a17694c176d39733', optimization_windows: typing.List[str] = 'd3043820717d74d9a17694c176d39733', - preferred_lifecycle: str = 'd3043820717d74d9a17694c176d39733', + preferred_lifecycle: + PreferredLifeCycle = 'd3043820717d74d9a17694c176d39733', revert_to_spot: RevertToSpot = 'd3043820717d74d9a17694c176d39733', signals: typing.List[spotinst_sdk2.models.stateful_node.Signal] = 'd3043820717d74d9a17694c176d39733' @@ -109,28 +277,60 @@ Strategy( __Arguments__ +- __availability_vs_cost__: int +- __capacity_reservation__: CapacityReservation - __draining_timeout__: int - __fallback_to_od__: bool - __od_windows__: List[str] - __optimization_windows__: List[str] -- __preferred_lifecycle__: str +- __preferred_lifecycle__: PreferredLifeCycle - __revert_to_spot__: RevertToSpot - __signals__: List[Signal] +

StorageType

+ +```python +StorageType(cls, value, names=None, *, module, qualname, type, start) +``` +An enumeration. +

managed

+ + +

unmanaged

+ +

BootDiagnostics

```python BootDiagnostics(self, is_enabled: bool = 'd3043820717d74d9a17694c176d39733', storage_uri: str = 'd3043820717d74d9a17694c176d39733', - type: str = 'd3043820717d74d9a17694c176d39733') + type: StorageType = 'd3043820717d74d9a17694c176d39733') ``` __Arguments__ - __is_enabled__: bool storage_uri = str -- __type__: str +- __type__: StorageType + +

DataDiskType

+ +```python +DataDiskType(cls, value, names=None, *, module, qualname, type, start) +``` +An enumeration. +

premium_lrs

+ + +

standard_lrs

+ + +

standard_ssd_lrs

+ + +

ultra_ssd_lrs

+

DataDisk

@@ -138,14 +338,14 @@ storage_uri = str DataDisk(self, lun: int = 'd3043820717d74d9a17694c176d39733', size_g_b: int = 'd3043820717d74d9a17694c176d39733', - type: str = 'd3043820717d74d9a17694c176d39733') + type: DataDiskType = 'd3043820717d74d9a17694c176d39733') ``` __Arguments__ - __lun__: int -size_gb = int -- __type__: str +size_g_b = int +- __type__: DataDiskType

Extension

@@ -164,6 +364,8 @@ __Arguments__ - __api_version__: str - __minor_version_auto_upgrade__: bool - __name__: str +- __protected_settings__: ProtectedSettings +- __public_settings__: PublicSettings - __publisher__: str - __type__: str @@ -231,6 +433,25 @@ __Arguments__ - __custom__: Custom - __gallery__: Gallery +

LoadBalancerType

+ +```python +LoadBalancerType(cls, + value, + names=None, + *, + module, + qualname, + type, + start) +``` +An enumeration. +

application_gateway

+ + +

load_balancer

+ +

LoadBalancer

```python @@ -241,7 +462,7 @@ LoadBalancer( load_balancer_sku: str = 'd3043820717d74d9a17694c176d39733', name: str = 'd3043820717d74d9a17694c176d39733', resource_group_name: str = 'd3043820717d74d9a17694c176d39733', - type: str = 'd3043820717d74d9a17694c176d39733') + type: LoadBalancerType = 'd3043820717d74d9a17694c176d39733') ``` __Arguments__ @@ -250,7 +471,7 @@ __Arguments__ - __load_balancer_sku__: str - __name__: str - __resource_group_name__: str -- __type__: str +- __type__: LoadBalancerType

LoadBalancerConfig

@@ -295,19 +516,39 @@ __Arguments__ - __resource_group_name__: str - __name__: str +

PrivateIpAddressVersion

+ +```python +PrivateIpAddressVersion(cls, + value, + names=None, + *, + module, + qualname, + type, + start) +``` +An enumeration. +

ipv4

+ + +

ipv6

+ +

AdditionalIpConfiguration

```python AdditionalIpConfiguration( - self, - name: str = 'd3043820717d74d9a17694c176d39733', - private_ip_address_version: str = 'd3043820717d74d9a17694c176d39733') + self, + name: str = 'd3043820717d74d9a17694c176d39733', + private_ip_address_version: + PrivateIpAddressVersion = 'd3043820717d74d9a17694c176d39733') ``` __Arguments__ - __name__: str -- __private_ip_address_version__: str +- __private_ip_address_version__: PrivateIpAddressVersion

ApplicationSecurityGroup

@@ -350,6 +591,18 @@ __Arguments__ - __name__: str - __resource_group_name__: str +

PublicIpSku

+ +```python +PublicIpSku(cls, value, names=None, *, module, qualname, type, start) +``` +An enumeration. +

basic

+ + +

standard

+ +

NetworkInterface

```python @@ -362,12 +615,13 @@ NetworkInterface( assign_public_ip: bool = 'd3043820717d74d9a17694c176d39733', enable_ip_forwarding: bool = 'd3043820717d74d9a17694c176d39733', is_primary: bool = 'd3043820717d74d9a17694c176d39733', - network_security_group='d3043820717d74d9a17694c176d39733', + network_security_group: + NetworkSecurityGroup = 'd3043820717d74d9a17694c176d39733', private_ip_addresses: typing.List[str] = 'd3043820717d74d9a17694c176d39733', public_ips: typing.List[spotinst_sdk2.models.stateful_node.PublicIp] = 'd3043820717d74d9a17694c176d39733', - public_ip_sku: str = 'd3043820717d74d9a17694c176d39733', + public_ip_sku: PublicIpSku = 'd3043820717d74d9a17694c176d39733', subnet_name: str = 'd3043820717d74d9a17694c176d39733') ``` @@ -406,13 +660,13 @@ __Arguments__ ```python OsDisk(self, size_g_b: int = 'd3043820717d74d9a17694c176d39733', - type: str = 'd3043820717d74d9a17694c176d39733') + type: DataDiskType = 'd3043820717d74d9a17694c176d39733') ``` __Arguments__ - __size_g_b__: int -- __type__: str +- __type__: DataDiskType

SourceVault

@@ -488,6 +742,48 @@ __Arguments__ - __preferred_spot_sizes__: List[str] - __spot_sizes__: List[str] +

ProximityPlacementGroups

+ +```python +ProximityPlacementGroups( + self, + name: str = 'd3043820717d74d9a17694c176d39733', + resource_group_name: str = 'd3043820717d74d9a17694c176d39733') +``` + +__Arguments__ + +- __name__: str +- __resource_group_name__: str + +

SecurityType

+ +```python +SecurityType(cls, value, names=None, *, module, qualname, type, start) +``` +An enumeration. +

standard

+ + +

trusted_launch

+ + +

Security

+ +```python +Security( + self, + secure_boot_enabled: bool = 'd3043820717d74d9a17694c176d39733', + security_type: SecurityType = 'd3043820717d74d9a17694c176d39733', + v_tpm_enabled: bool = 'd3043820717d74d9a17694c176d39733') +``` + +__Arguments__ + +- __secure_boot_enabled__: bool +- __security_type__: SecurityType +- __v_tpm_enabled__: bool +

LaunchSpecification

```python @@ -508,11 +804,15 @@ LaunchSpecification( typing.List[spotinst_sdk2.models.stateful_node.ManagedServiceIdentity] = 'd3043820717d74d9a17694c176d39733', network: Network = 'd3043820717d74d9a17694c176d39733', os_disk: OsDisk = 'd3043820717d74d9a17694c176d39733', + proximity_placement_groups: + typing.List[spotinst_sdk2.models.stateful_node.ProximityPlacementGroups] = 'd3043820717d74d9a17694c176d39733', secrets: typing.List[spotinst_sdk2.models.stateful_node.Secret] = 'd3043820717d74d9a17694c176d39733', + security: Security = 'd3043820717d74d9a17694c176d39733', shutdown_script: str = 'd3043820717d74d9a17694c176d39733', tags: typing.List[spotinst_sdk2.models.stateful_node.Tag] = 'd3043820717d74d9a17694c176d39733', + user_data: str = 'd3043820717d74d9a17694c176d39733', vm_name: str = 'd3043820717d74d9a17694c176d39733', vm_name_prefix: str = 'd3043820717d74d9a17694c176d39733') ``` @@ -530,19 +830,34 @@ __Arguments__ - __managed_service_identities__: List[ManagedServiceIdentity] - __network__: Network - __os_disk__: OsDisk +- __proximity_placement_groups__: List[ProximityPlacementGroups] - __secrets__: List[Secret] +- __security__: Security - __shutdown_script__: str - __tags__: List[Tag] +- __user_data__: str - __vm_name__: str - __vm_name_prefix__: str +

OsType

+ +```python +OsType(cls, value, names=None, *, module, qualname, type, start) +``` +An enumeration. +

linux

+ + +

windows

+ +

Compute

```python Compute(self, launch_specification: LaunchSpecification = 'd3043820717d74d9a17694c176d39733', - os: str = 'd3043820717d74d9a17694c176d39733', + os: OsType = 'd3043820717d74d9a17694c176d39733', preferred_zone: str = 'd3043820717d74d9a17694c176d39733', vm_sizes: VmSizes = 'd3043820717d74d9a17694c176d39733', zones: typing.List[str] = 'd3043820717d74d9a17694c176d39733') @@ -551,7 +866,7 @@ Compute(self, __Arguments__ - __launch_specification__: LaunchSpecification -- __os__: str +- __os__: OsType - __preferred_zone__: str - __vm_sizes__: VmSizes - __zones__: List[str] diff --git a/spotinst_sdk2/clients/stateful_node/__init__.py b/spotinst_sdk2/clients/stateful_node/__init__.py index b3fe4940..8d81a8d2 100644 --- a/spotinst_sdk2/clients/stateful_node/__init__.py +++ b/spotinst_sdk2/clients/stateful_node/__init__.py @@ -119,15 +119,18 @@ def get_stateful_node(self, node_id: str): return formatted_response["response"]["items"][0] - def get_all_stateful_nodes(self): + def get_all_stateful_nodes(self, name: str = None, region: str = None): """ Get all Stateful Nodes # Returns (List): List of Stateful Nodes API response """ + query_params = dict(name=name, region=region) + response = self.send_get( url=self.__base_stateful_node_url, + query_params=query_params, entity_name=self.ENTITY_NAME) formatted_response = self.convert_json( @@ -375,3 +378,111 @@ def get_stateful_node_logs(self, node_id, from_date, to_date, severity=None, res response, self.camel_to_underscore) return formatted_response["response"]["items"] + + def swap_os_disk_to_stateful_node(self, node_id: str, + swap_osdisk_configuration: azure_stateful_node.SwapOsDiskConfiguration): + """ + Configure a new managed OS disk for an OS persisted paused Stateful Node + + # Arguments + node_id (String): Stateful Node ID + swap_osdisk_configuration (SwapOsDiskConfiguration): Configuration of OS Disk + + # Returns + (Object): StatefulNode API response + """ + request = azure_stateful_node.SwapOsDiskToStatefulNodeRequest( + swap_osdisk_configuration) + + excluded_node_update_dict = self.exclude_missing( + json.loads(request.toJSON())) + + formatted_node_update_dict = self.convert_json( + excluded_node_update_dict, self.underscore_to_camel) + + body_json = json.dumps(formatted_node_update_dict) + + response = self.send_put( + body=body_json, + url=self.__base_stateful_node_url + "/" + node_id + "/osDisk/swap", + entity_name=self.ENTITY_NAME) + + formatted_response = self.convert_json( + response, self.camel_to_underscore) + + return formatted_response["response"] + + def get_all_stateful_node_costs(self, from_date: str, to_date: str, owner_id: str = None): + """ + Get the total costs of a single stateful node/all stateful nodes and for a specific time period. + + # Arguments + to_date (String): On or Before this date + from_date (String): On or After this date + ownerId (String) (Optional): Log level severity + + # Returns + (Object): Stateful Node API response + """ + query_params = dict( + toDate=to_date, fromDate=from_date, ownerId=owner_id) + + response = self.send_get( + url=self.__base_stateful_node_url + "/cost", + query_params=query_params, + entity_name=self.ENTITY_NAME) + + formatted_response = self.convert_json( + response, self.camel_to_underscore) + + return formatted_response["response"]["items"] + + def get_all_stateful_node_aggregated_daily_costs(self, from_date: str, to_date: str, owner_id: str = None): + """ + Get the total costs per day of a single stateful node/all stateful nodes and for a specific time period. + + # Arguments + to_date (String): On or Before this date + from_date (String): On or After this date + ownerId (String) (Optional): Log level severity + + # Returns + (Object): Stateful Node API response + """ + query_params = dict(fromDate=from_date, + toDate=to_date, ownerId=owner_id) + + response = self.send_get( + url=self.__base_stateful_node_url + "/cost/daily", + query_params=query_params, + entity_name=self.ENTITY_NAME) + + formatted_response = self.convert_json( + response, self.camel_to_underscore) + + return formatted_response["response"]["items"] + + def get_stateful_node_size_usage(self, from_date: str, to_date: str, owner_id: str = None): + """ + Get the daily costs per VM size of a single stateful node/all stateful nodes and for a specific time period. + + # Arguments + to_date (String): On or Before this date + from_date (String): On or After this date + ownerId (String) (Optional): Log level severity + + # Returns + (Object): Stateful Node API response + """ + query_params = dict(fromDate=from_date, + toDate=to_date, ownerId=owner_id) + + response = self.send_get( + url=self.__base_stateful_node_url + "/sizeUsage/daily", + query_params=query_params, + entity_name=self.ENTITY_NAME) + + formatted_response = self.convert_json( + response, self.camel_to_underscore) + + return formatted_response["response"]["items"] diff --git a/spotinst_sdk2/models/stateful_node/__init__.py b/spotinst_sdk2/models/stateful_node/__init__.py index 6c74f220..7ebf3259 100644 --- a/spotinst_sdk2/models/stateful_node/__init__.py +++ b/spotinst_sdk2/models/stateful_node/__init__.py @@ -1,22 +1,29 @@ import json +from enum import Enum from typing import List none = "d3043820717d74d9a17694c176d39733" + # region Persistence +class PersistenceMode(Enum): + reattach = "reattach" + on_launch = "onLaunch" + + class Persistence: """ # Arguments - data_disks_persistence_mode: str - os_disk_persistence_mode: str + data_disks_persistence_mode: PersistenceMode + os_disk_persistence_mode: PersistenceMode should_persist_data_disks: bool should_persist_network: bool should_persist_os_disk: bool """ - def __init__(self, data_disks_persistence_mode: str = none, os_disk_persistence_mode: str = none, + def __init__(self, data_disks_persistence_mode: PersistenceMode = none, os_disk_persistence_mode: PersistenceMode = none, should_persist_data_disks: bool = none, should_persist_network: bool = none, should_persist_os_disk: bool = none): self.data_disks_persistence_mode = data_disks_persistence_mode @@ -25,15 +32,20 @@ def __init__(self, data_disks_persistence_mode: str = none, os_disk_persistence_ self.should_persist_network = should_persist_network self.should_persist_os_disk = should_persist_os_disk + # endregion # region Health +class HealthCheckTypes(Enum): + vm_state = "vmState" + application_gateway = "applicationGateway" + class Health: """ # Arguments - health_check_types: List[str] + health_check_types: List[HealthCheckTypes] auto_healing: bool grace_period: int unhealthy_duration: int @@ -41,7 +53,7 @@ class Health: def __init__( self, - health_check_types: List[str] = none, + health_check_types: List[HealthCheckTypes] = none, auto_healing: bool = none, grace_period: int = none, unhealthy_duration: int = none): @@ -50,24 +62,31 @@ def __init__( self.grace_period = grace_period self.unhealthy_duration = unhealthy_duration + # endregion # region Scheduling +class SchedulingTaskType(Enum): + pause = "pause" + resume = "resume" + recycle = "recycle" + + class SchedulingTask: """ # Arguments is_enabled: bool cron_expression: str - type: str + type: SchedulingTaskType """ def __init__( self, is_enabled: bool = none, cron_expression: str = none, - type: str = none): + type: SchedulingTaskType = none): self.is_enabled = is_enabled self.cron_expression = cron_expression self.type = type @@ -82,54 +101,117 @@ class Scheduling: def __init__(self, tasks: List[SchedulingTask] = none): self.tasks = tasks + # endregion # region Strategy +class PerformAt(Enum): + time_window = "timeWindow" + never = "never" + always = "always" + + class RevertToSpot: """ # Arguments - perform_at: str + perform_at: PerformAt """ - def __init__(self, perform_at: str = none): + def __init__(self, perform_at: PerformAt = none): self.perform_at = perform_at +class SignalType(Enum): + vm_ready = "vmReady" + vm_ready_to_shutdown = "vmReadyToShutdown" + + class Signal: """ # Arguments timeout: int - type: str + type: SignalType """ - def __init__(self, timeout: int = none, type: str = none): + def __init__(self, timeout: int = none, type: SignalType = none): self.timeout = timeout self.type = type +class CapacityReservationGroups: + """ + # Arguments + name: str + resource_group_name: str + should_prioritize: bool + """ + + def __init__(self, + name: str = none, + resource_group_name: str = none, + should_prioritize: bool = none): + self.name = name + self.resource_group_name = resource_group_name + self.should_prioritize = should_prioritize + + +class UtilizationStrategy(Enum): + utilize_over_spot = "utilizeOverSpot" + utilize_over_od = "utilizeOverOD" + + +class CapacityReservation: + """ + # Arguments + capacity_reservation_groups: List[CapacityReservationGroups] + should_utilize: bool + utilization_strategy: UtilizationStrategy + """ + + def __init__( + self, + capacity_reservation_groups: List[CapacityReservationGroups] = none, + should_utilize: bool = none, + utilization_strategy: UtilizationStrategy = none): + self.capacity_reservation_groups = capacity_reservation_groups + self.should_utilize = should_utilize + self.utilization_strategy = utilization_strategy + + +class PreferredLifeCycle(Enum): + spot = "spot" + od = "od" + + class Strategy: """ # Arguments + availability_vs_cost: int + capacity_reservation: CapacityReservation draining_timeout: int fallback_to_od: bool od_windows: List[str] optimization_windows: List[str] - preferred_lifecycle: str + preferred_lifecycle: PreferredLifeCycle revert_to_spot: RevertToSpot signals: List[Signal] """ def __init__( self, + availability_vs_cost: int = none, + capacity_reservation: CapacityReservation = none, draining_timeout: int = none, fallback_to_od: bool = none, od_windows: List[str] = none, optimization_windows: List[str] = none, - preferred_lifecycle: str = none, + preferred_lifecycle: PreferredLifeCycle = none, revert_to_spot: RevertToSpot = none, signals: List[Signal] = none): + self.availability_vs_cost = availability_vs_cost + self.capacity_reservation = capacity_reservation self.draining_timeout = draining_timeout self.fallback_to_od = fallback_to_od self.od_windows = od_windows @@ -138,42 +220,54 @@ def __init__( self.revert_to_spot = revert_to_spot self.signals = signals + # endregion # region Compute +class StorageType(Enum): + managed = "managed" + unmanaged = "unmanaged" + class BootDiagnostics: """ # Arguments is_enabled: bool storage_uri = str - type: str + type: StorageType """ def __init__( self, is_enabled: bool = none, storage_uri: str = none, - type: str = none): + type: StorageType = none): self.is_enabled = is_enabled self.storage_uri = storage_uri self.type = type +class DataDiskType(Enum): + standard_lrs = "Standard_LRS" + premium_lrs = "Premium_LRS" + standard_ssd_lrs = "StandardSSD_LRS" + ultra_ssd_lrs = "UltraSSD_LRS" + + class DataDisk: """ # Arguments lun: int - size_gb = int - type: str + size_g_b = int + type: DataDiskType """ def __init__( self, lun: int = none, size_g_b: int = none, - type: str = none): + type: DataDiskType = none): self.lun = lun self.size_g_b = size_g_b self.type = type @@ -185,6 +279,8 @@ class Extension: api_version: str minor_version_auto_upgrade: bool name: str + protected_settings: ProtectedSettings + public_settings: PublicSettings publisher: str type: str """ @@ -277,6 +373,11 @@ def __init__(self, marketplace: Marketplace = none, custom: Custom = none, galle self.gallery = gallery +class LoadBalancerType(Enum): + load_balancer = "loadBalancer" + application_gateway = "applicationGateway" + + class LoadBalancer: """ # Arguments @@ -284,7 +385,7 @@ class LoadBalancer: load_balancer_sku: str name: str resource_group_name: str - type: str + type: LoadBalancerType """ def __init__( @@ -293,7 +394,7 @@ def __init__( load_balancer_sku: str = none, name: str = none, resource_group_name: str = none, - type: str = none): + type: LoadBalancerType = none): self.backend_pool_names = backend_pool_names self.load_balancer_sku = load_balancer_sku self.name = name @@ -344,17 +445,22 @@ def __init__( self.name = name +class PrivateIpAddressVersion(Enum): + ipv4 = "IPv4" + ipv6 = "IPv6" + + class AdditionalIpConfiguration: """ # Arguments name: str - private_ip_address_version: str + private_ip_address_version: PrivateIpAddressVersion """ def __init__( self, name: str = none, - private_ip_address_version: str = none): + private_ip_address_version: PrivateIpAddressVersion = none): self.name = name self.private_ip_address_version = private_ip_address_version @@ -404,6 +510,11 @@ def __init__( self.resource_group_name = resource_group_name +class PublicIpSku(Enum): + standard = "Standard" + basic = "Basic" + + class NetworkInterface: """ # Arguments @@ -426,10 +537,10 @@ def __init__( assign_public_ip: bool = none, enable_ip_forwarding: bool = none, is_primary: bool = none, - network_security_group=none, + network_security_group: NetworkSecurityGroup = none, private_ip_addresses: List[str] = none, public_ips: List[PublicIp] = none, - public_ip_sku: str = none, + public_ip_sku: PublicIpSku = none, subnet_name: str = none): self.additional_ip_configurations = additional_ip_configurations self.application_security_groups = application_security_groups @@ -465,13 +576,13 @@ class OsDisk: """ # Arguments size_g_b: int - type: str + type: DataDiskType """ def __init__( self, size_g_b: int = none, - type: str = none): + type: DataDiskType = none): self.size_g_b = size_g_b self.type = type @@ -554,6 +665,44 @@ def __init__( self.spot_sizes = spot_sizes +class ProximityPlacementGroups: + """ + # Arguments + name: str + resource_group_name: str + """ + + def __init__( + self, + name: str = none, + resource_group_name: str = none): + self.name = name + self.resource_group_name = resource_group_name + + +class SecurityType(Enum): + standard = "Standard" + trusted_launch = "TrustedLaunch" + + +class Security: + """ + # Arguments + secure_boot_enabled: bool + security_type: SecurityType + v_tpm_enabled: bool + """ + + def __init__( + self, + secure_boot_enabled: bool = none, + security_type: SecurityType = none, + v_tpm_enabled: bool = none): + self.secure_boot_enabled = secure_boot_enabled + self.security_type = security_type + self.v_tpm_enabled = v_tpm_enabled + + class LaunchSpecification: """ # Arguments @@ -568,9 +717,12 @@ class LaunchSpecification: managed_service_identities: List[ManagedServiceIdentity] network: Network os_disk: OsDisk + proximity_placement_groups: List[ProximityPlacementGroups] secrets: List[Secret] + security: Security shutdown_script: str tags: List[Tag] + user_data: str vm_name: str vm_name_prefix: str """ @@ -588,9 +740,12 @@ def __init__( managed_service_identities: List[ManagedServiceIdentity] = none, network: Network = none, os_disk: OsDisk = none, + proximity_placement_groups: List[ProximityPlacementGroups] = none, secrets: List[Secret] = none, + security: Security = none, shutdown_script: str = none, tags: List[Tag] = none, + user_data: str = none, vm_name: str = none, vm_name_prefix: str = none): self.boot_diagnostics = boot_diagnostics @@ -604,18 +759,26 @@ def __init__( self.managed_service_identities = managed_service_identities self.network = network self.os_disk = os_disk + self.proximity_placement_groups = proximity_placement_groups self.secrets = secrets + self.security = security self.shutdown_script = shutdown_script self.tags = tags + self.user_data = user_data self.vm_name = vm_name self.vm_name_prefix = vm_name_prefix +class OsType(Enum): + linux = "Linux" + windows = "Windows" + + class Compute: """ # Arguments launch_specification: LaunchSpecification - os: str + os: OsType preferred_zone: str vm_sizes: VmSizes zones: List[str] @@ -624,7 +787,7 @@ class Compute: def __init__( self, launch_specification: LaunchSpecification = none, - os: str = none, + os: OsType = none, preferred_zone: str = none, vm_sizes: VmSizes = none, zones: List[str] = none): @@ -634,6 +797,7 @@ def __init__( self.vm_sizes = vm_sizes self.zones = zones + # endregion # region StatefulNode @@ -644,7 +808,7 @@ class StatefulNode: # Arguments compute: Compute description: str - health: Health + health: Health name: str persistence: Persistence region: str @@ -674,6 +838,7 @@ def __init__( self.scheduling = scheduling self.strategy = strategy + # endregion @@ -738,11 +903,13 @@ def toJSON(self): class ImportVmConfiguration: def __init__(self, + convert_unmanaged_disks: bool = none, draining_timeout: int = none, node: StatefulNode = none, original_vm_name: str = none, resource_group_name: str = none, resource_retention_time: int = none): + self.convert_unmanaged_disks = convert_unmanaged_disks self.draining_timeout = draining_timeout self.node = node self.original_vm_name = original_vm_name @@ -770,7 +937,7 @@ def __init__( data_disk_resource_group_name: str = none, lun: int = none, size_g_b: int = none, - storage_account_type: str = none, + storage_account_type: DataDiskType = none, zone: str = none): self.data_disk_name = data_disk_name self.data_disk_resource_group_name = data_disk_resource_group_name @@ -824,4 +991,31 @@ def toJSON(self): sort_keys=True, indent=4) + +class SwapOsDiskConfiguration: + def __init__(self, os_disk_name: str = none, + os_disk_resource_group_name: str = none, + retention_time: int = none, + should_terminate: bool = none): + self.os_disk_name = os_disk_name + self.os_disk_resource_group_name = os_disk_resource_group_name + self.retention_time = retention_time + self.should_terminate = should_terminate + + +class SwapOsDiskToStatefulNodeRequest: + def __init__(self, config: SwapOsDiskConfiguration = none): + self.os_disk_name = config.os_disk_name + self.os_disk_resource_group_name = config.os_disk_resource_group_name + self.retention_time = config.retention_time + self.should_terminate = config.should_terminate + + def toJSON(self): + return json.dumps( + self, + default=lambda o: o.__dict__, + sort_keys=True, + indent=4) + + # endregion diff --git a/spotinst_sdk2/version.py b/spotinst_sdk2/version.py index f1edb192..82190396 100644 --- a/spotinst_sdk2/version.py +++ b/spotinst_sdk2/version.py @@ -1 +1 @@ -__version__ = '2.2.2' +__version__ = '2.3.0'