diff --git a/scaleway-async/scaleway_async/applesilicon/v1alpha1/api.py b/scaleway-async/scaleway_async/applesilicon/v1alpha1/api.py index 8e0879e09..8a49e6f15 100644 --- a/scaleway-async/scaleway_async/applesilicon/v1alpha1/api.py +++ b/scaleway-async/scaleway_async/applesilicon/v1alpha1/api.py @@ -1106,9 +1106,8 @@ async def wait_for_server_private_network( options = WaitForOptions() if not options.stop: - options.stop = ( - lambda res: res.status - not in SERVER_PRIVATE_NETWORK_SERVER_TRANSIENT_STATUSES + options.stop = lambda res: ( + res.status not in SERVER_PRIVATE_NETWORK_SERVER_TRANSIENT_STATUSES ) return await wait_for_resource_async( diff --git a/scaleway-async/scaleway_async/applesilicon/v1alpha1/marshalling.py b/scaleway-async/scaleway_async/applesilicon/v1alpha1/marshalling.py index f09b63282..1a24177fc 100644 --- a/scaleway-async/scaleway_async/applesilicon/v1alpha1/marshalling.py +++ b/scaleway-async/scaleway_async/applesilicon/v1alpha1/marshalling.py @@ -136,6 +136,12 @@ def unmarshal_OS(data: Any) -> OS: else: args["xcode_version"] = None + field = data.get("compatible_server_types", None) + if field is not None: + args["compatible_server_types"] = field + else: + args["compatible_server_types"] = [] + field = data.get("release_notes_url", None) if field is not None: args["release_notes_url"] = field @@ -164,12 +170,6 @@ def unmarshal_OS(data: Any) -> OS: else: args["supported_server_types"] = [] - field = data.get("compatible_server_types", None) - if field is not None: - args["compatible_server_types"] = field - else: - args["compatible_server_types"] = [] - return OS(**args) diff --git a/scaleway-async/scaleway_async/applesilicon/v1alpha1/types.py b/scaleway-async/scaleway_async/applesilicon/v1alpha1/types.py index 7a658f220..6a3f97653 100644 --- a/scaleway-async/scaleway_async/applesilicon/v1alpha1/types.py +++ b/scaleway-async/scaleway_async/applesilicon/v1alpha1/types.py @@ -205,6 +205,11 @@ class OS: The current xcode version for this OS. """ + compatible_server_types: list[str] + """ + List of compatible server types. Deprecated. + """ + release_notes_url: str """ Url of the release notes for the OS image or software pre-installed. @@ -225,11 +230,6 @@ class OS: List of server types which supports the OS configuration. Also gives information about immediate stock availability. """ - compatible_server_types: Optional[list[str]] = field(default_factory=list) - """ - List of compatible server types. Deprecated. - """ - @dataclass class RunnerConfiguration: diff --git a/scaleway-async/scaleway_async/dedibox/v1/api.py b/scaleway-async/scaleway_async/dedibox/v1/api.py index a6cf8a81a..90f3e71cb 100644 --- a/scaleway-async/scaleway_async/dedibox/v1/api.py +++ b/scaleway-async/scaleway_async/dedibox/v1/api.py @@ -1352,8 +1352,8 @@ async def wait_for_server_install( options = WaitForOptions() if not options.stop: - options.stop = ( - lambda res: res.status not in SERVER_INSTALL_TRANSIENT_STATUSES + options.stop = lambda res: ( + res.status not in SERVER_INSTALL_TRANSIENT_STATUSES ) return await wait_for_resource_async( diff --git a/scaleway-async/scaleway_async/function/v1beta1/api.py b/scaleway-async/scaleway_async/function/v1beta1/api.py index cf47a7a5a..a5b36eeb4 100644 --- a/scaleway-async/scaleway_async/function/v1beta1/api.py +++ b/scaleway-async/scaleway_async/function/v1beta1/api.py @@ -271,6 +271,7 @@ async def wait_for_namespace( async def create_namespace( self, *, + activate_vpc_integration: bool, region: Optional[ScwRegion] = None, name: Optional[str] = None, environment_variables: Optional[dict[str, str]] = None, @@ -278,11 +279,11 @@ async def create_namespace( description: Optional[str] = None, secret_environment_variables: Optional[list[Secret]] = None, tags: Optional[list[str]] = None, - activate_vpc_integration: Optional[bool] = None, ) -> Namespace: """ Create a new namespace. Create a new namespace in a specified Organization or Project. + :param activate_vpc_integration: Setting this field to true doesn't matter anymore. It will be removed in a near future. :param region: Region to target. If none is passed will use default region from the config. :param name: :param environment_variables: Environment variables of the namespace. @@ -290,13 +291,14 @@ async def create_namespace( :param description: Description of the namespace. :param secret_environment_variables: Secret environment variables of the namespace. :param tags: Tags of the Serverless Function Namespace. - :param activate_vpc_integration: Setting this field to true doesn't matter anymore. It will be removed in a near future. :return: :class:`Namespace ` Usage: :: - result = await api.create_namespace() + result = await api.create_namespace( + activate_vpc_integration=False, + ) """ param_region = validate_path_param( @@ -308,6 +310,7 @@ async def create_namespace( f"/functions/v1beta1/regions/{param_region}/namespaces", body=marshal_CreateNamespaceRequest( CreateNamespaceRequest( + activate_vpc_integration=activate_vpc_integration, region=region, name=name or random_name(prefix="ns"), environment_variables=environment_variables, @@ -315,7 +318,6 @@ async def create_namespace( description=description, secret_environment_variables=secret_environment_variables, tags=tags, - activate_vpc_integration=activate_vpc_integration, ), self.client, ), diff --git a/scaleway-async/scaleway_async/function/v1beta1/marshalling.py b/scaleway-async/scaleway_async/function/v1beta1/marshalling.py index 80a6e3a9b..9df8e13b0 100644 --- a/scaleway-async/scaleway_async/function/v1beta1/marshalling.py +++ b/scaleway-async/scaleway_async/function/v1beta1/marshalling.py @@ -437,6 +437,12 @@ def unmarshal_Namespace(data: Any) -> Namespace: else: args["tags"] = [] + field = data.get("vpc_integration_activated", None) + if field is not None: + args["vpc_integration_activated"] = field + else: + args["vpc_integration_activated"] = False + field = data.get("description", None) if field is not None: args["description"] = field @@ -455,12 +461,6 @@ def unmarshal_Namespace(data: Any) -> Namespace: else: args["updated_at"] = None - field = data.get("vpc_integration_activated", None) - if field is not None: - args["vpc_integration_activated"] = field - else: - args["vpc_integration_activated"] = False - return Namespace(**args) @@ -484,6 +484,12 @@ def unmarshal_Token(data: Any) -> Token: else: args["token"] = None + field = data.get("public_key", None) + if field is not None: + args["public_key"] = field + else: + args["public_key"] = None + field = data.get("status", None) if field is not None: args["status"] = field @@ -502,12 +508,6 @@ def unmarshal_Token(data: Any) -> Token: else: args["namespace_id"] = None - field = data.get("public_key", None) - if field is not None: - args["public_key"] = field - else: - args["public_key"] = None - field = data.get("description", None) if field is not None: args["description"] = field @@ -1114,6 +1114,9 @@ def marshal_CreateNamespaceRequest( ) -> dict[str, Any]: output: dict[str, Any] = {} + if request.activate_vpc_integration is not None: + output["activate_vpc_integration"] = request.activate_vpc_integration + if request.name is not None: output["name"] = request.name @@ -1137,9 +1140,6 @@ def marshal_CreateNamespaceRequest( if request.tags is not None: output["tags"] = request.tags - if request.activate_vpc_integration is not None: - output["activate_vpc_integration"] = request.activate_vpc_integration - return output diff --git a/scaleway-async/scaleway_async/function/v1beta1/types.py b/scaleway-async/scaleway_async/function/v1beta1/types.py index 85391b085..5d3c4332a 100644 --- a/scaleway-async/scaleway_async/function/v1beta1/types.py +++ b/scaleway-async/scaleway_async/function/v1beta1/types.py @@ -628,6 +628,11 @@ class Namespace: List of tags applied to the Serverless Function Namespace. """ + vpc_integration_activated: bool + """ + The value of this field doesn't matter anymore, and will be removed in a near future. + """ + error_message: Optional[str] = None """ Error message if the namespace is in "error" state. @@ -648,11 +653,6 @@ class Namespace: Last update date of the namespace. """ - vpc_integration_activated: Optional[bool] = False - """ - The value of this field doesn't matter anymore, and will be removed in a near future. - """ - @dataclass class Token: @@ -666,14 +666,14 @@ class Token: String of the token. """ - status: TokenStatus + public_key: str """ - Status of the token. + Public key of the token. """ - public_key: Optional[str] = None + status: TokenStatus """ - Public key of the token. + Status of the token. """ description: Optional[str] = None @@ -875,6 +875,11 @@ class CreateFunctionRequest: @dataclass class CreateNamespaceRequest: + activate_vpc_integration: bool + """ + Setting this field to true doesn't matter anymore. It will be removed in a near future. + """ + region: Optional[ScwRegion] = None """ Region to target. If none is passed will use default region from the config. @@ -906,11 +911,6 @@ class CreateNamespaceRequest: Tags of the Serverless Function Namespace. """ - activate_vpc_integration: Optional[bool] = False - """ - Setting this field to true doesn't matter anymore. It will be removed in a near future. - """ - @dataclass class CreateTokenRequest: diff --git a/scaleway-async/scaleway_async/iam/v1alpha1/marshalling.py b/scaleway-async/scaleway_async/iam/v1alpha1/marshalling.py index f808bb676..8b2c87aed 100644 --- a/scaleway-async/scaleway_async/iam/v1alpha1/marshalling.py +++ b/scaleway-async/scaleway_async/iam/v1alpha1/marshalling.py @@ -927,6 +927,18 @@ def unmarshal_User(data: Any) -> User: else: args["type_"] = UserType.UNKNOWN_TYPE + field = data.get("two_factor_enabled", None) + if field is not None: + args["two_factor_enabled"] = field + else: + args["two_factor_enabled"] = False + + field = data.get("status", None) + if field is not None: + args["status"] = field + else: + args["status"] = UserStatus.UNKNOWN_STATUS + field = data.get("mfa", None) if field is not None: args["mfa"] = field @@ -951,18 +963,6 @@ def unmarshal_User(data: Any) -> User: else: args["locked"] = False - field = data.get("two_factor_enabled", None) - if field is not None: - args["two_factor_enabled"] = field - else: - args["two_factor_enabled"] = False - - field = data.get("status", None) - if field is not None: - args["status"] = field - else: - args["status"] = UserStatus.UNKNOWN_STATUS - return User(**args) diff --git a/scaleway-async/scaleway_async/iam/v1alpha1/types.py b/scaleway-async/scaleway_async/iam/v1alpha1/types.py index f5ef0e7ac..4914299cf 100644 --- a/scaleway-async/scaleway_async/iam/v1alpha1/types.py +++ b/scaleway-async/scaleway_async/iam/v1alpha1/types.py @@ -977,6 +977,16 @@ class User: Type of user. """ + two_factor_enabled: bool + """ + Deprecated, use "mfa" instead. + """ + + status: UserStatus + """ + Status of user invitation. + """ + mfa: bool """ Defines whether MFA is enabled. @@ -1012,16 +1022,6 @@ class User: Date of the last login. """ - two_factor_enabled: Optional[bool] = False - """ - Deprecated, use "mfa" instead. - """ - - status: Optional[UserStatus] = UserStatus.UNKNOWN_STATUS - """ - Status of user invitation. - """ - @dataclass class SamlServiceProvider: diff --git a/scaleway-async/scaleway_async/instance/v1/api.py b/scaleway-async/scaleway_async/instance/v1/api.py index a27fb395c..7d316bec2 100644 --- a/scaleway-async/scaleway_async/instance/v1/api.py +++ b/scaleway-async/scaleway_async/instance/v1/api.py @@ -521,12 +521,12 @@ async def _create_server( *, zone: Optional[ScwZone] = None, commercial_type: str, + enable_ipv6: bool, name: Optional[str] = None, dynamic_ip_required: Optional[bool] = None, routed_ip_enabled: Optional[bool] = None, image: Optional[str] = None, volumes: Optional[dict[str, VolumeServerTemplate]] = None, - enable_ipv6: Optional[bool] = None, protected: bool, public_ip: Optional[str] = None, public_ips: Optional[list[str]] = None, @@ -544,12 +544,12 @@ async def _create_server( Get more information in the [Technical Information](#technical-information) section of the introduction. :param zone: Zone to target. If none is passed will use default zone from the config. :param commercial_type: Define the Instance commercial type (i.e. GP1-S). + :param enable_ipv6: True if IPv6 is enabled on the server (deprecated and always `False` when `routed_ip_enabled` is `True`). :param name: Instance name. :param dynamic_ip_required: By default, `dynamic_ip_required` is true, a dynamic ip is attached to the instance (if no flexible ip is already attached). :param routed_ip_enabled: If true, configure the Instance so it uses the new routed IP mode. :param image: Instance image ID or label. :param volumes: Volumes attached to the server. - :param enable_ipv6: True if IPv6 is enabled on the server (deprecated and always `False` when `routed_ip_enabled` is `True`). :param protected: True to activate server protection option. :param public_ip: ID of the reserved IP to attach to the Instance. :param public_ips: A list of reserved IP IDs to attach to the Instance. @@ -569,6 +569,7 @@ async def _create_server( result = await api._create_server( commercial_type="example", + enable_ipv6=False, protected=False, ) """ @@ -582,12 +583,12 @@ async def _create_server( CreateServerRequest( zone=zone, commercial_type=commercial_type, + enable_ipv6=enable_ipv6, name=name or random_name(prefix="srv"), dynamic_ip_required=dynamic_ip_required, routed_ip_enabled=routed_ip_enabled, image=image, volumes=volumes, - enable_ipv6=enable_ipv6, protected=protected, public_ip=public_ip, public_ips=public_ips, @@ -676,6 +677,7 @@ async def _set_server( name: str, commercial_type: str, dynamic_ip_required: bool, + enable_ipv6: bool, hostname: str, organization: Optional[str] = None, project: Optional[str] = None, @@ -683,7 +685,6 @@ async def _set_server( tags: Optional[list[str]] = None, creation_date: Optional[datetime] = None, routed_ip_enabled: Optional[bool] = None, - enable_ipv6: Optional[bool] = None, image: Optional[Image] = None, protected: bool, private_ip: Optional[str] = None, @@ -709,6 +710,7 @@ async def _set_server( :param name: Instance name. :param commercial_type: Instance commercial type (eg. GP1-M). :param dynamic_ip_required: True if a dynamic IPv4 is required. + :param enable_ipv6: True if IPv6 is enabled (deprecated and always `False` when `routed_ip_enabled` is `True`). :param hostname: Instance host name. :param organization: Instance Organization ID. :param project: Instance Project ID. @@ -716,7 +718,6 @@ async def _set_server( :param tags: Tags associated with the Instance. :param creation_date: Instance creation date. :param routed_ip_enabled: True to configure the instance so it uses the new routed IP mode (once this is set to True you cannot set it back to False). - :param enable_ipv6: True if IPv6 is enabled (deprecated and always `False` when `routed_ip_enabled` is `True`). :param image: Provide information on the Instance image. :param protected: Instance protection option is activated. :param private_ip: Instance private IP address (deprecated and always `null` when `routed_ip_enabled` is `True`). @@ -745,6 +746,7 @@ async def _set_server( name="example", commercial_type="example", dynamic_ip_required=False, + enable_ipv6=False, hostname="example", protected=False, state_detail="example", @@ -763,8 +765,9 @@ async def _set_server( id=id, name=name, commercial_type=commercial_type, - organization=organization, dynamic_ip_required=dynamic_ip_required, + organization=organization, + enable_ipv6=enable_ipv6, hostname=hostname, protected=protected, state_detail=state_detail, @@ -773,7 +776,6 @@ async def _set_server( tags=tags, creation_date=creation_date, routed_ip_enabled=routed_ip_enabled, - enable_ipv6=enable_ipv6, image=image, private_ip=private_ip, public_ip=public_ip, @@ -2522,15 +2524,15 @@ async def _set_security_group( description: str, enable_default_security: bool, tags: Optional[list[str]] = None, - creation_date: Optional[datetime] = None, - modification_date: Optional[datetime] = None, + organization_default: bool, project_default: bool, stateful: bool, + creation_date: Optional[datetime] = None, + modification_date: Optional[datetime] = None, inbound_default_policy: Optional[SecurityGroupPolicy] = None, outbound_default_policy: Optional[SecurityGroupPolicy] = None, organization: Optional[str] = None, project: Optional[str] = None, - organization_default: Optional[bool] = None, servers: Optional[list[ServerSummary]] = None, ) -> _SetSecurityGroupResponse: """ @@ -2542,15 +2544,15 @@ async def _set_security_group( :param description: Description of the security group. :param enable_default_security: True to block SMTP on IPv4 and IPv6. This feature is read only, please open a support ticket if you need to make it configurable. :param tags: Tags of the security group. - :param creation_date: Creation date of the security group (will be ignored). - :param modification_date: Modification date of the security group (will be ignored). + :param organization_default: Please use project_default instead. :param project_default: True use this security group for future Instances created in this project. :param stateful: True to set the security group as stateful. + :param creation_date: Creation date of the security group (will be ignored). + :param modification_date: Modification date of the security group (will be ignored). :param inbound_default_policy: Default inbound policy. :param outbound_default_policy: Default outbound policy. :param organization: Security groups Organization ID. :param project: Security group Project ID. - :param organization_default: Please use project_default instead. :param servers: Instances attached to this security group. :return: :class:`_SetSecurityGroupResponse <_SetSecurityGroupResponse>` @@ -2562,6 +2564,7 @@ async def _set_security_group( name="example", description="example", enable_default_security=False, + organization_default=False, project_default=False, stateful=False, ) @@ -2581,15 +2584,15 @@ async def _set_security_group( description=description, enable_default_security=enable_default_security, tags=tags, - creation_date=creation_date, - modification_date=modification_date, + organization_default=organization_default, project_default=project_default, stateful=stateful, + creation_date=creation_date, + modification_date=modification_date, inbound_default_policy=inbound_default_policy, outbound_default_policy=outbound_default_policy, organization=organization, project=project, - organization_default=organization_default, servers=servers, ), self.client, diff --git a/scaleway-async/scaleway_async/instance/v1/marshalling.py b/scaleway-async/scaleway_async/instance/v1/marshalling.py index 2e72fdb36..3c72a53ec 100644 --- a/scaleway-async/scaleway_async/instance/v1/marshalling.py +++ b/scaleway-async/scaleway_async/instance/v1/marshalling.py @@ -353,6 +353,12 @@ def unmarshal_Volume(data: Any) -> Volume: else: args["name"] = None + field = data.get("export_uri", None) + if field is not None: + args["export_uri"] = field + else: + args["export_uri"] = None + field = data.get("size", None) if field is not None: args["size"] = field @@ -377,12 +383,6 @@ def unmarshal_Volume(data: Any) -> Volume: else: args["project"] = None - field = data.get("export_uri", None) - if field is not None: - args["export_uri"] = field - else: - args["export_uri"] = None - field = data.get("creation_date", None) if field is not None: args["creation_date"] = ( @@ -990,6 +990,18 @@ def unmarshal_Server(data: Any) -> Server: else: args["commercial_type"] = None + field = data.get("dynamic_ip_required", None) + if field is not None: + args["dynamic_ip_required"] = field + else: + args["dynamic_ip_required"] = False + + field = data.get("routed_ip_enabled", None) + if field is not None: + args["routed_ip_enabled"] = field + else: + args["routed_ip_enabled"] = False + field = data.get("creation_date", None) if field is not None: args["creation_date"] = ( @@ -998,11 +1010,11 @@ def unmarshal_Server(data: Any) -> Server: else: args["creation_date"] = None - field = data.get("dynamic_ip_required", None) + field = data.get("enable_ipv6", None) if field is not None: - args["dynamic_ip_required"] = field + args["enable_ipv6"] = field else: - args["dynamic_ip_required"] = False + args["enable_ipv6"] = False field = data.get("hostname", None) if field is not None: @@ -1068,54 +1080,6 @@ def unmarshal_Server(data: Any) -> Server: else: args["state_detail"] = None - field = data.get("arch", None) - if field is not None: - args["arch"] = field - else: - args["arch"] = Arch.UNKNOWN_ARCH - - field = data.get("private_nics", None) - if field is not None: - args["private_nics"] = ( - [unmarshal_PrivateNIC(v) for v in field] if field is not None else None - ) - else: - args["private_nics"] = [] - - field = data.get("zone", None) - if field is not None: - args["zone"] = field - else: - args["zone"] = None - - field = data.get("filesystems", None) - if field is not None: - args["filesystems"] = ( - [unmarshal_ServerFilesystem(v) for v in field] - if field is not None - else None - ) - else: - args["filesystems"] = [] - - field = data.get("end_of_service", None) - if field is not None: - args["end_of_service"] = field - else: - args["end_of_service"] = False - - field = data.get("routed_ip_enabled", None) - if field is not None: - args["routed_ip_enabled"] = field - else: - args["routed_ip_enabled"] = False - - field = data.get("enable_ipv6", None) - if field is not None: - args["enable_ipv6"] = field - else: - args["enable_ipv6"] = False - field = data.get("image", None) if field is not None: args["image"] = unmarshal_Image(field) @@ -1160,6 +1124,42 @@ def unmarshal_Server(data: Any) -> Server: else: args["security_group"] = None + field = data.get("arch", None) + if field is not None: + args["arch"] = field + else: + args["arch"] = Arch.UNKNOWN_ARCH + + field = data.get("private_nics", None) + if field is not None: + args["private_nics"] = ( + [unmarshal_PrivateNIC(v) for v in field] if field is not None else None + ) + else: + args["private_nics"] = [] + + field = data.get("zone", None) + if field is not None: + args["zone"] = field + else: + args["zone"] = None + + field = data.get("filesystems", None) + if field is not None: + args["filesystems"] = ( + [unmarshal_ServerFilesystem(v) for v in field] + if field is not None + else None + ) + else: + args["filesystems"] = [] + + field = data.get("end_of_service", None) + if field is not None: + args["end_of_service"] = field + else: + args["end_of_service"] = False + field = data.get("placement_group", None) if field is not None: args["placement_group"] = unmarshal_PlacementGroup(field) @@ -1436,6 +1436,12 @@ def unmarshal_SecurityGroup(data: Any) -> SecurityGroup: else: args["tags"] = [] + field = data.get("organization_default", None) + if field is not None: + args["organization_default"] = field + else: + args["organization_default"] = False + field = data.get("project_default", None) if field is not None: args["project_default"] = field @@ -1468,12 +1474,6 @@ def unmarshal_SecurityGroup(data: Any) -> SecurityGroup: else: args["zone"] = None - field = data.get("organization_default", None) - if field is not None: - args["organization_default"] = field - else: - args["organization_default"] = False - field = data.get("creation_date", None) if field is not None: args["creation_date"] = ( @@ -1905,97 +1905,97 @@ def unmarshal_Dashboard(data: Any) -> Dashboard: if field is not None: args["volumes_count"] = field else: - args["volumes_count"] = None + args["volumes_count"] = 0 field = data.get("running_servers_count", None) if field is not None: args["running_servers_count"] = field else: - args["running_servers_count"] = None + args["running_servers_count"] = 0 field = data.get("servers_by_types", None) if field is not None: args["servers_by_types"] = field else: - args["servers_by_types"] = None + args["servers_by_types"] = {} field = data.get("images_count", None) if field is not None: args["images_count"] = field else: - args["images_count"] = None + args["images_count"] = 0 field = data.get("snapshots_count", None) if field is not None: args["snapshots_count"] = field else: - args["snapshots_count"] = None + args["snapshots_count"] = 0 field = data.get("servers_count", None) if field is not None: args["servers_count"] = field else: - args["servers_count"] = None + args["servers_count"] = 0 field = data.get("ips_count", None) if field is not None: args["ips_count"] = field else: - args["ips_count"] = None + args["ips_count"] = 0 field = data.get("security_groups_count", None) if field is not None: args["security_groups_count"] = field else: - args["security_groups_count"] = None + args["security_groups_count"] = 0 field = data.get("ips_unused", None) if field is not None: args["ips_unused"] = field else: - args["ips_unused"] = None + args["ips_unused"] = 0 field = data.get("volumes_l_ssd_count", None) if field is not None: args["volumes_l_ssd_count"] = field else: - args["volumes_l_ssd_count"] = None + args["volumes_l_ssd_count"] = 0 field = data.get("volumes_l_ssd_total_size", None) if field is not None: args["volumes_l_ssd_total_size"] = field else: - args["volumes_l_ssd_total_size"] = None + args["volumes_l_ssd_total_size"] = 0 field = data.get("private_nics_count", None) if field is not None: args["private_nics_count"] = field else: - args["private_nics_count"] = None + args["private_nics_count"] = 0 field = data.get("placement_groups_count", None) if field is not None: args["placement_groups_count"] = field else: - args["placement_groups_count"] = None + args["placement_groups_count"] = 0 field = data.get("volumes_scratch_count", None) if field is not None: args["volumes_scratch_count"] = field else: - args["volumes_scratch_count"] = None + args["volumes_scratch_count"] = 0 field = data.get("volumes_b_ssd_count", None) if field is not None: args["volumes_b_ssd_count"] = field else: - args["volumes_b_ssd_count"] = None + args["volumes_b_ssd_count"] = 0 field = data.get("volumes_b_ssd_total_size", None) if field is not None: args["volumes_b_ssd_total_size"] = field else: - args["volumes_b_ssd_total_size"] = None + args["volumes_b_ssd_total_size"] = 0 return Dashboard(**args) @@ -3712,6 +3712,9 @@ def marshal_CreateServerRequest( if request.commercial_type is not None: output["commercial_type"] = request.commercial_type + if request.enable_ipv6 is not None: + output["enable_ipv6"] = request.enable_ipv6 + if request.name is not None: output["name"] = request.name @@ -3730,9 +3733,6 @@ def marshal_CreateServerRequest( for key, value in request.volumes.items() } - if request.enable_ipv6 is not None: - output["enable_ipv6"] = request.enable_ipv6 - if request.protected is not None: output["protected"] = request.protected @@ -4032,6 +4032,9 @@ def marshal_Volume( if request.name is not None: output["name"] = request.name + if request.export_uri is not None: + output["export_uri"] = request.export_uri + if request.size is not None: output["size"] = request.size @@ -4048,9 +4051,6 @@ def marshal_Volume( else: output["project"] = defaults.default_project_id - if request.export_uri is not None: - output["export_uri"] = request.export_uri - if request.creation_date is not None: output["creation_date"] = request.creation_date.isoformat() @@ -4544,11 +4544,8 @@ def marshal__SetSecurityGroupRequest( if request.tags is not None: output["tags"] = request.tags - if request.creation_date is not None: - output["creation_date"] = request.creation_date.isoformat() - - if request.modification_date is not None: - output["modification_date"] = request.modification_date.isoformat() + if request.organization_default is not None: + output["organization_default"] = request.organization_default if request.project_default is not None: output["project_default"] = request.project_default @@ -4556,6 +4553,12 @@ def marshal__SetSecurityGroupRequest( if request.stateful is not None: output["stateful"] = request.stateful + if request.creation_date is not None: + output["creation_date"] = request.creation_date.isoformat() + + if request.modification_date is not None: + output["modification_date"] = request.modification_date.isoformat() + if request.inbound_default_policy is not None: output["inbound_default_policy"] = request.inbound_default_policy @@ -4572,9 +4575,6 @@ def marshal__SetSecurityGroupRequest( else: output["project"] = defaults.default_project_id - if request.organization_default is not None: - output["organization_default"] = request.organization_default - if request.servers is not None: output["servers"] = [ marshal_ServerSummary(item, defaults) for item in request.servers @@ -4884,13 +4884,16 @@ def marshal__SetServerRequest( if request.commercial_type is not None: output["commercial_type"] = request.commercial_type + if request.dynamic_ip_required is not None: + output["dynamic_ip_required"] = request.dynamic_ip_required + if request.organization is not None: output["organization"] = request.organization else: output["organization"] = defaults.default_organization_id - if request.dynamic_ip_required is not None: - output["dynamic_ip_required"] = request.dynamic_ip_required + if request.enable_ipv6 is not None: + output["enable_ipv6"] = request.enable_ipv6 if request.hostname is not None: output["hostname"] = request.hostname @@ -4918,9 +4921,6 @@ def marshal__SetServerRequest( if request.routed_ip_enabled is not None: output["routed_ip_enabled"] = request.routed_ip_enabled - if request.enable_ipv6 is not None: - output["enable_ipv6"] = request.enable_ipv6 - if request.image is not None: output["image"] = marshal_Image(request.image, defaults) diff --git a/scaleway-async/scaleway_async/instance/v1/types.py b/scaleway-async/scaleway_async/instance/v1/types.py index 4470ba522..7471bebe2 100644 --- a/scaleway-async/scaleway_async/instance/v1/types.py +++ b/scaleway-async/scaleway_async/instance/v1/types.py @@ -347,6 +347,11 @@ class Volume: Volume name. """ + export_uri: str + """ + Show the volume NBD export URI (deprecated, will always be empty). + """ + size: int """ Volume disk size. @@ -382,11 +387,6 @@ class Volume: Zone in which the volume is located. """ - export_uri: Optional[str] = None - """ - Show the volume NBD export URI (deprecated, will always be empty). - """ - creation_date: Optional[datetime] = None """ Volume creation date. @@ -804,6 +804,16 @@ class Server: True if a dynamic IPv4 is required. """ + routed_ip_enabled: bool + """ + True to configure the instance so it uses the routed IP mode. Use of `routed_ip_enabled` as `False` is deprecated. + """ + + enable_ipv6: bool + """ + True if IPv6 is enabled (deprecated and always `False` when `routed_ip_enabled` is `True`). + """ + hostname: str """ Instance host name. @@ -879,16 +889,6 @@ class Server: Instance creation date. """ - routed_ip_enabled: Optional[bool] = False - """ - True to configure the instance so it uses the routed IP mode. Use of `routed_ip_enabled` as `False` is deprecated. - """ - - enable_ipv6: Optional[bool] = False - """ - True if IPv6 is enabled (deprecated and always `False` when `routed_ip_enabled` is `True`). - """ - image: Optional[Image] = None """ Information about the Instance image. @@ -1039,6 +1039,11 @@ class SecurityGroup: Security group tags. """ + organization_default: bool + """ + True if it is your default security group for this Organization ID. + """ + project_default: bool """ True if it is your default security group for this Project ID. @@ -1064,11 +1069,6 @@ class SecurityGroup: Zone in which the security group is located. """ - organization_default: Optional[bool] = False - """ - True if it is your default security group for this Organization ID. - """ - creation_date: Optional[datetime] = None """ Security group creation date. @@ -1265,8 +1265,8 @@ class Dashboard: private_nics_count: int placement_groups_count: int volumes_scratch_count: int - volumes_b_ssd_count: Optional[int] = None - volumes_b_ssd_total_size: Optional[int] = None + volumes_b_ssd_count: int + volumes_b_ssd_total_size: int @dataclass @@ -1294,6 +1294,11 @@ class GetServerTypesAvailabilityResponseAvailability: @dataclass class ServerType: + monthly_price: float + """ + Estimated monthly price, for a 30 days month, in Euro. + """ + hourly_price: float """ Hourly price in Euro. @@ -1329,11 +1334,6 @@ class ServerType: True if this Instance type has reached end of service. """ - monthly_price: Optional[float] = 0.0 - """ - Estimated monthly price, for a 30 days month, in Euro. - """ - per_volume_constraint: Optional[ServerTypeVolumeConstraintsByType] = None """ Additional volume constraints. @@ -1783,6 +1783,11 @@ class CreateServerRequest: Define the Instance commercial type (i.e. GP1-S). """ + enable_ipv6: bool + """ + True if IPv6 is enabled on the server (deprecated and always `False` when `routed_ip_enabled` is `True`). + """ + protected: bool """ True to activate server protection option. @@ -1818,11 +1823,6 @@ class CreateServerRequest: Volumes attached to the server. """ - enable_ipv6: Optional[bool] = False - """ - True if IPv6 is enabled on the server (deprecated and always `False` when `routed_ip_enabled` is `True`). - """ - public_ip: Optional[str] = None """ ID of the reserved IP to attach to the Instance. diff --git a/scaleway-async/scaleway_async/instance/v1/types_private.py b/scaleway-async/scaleway_async/instance/v1/types_private.py index 53890fe56..233583dc7 100644 --- a/scaleway-async/scaleway_async/instance/v1/types_private.py +++ b/scaleway-async/scaleway_async/instance/v1/types_private.py @@ -70,13 +70,9 @@ class _SetSecurityGroupRequest: """ Tags of the security group. """ - creation_date: Optional[datetime] - """ - Creation date of the security group (will be ignored). + organization_default: bool """ - modification_date: Optional[datetime] - """ - Modification date of the security group (will be ignored). + Please use project_default instead. """ project_default: bool """ @@ -86,6 +82,14 @@ class _SetSecurityGroupRequest: """ True to set the security group as stateful. """ + creation_date: Optional[datetime] + """ + Creation date of the security group (will be ignored). + """ + modification_date: Optional[datetime] + """ + Modification date of the security group (will be ignored). + """ inbound_default_policy: Optional[SecurityGroupPolicy] """ Default inbound policy. @@ -102,10 +106,6 @@ class _SetSecurityGroupRequest: """ Security group Project ID. """ - organization_default: Optional[bool] - """ - Please use project_default instead. - """ servers: Optional[list[ServerSummary]] """ Instances attached to this security group. @@ -159,13 +159,17 @@ class _SetServerRequest: """ Instance commercial type (eg. GP1-M). """ + dynamic_ip_required: bool + """ + True if a dynamic IPv4 is required. + """ organization: Optional[str] """ Instance Organization ID. """ - dynamic_ip_required: bool + enable_ipv6: bool """ - True if a dynamic IPv4 is required. + True if IPv6 is enabled (deprecated and always `False` when `routed_ip_enabled` is `True`). """ hostname: str """ @@ -199,10 +203,6 @@ class _SetServerRequest: """ True to configure the instance so it uses the new routed IP mode (once this is set to True you cannot set it back to False). """ - enable_ipv6: Optional[bool] - """ - True if IPv6 is enabled (deprecated and always `False` when `routed_ip_enabled` is `True`). - """ image: Optional[Image] """ Provide information on the Instance image. diff --git a/scaleway-async/scaleway_async/interlink/v1beta1/api.py b/scaleway-async/scaleway_async/interlink/v1beta1/api.py index e0ac46b7e..f2140b4ec 100644 --- a/scaleway-async/scaleway_async/interlink/v1beta1/api.py +++ b/scaleway-async/scaleway_async/interlink/v1beta1/api.py @@ -253,8 +253,8 @@ async def wait_for_dedicated_connection( options = WaitForOptions() if not options.stop: - options.stop = ( - lambda res: res.status not in DEDICATED_CONNECTION_TRANSIENT_STATUSES + options.stop = lambda res: ( + res.status not in DEDICATED_CONNECTION_TRANSIENT_STATUSES ) return await wait_for_resource_async( diff --git a/scaleway-async/scaleway_async/jobs/v1alpha2/__init__.py b/scaleway-async/scaleway_async/jobs/v1alpha2/__init__.py index 453c9acd3..1e3d1ebdc 100644 --- a/scaleway-async/scaleway_async/jobs/v1alpha2/__init__.py +++ b/scaleway-async/scaleway_async/jobs/v1alpha2/__init__.py @@ -5,26 +5,34 @@ from .content import JOB_RUN_TRANSIENT_STATUSES from .types import ListJobDefinitionsRequestOrderBy from .types import ListJobRunsRequestOrderBy +from .types import ListTriggersRequestOrderBy from .types import SecretEnvVar from .types import SecretFile from .types import CronSchedule from .types import RetryPolicy +from .types import TriggerCronConfig from .types import CreateJobDefinitionRequestCronScheduleConfig from .types import CreateSecretsRequestSecretConfig from .types import Secret +from .types import CreateTriggerRequestCronConfig from .types import JobDefinition from .types import Resource from .types import JobRun +from .types import Trigger from .types import UpdateJobDefinitionRequestCronScheduleConfig +from .types import UpdateTriggerRequestCronConfig from .types import CreateJobDefinitionRequest from .types import CreateSecretsRequest from .types import CreateSecretsResponse +from .types import CreateTriggerRequest from .types import DeleteJobDefinitionRequest from .types import DeleteSecretRequest +from .types import DeleteTriggerRequest from .types import GetJobDefinitionRequest from .types import GetJobLimitsRequest from .types import GetJobRunRequest from .types import GetSecretRequest +from .types import GetTriggerRequest from .types import JobLimits from .types import ListJobDefinitionsRequest from .types import ListJobDefinitionsResponse @@ -34,11 +42,14 @@ from .types import ListJobRunsResponse from .types import ListSecretsRequest from .types import ListSecretsResponse +from .types import ListTriggersRequest +from .types import ListTriggersResponse from .types import StartJobDefinitionRequest from .types import StartJobDefinitionResponse from .types import StopJobRunRequest from .types import UpdateJobDefinitionRequest from .types import UpdateSecretRequest +from .types import UpdateTriggerRequest from .api import JobsV1Alpha2API __all__ = [ @@ -47,26 +58,34 @@ "JOB_RUN_TRANSIENT_STATUSES", "ListJobDefinitionsRequestOrderBy", "ListJobRunsRequestOrderBy", + "ListTriggersRequestOrderBy", "SecretEnvVar", "SecretFile", "CronSchedule", "RetryPolicy", + "TriggerCronConfig", "CreateJobDefinitionRequestCronScheduleConfig", "CreateSecretsRequestSecretConfig", "Secret", + "CreateTriggerRequestCronConfig", "JobDefinition", "Resource", "JobRun", + "Trigger", "UpdateJobDefinitionRequestCronScheduleConfig", + "UpdateTriggerRequestCronConfig", "CreateJobDefinitionRequest", "CreateSecretsRequest", "CreateSecretsResponse", + "CreateTriggerRequest", "DeleteJobDefinitionRequest", "DeleteSecretRequest", + "DeleteTriggerRequest", "GetJobDefinitionRequest", "GetJobLimitsRequest", "GetJobRunRequest", "GetSecretRequest", + "GetTriggerRequest", "JobLimits", "ListJobDefinitionsRequest", "ListJobDefinitionsResponse", @@ -76,10 +95,13 @@ "ListJobRunsResponse", "ListSecretsRequest", "ListSecretsResponse", + "ListTriggersRequest", + "ListTriggersResponse", "StartJobDefinitionRequest", "StartJobDefinitionResponse", "StopJobRunRequest", "UpdateJobDefinitionRequest", "UpdateSecretRequest", + "UpdateTriggerRequest", "JobsV1Alpha2API", ] diff --git a/scaleway-async/scaleway_async/jobs/v1alpha2/api.py b/scaleway-async/scaleway_async/jobs/v1alpha2/api.py index 0057f5cf8..efd09f7b2 100644 --- a/scaleway-async/scaleway_async/jobs/v1alpha2/api.py +++ b/scaleway-async/scaleway_async/jobs/v1alpha2/api.py @@ -17,11 +17,14 @@ JobRunState, ListJobDefinitionsRequestOrderBy, ListJobRunsRequestOrderBy, + ListTriggersRequestOrderBy, CreateJobDefinitionRequest, CreateJobDefinitionRequestCronScheduleConfig, CreateSecretsRequest, CreateSecretsRequestSecretConfig, CreateSecretsResponse, + CreateTriggerRequest, + CreateTriggerRequestCronConfig, JobDefinition, JobLimits, JobRun, @@ -29,30 +32,38 @@ ListJobResourcesResponse, ListJobRunsResponse, ListSecretsResponse, + ListTriggersResponse, RetryPolicy, Secret, StartJobDefinitionRequest, StartJobDefinitionResponse, + Trigger, UpdateJobDefinitionRequest, UpdateJobDefinitionRequestCronScheduleConfig, UpdateSecretRequest, + UpdateTriggerRequest, + UpdateTriggerRequestCronConfig, ) from .marshalling import ( unmarshal_Secret, unmarshal_JobDefinition, unmarshal_JobRun, + unmarshal_Trigger, unmarshal_CreateSecretsResponse, unmarshal_JobLimits, unmarshal_ListJobDefinitionsResponse, unmarshal_ListJobResourcesResponse, unmarshal_ListJobRunsResponse, unmarshal_ListSecretsResponse, + unmarshal_ListTriggersResponse, unmarshal_StartJobDefinitionResponse, marshal_CreateJobDefinitionRequest, marshal_CreateSecretsRequest, + marshal_CreateTriggerRequest, marshal_StartJobDefinitionRequest, marshal_UpdateJobDefinitionRequest, marshal_UpdateSecretRequest, + marshal_UpdateTriggerRequest, ) @@ -64,14 +75,14 @@ class JobsV1Alpha2API(API): async def create_job_definition( self, *, - region: Optional[ScwRegion] = None, cpu_limit: int, memory_limit: int, local_storage_capacity: int, image_uri: str, + region: Optional[ScwRegion] = None, name: Optional[str] = None, + command: str, description: str, - command: Optional[str] = None, startup_command: Optional[list[str]] = None, args: Optional[list[str]] = None, project_id: Optional[str] = None, @@ -82,14 +93,14 @@ async def create_job_definition( ) -> JobDefinition: """ Create a new job definition in a specified Project. - :param region: Region to target. If none is passed will use default region from the config. :param cpu_limit: CPU limit of the job (in mvCPU). :param memory_limit: Memory limit of the job (in MiB). :param local_storage_capacity: Local storage capacity of the job (in MiB). :param image_uri: Image to use for the job. + :param region: Region to target. If none is passed will use default region from the config. :param name: Name of the job definition. - :param description: Description of the job. :param command: Deprecated: please use startup_command instead. + :param description: Description of the job. :param startup_command: The main executable or entrypoint script to run. If both command and startup_command are provided, only startup_command will be used. :param args: Passed to the startup command at runtime. @@ -109,6 +120,7 @@ async def create_job_definition( memory_limit=1, local_storage_capacity=1, image_uri="example", + command="example", description="example", ) """ @@ -122,14 +134,14 @@ async def create_job_definition( f"/serverless-jobs/v1alpha2/regions/{param_region}/job-definitions", body=marshal_CreateJobDefinitionRequest( CreateJobDefinitionRequest( - region=region, cpu_limit=cpu_limit, memory_limit=memory_limit, local_storage_capacity=local_storage_capacity, image_uri=image_uri, + region=region, name=name or random_name(prefix="job"), - description=description, command=command, + description=description, startup_command=startup_command, args=args, project_id=project_id, @@ -814,6 +826,247 @@ async def delete_secret( self._throw_on_error(res) + async def create_trigger( + self, + *, + job_definition_id: str, + name: str, + region: Optional[ScwRegion] = None, + cron_config: Optional[CreateTriggerRequestCronConfig] = None, + ) -> Trigger: + """ + Create a trigger. + :param job_definition_id: UUID of the job definition. + :param name: Name of the trigger. + :param region: Region to target. If none is passed will use default region from the config. + :param cron_config: Configuration of the CRON trigger. + One-Of ('config'): at most one of 'cron_config' could be set. + :return: :class:`Trigger ` + + Usage: + :: + + result = await api.create_trigger( + job_definition_id="example", + name="example", + ) + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + + res = self._request( + "POST", + f"/serverless-jobs/v1alpha2/regions/{param_region}/triggers", + body=marshal_CreateTriggerRequest( + CreateTriggerRequest( + job_definition_id=job_definition_id, + name=name, + region=region, + cron_config=cron_config, + ), + self.client, + ), + ) + + self._throw_on_error(res) + return unmarshal_Trigger(res.json()) + + async def get_trigger( + self, + *, + trigger_id: str, + region: Optional[ScwRegion] = None, + ) -> Trigger: + """ + Get a trigger. + :param trigger_id: UUID of the trigger. + :param region: Region to target. If none is passed will use default region from the config. + :return: :class:`Trigger ` + + Usage: + :: + + result = await api.get_trigger( + trigger_id="example", + ) + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + param_trigger_id = validate_path_param("trigger_id", trigger_id) + + res = self._request( + "GET", + f"/serverless-jobs/v1alpha2/regions/{param_region}/triggers/{param_trigger_id}", + ) + + self._throw_on_error(res) + return unmarshal_Trigger(res.json()) + + async def list_triggers( + self, + *, + job_definition_id: str, + region: Optional[ScwRegion] = None, + page: Optional[int] = None, + page_size: Optional[int] = None, + order_by: Optional[ListTriggersRequestOrderBy] = None, + ) -> ListTriggersResponse: + """ + List triggers of a job definition. + :param job_definition_id: UUID of the job definition. + :param region: Region to target. If none is passed will use default region from the config. + :param page: Page number from paginated list of triggers. + :param page_size: Number of triggers per page. + :param order_by: Sorting order of triggers. + :return: :class:`ListTriggersResponse ` + + Usage: + :: + + result = await api.list_triggers( + job_definition_id="example", + ) + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + + res = self._request( + "GET", + f"/serverless-jobs/v1alpha2/regions/{param_region}/triggers", + params={ + "job_definition_id": job_definition_id, + "order_by": order_by, + "page": page, + "page_size": page_size or self.client.default_page_size, + }, + ) + + self._throw_on_error(res) + return unmarshal_ListTriggersResponse(res.json()) + + async def list_triggers_all( + self, + *, + job_definition_id: str, + region: Optional[ScwRegion] = None, + page: Optional[int] = None, + page_size: Optional[int] = None, + order_by: Optional[ListTriggersRequestOrderBy] = None, + ) -> list[Trigger]: + """ + List triggers of a job definition. + :param job_definition_id: UUID of the job definition. + :param region: Region to target. If none is passed will use default region from the config. + :param page: Page number from paginated list of triggers. + :param page_size: Number of triggers per page. + :param order_by: Sorting order of triggers. + :return: :class:`list[Trigger] ` + + Usage: + :: + + result = await api.list_triggers_all( + job_definition_id="example", + ) + """ + + return await fetch_all_pages_async( + type=ListTriggersResponse, + key="triggers", + fetcher=self.list_triggers, + args={ + "job_definition_id": job_definition_id, + "region": region, + "page": page, + "page_size": page_size, + "order_by": order_by, + }, + ) + + async def update_trigger( + self, + *, + trigger_id: str, + region: Optional[ScwRegion] = None, + name: Optional[str] = None, + cron_config: Optional[UpdateTriggerRequestCronConfig] = None, + ) -> Trigger: + """ + Update a trigger. + :param trigger_id: UUID of the trigger. + :param region: Region to target. If none is passed will use default region from the config. + :param name: Name of the trigger. + :param cron_config: Configuration of the CRON trigger. + One-Of ('config'): at most one of 'cron_config' could be set. + :return: :class:`Trigger ` + + Usage: + :: + + result = await api.update_trigger( + trigger_id="example", + ) + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + param_trigger_id = validate_path_param("trigger_id", trigger_id) + + res = self._request( + "PATCH", + f"/serverless-jobs/v1alpha2/regions/{param_region}/triggers/{param_trigger_id}", + body=marshal_UpdateTriggerRequest( + UpdateTriggerRequest( + trigger_id=trigger_id, + region=region, + name=name, + cron_config=cron_config, + ), + self.client, + ), + ) + + self._throw_on_error(res) + return unmarshal_Trigger(res.json()) + + async def delete_trigger( + self, + *, + trigger_id: str, + region: Optional[ScwRegion] = None, + ) -> None: + """ + Delete a trigger. + :param trigger_id: UUID of the trigger. + :param region: Region to target. If none is passed will use default region from the config. + + Usage: + :: + + result = await api.delete_trigger( + trigger_id="example", + ) + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + param_trigger_id = validate_path_param("trigger_id", trigger_id) + + res = self._request( + "DELETE", + f"/serverless-jobs/v1alpha2/regions/{param_region}/triggers/{param_trigger_id}", + ) + + self._throw_on_error(res) + async def list_job_resources( self, *, diff --git a/scaleway-async/scaleway_async/jobs/v1alpha2/marshalling.py b/scaleway-async/scaleway_async/jobs/v1alpha2/marshalling.py index 6d4729d1e..02195315a 100644 --- a/scaleway-async/scaleway_async/jobs/v1alpha2/marshalling.py +++ b/scaleway-async/scaleway_async/jobs/v1alpha2/marshalling.py @@ -10,6 +10,8 @@ resolve_one_of, ) from .types import ( + JobRunReason, + JobRunState, SecretEnvVar, SecretFile, Secret, @@ -17,6 +19,8 @@ RetryPolicy, JobDefinition, JobRun, + TriggerCronConfig, + Trigger, CreateSecretsResponse, JobLimits, ListJobDefinitionsResponse, @@ -24,15 +28,20 @@ ListJobResourcesResponse, ListJobRunsResponse, ListSecretsResponse, + ListTriggersResponse, StartJobDefinitionResponse, CreateJobDefinitionRequestCronScheduleConfig, CreateJobDefinitionRequest, CreateSecretsRequestSecretConfig, CreateSecretsRequest, + CreateTriggerRequestCronConfig, + CreateTriggerRequest, StartJobDefinitionRequest, UpdateJobDefinitionRequestCronScheduleConfig, UpdateJobDefinitionRequest, UpdateSecretRequest, + UpdateTriggerRequestCronConfig, + UpdateTriggerRequest, ) @@ -187,19 +196,19 @@ def unmarshal_JobDefinition(data: Any) -> JobDefinition: if field is not None: args["cpu_limit"] = field else: - args["cpu_limit"] = None + args["cpu_limit"] = 0 field = data.get("memory_limit", None) if field is not None: args["memory_limit"] = field else: - args["memory_limit"] = None + args["memory_limit"] = 0 field = data.get("local_storage_capacity", None) if field is not None: args["local_storage_capacity"] = field else: - args["local_storage_capacity"] = None + args["local_storage_capacity"] = 0 field = data.get("image_uri", None) if field is not None: @@ -207,11 +216,17 @@ def unmarshal_JobDefinition(data: Any) -> JobDefinition: else: args["image_uri"] = None + field = data.get("command", None) + if field is not None: + args["command"] = field + else: + args["command"] = None + field = data.get("environment_variables", None) if field is not None: args["environment_variables"] = field else: - args["environment_variables"] = None + args["environment_variables"] = {} field = data.get("created_at", None) if field is not None: @@ -225,12 +240,6 @@ def unmarshal_JobDefinition(data: Any) -> JobDefinition: else: args["updated_at"] = None - field = data.get("command", None) - if field is not None: - args["command"] = field - else: - args["command"] = None - field = data.get("job_timeout", None) if field is not None: args["job_timeout"] = field @@ -247,13 +256,13 @@ def unmarshal_JobDefinition(data: Any) -> JobDefinition: if field is not None: args["startup_command"] = field else: - args["startup_command"] = None + args["startup_command"] = [] field = data.get("args", None) if field is not None: args["args"] = field else: - args["args"] = None + args["args"] = [] field = data.get("region", None) if field is not None: @@ -300,13 +309,7 @@ def unmarshal_JobRun(data: Any) -> JobRun: if field is not None: args["state"] = field else: - args["state"] = None - - field = data.get("cpu_limit", None) - if field is not None: - args["cpu_limit"] = field - else: - args["cpu_limit"] = None + args["state"] = JobRunState.UNKNOWN_STATE field = data.get("created_at", None) if field is not None: @@ -326,35 +329,47 @@ def unmarshal_JobRun(data: Any) -> JobRun: else: args["started_at"] = None + field = data.get("cpu_limit", None) + if field is not None: + args["cpu_limit"] = field + else: + args["cpu_limit"] = 0 + field = data.get("memory_limit", None) if field is not None: args["memory_limit"] = field else: - args["memory_limit"] = None + args["memory_limit"] = 0 field = data.get("local_storage_capacity", None) if field is not None: args["local_storage_capacity"] = field else: - args["local_storage_capacity"] = None + args["local_storage_capacity"] = 0 + + field = data.get("command", None) + if field is not None: + args["command"] = field + else: + args["command"] = None field = data.get("environment_variables", None) if field is not None: args["environment_variables"] = field else: - args["environment_variables"] = None + args["environment_variables"] = {} field = data.get("startup_command", None) if field is not None: args["startup_command"] = field else: - args["startup_command"] = None + args["startup_command"] = [] field = data.get("args", None) if field is not None: args["args"] = field else: - args["args"] = None + args["args"] = [] field = data.get("region", None) if field is not None: @@ -380,13 +395,13 @@ def unmarshal_JobRun(data: Any) -> JobRun: if field is not None: args["reason"] = field else: - args["reason"] = None + args["reason"] = JobRunReason.UNKNOWN_REASON field = data.get("exit_code", None) if field is not None: args["exit_code"] = field else: - args["exit_code"] = None + args["exit_code"] = 0 field = data.get("error_message", None) if field is not None: @@ -394,21 +409,97 @@ def unmarshal_JobRun(data: Any) -> JobRun: else: args["error_message"] = None - field = data.get("command", None) - if field is not None: - args["command"] = field - else: - args["command"] = None - field = data.get("attempts", None) if field is not None: args["attempts"] = field else: - args["attempts"] = None + args["attempts"] = 0 return JobRun(**args) +def unmarshal_TriggerCronConfig(data: Any) -> TriggerCronConfig: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'TriggerCronConfig' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("schedule", None) + if field is not None: + args["schedule"] = field + else: + args["schedule"] = None + + field = data.get("timezone", None) + if field is not None: + args["timezone"] = field + else: + args["timezone"] = None + + field = data.get("startup_command", None) + if field is not None: + args["startup_command"] = field + else: + args["startup_command"] = [] + + field = data.get("args", None) + if field is not None: + args["args"] = field + else: + args["args"] = [] + + return TriggerCronConfig(**args) + + +def unmarshal_Trigger(data: Any) -> Trigger: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'Trigger' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("id", None) + if field is not None: + args["id"] = field + else: + args["id"] = None + + field = data.get("job_definition_id", None) + if field is not None: + args["job_definition_id"] = field + else: + args["job_definition_id"] = None + + field = data.get("name", None) + if field is not None: + args["name"] = field + else: + args["name"] = None + + field = data.get("created_at", None) + if field is not None: + args["created_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["created_at"] = None + + field = data.get("updated_at", None) + if field is not None: + args["updated_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["updated_at"] = None + + field = data.get("cron_config", None) + if field is not None: + args["cron_config"] = unmarshal_TriggerCronConfig(field) + else: + args["cron_config"] = None + + return Trigger(**args) + + def unmarshal_CreateSecretsResponse(data: Any) -> CreateSecretsResponse: if not isinstance(data, dict): raise TypeError( @@ -562,6 +653,31 @@ def unmarshal_ListSecretsResponse(data: Any) -> ListSecretsResponse: return ListSecretsResponse(**args) +def unmarshal_ListTriggersResponse(data: Any) -> ListTriggersResponse: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'ListTriggersResponse' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("triggers", None) + if field is not None: + args["triggers"] = ( + [unmarshal_Trigger(v) for v in field] if field is not None else None + ) + else: + args["triggers"] = [] + + field = data.get("total_count", None) + if field is not None: + args["total_count"] = field + else: + args["total_count"] = 0 + + return ListTriggersResponse(**args) + + def unmarshal_StartJobDefinitionResponse(data: Any) -> StartJobDefinitionResponse: if not isinstance(data, dict): raise TypeError( @@ -629,12 +745,12 @@ def marshal_CreateJobDefinitionRequest( if request.name is not None: output["name"] = request.name - if request.description is not None: - output["description"] = request.description - if request.command is not None: output["command"] = request.command + if request.description is not None: + output["description"] = request.description + if request.startup_command is not None: output["startup_command"] = request.startup_command @@ -708,6 +824,53 @@ def marshal_CreateSecretsRequest( return output +def marshal_CreateTriggerRequestCronConfig( + request: CreateTriggerRequestCronConfig, + defaults: ProfileDefaults, +) -> dict[str, Any]: + output: dict[str, Any] = {} + + if request.schedule is not None: + output["schedule"] = request.schedule + + if request.timezone is not None: + output["timezone"] = request.timezone + + if request.startup_command is not None: + output["startup_command"] = request.startup_command + + if request.args is not None: + output["args"] = request.args + + return output + + +def marshal_CreateTriggerRequest( + request: CreateTriggerRequest, + defaults: ProfileDefaults, +) -> dict[str, Any]: + output: dict[str, Any] = {} + output.update( + resolve_one_of( + [ + OneOfPossibility( + param="cron_config", + value=request.cron_config, + marshal_func=marshal_CreateTriggerRequestCronConfig, + ), + ] + ), + ) + + if request.job_definition_id is not None: + output["job_definition_id"] = request.job_definition_id + + if request.name is not None: + output["name"] = request.name + + return output + + def marshal_StartJobDefinitionRequest( request: StartJobDefinitionRequest, defaults: ProfileDefaults, @@ -817,3 +980,47 @@ def marshal_UpdateSecretRequest( output["secret_manager_version"] = request.secret_manager_version return output + + +def marshal_UpdateTriggerRequestCronConfig( + request: UpdateTriggerRequestCronConfig, + defaults: ProfileDefaults, +) -> dict[str, Any]: + output: dict[str, Any] = {} + + if request.schedule is not None: + output["schedule"] = request.schedule + + if request.timezone is not None: + output["timezone"] = request.timezone + + if request.startup_command is not None: + output["startup_command"] = request.startup_command + + if request.args is not None: + output["args"] = request.args + + return output + + +def marshal_UpdateTriggerRequest( + request: UpdateTriggerRequest, + defaults: ProfileDefaults, +) -> dict[str, Any]: + output: dict[str, Any] = {} + output.update( + resolve_one_of( + [ + OneOfPossibility( + param="cron_config", + value=request.cron_config, + marshal_func=marshal_UpdateTriggerRequestCronConfig, + ), + ] + ), + ) + + if request.name is not None: + output["name"] = request.name + + return output diff --git a/scaleway-async/scaleway_async/jobs/v1alpha2/types.py b/scaleway-async/scaleway_async/jobs/v1alpha2/types.py index 1f13dc4f4..5dcf6b2ce 100644 --- a/scaleway-async/scaleway_async/jobs/v1alpha2/types.py +++ b/scaleway-async/scaleway_async/jobs/v1alpha2/types.py @@ -66,6 +66,14 @@ def __str__(self) -> str: return str(self.value) +class ListTriggersRequestOrderBy(str, Enum, metaclass=StrEnumMeta): + CREATED_AT_ASC = "created_at_asc" + CREATED_AT_DESC = "created_at_desc" + + def __str__(self) -> str: + return str(self.value) + + @dataclass class SecretEnvVar: name: str @@ -97,6 +105,29 @@ class RetryPolicy: """ +@dataclass +class TriggerCronConfig: + schedule: str + """ + CRON schedule in UNIX format. + """ + + timezone: str + """ + Time zone for the CRON schedule. + """ + + startup_command: list[str] + """ + Startup command that will be used by the triggered job. + """ + + args: list[str] + """ + Arguments passed to the startup command used by the triggered job. + """ + + @dataclass class CreateJobDefinitionRequestCronScheduleConfig: schedule: str @@ -139,30 +170,120 @@ class Secret: env_var: Optional[SecretEnvVar] = None +@dataclass +class CreateTriggerRequestCronConfig: + schedule: str + """ + CRON schedule in UNIX format. + """ + + timezone: str + """ + Time zone for the CRON schedule. + """ + + startup_command: list[str] + """ + Startup command that will be used by the triggered job. + """ + + args: list[str] + """ + Arguments passed to the startup command used by the triggered job. + """ + + @dataclass class JobDefinition: id: str + """ + UUID of the job definition. + """ + name: str + """ + Name of the job definition. + """ + project_id: str + """ + UUID of the Scaleway Project containing the job. + """ + cpu_limit: int + """ + CPU limit of the job (in mvCPU). + """ + memory_limit: int + """ + Memory limit of the job (in MiB). + """ + local_storage_capacity: int + """ + Local storage capacity of the job (in MiB). + """ + image_uri: str + """ + Image to use for the job. + """ + + command: str + """ + Deprecated, please use startup_command instead. + """ + environment_variables: dict[str, str] + """ + Environment variables of the job. + """ + description: str + """ + Description of the job. + """ + startup_command: list[str] + """ + Job startup command. + """ + args: list[str] + """ + Job arguments passed to the startup command at runtime. + """ + region: ScwRegion """ Region to target. If none is passed will use default region from the config. """ created_at: Optional[datetime] = None + """ + Creation date of the job definition. + """ + updated_at: Optional[datetime] = None - command: Optional[str] = None + """ + Last update date of the job definition. + """ + job_timeout: Optional[str] = None + """ + Timeout of the job in seconds. + """ + cron_schedule: Optional[CronSchedule] = None + """ + Configure a cron for the job. + """ + retry_policy: Optional[RetryPolicy] = None + """ + Retry behaviour in case of job failure. + """ @dataclass @@ -174,29 +295,134 @@ class Resource: @dataclass class JobRun: id: str + """ + UUID of the job run. + """ + job_definition_id: str + """ + UUID of the job definition. + """ + state: JobRunState + """ + State of the job run. + """ + cpu_limit: int + """ + CPU limit of the job (in mvCPU). + """ + memory_limit: int + """ + Memory limit of the job (in MiB). + """ + local_storage_capacity: int + """ + Local storage capacity of the job (in MiB). + """ + + command: str + """ + Deprecated, please use startup_command instead. + """ + environment_variables: dict[str, str] + """ + Environment variables of the job run. + """ + startup_command: list[str] + """ + Job startup command. + """ + args: list[str] + """ + Job arguments passed to the startup command at runtime. + """ + region: ScwRegion """ Region to target. If none is passed will use default region from the config. """ created_at: Optional[datetime] = None + """ + Creation date of the job run. + """ + updated_at: Optional[datetime] = None + """ + Last update date of the job run. + """ + started_at: Optional[datetime] = None + """ + Start date of the job run. + """ + terminated_at: Optional[datetime] = None + """ + Termination date of the job run. + """ + run_duration: Optional[str] = None - reason: Optional[JobRunReason] = None - exit_code: Optional[int] = None + """ + Duration of the job run. + """ + + reason: Optional[JobRunReason] = JobRunReason.UNKNOWN_REASON + """ + Reason for failure if the job failed. + """ + + exit_code: Optional[int] = 0 + """ + Exit code of the job. + """ + error_message: Optional[str] = None - command: Optional[str] = None - attempts: Optional[int] = None + """ + Error message if the job failed. + """ + + attempts: Optional[int] = 0 + """ + Number of retry attempts. + """ + + +@dataclass +class Trigger: + id: str + """ + UUID of the trigger. + """ + + job_definition_id: str + """ + UUID of the job definition. + """ + + name: str + """ + Human readable name of the trigger. + """ + + created_at: Optional[datetime] = None + """ + Creation time of the trigger. + """ + + updated_at: Optional[datetime] = None + """ + Last update time of the trigger. + """ + + cron_config: Optional[TriggerCronConfig] = None @dataclass @@ -205,6 +431,29 @@ class UpdateJobDefinitionRequestCronScheduleConfig: timezone: Optional[str] = None +@dataclass +class UpdateTriggerRequestCronConfig: + schedule: Optional[str] = None + """ + CRON schedule in UNIX format. + """ + + timezone: Optional[str] = None + """ + Time zone for the CRON schedule. + """ + + startup_command: Optional[list[str]] = field(default_factory=list) + """ + Startup command that will be used by the triggered job. + """ + + args: Optional[list[str]] = field(default_factory=list) + """ + Arguments passed to the startup command used by the triggered job. + """ + + @dataclass class CreateJobDefinitionRequest: cpu_limit: int @@ -227,6 +476,11 @@ class CreateJobDefinitionRequest: Image to use for the job. """ + command: str + """ + Deprecated: please use startup_command instead. + """ + description: str """ Description of the job. @@ -242,11 +496,6 @@ class CreateJobDefinitionRequest: Name of the job definition. """ - command: Optional[str] = None - """ - Deprecated: please use startup_command instead. - """ - startup_command: Optional[list[str]] = field(default_factory=list) """ The main executable or entrypoint script to run. @@ -311,6 +560,26 @@ class CreateSecretsResponse: """ +@dataclass +class CreateTriggerRequest: + job_definition_id: str + """ + UUID of the job definition. + """ + + name: str + """ + Name of the trigger. + """ + + region: Optional[ScwRegion] = None + """ + Region to target. If none is passed will use default region from the config. + """ + + cron_config: Optional[CreateTriggerRequestCronConfig] = None + + @dataclass class DeleteJobDefinitionRequest: job_definition_id: str @@ -337,6 +606,19 @@ class DeleteSecretRequest: """ +@dataclass +class DeleteTriggerRequest: + trigger_id: str + """ + UUID of the trigger. + """ + + region: Optional[ScwRegion] = None + """ + Region to target. If none is passed will use default region from the config. + """ + + @dataclass class GetJobDefinitionRequest: job_definition_id: str @@ -384,6 +666,19 @@ class GetSecretRequest: """ +@dataclass +class GetTriggerRequest: + trigger_id: str + """ + UUID of the trigger. + """ + + region: Optional[ScwRegion] = None + """ + Region to target. If none is passed will use default region from the config. + """ + + @dataclass class JobLimits: secrets_per_job_definition: int @@ -472,6 +767,49 @@ class ListSecretsResponse: """ +@dataclass +class ListTriggersRequest: + job_definition_id: str + """ + UUID of the job definition. + """ + + region: Optional[ScwRegion] = None + """ + Region to target. If none is passed will use default region from the config. + """ + + page: Optional[int] = 0 + """ + Page number from paginated list of triggers. + """ + + page_size: Optional[int] = 0 + """ + Number of triggers per page. + """ + + order_by: Optional[ListTriggersRequestOrderBy] = ( + ListTriggersRequestOrderBy.CREATED_AT_ASC + ) + """ + Sorting order of triggers. + """ + + +@dataclass +class ListTriggersResponse: + triggers: list[Trigger] + """ + List of triggers. + """ + + total_count: int + """ + Total count of triggers. + """ + + @dataclass class StartJobDefinitionRequest: job_definition_id: str @@ -636,3 +974,23 @@ class UpdateSecretRequest: path: Optional[str] = None env_var_name: Optional[str] = None + + +@dataclass +class UpdateTriggerRequest: + trigger_id: str + """ + UUID of the trigger. + """ + + region: Optional[ScwRegion] = None + """ + Region to target. If none is passed will use default region from the config. + """ + + name: Optional[str] = None + """ + Name of the trigger. + """ + + cron_config: Optional[UpdateTriggerRequestCronConfig] = None diff --git a/scaleway-async/scaleway_async/lb/v1/api.py b/scaleway-async/scaleway_async/lb/v1/api.py index 3d8fd1c45..ffced406b 100644 --- a/scaleway-async/scaleway_async/lb/v1/api.py +++ b/scaleway-async/scaleway_async/lb/v1/api.py @@ -939,7 +939,7 @@ async def create_backend( server_ip: list[str], zone: Optional[ScwZone] = None, name: Optional[str] = None, - send_proxy_v2: Optional[bool] = None, + send_proxy_v2: bool, timeout_server: Optional[str] = None, timeout_connect: Optional[str] = None, timeout_tunnel: Optional[str] = None, @@ -993,6 +993,7 @@ async def create_backend( lb_id="example", health_check=HealthCheck(), server_ip=[], + send_proxy_v2=False, ) """ @@ -1077,8 +1078,8 @@ async def update_backend( forward_port_algorithm: ForwardPortAlgorithm, sticky_sessions: StickySessionsType, sticky_sessions_cookie_name: str, + send_proxy_v2: bool, zone: Optional[ScwZone] = None, - send_proxy_v2: Optional[bool] = None, timeout_server: Optional[str] = None, timeout_connect: Optional[str] = None, timeout_tunnel: Optional[str] = None, @@ -1102,8 +1103,8 @@ async def update_backend( :param forward_port_algorithm: Load balancing algorithm to be used when determining which backend server to forward new traffic to. :param sticky_sessions: Defines whether to activate sticky sessions (binding a particular session to a particular backend server) and the method to use if so. None disables sticky sessions. Cookie-based uses an HTTP cookie to stick a session to a backend server. Table-based uses the source (client) IP address to stick a session to a backend server. :param sticky_sessions_cookie_name: Cookie name for cookie-based sticky sessions. - :param zone: Zone to target. If none is passed will use default zone from the config. :param send_proxy_v2: Deprecated in favor of proxy_protocol field. + :param zone: Zone to target. If none is passed will use default zone from the config. :param timeout_server: Maximum allowed time for a backend server to process a request. :param timeout_connect: Maximum allowed time for establishing a connection to a backend server. :param timeout_tunnel: Maximum allowed tunnel inactivity time after Websocket is established (takes precedence over client and server timeout). @@ -1129,6 +1130,7 @@ async def update_backend( forward_port_algorithm=ForwardPortAlgorithm.roundrobin, sticky_sessions=StickySessionsType.none, sticky_sessions_cookie_name="example", + send_proxy_v2=False, ) """ @@ -1147,8 +1149,8 @@ async def update_backend( forward_port_algorithm=forward_port_algorithm, sticky_sessions=sticky_sessions, sticky_sessions_cookie_name=sticky_sessions_cookie_name, - zone=zone, send_proxy_v2=send_proxy_v2, + zone=zone, timeout_server=timeout_server, timeout_connect=timeout_connect, timeout_tunnel=timeout_tunnel, @@ -3979,7 +3981,7 @@ async def create_backend( server_ip: list[str], region: Optional[ScwRegion] = None, name: Optional[str] = None, - send_proxy_v2: Optional[bool] = None, + send_proxy_v2: bool, timeout_server: Optional[str] = None, timeout_connect: Optional[str] = None, timeout_tunnel: Optional[str] = None, @@ -4032,6 +4034,7 @@ async def create_backend( lb_id="example", health_check=HealthCheck(), server_ip=[], + send_proxy_v2=False, ) """ @@ -4119,8 +4122,8 @@ async def update_backend( forward_port_algorithm: ForwardPortAlgorithm, sticky_sessions: StickySessionsType, sticky_sessions_cookie_name: str, + send_proxy_v2: bool, region: Optional[ScwRegion] = None, - send_proxy_v2: Optional[bool] = None, timeout_server: Optional[str] = None, timeout_connect: Optional[str] = None, timeout_tunnel: Optional[str] = None, @@ -4143,8 +4146,8 @@ async def update_backend( :param forward_port_algorithm: Load balancing algorithm to be used when determining which backend server to forward new traffic to. :param sticky_sessions: Defines whether to activate sticky sessions (binding a particular session to a particular backend server) and the method to use if so. None disables sticky sessions. Cookie-based uses an HTTP cookie to stick a session to a backend server. Table-based uses the source (client) IP address to stick a session to a backend server. :param sticky_sessions_cookie_name: Cookie name for cookie-based sticky sessions. - :param region: Region to target. If none is passed will use default region from the config. :param send_proxy_v2: Deprecated in favor of proxy_protocol field. + :param region: Region to target. If none is passed will use default region from the config. :param timeout_server: Maximum allowed time for a backend server to process a request. :param timeout_connect: Maximum allowed time for establishing a connection to a backend server. :param timeout_tunnel: Maximum allowed tunnel inactivity time after Websocket is established (takes precedence over client and server timeout). @@ -4170,6 +4173,7 @@ async def update_backend( forward_port_algorithm=ForwardPortAlgorithm.roundrobin, sticky_sessions=StickySessionsType.none, sticky_sessions_cookie_name="example", + send_proxy_v2=False, ) """ @@ -4190,8 +4194,8 @@ async def update_backend( forward_port_algorithm=forward_port_algorithm, sticky_sessions=sticky_sessions, sticky_sessions_cookie_name=sticky_sessions_cookie_name, - region=region, send_proxy_v2=send_proxy_v2, + region=region, timeout_server=timeout_server, timeout_connect=timeout_connect, timeout_tunnel=timeout_tunnel, diff --git a/scaleway-async/scaleway_async/lb/v1/marshalling.py b/scaleway-async/scaleway_async/lb/v1/marshalling.py index a1d2aef14..13215d66e 100644 --- a/scaleway-async/scaleway_async/lb/v1/marshalling.py +++ b/scaleway-async/scaleway_async/lb/v1/marshalling.py @@ -167,6 +167,12 @@ def unmarshal_Ip(data: Any) -> Ip: else: args["tags"] = [] + field = data.get("region", None) + if field is not None: + args["region"] = field + else: + args["region"] = None + field = data.get("zone", None) if field is not None: args["zone"] = field @@ -179,12 +185,6 @@ def unmarshal_Ip(data: Any) -> Ip: else: args["lb_id"] = None - field = data.get("region", None) - if field is not None: - args["region"] = field - else: - args["region"] = None - return Ip(**args) @@ -515,6 +515,12 @@ def unmarshal_Instance(data: Any) -> Instance: else: args["ip_address"] = None + field = data.get("region", None) + if field is not None: + args["region"] = field + else: + args["region"] = None + field = data.get("zone", None) if field is not None: args["zone"] = field @@ -533,12 +539,6 @@ def unmarshal_Instance(data: Any) -> Instance: else: args["updated_at"] = None - field = data.get("region", None) - if field is not None: - args["region"] = field - else: - args["region"] = None - return Instance(**args) @@ -644,6 +644,12 @@ def unmarshal_Lb(data: Any) -> Lb: else: args["route_count"] = 0 + field = data.get("region", None) + if field is not None: + args["region"] = field + else: + args["region"] = None + field = data.get("zone", None) if field is not None: args["zone"] = field @@ -668,12 +674,6 @@ def unmarshal_Lb(data: Any) -> Lb: else: args["updated_at"] = None - field = data.get("region", None) - if field is not None: - args["region"] = field - else: - args["region"] = None - return Lb(**args) @@ -733,6 +733,12 @@ def unmarshal_Backend(data: Any) -> Backend: else: args["pool"] = [] + field = data.get("send_proxy_v2", None) + if field is not None: + args["send_proxy_v2"] = field + else: + args["send_proxy_v2"] = False + field = data.get("on_marked_down_action", None) if field is not None: args["on_marked_down_action"] = field @@ -757,12 +763,6 @@ def unmarshal_Backend(data: Any) -> Backend: else: args["lb"] = None - field = data.get("send_proxy_v2", None) - if field is not None: - args["send_proxy_v2"] = field - else: - args["send_proxy_v2"] = False - field = data.get("timeout_server", None) if field is not None: args["timeout_server"] = field @@ -1645,18 +1645,18 @@ def unmarshal_LbType(data: Any) -> LbType: else: args["description"] = None - field = data.get("zone", None) - if field is not None: - args["zone"] = field - else: - args["zone"] = None - field = data.get("region", None) if field is not None: args["region"] = field else: args["region"] = None + field = data.get("zone", None) + if field is not None: + args["zone"] = field + else: + args["zone"] = None + return LbType(**args) diff --git a/scaleway-async/scaleway_async/lb/v1/types.py b/scaleway-async/scaleway_async/lb/v1/types.py index f6ab10591..81d8f7e08 100644 --- a/scaleway-async/scaleway_async/lb/v1/types.py +++ b/scaleway-async/scaleway_async/lb/v1/types.py @@ -393,6 +393,11 @@ class Instance: Instance IP address. """ + region: ScwRegion + """ + The region the Instance is in. + """ + zone: ScwZone """ The zone the Instance is in. @@ -408,11 +413,6 @@ class Instance: Date on which the Instance was last updated. """ - region: Optional[ScwRegion] = None - """ - The region the Instance is in. - """ - @dataclass class Ip: @@ -446,6 +446,11 @@ class Ip: IP tags. """ + region: ScwRegion + """ + The region the IP address is in. + """ + zone: ScwZone """ The zone the IP address is in. @@ -456,11 +461,6 @@ class Ip: Load Balancer ID. """ - region: Optional[ScwRegion] = None - """ - The region the IP address is in. - """ - @dataclass class Subscriber: @@ -607,6 +607,11 @@ class Lb: Number of routes configured on the Load Balancer. """ + region: ScwRegion + """ + The region the Load Balancer is in. + """ + zone: ScwZone """ The zone the Load Balancer is in. @@ -627,11 +632,6 @@ class Lb: Date on which the Load Balancer was last updated. """ - region: Optional[ScwRegion] = None - """ - The region the Load Balancer is in. - """ - @dataclass class AclActionRedirect: @@ -693,6 +693,11 @@ class Backend: List of IP addresses of backend servers attached to this backend. """ + send_proxy_v2: bool + """ + Deprecated in favor of proxy_protocol field. + """ + on_marked_down_action: OnMarkedDownAction """ Action to take when a backend server is marked as down. @@ -713,11 +718,6 @@ class Backend: Load Balancer the backend is attached to. """ - send_proxy_v2: Optional[bool] = False - """ - Deprecated in favor of proxy_protocol field. - """ - timeout_server: Optional[str] = None """ Maximum allowed time for a backend server to process a request. @@ -973,7 +973,7 @@ class PrivateNetworkIpamConfig: @dataclass class PrivateNetworkStaticConfig: - ip_address: Optional[list[str]] = field(default_factory=list) + ip_address: list[str] """ Array of a local IP address for the Load Balancer on this Private Network. """ @@ -1151,14 +1151,14 @@ class LbType: Load Balancer commercial offer type description. """ - zone: ScwZone + region: ScwRegion """ - The zone the Load Balancer stock is in. + The region the Load Balancer stock is in. """ - region: Optional[ScwRegion] = None + zone: ScwZone """ - The region the Load Balancer stock is in. + The zone the Load Balancer stock is in. """ @@ -1354,6 +1354,11 @@ class CreateBackendRequest: List of backend server IP addresses (IPv4 or IPv6) the backend should forward traffic to. """ + send_proxy_v2: bool + """ + Deprecated in favor of proxy_protocol field. + """ + region: Optional[ScwRegion] = None """ Region to target. If none is passed will use default region from the config. @@ -1364,11 +1369,6 @@ class CreateBackendRequest: Name for the backend. """ - send_proxy_v2: Optional[bool] = False - """ - Deprecated in favor of proxy_protocol field. - """ - timeout_server: Optional[str] = None """ Maximum allowed time for a backend server to process a request. @@ -2593,14 +2593,14 @@ class UpdateBackendRequest: Cookie name for cookie-based sticky sessions. """ - region: Optional[ScwRegion] = None + send_proxy_v2: bool """ - Region to target. If none is passed will use default region from the config. + Deprecated in favor of proxy_protocol field. """ - send_proxy_v2: Optional[bool] = False + region: Optional[ScwRegion] = None """ - Deprecated in favor of proxy_protocol field. + Region to target. If none is passed will use default region from the config. """ timeout_server: Optional[str] = None @@ -3038,6 +3038,11 @@ class ZonedApiCreateBackendRequest: List of backend server IP addresses (IPv4 or IPv6) the backend should forward traffic to. """ + send_proxy_v2: bool + """ + Deprecated in favor of proxy_protocol field. + """ + zone: Optional[ScwZone] = None """ Zone to target. If none is passed will use default zone from the config. @@ -3048,11 +3053,6 @@ class ZonedApiCreateBackendRequest: Name for the backend. """ - send_proxy_v2: Optional[bool] = False - """ - Deprecated in favor of proxy_protocol field. - """ - timeout_server: Optional[str] = None """ Maximum allowed time for a backend server to process a request. @@ -4131,14 +4131,14 @@ class ZonedApiUpdateBackendRequest: Cookie name for cookie-based sticky sessions. """ - zone: Optional[ScwZone] = None + send_proxy_v2: bool """ - Zone to target. If none is passed will use default zone from the config. + Deprecated in favor of proxy_protocol field. """ - send_proxy_v2: Optional[bool] = False + zone: Optional[ScwZone] = None """ - Deprecated in favor of proxy_protocol field. + Zone to target. If none is passed will use default zone from the config. """ timeout_server: Optional[str] = None diff --git a/scaleway-async/scaleway_async/partner/__init__.py b/scaleway-async/scaleway_async/partner/__init__.py new file mode 100644 index 000000000..8b74a5ed7 --- /dev/null +++ b/scaleway-async/scaleway_async/partner/__init__.py @@ -0,0 +1,2 @@ +# This file was automatically generated. DO NOT EDIT. +# If you have any remark or suggestion do not hesitate to open an issue. diff --git a/scaleway-async/scaleway_async/partner/v1/__init__.py b/scaleway-async/scaleway_async/partner/v1/__init__.py new file mode 100644 index 000000000..13de5e968 --- /dev/null +++ b/scaleway-async/scaleway_async/partner/v1/__init__.py @@ -0,0 +1,31 @@ +# This file was automatically generated. DO NOT EDIT. +# If you have any remark or suggestion do not hesitate to open an issue. +from .types import ListOrganizationsRequestOrderBy +from .types import OrganizationLockedBy +from .types import OrganizationStatus +from .types import Organization +from .types import CreateOrganizationRequest +from .types import GetOrganizationRequest +from .types import ListOrganizationsRequest +from .types import ListOrganizationsResponse +from .types import LockOrganizationRequest +from .types import RequestAdminRoleRequest +from .types import UnlockOrganizationRequest +from .types import UpdateOrganizationRequest +from .api import PartnerV1API + +__all__ = [ + "ListOrganizationsRequestOrderBy", + "OrganizationLockedBy", + "OrganizationStatus", + "Organization", + "CreateOrganizationRequest", + "GetOrganizationRequest", + "ListOrganizationsRequest", + "ListOrganizationsResponse", + "LockOrganizationRequest", + "RequestAdminRoleRequest", + "UnlockOrganizationRequest", + "UpdateOrganizationRequest", + "PartnerV1API", +] diff --git a/scaleway-async/scaleway_async/partner/v1/api.py b/scaleway-async/scaleway_async/partner/v1/api.py new file mode 100644 index 000000000..1745319f3 --- /dev/null +++ b/scaleway-async/scaleway_async/partner/v1/api.py @@ -0,0 +1,369 @@ +# This file was automatically generated. DO NOT EDIT. +# If you have any remark or suggestion do not hesitate to open an issue. + +from typing import Optional + +from scaleway_core.api import API +from scaleway_core.utils import ( + validate_path_param, + fetch_all_pages_async, +) +from .types import ( + ListOrganizationsRequestOrderBy, + OrganizationLockedBy, + OrganizationStatus, + CreateOrganizationRequest, + ListOrganizationsResponse, + Organization, + RequestAdminRoleRequest, + UpdateOrganizationRequest, +) +from .marshalling import ( + unmarshal_Organization, + unmarshal_ListOrganizationsResponse, + marshal_CreateOrganizationRequest, + marshal_RequestAdminRoleRequest, + marshal_UpdateOrganizationRequest, +) + + +class PartnerV1API(API): + """ + Scaleway Partner API ( for partner only ). + """ + + async def request_admin_role( + self, + *, + username: str, + email: str, + password: str, + organization_id: Optional[str] = None, + ) -> None: + """ + Invite a partner user in the customer organization. + :param username: The member username. + :param email: The member email. + :param password: The member password. + :param organization_id: The ID of the organization you want to be invited to. + + Usage: + :: + + result = await api.request_admin_role( + username="example", + email="example", + password="example", + ) + """ + + param_organization_id = validate_path_param( + "organization_id", organization_id or self.client.default_organization_id + ) + + res = self._request( + "POST", + f"/partner/v1/organizations/{param_organization_id}/request-admin-role", + body=marshal_RequestAdminRoleRequest( + RequestAdminRoleRequest( + username=username, + email=email, + password=password, + organization_id=organization_id, + ), + self.client, + ), + ) + + self._throw_on_error(res) + + async def create_organization( + self, + *, + partner_id: str, + email: str, + organization_name: str, + owner_firstname: str, + owner_lastname: str, + customer_id: str, + phone_number: Optional[str] = None, + siren_number: Optional[str] = None, + ) -> Organization: + """ + Create a new organization. + :param partner_id: Your personal `partner_id`. This is the same as your Organization ID. + :param email: The email of the new organization owner. + :param organization_name: The name of the organization you want to create. Usually the company name. + :param owner_firstname: The first name of the new organization owner. + :param owner_lastname: The last name of the new organization owner. + :param customer_id: A custom ID for the customer in your own infrastructure. + :param phone_number: The phone number of the new organization owner. + :param siren_number: A SIREN number for the customer. + :return: :class:`Organization ` + + Usage: + :: + + result = await api.create_organization( + partner_id="example", + email="example", + organization_name="example", + owner_firstname="example", + owner_lastname="example", + customer_id="example", + ) + """ + + res = self._request( + "POST", + "/partner/v1/organizations", + body=marshal_CreateOrganizationRequest( + CreateOrganizationRequest( + partner_id=partner_id, + email=email, + organization_name=organization_name, + owner_firstname=owner_firstname, + owner_lastname=owner_lastname, + customer_id=customer_id, + phone_number=phone_number, + siren_number=siren_number, + ), + self.client, + ), + ) + + self._throw_on_error(res) + return unmarshal_Organization(res.json()) + + async def get_organization( + self, + *, + organization_id: Optional[str] = None, + ) -> Organization: + """ + Get an organization. + :param organization_id: The ID of the organization you want to GET. + :return: :class:`Organization ` + + Usage: + :: + + result = await api.get_organization() + """ + + param_organization_id = validate_path_param( + "organization_id", organization_id or self.client.default_organization_id + ) + + res = self._request( + "GET", + f"/partner/v1/organizations/{param_organization_id}", + ) + + self._throw_on_error(res) + return unmarshal_Organization(res.json()) + + async def list_organizations( + self, + *, + page_size: Optional[int] = None, + page: Optional[int] = None, + order_by: Optional[ListOrganizationsRequestOrderBy] = None, + status: Optional[OrganizationStatus] = None, + email: Optional[str] = None, + customer_id: Optional[str] = None, + locked_by: Optional[OrganizationLockedBy] = None, + ) -> ListOrganizationsResponse: + """ + List Organizations. + :param page_size: + :param page: + :param order_by: + :param status: Only list organizations with this status. + :param email: Only list organizations created with this email. + :param customer_id: Only list organizations attached to this Customer ID. + If the customer ID was changed only the last one can be used. + :param locked_by: Only list organizations locked by a certain entity. + :return: :class:`ListOrganizationsResponse ` + + Usage: + :: + + result = await api.list_organizations() + """ + + res = self._request( + "GET", + "/partner/v1/organizations", + params={ + "customer_id": customer_id, + "email": email, + "locked_by": locked_by, + "order_by": order_by, + "page": page, + "page_size": page_size or self.client.default_page_size, + "status": status, + }, + ) + + self._throw_on_error(res) + return unmarshal_ListOrganizationsResponse(res.json()) + + async def list_organizations_all( + self, + *, + page_size: Optional[int] = None, + page: Optional[int] = None, + order_by: Optional[ListOrganizationsRequestOrderBy] = None, + status: Optional[OrganizationStatus] = None, + email: Optional[str] = None, + customer_id: Optional[str] = None, + locked_by: Optional[OrganizationLockedBy] = None, + ) -> list[Organization]: + """ + List Organizations. + :param page_size: + :param page: + :param order_by: + :param status: Only list organizations with this status. + :param email: Only list organizations created with this email. + :param customer_id: Only list organizations attached to this Customer ID. + If the customer ID was changed only the last one can be used. + :param locked_by: Only list organizations locked by a certain entity. + :return: :class:`list[Organization] ` + + Usage: + :: + + result = await api.list_organizations_all() + """ + + return await fetch_all_pages_async( + type=ListOrganizationsResponse, + key="organizations", + fetcher=self.list_organizations, + args={ + "page_size": page_size, + "page": page, + "order_by": order_by, + "status": status, + "email": email, + "customer_id": customer_id, + "locked_by": locked_by, + }, + ) + + async def lock_organization( + self, + *, + organization_id: Optional[str] = None, + ) -> Organization: + """ + Lock an organization. + :param organization_id: The ID of the organization you want to lock. + :return: :class:`Organization ` + + Usage: + :: + + result = await api.lock_organization() + """ + + param_organization_id = validate_path_param( + "organization_id", organization_id or self.client.default_organization_id + ) + + res = self._request( + "POST", + f"/partner/v1/organizations/{param_organization_id}/lock", + body={}, + ) + + self._throw_on_error(res) + return unmarshal_Organization(res.json()) + + async def unlock_organization( + self, + *, + organization_id: Optional[str] = None, + ) -> Organization: + """ + Unlock an organization. + :param organization_id: The ID of the organization you want to unlock. + :return: :class:`Organization ` + + Usage: + :: + + result = await api.unlock_organization() + """ + + param_organization_id = validate_path_param( + "organization_id", organization_id or self.client.default_organization_id + ) + + res = self._request( + "POST", + f"/partner/v1/organizations/{param_organization_id}/unlock", + body={}, + ) + + self._throw_on_error(res) + return unmarshal_Organization(res.json()) + + async def update_organization( + self, + *, + organization_id: Optional[str] = None, + email: Optional[str] = None, + name: Optional[str] = None, + owner_firstname: Optional[str] = None, + owner_lastname: Optional[str] = None, + phone_number: Optional[str] = None, + customer_id: Optional[str] = None, + comment: Optional[str] = None, + ) -> Organization: + """ + Update an organization. + :param organization_id: The ID of the organization you want to update. + :param email: The new email. + :param name: The new name. + :param owner_firstname: The first name of the new owner. + :param owner_lastname: The last name of the new owner. + :param phone_number: The phone number of the new owner. + :param customer_id: Customer ID associated with this organization. + Warning: Changing this value will only affect future invoices. + If you try to change this value after the 25th of the month, we cannot guarantee that this will take effect on the invoice issued for the current month. + :param comment: A comment about the organization. + :return: :class:`Organization ` + + Usage: + :: + + result = await api.update_organization() + """ + + param_organization_id = validate_path_param( + "organization_id", organization_id or self.client.default_organization_id + ) + + res = self._request( + "PATCH", + f"/partner/v1/organizations/{param_organization_id}", + body=marshal_UpdateOrganizationRequest( + UpdateOrganizationRequest( + organization_id=organization_id, + email=email, + name=name, + owner_firstname=owner_firstname, + owner_lastname=owner_lastname, + phone_number=phone_number, + customer_id=customer_id, + comment=comment, + ), + self.client, + ), + ) + + self._throw_on_error(res) + return unmarshal_Organization(res.json()) diff --git a/scaleway-async/scaleway_async/partner/v1/marshalling.py b/scaleway-async/scaleway_async/partner/v1/marshalling.py new file mode 100644 index 000000000..976bc4151 --- /dev/null +++ b/scaleway-async/scaleway_async/partner/v1/marshalling.py @@ -0,0 +1,223 @@ +# This file was automatically generated. DO NOT EDIT. +# If you have any remark or suggestion do not hesitate to open an issue. + +from typing import Any +from dateutil import parser + +from scaleway_core.profile import ProfileDefaults +from .types import ( + OrganizationLockedBy, + OrganizationStatus, + Organization, + ListOrganizationsResponse, + CreateOrganizationRequest, + RequestAdminRoleRequest, + UpdateOrganizationRequest, +) + + +def unmarshal_Organization(data: Any) -> Organization: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'Organization' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("id", None) + if field is not None: + args["id"] = field + else: + args["id"] = None + + field = data.get("name", None) + if field is not None: + args["name"] = field + else: + args["name"] = None + + field = data.get("email", None) + if field is not None: + args["email"] = field + else: + args["email"] = None + + field = data.get("status", None) + if field is not None: + args["status"] = field + else: + args["status"] = OrganizationStatus.UNKNOWN_STATUS + + field = data.get("owner_firstname", None) + if field is not None: + args["owner_firstname"] = field + else: + args["owner_firstname"] = None + + field = data.get("owner_lastname", None) + if field is not None: + args["owner_lastname"] = field + else: + args["owner_lastname"] = None + + field = data.get("created_at", None) + if field is not None: + args["created_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["created_at"] = None + + field = data.get("phone_number", None) + if field is not None: + args["phone_number"] = field + else: + args["phone_number"] = None + + field = data.get("siren_number", None) + if field is not None: + args["siren_number"] = field + else: + args["siren_number"] = None + + field = data.get("customer_id", None) + if field is not None: + args["customer_id"] = field + else: + args["customer_id"] = None + + field = data.get("lock_reason_message", None) + if field is not None: + args["lock_reason_message"] = field + else: + args["lock_reason_message"] = None + + field = data.get("locked_by", None) + if field is not None: + args["locked_by"] = field + else: + args["locked_by"] = OrganizationLockedBy.UNKNOWN_LOCKED_BY + + field = data.get("comment", None) + if field is not None: + args["comment"] = field + else: + args["comment"] = None + + field = data.get("locked_at", None) + if field is not None: + args["locked_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["locked_at"] = None + + field = data.get("picture_link", None) + if field is not None: + args["picture_link"] = field + else: + args["picture_link"] = None + + return Organization(**args) + + +def unmarshal_ListOrganizationsResponse(data: Any) -> ListOrganizationsResponse: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'ListOrganizationsResponse' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("organizations", None) + if field is not None: + args["organizations"] = ( + [unmarshal_Organization(v) for v in field] if field is not None else None + ) + else: + args["organizations"] = [] + + field = data.get("total_count", None) + if field is not None: + args["total_count"] = field + else: + args["total_count"] = 0 + + return ListOrganizationsResponse(**args) + + +def marshal_CreateOrganizationRequest( + request: CreateOrganizationRequest, + defaults: ProfileDefaults, +) -> dict[str, Any]: + output: dict[str, Any] = {} + + if request.partner_id is not None: + output["partner_id"] = request.partner_id + + if request.email is not None: + output["email"] = request.email + + if request.organization_name is not None: + output["organization_name"] = request.organization_name + + if request.owner_firstname is not None: + output["owner_firstname"] = request.owner_firstname + + if request.owner_lastname is not None: + output["owner_lastname"] = request.owner_lastname + + if request.customer_id is not None: + output["customer_id"] = request.customer_id + + if request.phone_number is not None: + output["phone_number"] = request.phone_number + + if request.siren_number is not None: + output["siren_number"] = request.siren_number + + return output + + +def marshal_RequestAdminRoleRequest( + request: RequestAdminRoleRequest, + defaults: ProfileDefaults, +) -> dict[str, Any]: + output: dict[str, Any] = {} + + if request.username is not None: + output["username"] = request.username + + if request.email is not None: + output["email"] = request.email + + if request.password is not None: + output["password"] = request.password + + return output + + +def marshal_UpdateOrganizationRequest( + request: UpdateOrganizationRequest, + defaults: ProfileDefaults, +) -> dict[str, Any]: + output: dict[str, Any] = {} + + if request.email is not None: + output["email"] = request.email + + if request.name is not None: + output["name"] = request.name + + if request.owner_firstname is not None: + output["owner_firstname"] = request.owner_firstname + + if request.owner_lastname is not None: + output["owner_lastname"] = request.owner_lastname + + if request.phone_number is not None: + output["phone_number"] = request.phone_number + + if request.customer_id is not None: + output["customer_id"] = request.customer_id + + if request.comment is not None: + output["comment"] = request.comment + + return output diff --git a/scaleway-async/scaleway_async/partner/v1/types.py b/scaleway-async/scaleway_async/partner/v1/types.py new file mode 100644 index 000000000..65f805613 --- /dev/null +++ b/scaleway-async/scaleway_async/partner/v1/types.py @@ -0,0 +1,294 @@ +# This file was automatically generated. DO NOT EDIT. +# If you have any remark or suggestion do not hesitate to open an issue. +from __future__ import annotations + +from dataclasses import dataclass +from datetime import datetime +from enum import Enum +from typing import Optional + +from scaleway_core.utils import ( + StrEnumMeta, +) + + +class ListOrganizationsRequestOrderBy(str, Enum, metaclass=StrEnumMeta): + CREATED_AT_ASC = "created_at_asc" + CREATED_AT_DESC = "created_at_desc" + + def __str__(self) -> str: + return str(self.value) + + +class OrganizationLockedBy(str, Enum, metaclass=StrEnumMeta): + UNKNOWN_LOCKED_BY = "unknown_locked_by" + PARTNER = "partner" + SCALEWAY = "scaleway" + + def __str__(self) -> str: + return str(self.value) + + +class OrganizationStatus(str, Enum, metaclass=StrEnumMeta): + UNKNOWN_STATUS = "unknown_status" + OPENED = "opened" + LOCKED = "locked" + CLOSED = "closed" + + def __str__(self) -> str: + return str(self.value) + + +@dataclass +class Organization: + id: str + """ + ID of the organization. + """ + + name: str + """ + Name of the organization. + """ + + email: str + """ + Organization owner's email. + """ + + status: OrganizationStatus + """ + The current status of the organization. + """ + + owner_firstname: str + """ + Organization owner's first name. + """ + + owner_lastname: str + """ + Organization owner's last name. + """ + + customer_id: str + """ + Customer ID associated with this organization. + """ + + lock_reason_message: str + """ + If the organization is locked, this field will contain a human-readable reason. + """ + + locked_by: OrganizationLockedBy + """ + Originator of the lock. Can be one of "partner" or "scaleway". + """ + + comment: str + """ + A comment about the organization. + """ + + created_at: Optional[datetime] = None + """ + Date of organization creation. + """ + + phone_number: Optional[str] = None + """ + Organization owner's phone number. + """ + + siren_number: Optional[str] = None + """ + Siren number of the organization. + """ + + locked_at: Optional[datetime] = None + """ + Date of lock. + """ + + picture_link: Optional[str] = None + """ + Link to the Organization's picture. + """ + + +@dataclass +class CreateOrganizationRequest: + partner_id: str + """ + Your personal `partner_id`. This is the same as your Organization ID. + """ + + email: str + """ + The email of the new organization owner. + """ + + organization_name: str + """ + The name of the organization you want to create. Usually the company name. + """ + + owner_firstname: str + """ + The first name of the new organization owner. + """ + + owner_lastname: str + """ + The last name of the new organization owner. + """ + + customer_id: str + """ + A custom ID for the customer in your own infrastructure. + """ + + phone_number: Optional[str] = None + """ + The phone number of the new organization owner. + """ + + siren_number: Optional[str] = None + """ + A SIREN number for the customer. + """ + + +@dataclass +class GetOrganizationRequest: + organization_id: Optional[str] = None + """ + The ID of the organization you want to GET. + """ + + +@dataclass +class ListOrganizationsRequest: + page_size: Optional[int] = 0 + page: Optional[int] = 0 + order_by: Optional[ListOrganizationsRequestOrderBy] = ( + ListOrganizationsRequestOrderBy.CREATED_AT_ASC + ) + status: Optional[OrganizationStatus] = OrganizationStatus.UNKNOWN_STATUS + """ + Only list organizations with this status. + """ + + email: Optional[str] = None + """ + Only list organizations created with this email. + """ + + customer_id: Optional[str] = None + """ + Only list organizations attached to this Customer ID. +If the customer ID was changed only the last one can be used. + """ + + locked_by: Optional[OrganizationLockedBy] = OrganizationLockedBy.UNKNOWN_LOCKED_BY + """ + Only list organizations locked by a certain entity. + """ + + +@dataclass +class ListOrganizationsResponse: + organizations: list[Organization] + """ + List of organizations. + """ + + total_count: int + """ + Total number of organizations. + """ + + +@dataclass +class LockOrganizationRequest: + organization_id: Optional[str] = None + """ + The ID of the organization you want to lock. + """ + + +@dataclass +class RequestAdminRoleRequest: + username: str + """ + The member username. + """ + + email: str + """ + The member email. + """ + + password: str + """ + The member password. + """ + + organization_id: Optional[str] = None + """ + The ID of the organization you want to be invited to. + """ + + +@dataclass +class UnlockOrganizationRequest: + organization_id: Optional[str] = None + """ + The ID of the organization you want to unlock. + """ + + +@dataclass +class UpdateOrganizationRequest: + organization_id: Optional[str] = None + """ + The ID of the organization you want to update. + """ + + email: Optional[str] = None + """ + The new email. + """ + + name: Optional[str] = None + """ + The new name. + """ + + owner_firstname: Optional[str] = None + """ + The first name of the new owner. + """ + + owner_lastname: Optional[str] = None + """ + The last name of the new owner. + """ + + phone_number: Optional[str] = None + """ + The phone number of the new owner. + """ + + customer_id: Optional[str] = None + """ + Customer ID associated with this organization. +Warning: Changing this value will only affect future invoices. +If you try to change this value after the 25th of the month, we cannot guarantee that this will take effect on the invoice issued for the current month. + """ + + comment: Optional[str] = None + """ + A comment about the organization. + """ diff --git a/scaleway-async/scaleway_async/rdb/v1/api.py b/scaleway-async/scaleway_async/rdb/v1/api.py index 7cce9e877..4dc748c21 100644 --- a/scaleway-async/scaleway_async/rdb/v1/api.py +++ b/scaleway-async/scaleway_async/rdb/v1/api.py @@ -538,8 +538,8 @@ async def wait_for_database_backup( options = WaitForOptions() if not options.stop: - options.stop = ( - lambda res: res.status not in DATABASE_BACKUP_TRANSIENT_STATUSES + options.stop = lambda res: ( + res.status not in DATABASE_BACKUP_TRANSIENT_STATUSES ) return await wait_for_resource_async( diff --git a/scaleway-async/scaleway_async/rdb/v1/marshalling.py b/scaleway-async/scaleway_async/rdb/v1/marshalling.py index 1b3c0ab92..0ca045b2c 100644 --- a/scaleway-async/scaleway_async/rdb/v1/marshalling.py +++ b/scaleway-async/scaleway_async/rdb/v1/marshalling.py @@ -13,6 +13,9 @@ resolve_one_of, ) from .types import ( + ACLRuleAction, + ACLRuleDirection, + ACLRuleProtocol, DatabaseBackupStatus, EndpointPrivateNetworkDetailsProvisioningMode, EngineSettingPropertyType, @@ -1018,19 +1021,19 @@ def unmarshal_ACLRule(data: Any) -> ACLRule: if field is not None: args["protocol"] = field else: - args["protocol"] = None + args["protocol"] = ACLRuleProtocol.TCP field = data.get("direction", None) if field is not None: args["direction"] = field else: - args["direction"] = None + args["direction"] = ACLRuleDirection.INBOUND field = data.get("action", None) if field is not None: args["action"] = field else: - args["action"] = None + args["action"] = ACLRuleAction.ALLOW field = data.get("description", None) if field is not None: @@ -1042,7 +1045,7 @@ def unmarshal_ACLRule(data: Any) -> ACLRule: if field is not None: args["port"] = field else: - args["port"] = None + args["port"] = 0 return ACLRule(**args) @@ -1622,18 +1625,6 @@ def unmarshal_NodeType(data: Any) -> NodeType: else: args["memory"] = 0 - field = data.get("disabled", None) - if field is not None: - args["disabled"] = field - else: - args["disabled"] = False - - field = data.get("beta", None) - if field is not None: - args["beta"] = field - else: - args["beta"] = False - field = data.get("volume_constraint", None) if field is not None: args["volume_constraint"] = unmarshal_NodeTypeVolumeConstraintSizes(field) @@ -1646,6 +1637,18 @@ def unmarshal_NodeType(data: Any) -> NodeType: else: args["is_bssd_compatible"] = False + field = data.get("disabled", None) + if field is not None: + args["disabled"] = field + else: + args["disabled"] = False + + field = data.get("beta", None) + if field is not None: + args["beta"] = field + else: + args["beta"] = False + field = data.get("available_volume_types", None) if field is not None: args["available_volume_types"] = ( diff --git a/scaleway-async/scaleway_async/rdb/v1/types.py b/scaleway-async/scaleway_async/rdb/v1/types.py index 046a2b107..0c6b7d6fa 100644 --- a/scaleway-async/scaleway_async/rdb/v1/types.py +++ b/scaleway-async/scaleway_async/rdb/v1/types.py @@ -666,7 +666,7 @@ class ACLRule: direction: ACLRuleDirection action: ACLRuleAction description: str - port: Optional[int] = None + port: int @dataclass @@ -991,6 +991,11 @@ class NodeType: Quantity of RAM. """ + is_bssd_compatible: bool + """ + The Node Type is compliant with Block Storage. + """ + disabled: bool """ The Node Type is currently disabled. @@ -1031,11 +1036,6 @@ class NodeType: [deprecated] Node Type volume constraints. """ - is_bssd_compatible: Optional[bool] = False - """ - The Node Type is compliant with Block Storage. - """ - @dataclass class Privilege: diff --git a/scaleway-async/scaleway_async/registry/v1/api.py b/scaleway-async/scaleway_async/registry/v1/api.py index bcc8c2550..cac3ed816 100644 --- a/scaleway-async/scaleway_async/registry/v1/api.py +++ b/scaleway-async/scaleway_async/registry/v1/api.py @@ -770,15 +770,15 @@ async def delete_tag( self, *, tag_id: str, + force: bool, region: Optional[ScwRegion] = None, - force: Optional[bool] = None, ) -> Tag: """ Delete a tag. Delete a given image tag. You must specify, in the endpoint, the `region` and `tag_id` parameters of the tag you want to delete. :param tag_id: UUID of the tag. - :param region: Region to target. If none is passed will use default region from the config. :param force: If two tags share the same digest the deletion will fail unless this parameter is set to true (deprecated). + :param region: Region to target. If none is passed will use default region from the config. :return: :class:`Tag ` Usage: @@ -786,6 +786,7 @@ async def delete_tag( result = await api.delete_tag( tag_id="example", + force=False, ) """ diff --git a/scaleway-async/scaleway_async/registry/v1/types.py b/scaleway-async/scaleway_async/registry/v1/types.py index 2c46e2521..ac263fac3 100644 --- a/scaleway-async/scaleway_async/registry/v1/types.py +++ b/scaleway-async/scaleway_async/registry/v1/types.py @@ -314,14 +314,14 @@ class DeleteTagRequest: UUID of the tag. """ - region: Optional[ScwRegion] = None + force: bool """ - Region to target. If none is passed will use default region from the config. + If two tags share the same digest the deletion will fail unless this parameter is set to true (deprecated). """ - force: Optional[bool] = False + region: Optional[ScwRegion] = None """ - If two tags share the same digest the deletion will fail unless this parameter is set to true (deprecated). + Region to target. If none is passed will use default region from the config. """ diff --git a/scaleway-async/scaleway_async/searchdb/v1alpha1/marshalling.py b/scaleway-async/scaleway_async/searchdb/v1alpha1/marshalling.py index 3e2de3e49..0103c40e2 100644 --- a/scaleway-async/scaleway_async/searchdb/v1alpha1/marshalling.py +++ b/scaleway-async/scaleway_async/searchdb/v1alpha1/marshalling.py @@ -110,6 +110,12 @@ def unmarshal_Endpoint(data: Any) -> Endpoint: else: args["id"] = None + field = data.get("dns_record", None) + if field is not None: + args["dns_record"] = field + else: + args["dns_record"] = None + field = data.get("services", None) if field is not None: args["services"] = ( @@ -118,12 +124,6 @@ def unmarshal_Endpoint(data: Any) -> Endpoint: else: args["services"] = [] - field = data.get("dns_record", None) - if field is not None: - args["dns_record"] = field - else: - args["dns_record"] = None - field = data.get("public", None) if field is not None: args["public"] = unmarshal_EndpointPublicDetails(field) diff --git a/scaleway-async/scaleway_async/searchdb/v1alpha1/types.py b/scaleway-async/scaleway_async/searchdb/v1alpha1/types.py index 6cb8184c2..ef52096f6 100644 --- a/scaleway-async/scaleway_async/searchdb/v1alpha1/types.py +++ b/scaleway-async/scaleway_async/searchdb/v1alpha1/types.py @@ -128,14 +128,14 @@ class Endpoint: Unique identifier of the Endpoint. """ - services: list[EndpointService] + dns_record: str """ - List of available services, their ports and URLs. + DNS entry to access to the service. Now deprecated. Use the `url` field from `services` field instead. """ - dns_record: Optional[str] = None + services: list[EndpointService] """ - DNS entry to access to the service. Now deprecated. Use the `url` field from `services` field instead. + List of available services, their ports and URLs. """ public: Optional[EndpointPublicDetails] = None diff --git a/scaleway-async/scaleway_async/tem/v1alpha1/api.py b/scaleway-async/scaleway_async/tem/v1alpha1/api.py index f576782d0..44e88e52a 100644 --- a/scaleway-async/scaleway_async/tem/v1alpha1/api.py +++ b/scaleway-async/scaleway_async/tem/v1alpha1/api.py @@ -475,19 +475,19 @@ async def create_domain( self, *, domain_name: str, + accept_tos: bool, autoconfig: bool, region: Optional[ScwRegion] = None, project_id: Optional[str] = None, - accept_tos: Optional[bool] = None, ) -> Domain: """ Register a domain in a project. You must specify the `region`, `project_id` and `domain_name` to register a domain in a specific Project. :param domain_name: Fully qualified domain dame. + :param accept_tos: Deprecated. Accept Scaleway's Terms of Service. :param autoconfig: Activate auto-configuration of the domain's DNS zone. :param region: Region to target. If none is passed will use default region from the config. :param project_id: ID of the project to which the domain belongs. - :param accept_tos: Deprecated. Accept Scaleway's Terms of Service. :return: :class:`Domain ` Usage: @@ -495,6 +495,7 @@ async def create_domain( result = await api.create_domain( domain_name="example", + accept_tos=False, autoconfig=False, ) """ @@ -509,10 +510,10 @@ async def create_domain( body=marshal_CreateDomainRequest( CreateDomainRequest( domain_name=domain_name, + accept_tos=accept_tos, autoconfig=autoconfig, region=region, project_id=project_id, - accept_tos=accept_tos, ), self.client, ), diff --git a/scaleway-async/scaleway_async/tem/v1alpha1/marshalling.py b/scaleway-async/scaleway_async/tem/v1alpha1/marshalling.py index 491d43ee2..91a274dc4 100644 --- a/scaleway-async/scaleway_async/tem/v1alpha1/marshalling.py +++ b/scaleway-async/scaleway_async/tem/v1alpha1/marshalling.py @@ -137,18 +137,18 @@ def unmarshal_Email(data: Any) -> Email: else: args["mail_from"] = None - field = data.get("mail_rcpt", None) - if field is not None: - args["mail_rcpt"] = field - else: - args["mail_rcpt"] = None - field = data.get("rcpt_to", None) if field is not None: args["rcpt_to"] = field else: args["rcpt_to"] = None + field = data.get("mail_rcpt", None) + if field is not None: + args["mail_rcpt"] = field + else: + args["mail_rcpt"] = None + field = data.get("rcpt_type", None) if field is not None: args["rcpt_type"] = field @@ -1558,6 +1558,9 @@ def marshal_CreateDomainRequest( if request.domain_name is not None: output["domain_name"] = request.domain_name + if request.accept_tos is not None: + output["accept_tos"] = request.accept_tos + if request.autoconfig is not None: output["autoconfig"] = request.autoconfig @@ -1566,9 +1569,6 @@ def marshal_CreateDomainRequest( else: output["project_id"] = defaults.default_project_id - if request.accept_tos is not None: - output["accept_tos"] = request.accept_tos - return output diff --git a/scaleway-async/scaleway_async/tem/v1alpha1/types.py b/scaleway-async/scaleway_async/tem/v1alpha1/types.py index f1cfe51bb..717b6deb5 100644 --- a/scaleway-async/scaleway_async/tem/v1alpha1/types.py +++ b/scaleway-async/scaleway_async/tem/v1alpha1/types.py @@ -453,6 +453,11 @@ class Email: Email address of the sender. """ + rcpt_to: str + """ + Deprecated. Email address of the recipient. + """ + mail_rcpt: str """ Email address of the recipient. @@ -488,11 +493,6 @@ class Email: Flags categorize emails. They allow you to obtain more information about recurring errors, for example. """ - rcpt_to: Optional[str] = None - """ - Deprecated. Email address of the recipient. - """ - created_at: Optional[datetime] = None """ Creation date of the email object. @@ -1051,6 +1051,11 @@ class CreateDomainRequest: Fully qualified domain dame. """ + accept_tos: bool + """ + Deprecated. Accept Scaleway's Terms of Service. + """ + autoconfig: bool """ Activate auto-configuration of the domain's DNS zone. @@ -1066,11 +1071,6 @@ class CreateDomainRequest: ID of the project to which the domain belongs. """ - accept_tos: Optional[bool] = False - """ - Deprecated. Accept Scaleway's Terms of Service. - """ - @dataclass class CreateEmailRequest: diff --git a/scaleway-async/scaleway_async/vpcgw/v1/api.py b/scaleway-async/scaleway_async/vpcgw/v1/api.py index abd53c64f..92d912273 100644 --- a/scaleway-async/scaleway_async/vpcgw/v1/api.py +++ b/scaleway-async/scaleway_async/vpcgw/v1/api.py @@ -696,8 +696,8 @@ async def wait_for_gateway_network( options = WaitForOptions() if not options.stop: - options.stop = ( - lambda res: res.status not in GATEWAY_NETWORK_TRANSIENT_STATUSES + options.stop = lambda res: ( + res.status not in GATEWAY_NETWORK_TRANSIENT_STATUSES ) return await wait_for_resource_async( diff --git a/scaleway-async/scaleway_async/vpcgw/v2/api.py b/scaleway-async/scaleway_async/vpcgw/v2/api.py index 7d104ab35..14e427605 100644 --- a/scaleway-async/scaleway_async/vpcgw/v2/api.py +++ b/scaleway-async/scaleway_async/vpcgw/v2/api.py @@ -630,8 +630,8 @@ async def wait_for_gateway_network( options = WaitForOptions() if not options.stop: - options.stop = ( - lambda res: res.status not in GATEWAY_NETWORK_TRANSIENT_STATUSES + options.stop = lambda res: ( + res.status not in GATEWAY_NETWORK_TRANSIENT_STATUSES ) return await wait_for_resource_async( diff --git a/scaleway/scaleway/applesilicon/v1alpha1/api.py b/scaleway/scaleway/applesilicon/v1alpha1/api.py index 00eca7991..1972f3ef8 100644 --- a/scaleway/scaleway/applesilicon/v1alpha1/api.py +++ b/scaleway/scaleway/applesilicon/v1alpha1/api.py @@ -1104,9 +1104,8 @@ def wait_for_server_private_network( options = WaitForOptions() if not options.stop: - options.stop = ( - lambda res: res.status - not in SERVER_PRIVATE_NETWORK_SERVER_TRANSIENT_STATUSES + options.stop = lambda res: ( + res.status not in SERVER_PRIVATE_NETWORK_SERVER_TRANSIENT_STATUSES ) return wait_for_resource( diff --git a/scaleway/scaleway/applesilicon/v1alpha1/marshalling.py b/scaleway/scaleway/applesilicon/v1alpha1/marshalling.py index f09b63282..1a24177fc 100644 --- a/scaleway/scaleway/applesilicon/v1alpha1/marshalling.py +++ b/scaleway/scaleway/applesilicon/v1alpha1/marshalling.py @@ -136,6 +136,12 @@ def unmarshal_OS(data: Any) -> OS: else: args["xcode_version"] = None + field = data.get("compatible_server_types", None) + if field is not None: + args["compatible_server_types"] = field + else: + args["compatible_server_types"] = [] + field = data.get("release_notes_url", None) if field is not None: args["release_notes_url"] = field @@ -164,12 +170,6 @@ def unmarshal_OS(data: Any) -> OS: else: args["supported_server_types"] = [] - field = data.get("compatible_server_types", None) - if field is not None: - args["compatible_server_types"] = field - else: - args["compatible_server_types"] = [] - return OS(**args) diff --git a/scaleway/scaleway/applesilicon/v1alpha1/types.py b/scaleway/scaleway/applesilicon/v1alpha1/types.py index 7a658f220..6a3f97653 100644 --- a/scaleway/scaleway/applesilicon/v1alpha1/types.py +++ b/scaleway/scaleway/applesilicon/v1alpha1/types.py @@ -205,6 +205,11 @@ class OS: The current xcode version for this OS. """ + compatible_server_types: list[str] + """ + List of compatible server types. Deprecated. + """ + release_notes_url: str """ Url of the release notes for the OS image or software pre-installed. @@ -225,11 +230,6 @@ class OS: List of server types which supports the OS configuration. Also gives information about immediate stock availability. """ - compatible_server_types: Optional[list[str]] = field(default_factory=list) - """ - List of compatible server types. Deprecated. - """ - @dataclass class RunnerConfiguration: diff --git a/scaleway/scaleway/dedibox/v1/api.py b/scaleway/scaleway/dedibox/v1/api.py index f11df7de9..88be35b11 100644 --- a/scaleway/scaleway/dedibox/v1/api.py +++ b/scaleway/scaleway/dedibox/v1/api.py @@ -1350,8 +1350,8 @@ def wait_for_server_install( options = WaitForOptions() if not options.stop: - options.stop = ( - lambda res: res.status not in SERVER_INSTALL_TRANSIENT_STATUSES + options.stop = lambda res: ( + res.status not in SERVER_INSTALL_TRANSIENT_STATUSES ) return wait_for_resource( diff --git a/scaleway/scaleway/function/v1beta1/api.py b/scaleway/scaleway/function/v1beta1/api.py index 8e80bc8fd..32fd9dac0 100644 --- a/scaleway/scaleway/function/v1beta1/api.py +++ b/scaleway/scaleway/function/v1beta1/api.py @@ -269,6 +269,7 @@ def wait_for_namespace( def create_namespace( self, *, + activate_vpc_integration: bool, region: Optional[ScwRegion] = None, name: Optional[str] = None, environment_variables: Optional[dict[str, str]] = None, @@ -276,11 +277,11 @@ def create_namespace( description: Optional[str] = None, secret_environment_variables: Optional[list[Secret]] = None, tags: Optional[list[str]] = None, - activate_vpc_integration: Optional[bool] = None, ) -> Namespace: """ Create a new namespace. Create a new namespace in a specified Organization or Project. + :param activate_vpc_integration: Setting this field to true doesn't matter anymore. It will be removed in a near future. :param region: Region to target. If none is passed will use default region from the config. :param name: :param environment_variables: Environment variables of the namespace. @@ -288,13 +289,14 @@ def create_namespace( :param description: Description of the namespace. :param secret_environment_variables: Secret environment variables of the namespace. :param tags: Tags of the Serverless Function Namespace. - :param activate_vpc_integration: Setting this field to true doesn't matter anymore. It will be removed in a near future. :return: :class:`Namespace ` Usage: :: - result = api.create_namespace() + result = api.create_namespace( + activate_vpc_integration=False, + ) """ param_region = validate_path_param( @@ -306,6 +308,7 @@ def create_namespace( f"/functions/v1beta1/regions/{param_region}/namespaces", body=marshal_CreateNamespaceRequest( CreateNamespaceRequest( + activate_vpc_integration=activate_vpc_integration, region=region, name=name or random_name(prefix="ns"), environment_variables=environment_variables, @@ -313,7 +316,6 @@ def create_namespace( description=description, secret_environment_variables=secret_environment_variables, tags=tags, - activate_vpc_integration=activate_vpc_integration, ), self.client, ), diff --git a/scaleway/scaleway/function/v1beta1/marshalling.py b/scaleway/scaleway/function/v1beta1/marshalling.py index 80a6e3a9b..9df8e13b0 100644 --- a/scaleway/scaleway/function/v1beta1/marshalling.py +++ b/scaleway/scaleway/function/v1beta1/marshalling.py @@ -437,6 +437,12 @@ def unmarshal_Namespace(data: Any) -> Namespace: else: args["tags"] = [] + field = data.get("vpc_integration_activated", None) + if field is not None: + args["vpc_integration_activated"] = field + else: + args["vpc_integration_activated"] = False + field = data.get("description", None) if field is not None: args["description"] = field @@ -455,12 +461,6 @@ def unmarshal_Namespace(data: Any) -> Namespace: else: args["updated_at"] = None - field = data.get("vpc_integration_activated", None) - if field is not None: - args["vpc_integration_activated"] = field - else: - args["vpc_integration_activated"] = False - return Namespace(**args) @@ -484,6 +484,12 @@ def unmarshal_Token(data: Any) -> Token: else: args["token"] = None + field = data.get("public_key", None) + if field is not None: + args["public_key"] = field + else: + args["public_key"] = None + field = data.get("status", None) if field is not None: args["status"] = field @@ -502,12 +508,6 @@ def unmarshal_Token(data: Any) -> Token: else: args["namespace_id"] = None - field = data.get("public_key", None) - if field is not None: - args["public_key"] = field - else: - args["public_key"] = None - field = data.get("description", None) if field is not None: args["description"] = field @@ -1114,6 +1114,9 @@ def marshal_CreateNamespaceRequest( ) -> dict[str, Any]: output: dict[str, Any] = {} + if request.activate_vpc_integration is not None: + output["activate_vpc_integration"] = request.activate_vpc_integration + if request.name is not None: output["name"] = request.name @@ -1137,9 +1140,6 @@ def marshal_CreateNamespaceRequest( if request.tags is not None: output["tags"] = request.tags - if request.activate_vpc_integration is not None: - output["activate_vpc_integration"] = request.activate_vpc_integration - return output diff --git a/scaleway/scaleway/function/v1beta1/types.py b/scaleway/scaleway/function/v1beta1/types.py index 85391b085..5d3c4332a 100644 --- a/scaleway/scaleway/function/v1beta1/types.py +++ b/scaleway/scaleway/function/v1beta1/types.py @@ -628,6 +628,11 @@ class Namespace: List of tags applied to the Serverless Function Namespace. """ + vpc_integration_activated: bool + """ + The value of this field doesn't matter anymore, and will be removed in a near future. + """ + error_message: Optional[str] = None """ Error message if the namespace is in "error" state. @@ -648,11 +653,6 @@ class Namespace: Last update date of the namespace. """ - vpc_integration_activated: Optional[bool] = False - """ - The value of this field doesn't matter anymore, and will be removed in a near future. - """ - @dataclass class Token: @@ -666,14 +666,14 @@ class Token: String of the token. """ - status: TokenStatus + public_key: str """ - Status of the token. + Public key of the token. """ - public_key: Optional[str] = None + status: TokenStatus """ - Public key of the token. + Status of the token. """ description: Optional[str] = None @@ -875,6 +875,11 @@ class CreateFunctionRequest: @dataclass class CreateNamespaceRequest: + activate_vpc_integration: bool + """ + Setting this field to true doesn't matter anymore. It will be removed in a near future. + """ + region: Optional[ScwRegion] = None """ Region to target. If none is passed will use default region from the config. @@ -906,11 +911,6 @@ class CreateNamespaceRequest: Tags of the Serverless Function Namespace. """ - activate_vpc_integration: Optional[bool] = False - """ - Setting this field to true doesn't matter anymore. It will be removed in a near future. - """ - @dataclass class CreateTokenRequest: diff --git a/scaleway/scaleway/iam/v1alpha1/marshalling.py b/scaleway/scaleway/iam/v1alpha1/marshalling.py index f808bb676..8b2c87aed 100644 --- a/scaleway/scaleway/iam/v1alpha1/marshalling.py +++ b/scaleway/scaleway/iam/v1alpha1/marshalling.py @@ -927,6 +927,18 @@ def unmarshal_User(data: Any) -> User: else: args["type_"] = UserType.UNKNOWN_TYPE + field = data.get("two_factor_enabled", None) + if field is not None: + args["two_factor_enabled"] = field + else: + args["two_factor_enabled"] = False + + field = data.get("status", None) + if field is not None: + args["status"] = field + else: + args["status"] = UserStatus.UNKNOWN_STATUS + field = data.get("mfa", None) if field is not None: args["mfa"] = field @@ -951,18 +963,6 @@ def unmarshal_User(data: Any) -> User: else: args["locked"] = False - field = data.get("two_factor_enabled", None) - if field is not None: - args["two_factor_enabled"] = field - else: - args["two_factor_enabled"] = False - - field = data.get("status", None) - if field is not None: - args["status"] = field - else: - args["status"] = UserStatus.UNKNOWN_STATUS - return User(**args) diff --git a/scaleway/scaleway/iam/v1alpha1/types.py b/scaleway/scaleway/iam/v1alpha1/types.py index f5ef0e7ac..4914299cf 100644 --- a/scaleway/scaleway/iam/v1alpha1/types.py +++ b/scaleway/scaleway/iam/v1alpha1/types.py @@ -977,6 +977,16 @@ class User: Type of user. """ + two_factor_enabled: bool + """ + Deprecated, use "mfa" instead. + """ + + status: UserStatus + """ + Status of user invitation. + """ + mfa: bool """ Defines whether MFA is enabled. @@ -1012,16 +1022,6 @@ class User: Date of the last login. """ - two_factor_enabled: Optional[bool] = False - """ - Deprecated, use "mfa" instead. - """ - - status: Optional[UserStatus] = UserStatus.UNKNOWN_STATUS - """ - Status of user invitation. - """ - @dataclass class SamlServiceProvider: diff --git a/scaleway/scaleway/instance/v1/api.py b/scaleway/scaleway/instance/v1/api.py index 7ed8b4ecd..d2f81420e 100644 --- a/scaleway/scaleway/instance/v1/api.py +++ b/scaleway/scaleway/instance/v1/api.py @@ -521,12 +521,12 @@ def _create_server( *, zone: Optional[ScwZone] = None, commercial_type: str, + enable_ipv6: bool, name: Optional[str] = None, dynamic_ip_required: Optional[bool] = None, routed_ip_enabled: Optional[bool] = None, image: Optional[str] = None, volumes: Optional[dict[str, VolumeServerTemplate]] = None, - enable_ipv6: Optional[bool] = None, protected: bool, public_ip: Optional[str] = None, public_ips: Optional[list[str]] = None, @@ -544,12 +544,12 @@ def _create_server( Get more information in the [Technical Information](#technical-information) section of the introduction. :param zone: Zone to target. If none is passed will use default zone from the config. :param commercial_type: Define the Instance commercial type (i.e. GP1-S). + :param enable_ipv6: True if IPv6 is enabled on the server (deprecated and always `False` when `routed_ip_enabled` is `True`). :param name: Instance name. :param dynamic_ip_required: By default, `dynamic_ip_required` is true, a dynamic ip is attached to the instance (if no flexible ip is already attached). :param routed_ip_enabled: If true, configure the Instance so it uses the new routed IP mode. :param image: Instance image ID or label. :param volumes: Volumes attached to the server. - :param enable_ipv6: True if IPv6 is enabled on the server (deprecated and always `False` when `routed_ip_enabled` is `True`). :param protected: True to activate server protection option. :param public_ip: ID of the reserved IP to attach to the Instance. :param public_ips: A list of reserved IP IDs to attach to the Instance. @@ -569,6 +569,7 @@ def _create_server( result = api._create_server( commercial_type="example", + enable_ipv6=False, protected=False, ) """ @@ -582,12 +583,12 @@ def _create_server( CreateServerRequest( zone=zone, commercial_type=commercial_type, + enable_ipv6=enable_ipv6, name=name or random_name(prefix="srv"), dynamic_ip_required=dynamic_ip_required, routed_ip_enabled=routed_ip_enabled, image=image, volumes=volumes, - enable_ipv6=enable_ipv6, protected=protected, public_ip=public_ip, public_ips=public_ips, @@ -676,6 +677,7 @@ def _set_server( name: str, commercial_type: str, dynamic_ip_required: bool, + enable_ipv6: bool, hostname: str, organization: Optional[str] = None, project: Optional[str] = None, @@ -683,7 +685,6 @@ def _set_server( tags: Optional[list[str]] = None, creation_date: Optional[datetime] = None, routed_ip_enabled: Optional[bool] = None, - enable_ipv6: Optional[bool] = None, image: Optional[Image] = None, protected: bool, private_ip: Optional[str] = None, @@ -709,6 +710,7 @@ def _set_server( :param name: Instance name. :param commercial_type: Instance commercial type (eg. GP1-M). :param dynamic_ip_required: True if a dynamic IPv4 is required. + :param enable_ipv6: True if IPv6 is enabled (deprecated and always `False` when `routed_ip_enabled` is `True`). :param hostname: Instance host name. :param organization: Instance Organization ID. :param project: Instance Project ID. @@ -716,7 +718,6 @@ def _set_server( :param tags: Tags associated with the Instance. :param creation_date: Instance creation date. :param routed_ip_enabled: True to configure the instance so it uses the new routed IP mode (once this is set to True you cannot set it back to False). - :param enable_ipv6: True if IPv6 is enabled (deprecated and always `False` when `routed_ip_enabled` is `True`). :param image: Provide information on the Instance image. :param protected: Instance protection option is activated. :param private_ip: Instance private IP address (deprecated and always `null` when `routed_ip_enabled` is `True`). @@ -745,6 +746,7 @@ def _set_server( name="example", commercial_type="example", dynamic_ip_required=False, + enable_ipv6=False, hostname="example", protected=False, state_detail="example", @@ -763,8 +765,9 @@ def _set_server( id=id, name=name, commercial_type=commercial_type, - organization=organization, dynamic_ip_required=dynamic_ip_required, + organization=organization, + enable_ipv6=enable_ipv6, hostname=hostname, protected=protected, state_detail=state_detail, @@ -773,7 +776,6 @@ def _set_server( tags=tags, creation_date=creation_date, routed_ip_enabled=routed_ip_enabled, - enable_ipv6=enable_ipv6, image=image, private_ip=private_ip, public_ip=public_ip, @@ -2522,15 +2524,15 @@ def _set_security_group( description: str, enable_default_security: bool, tags: Optional[list[str]] = None, - creation_date: Optional[datetime] = None, - modification_date: Optional[datetime] = None, + organization_default: bool, project_default: bool, stateful: bool, + creation_date: Optional[datetime] = None, + modification_date: Optional[datetime] = None, inbound_default_policy: Optional[SecurityGroupPolicy] = None, outbound_default_policy: Optional[SecurityGroupPolicy] = None, organization: Optional[str] = None, project: Optional[str] = None, - organization_default: Optional[bool] = None, servers: Optional[list[ServerSummary]] = None, ) -> _SetSecurityGroupResponse: """ @@ -2542,15 +2544,15 @@ def _set_security_group( :param description: Description of the security group. :param enable_default_security: True to block SMTP on IPv4 and IPv6. This feature is read only, please open a support ticket if you need to make it configurable. :param tags: Tags of the security group. - :param creation_date: Creation date of the security group (will be ignored). - :param modification_date: Modification date of the security group (will be ignored). + :param organization_default: Please use project_default instead. :param project_default: True use this security group for future Instances created in this project. :param stateful: True to set the security group as stateful. + :param creation_date: Creation date of the security group (will be ignored). + :param modification_date: Modification date of the security group (will be ignored). :param inbound_default_policy: Default inbound policy. :param outbound_default_policy: Default outbound policy. :param organization: Security groups Organization ID. :param project: Security group Project ID. - :param organization_default: Please use project_default instead. :param servers: Instances attached to this security group. :return: :class:`_SetSecurityGroupResponse <_SetSecurityGroupResponse>` @@ -2562,6 +2564,7 @@ def _set_security_group( name="example", description="example", enable_default_security=False, + organization_default=False, project_default=False, stateful=False, ) @@ -2581,15 +2584,15 @@ def _set_security_group( description=description, enable_default_security=enable_default_security, tags=tags, - creation_date=creation_date, - modification_date=modification_date, + organization_default=organization_default, project_default=project_default, stateful=stateful, + creation_date=creation_date, + modification_date=modification_date, inbound_default_policy=inbound_default_policy, outbound_default_policy=outbound_default_policy, organization=organization, project=project, - organization_default=organization_default, servers=servers, ), self.client, diff --git a/scaleway/scaleway/instance/v1/custom_api.py b/scaleway/scaleway/instance/v1/custom_api.py index 853dcc7af..5c85e86f7 100644 --- a/scaleway/scaleway/instance/v1/custom_api.py +++ b/scaleway/scaleway/instance/v1/custom_api.py @@ -111,7 +111,7 @@ def set_all_server_user_data( server_id: str, user_data: Dict[str, bytes], zone: Optional[ScwZone] = None, - ) -> Optional[None]: + ) -> None: param_zone = validate_path_param("zone", zone or self.client.default_zone) param_server_id = validate_path_param("server_id", server_id) @@ -134,7 +134,7 @@ def set_all_server_user_data( content=user_data[key], ) - return None + return def wait_instance_server(self, server_id: str, zone: ScwZone) -> GetServerResponse: wait_interval = interval diff --git a/scaleway/scaleway/instance/v1/marshalling.py b/scaleway/scaleway/instance/v1/marshalling.py index 2e72fdb36..3c72a53ec 100644 --- a/scaleway/scaleway/instance/v1/marshalling.py +++ b/scaleway/scaleway/instance/v1/marshalling.py @@ -353,6 +353,12 @@ def unmarshal_Volume(data: Any) -> Volume: else: args["name"] = None + field = data.get("export_uri", None) + if field is not None: + args["export_uri"] = field + else: + args["export_uri"] = None + field = data.get("size", None) if field is not None: args["size"] = field @@ -377,12 +383,6 @@ def unmarshal_Volume(data: Any) -> Volume: else: args["project"] = None - field = data.get("export_uri", None) - if field is not None: - args["export_uri"] = field - else: - args["export_uri"] = None - field = data.get("creation_date", None) if field is not None: args["creation_date"] = ( @@ -990,6 +990,18 @@ def unmarshal_Server(data: Any) -> Server: else: args["commercial_type"] = None + field = data.get("dynamic_ip_required", None) + if field is not None: + args["dynamic_ip_required"] = field + else: + args["dynamic_ip_required"] = False + + field = data.get("routed_ip_enabled", None) + if field is not None: + args["routed_ip_enabled"] = field + else: + args["routed_ip_enabled"] = False + field = data.get("creation_date", None) if field is not None: args["creation_date"] = ( @@ -998,11 +1010,11 @@ def unmarshal_Server(data: Any) -> Server: else: args["creation_date"] = None - field = data.get("dynamic_ip_required", None) + field = data.get("enable_ipv6", None) if field is not None: - args["dynamic_ip_required"] = field + args["enable_ipv6"] = field else: - args["dynamic_ip_required"] = False + args["enable_ipv6"] = False field = data.get("hostname", None) if field is not None: @@ -1068,54 +1080,6 @@ def unmarshal_Server(data: Any) -> Server: else: args["state_detail"] = None - field = data.get("arch", None) - if field is not None: - args["arch"] = field - else: - args["arch"] = Arch.UNKNOWN_ARCH - - field = data.get("private_nics", None) - if field is not None: - args["private_nics"] = ( - [unmarshal_PrivateNIC(v) for v in field] if field is not None else None - ) - else: - args["private_nics"] = [] - - field = data.get("zone", None) - if field is not None: - args["zone"] = field - else: - args["zone"] = None - - field = data.get("filesystems", None) - if field is not None: - args["filesystems"] = ( - [unmarshal_ServerFilesystem(v) for v in field] - if field is not None - else None - ) - else: - args["filesystems"] = [] - - field = data.get("end_of_service", None) - if field is not None: - args["end_of_service"] = field - else: - args["end_of_service"] = False - - field = data.get("routed_ip_enabled", None) - if field is not None: - args["routed_ip_enabled"] = field - else: - args["routed_ip_enabled"] = False - - field = data.get("enable_ipv6", None) - if field is not None: - args["enable_ipv6"] = field - else: - args["enable_ipv6"] = False - field = data.get("image", None) if field is not None: args["image"] = unmarshal_Image(field) @@ -1160,6 +1124,42 @@ def unmarshal_Server(data: Any) -> Server: else: args["security_group"] = None + field = data.get("arch", None) + if field is not None: + args["arch"] = field + else: + args["arch"] = Arch.UNKNOWN_ARCH + + field = data.get("private_nics", None) + if field is not None: + args["private_nics"] = ( + [unmarshal_PrivateNIC(v) for v in field] if field is not None else None + ) + else: + args["private_nics"] = [] + + field = data.get("zone", None) + if field is not None: + args["zone"] = field + else: + args["zone"] = None + + field = data.get("filesystems", None) + if field is not None: + args["filesystems"] = ( + [unmarshal_ServerFilesystem(v) for v in field] + if field is not None + else None + ) + else: + args["filesystems"] = [] + + field = data.get("end_of_service", None) + if field is not None: + args["end_of_service"] = field + else: + args["end_of_service"] = False + field = data.get("placement_group", None) if field is not None: args["placement_group"] = unmarshal_PlacementGroup(field) @@ -1436,6 +1436,12 @@ def unmarshal_SecurityGroup(data: Any) -> SecurityGroup: else: args["tags"] = [] + field = data.get("organization_default", None) + if field is not None: + args["organization_default"] = field + else: + args["organization_default"] = False + field = data.get("project_default", None) if field is not None: args["project_default"] = field @@ -1468,12 +1474,6 @@ def unmarshal_SecurityGroup(data: Any) -> SecurityGroup: else: args["zone"] = None - field = data.get("organization_default", None) - if field is not None: - args["organization_default"] = field - else: - args["organization_default"] = False - field = data.get("creation_date", None) if field is not None: args["creation_date"] = ( @@ -1905,97 +1905,97 @@ def unmarshal_Dashboard(data: Any) -> Dashboard: if field is not None: args["volumes_count"] = field else: - args["volumes_count"] = None + args["volumes_count"] = 0 field = data.get("running_servers_count", None) if field is not None: args["running_servers_count"] = field else: - args["running_servers_count"] = None + args["running_servers_count"] = 0 field = data.get("servers_by_types", None) if field is not None: args["servers_by_types"] = field else: - args["servers_by_types"] = None + args["servers_by_types"] = {} field = data.get("images_count", None) if field is not None: args["images_count"] = field else: - args["images_count"] = None + args["images_count"] = 0 field = data.get("snapshots_count", None) if field is not None: args["snapshots_count"] = field else: - args["snapshots_count"] = None + args["snapshots_count"] = 0 field = data.get("servers_count", None) if field is not None: args["servers_count"] = field else: - args["servers_count"] = None + args["servers_count"] = 0 field = data.get("ips_count", None) if field is not None: args["ips_count"] = field else: - args["ips_count"] = None + args["ips_count"] = 0 field = data.get("security_groups_count", None) if field is not None: args["security_groups_count"] = field else: - args["security_groups_count"] = None + args["security_groups_count"] = 0 field = data.get("ips_unused", None) if field is not None: args["ips_unused"] = field else: - args["ips_unused"] = None + args["ips_unused"] = 0 field = data.get("volumes_l_ssd_count", None) if field is not None: args["volumes_l_ssd_count"] = field else: - args["volumes_l_ssd_count"] = None + args["volumes_l_ssd_count"] = 0 field = data.get("volumes_l_ssd_total_size", None) if field is not None: args["volumes_l_ssd_total_size"] = field else: - args["volumes_l_ssd_total_size"] = None + args["volumes_l_ssd_total_size"] = 0 field = data.get("private_nics_count", None) if field is not None: args["private_nics_count"] = field else: - args["private_nics_count"] = None + args["private_nics_count"] = 0 field = data.get("placement_groups_count", None) if field is not None: args["placement_groups_count"] = field else: - args["placement_groups_count"] = None + args["placement_groups_count"] = 0 field = data.get("volumes_scratch_count", None) if field is not None: args["volumes_scratch_count"] = field else: - args["volumes_scratch_count"] = None + args["volumes_scratch_count"] = 0 field = data.get("volumes_b_ssd_count", None) if field is not None: args["volumes_b_ssd_count"] = field else: - args["volumes_b_ssd_count"] = None + args["volumes_b_ssd_count"] = 0 field = data.get("volumes_b_ssd_total_size", None) if field is not None: args["volumes_b_ssd_total_size"] = field else: - args["volumes_b_ssd_total_size"] = None + args["volumes_b_ssd_total_size"] = 0 return Dashboard(**args) @@ -3712,6 +3712,9 @@ def marshal_CreateServerRequest( if request.commercial_type is not None: output["commercial_type"] = request.commercial_type + if request.enable_ipv6 is not None: + output["enable_ipv6"] = request.enable_ipv6 + if request.name is not None: output["name"] = request.name @@ -3730,9 +3733,6 @@ def marshal_CreateServerRequest( for key, value in request.volumes.items() } - if request.enable_ipv6 is not None: - output["enable_ipv6"] = request.enable_ipv6 - if request.protected is not None: output["protected"] = request.protected @@ -4032,6 +4032,9 @@ def marshal_Volume( if request.name is not None: output["name"] = request.name + if request.export_uri is not None: + output["export_uri"] = request.export_uri + if request.size is not None: output["size"] = request.size @@ -4048,9 +4051,6 @@ def marshal_Volume( else: output["project"] = defaults.default_project_id - if request.export_uri is not None: - output["export_uri"] = request.export_uri - if request.creation_date is not None: output["creation_date"] = request.creation_date.isoformat() @@ -4544,11 +4544,8 @@ def marshal__SetSecurityGroupRequest( if request.tags is not None: output["tags"] = request.tags - if request.creation_date is not None: - output["creation_date"] = request.creation_date.isoformat() - - if request.modification_date is not None: - output["modification_date"] = request.modification_date.isoformat() + if request.organization_default is not None: + output["organization_default"] = request.organization_default if request.project_default is not None: output["project_default"] = request.project_default @@ -4556,6 +4553,12 @@ def marshal__SetSecurityGroupRequest( if request.stateful is not None: output["stateful"] = request.stateful + if request.creation_date is not None: + output["creation_date"] = request.creation_date.isoformat() + + if request.modification_date is not None: + output["modification_date"] = request.modification_date.isoformat() + if request.inbound_default_policy is not None: output["inbound_default_policy"] = request.inbound_default_policy @@ -4572,9 +4575,6 @@ def marshal__SetSecurityGroupRequest( else: output["project"] = defaults.default_project_id - if request.organization_default is not None: - output["organization_default"] = request.organization_default - if request.servers is not None: output["servers"] = [ marshal_ServerSummary(item, defaults) for item in request.servers @@ -4884,13 +4884,16 @@ def marshal__SetServerRequest( if request.commercial_type is not None: output["commercial_type"] = request.commercial_type + if request.dynamic_ip_required is not None: + output["dynamic_ip_required"] = request.dynamic_ip_required + if request.organization is not None: output["organization"] = request.organization else: output["organization"] = defaults.default_organization_id - if request.dynamic_ip_required is not None: - output["dynamic_ip_required"] = request.dynamic_ip_required + if request.enable_ipv6 is not None: + output["enable_ipv6"] = request.enable_ipv6 if request.hostname is not None: output["hostname"] = request.hostname @@ -4918,9 +4921,6 @@ def marshal__SetServerRequest( if request.routed_ip_enabled is not None: output["routed_ip_enabled"] = request.routed_ip_enabled - if request.enable_ipv6 is not None: - output["enable_ipv6"] = request.enable_ipv6 - if request.image is not None: output["image"] = marshal_Image(request.image, defaults) diff --git a/scaleway/scaleway/instance/v1/types.py b/scaleway/scaleway/instance/v1/types.py index 4470ba522..7471bebe2 100644 --- a/scaleway/scaleway/instance/v1/types.py +++ b/scaleway/scaleway/instance/v1/types.py @@ -347,6 +347,11 @@ class Volume: Volume name. """ + export_uri: str + """ + Show the volume NBD export URI (deprecated, will always be empty). + """ + size: int """ Volume disk size. @@ -382,11 +387,6 @@ class Volume: Zone in which the volume is located. """ - export_uri: Optional[str] = None - """ - Show the volume NBD export URI (deprecated, will always be empty). - """ - creation_date: Optional[datetime] = None """ Volume creation date. @@ -804,6 +804,16 @@ class Server: True if a dynamic IPv4 is required. """ + routed_ip_enabled: bool + """ + True to configure the instance so it uses the routed IP mode. Use of `routed_ip_enabled` as `False` is deprecated. + """ + + enable_ipv6: bool + """ + True if IPv6 is enabled (deprecated and always `False` when `routed_ip_enabled` is `True`). + """ + hostname: str """ Instance host name. @@ -879,16 +889,6 @@ class Server: Instance creation date. """ - routed_ip_enabled: Optional[bool] = False - """ - True to configure the instance so it uses the routed IP mode. Use of `routed_ip_enabled` as `False` is deprecated. - """ - - enable_ipv6: Optional[bool] = False - """ - True if IPv6 is enabled (deprecated and always `False` when `routed_ip_enabled` is `True`). - """ - image: Optional[Image] = None """ Information about the Instance image. @@ -1039,6 +1039,11 @@ class SecurityGroup: Security group tags. """ + organization_default: bool + """ + True if it is your default security group for this Organization ID. + """ + project_default: bool """ True if it is your default security group for this Project ID. @@ -1064,11 +1069,6 @@ class SecurityGroup: Zone in which the security group is located. """ - organization_default: Optional[bool] = False - """ - True if it is your default security group for this Organization ID. - """ - creation_date: Optional[datetime] = None """ Security group creation date. @@ -1265,8 +1265,8 @@ class Dashboard: private_nics_count: int placement_groups_count: int volumes_scratch_count: int - volumes_b_ssd_count: Optional[int] = None - volumes_b_ssd_total_size: Optional[int] = None + volumes_b_ssd_count: int + volumes_b_ssd_total_size: int @dataclass @@ -1294,6 +1294,11 @@ class GetServerTypesAvailabilityResponseAvailability: @dataclass class ServerType: + monthly_price: float + """ + Estimated monthly price, for a 30 days month, in Euro. + """ + hourly_price: float """ Hourly price in Euro. @@ -1329,11 +1334,6 @@ class ServerType: True if this Instance type has reached end of service. """ - monthly_price: Optional[float] = 0.0 - """ - Estimated monthly price, for a 30 days month, in Euro. - """ - per_volume_constraint: Optional[ServerTypeVolumeConstraintsByType] = None """ Additional volume constraints. @@ -1783,6 +1783,11 @@ class CreateServerRequest: Define the Instance commercial type (i.e. GP1-S). """ + enable_ipv6: bool + """ + True if IPv6 is enabled on the server (deprecated and always `False` when `routed_ip_enabled` is `True`). + """ + protected: bool """ True to activate server protection option. @@ -1818,11 +1823,6 @@ class CreateServerRequest: Volumes attached to the server. """ - enable_ipv6: Optional[bool] = False - """ - True if IPv6 is enabled on the server (deprecated and always `False` when `routed_ip_enabled` is `True`). - """ - public_ip: Optional[str] = None """ ID of the reserved IP to attach to the Instance. diff --git a/scaleway/scaleway/instance/v1/types_private.py b/scaleway/scaleway/instance/v1/types_private.py index 53890fe56..233583dc7 100644 --- a/scaleway/scaleway/instance/v1/types_private.py +++ b/scaleway/scaleway/instance/v1/types_private.py @@ -70,13 +70,9 @@ class _SetSecurityGroupRequest: """ Tags of the security group. """ - creation_date: Optional[datetime] - """ - Creation date of the security group (will be ignored). + organization_default: bool """ - modification_date: Optional[datetime] - """ - Modification date of the security group (will be ignored). + Please use project_default instead. """ project_default: bool """ @@ -86,6 +82,14 @@ class _SetSecurityGroupRequest: """ True to set the security group as stateful. """ + creation_date: Optional[datetime] + """ + Creation date of the security group (will be ignored). + """ + modification_date: Optional[datetime] + """ + Modification date of the security group (will be ignored). + """ inbound_default_policy: Optional[SecurityGroupPolicy] """ Default inbound policy. @@ -102,10 +106,6 @@ class _SetSecurityGroupRequest: """ Security group Project ID. """ - organization_default: Optional[bool] - """ - Please use project_default instead. - """ servers: Optional[list[ServerSummary]] """ Instances attached to this security group. @@ -159,13 +159,17 @@ class _SetServerRequest: """ Instance commercial type (eg. GP1-M). """ + dynamic_ip_required: bool + """ + True if a dynamic IPv4 is required. + """ organization: Optional[str] """ Instance Organization ID. """ - dynamic_ip_required: bool + enable_ipv6: bool """ - True if a dynamic IPv4 is required. + True if IPv6 is enabled (deprecated and always `False` when `routed_ip_enabled` is `True`). """ hostname: str """ @@ -199,10 +203,6 @@ class _SetServerRequest: """ True to configure the instance so it uses the new routed IP mode (once this is set to True you cannot set it back to False). """ - enable_ipv6: Optional[bool] - """ - True if IPv6 is enabled (deprecated and always `False` when `routed_ip_enabled` is `True`). - """ image: Optional[Image] """ Provide information on the Instance image. diff --git a/scaleway/scaleway/interlink/v1beta1/api.py b/scaleway/scaleway/interlink/v1beta1/api.py index cb5ce9d15..225646c9c 100644 --- a/scaleway/scaleway/interlink/v1beta1/api.py +++ b/scaleway/scaleway/interlink/v1beta1/api.py @@ -251,8 +251,8 @@ def wait_for_dedicated_connection( options = WaitForOptions() if not options.stop: - options.stop = ( - lambda res: res.status not in DEDICATED_CONNECTION_TRANSIENT_STATUSES + options.stop = lambda res: ( + res.status not in DEDICATED_CONNECTION_TRANSIENT_STATUSES ) return wait_for_resource( diff --git a/scaleway/scaleway/jobs/v1alpha2/__init__.py b/scaleway/scaleway/jobs/v1alpha2/__init__.py index 453c9acd3..1e3d1ebdc 100644 --- a/scaleway/scaleway/jobs/v1alpha2/__init__.py +++ b/scaleway/scaleway/jobs/v1alpha2/__init__.py @@ -5,26 +5,34 @@ from .content import JOB_RUN_TRANSIENT_STATUSES from .types import ListJobDefinitionsRequestOrderBy from .types import ListJobRunsRequestOrderBy +from .types import ListTriggersRequestOrderBy from .types import SecretEnvVar from .types import SecretFile from .types import CronSchedule from .types import RetryPolicy +from .types import TriggerCronConfig from .types import CreateJobDefinitionRequestCronScheduleConfig from .types import CreateSecretsRequestSecretConfig from .types import Secret +from .types import CreateTriggerRequestCronConfig from .types import JobDefinition from .types import Resource from .types import JobRun +from .types import Trigger from .types import UpdateJobDefinitionRequestCronScheduleConfig +from .types import UpdateTriggerRequestCronConfig from .types import CreateJobDefinitionRequest from .types import CreateSecretsRequest from .types import CreateSecretsResponse +from .types import CreateTriggerRequest from .types import DeleteJobDefinitionRequest from .types import DeleteSecretRequest +from .types import DeleteTriggerRequest from .types import GetJobDefinitionRequest from .types import GetJobLimitsRequest from .types import GetJobRunRequest from .types import GetSecretRequest +from .types import GetTriggerRequest from .types import JobLimits from .types import ListJobDefinitionsRequest from .types import ListJobDefinitionsResponse @@ -34,11 +42,14 @@ from .types import ListJobRunsResponse from .types import ListSecretsRequest from .types import ListSecretsResponse +from .types import ListTriggersRequest +from .types import ListTriggersResponse from .types import StartJobDefinitionRequest from .types import StartJobDefinitionResponse from .types import StopJobRunRequest from .types import UpdateJobDefinitionRequest from .types import UpdateSecretRequest +from .types import UpdateTriggerRequest from .api import JobsV1Alpha2API __all__ = [ @@ -47,26 +58,34 @@ "JOB_RUN_TRANSIENT_STATUSES", "ListJobDefinitionsRequestOrderBy", "ListJobRunsRequestOrderBy", + "ListTriggersRequestOrderBy", "SecretEnvVar", "SecretFile", "CronSchedule", "RetryPolicy", + "TriggerCronConfig", "CreateJobDefinitionRequestCronScheduleConfig", "CreateSecretsRequestSecretConfig", "Secret", + "CreateTriggerRequestCronConfig", "JobDefinition", "Resource", "JobRun", + "Trigger", "UpdateJobDefinitionRequestCronScheduleConfig", + "UpdateTriggerRequestCronConfig", "CreateJobDefinitionRequest", "CreateSecretsRequest", "CreateSecretsResponse", + "CreateTriggerRequest", "DeleteJobDefinitionRequest", "DeleteSecretRequest", + "DeleteTriggerRequest", "GetJobDefinitionRequest", "GetJobLimitsRequest", "GetJobRunRequest", "GetSecretRequest", + "GetTriggerRequest", "JobLimits", "ListJobDefinitionsRequest", "ListJobDefinitionsResponse", @@ -76,10 +95,13 @@ "ListJobRunsResponse", "ListSecretsRequest", "ListSecretsResponse", + "ListTriggersRequest", + "ListTriggersResponse", "StartJobDefinitionRequest", "StartJobDefinitionResponse", "StopJobRunRequest", "UpdateJobDefinitionRequest", "UpdateSecretRequest", + "UpdateTriggerRequest", "JobsV1Alpha2API", ] diff --git a/scaleway/scaleway/jobs/v1alpha2/api.py b/scaleway/scaleway/jobs/v1alpha2/api.py index ee6b54cc8..3353ecf2c 100644 --- a/scaleway/scaleway/jobs/v1alpha2/api.py +++ b/scaleway/scaleway/jobs/v1alpha2/api.py @@ -17,11 +17,14 @@ JobRunState, ListJobDefinitionsRequestOrderBy, ListJobRunsRequestOrderBy, + ListTriggersRequestOrderBy, CreateJobDefinitionRequest, CreateJobDefinitionRequestCronScheduleConfig, CreateSecretsRequest, CreateSecretsRequestSecretConfig, CreateSecretsResponse, + CreateTriggerRequest, + CreateTriggerRequestCronConfig, JobDefinition, JobLimits, JobRun, @@ -29,30 +32,38 @@ ListJobResourcesResponse, ListJobRunsResponse, ListSecretsResponse, + ListTriggersResponse, RetryPolicy, Secret, StartJobDefinitionRequest, StartJobDefinitionResponse, + Trigger, UpdateJobDefinitionRequest, UpdateJobDefinitionRequestCronScheduleConfig, UpdateSecretRequest, + UpdateTriggerRequest, + UpdateTriggerRequestCronConfig, ) from .marshalling import ( unmarshal_Secret, unmarshal_JobDefinition, unmarshal_JobRun, + unmarshal_Trigger, unmarshal_CreateSecretsResponse, unmarshal_JobLimits, unmarshal_ListJobDefinitionsResponse, unmarshal_ListJobResourcesResponse, unmarshal_ListJobRunsResponse, unmarshal_ListSecretsResponse, + unmarshal_ListTriggersResponse, unmarshal_StartJobDefinitionResponse, marshal_CreateJobDefinitionRequest, marshal_CreateSecretsRequest, + marshal_CreateTriggerRequest, marshal_StartJobDefinitionRequest, marshal_UpdateJobDefinitionRequest, marshal_UpdateSecretRequest, + marshal_UpdateTriggerRequest, ) @@ -64,14 +75,14 @@ class JobsV1Alpha2API(API): def create_job_definition( self, *, - region: Optional[ScwRegion] = None, cpu_limit: int, memory_limit: int, local_storage_capacity: int, image_uri: str, + region: Optional[ScwRegion] = None, name: Optional[str] = None, + command: str, description: str, - command: Optional[str] = None, startup_command: Optional[list[str]] = None, args: Optional[list[str]] = None, project_id: Optional[str] = None, @@ -82,14 +93,14 @@ def create_job_definition( ) -> JobDefinition: """ Create a new job definition in a specified Project. - :param region: Region to target. If none is passed will use default region from the config. :param cpu_limit: CPU limit of the job (in mvCPU). :param memory_limit: Memory limit of the job (in MiB). :param local_storage_capacity: Local storage capacity of the job (in MiB). :param image_uri: Image to use for the job. + :param region: Region to target. If none is passed will use default region from the config. :param name: Name of the job definition. - :param description: Description of the job. :param command: Deprecated: please use startup_command instead. + :param description: Description of the job. :param startup_command: The main executable or entrypoint script to run. If both command and startup_command are provided, only startup_command will be used. :param args: Passed to the startup command at runtime. @@ -109,6 +120,7 @@ def create_job_definition( memory_limit=1, local_storage_capacity=1, image_uri="example", + command="example", description="example", ) """ @@ -122,14 +134,14 @@ def create_job_definition( f"/serverless-jobs/v1alpha2/regions/{param_region}/job-definitions", body=marshal_CreateJobDefinitionRequest( CreateJobDefinitionRequest( - region=region, cpu_limit=cpu_limit, memory_limit=memory_limit, local_storage_capacity=local_storage_capacity, image_uri=image_uri, + region=region, name=name or random_name(prefix="job"), - description=description, command=command, + description=description, startup_command=startup_command, args=args, project_id=project_id, @@ -814,6 +826,247 @@ def delete_secret( self._throw_on_error(res) + def create_trigger( + self, + *, + job_definition_id: str, + name: str, + region: Optional[ScwRegion] = None, + cron_config: Optional[CreateTriggerRequestCronConfig] = None, + ) -> Trigger: + """ + Create a trigger. + :param job_definition_id: UUID of the job definition. + :param name: Name of the trigger. + :param region: Region to target. If none is passed will use default region from the config. + :param cron_config: Configuration of the CRON trigger. + One-Of ('config'): at most one of 'cron_config' could be set. + :return: :class:`Trigger ` + + Usage: + :: + + result = api.create_trigger( + job_definition_id="example", + name="example", + ) + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + + res = self._request( + "POST", + f"/serverless-jobs/v1alpha2/regions/{param_region}/triggers", + body=marshal_CreateTriggerRequest( + CreateTriggerRequest( + job_definition_id=job_definition_id, + name=name, + region=region, + cron_config=cron_config, + ), + self.client, + ), + ) + + self._throw_on_error(res) + return unmarshal_Trigger(res.json()) + + def get_trigger( + self, + *, + trigger_id: str, + region: Optional[ScwRegion] = None, + ) -> Trigger: + """ + Get a trigger. + :param trigger_id: UUID of the trigger. + :param region: Region to target. If none is passed will use default region from the config. + :return: :class:`Trigger ` + + Usage: + :: + + result = api.get_trigger( + trigger_id="example", + ) + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + param_trigger_id = validate_path_param("trigger_id", trigger_id) + + res = self._request( + "GET", + f"/serverless-jobs/v1alpha2/regions/{param_region}/triggers/{param_trigger_id}", + ) + + self._throw_on_error(res) + return unmarshal_Trigger(res.json()) + + def list_triggers( + self, + *, + job_definition_id: str, + region: Optional[ScwRegion] = None, + page: Optional[int] = None, + page_size: Optional[int] = None, + order_by: Optional[ListTriggersRequestOrderBy] = None, + ) -> ListTriggersResponse: + """ + List triggers of a job definition. + :param job_definition_id: UUID of the job definition. + :param region: Region to target. If none is passed will use default region from the config. + :param page: Page number from paginated list of triggers. + :param page_size: Number of triggers per page. + :param order_by: Sorting order of triggers. + :return: :class:`ListTriggersResponse ` + + Usage: + :: + + result = api.list_triggers( + job_definition_id="example", + ) + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + + res = self._request( + "GET", + f"/serverless-jobs/v1alpha2/regions/{param_region}/triggers", + params={ + "job_definition_id": job_definition_id, + "order_by": order_by, + "page": page, + "page_size": page_size or self.client.default_page_size, + }, + ) + + self._throw_on_error(res) + return unmarshal_ListTriggersResponse(res.json()) + + def list_triggers_all( + self, + *, + job_definition_id: str, + region: Optional[ScwRegion] = None, + page: Optional[int] = None, + page_size: Optional[int] = None, + order_by: Optional[ListTriggersRequestOrderBy] = None, + ) -> list[Trigger]: + """ + List triggers of a job definition. + :param job_definition_id: UUID of the job definition. + :param region: Region to target. If none is passed will use default region from the config. + :param page: Page number from paginated list of triggers. + :param page_size: Number of triggers per page. + :param order_by: Sorting order of triggers. + :return: :class:`list[Trigger] ` + + Usage: + :: + + result = api.list_triggers_all( + job_definition_id="example", + ) + """ + + return fetch_all_pages( + type=ListTriggersResponse, + key="triggers", + fetcher=self.list_triggers, + args={ + "job_definition_id": job_definition_id, + "region": region, + "page": page, + "page_size": page_size, + "order_by": order_by, + }, + ) + + def update_trigger( + self, + *, + trigger_id: str, + region: Optional[ScwRegion] = None, + name: Optional[str] = None, + cron_config: Optional[UpdateTriggerRequestCronConfig] = None, + ) -> Trigger: + """ + Update a trigger. + :param trigger_id: UUID of the trigger. + :param region: Region to target. If none is passed will use default region from the config. + :param name: Name of the trigger. + :param cron_config: Configuration of the CRON trigger. + One-Of ('config'): at most one of 'cron_config' could be set. + :return: :class:`Trigger ` + + Usage: + :: + + result = api.update_trigger( + trigger_id="example", + ) + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + param_trigger_id = validate_path_param("trigger_id", trigger_id) + + res = self._request( + "PATCH", + f"/serverless-jobs/v1alpha2/regions/{param_region}/triggers/{param_trigger_id}", + body=marshal_UpdateTriggerRequest( + UpdateTriggerRequest( + trigger_id=trigger_id, + region=region, + name=name, + cron_config=cron_config, + ), + self.client, + ), + ) + + self._throw_on_error(res) + return unmarshal_Trigger(res.json()) + + def delete_trigger( + self, + *, + trigger_id: str, + region: Optional[ScwRegion] = None, + ) -> None: + """ + Delete a trigger. + :param trigger_id: UUID of the trigger. + :param region: Region to target. If none is passed will use default region from the config. + + Usage: + :: + + result = api.delete_trigger( + trigger_id="example", + ) + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + param_trigger_id = validate_path_param("trigger_id", trigger_id) + + res = self._request( + "DELETE", + f"/serverless-jobs/v1alpha2/regions/{param_region}/triggers/{param_trigger_id}", + ) + + self._throw_on_error(res) + def list_job_resources( self, *, diff --git a/scaleway/scaleway/jobs/v1alpha2/marshalling.py b/scaleway/scaleway/jobs/v1alpha2/marshalling.py index 6d4729d1e..02195315a 100644 --- a/scaleway/scaleway/jobs/v1alpha2/marshalling.py +++ b/scaleway/scaleway/jobs/v1alpha2/marshalling.py @@ -10,6 +10,8 @@ resolve_one_of, ) from .types import ( + JobRunReason, + JobRunState, SecretEnvVar, SecretFile, Secret, @@ -17,6 +19,8 @@ RetryPolicy, JobDefinition, JobRun, + TriggerCronConfig, + Trigger, CreateSecretsResponse, JobLimits, ListJobDefinitionsResponse, @@ -24,15 +28,20 @@ ListJobResourcesResponse, ListJobRunsResponse, ListSecretsResponse, + ListTriggersResponse, StartJobDefinitionResponse, CreateJobDefinitionRequestCronScheduleConfig, CreateJobDefinitionRequest, CreateSecretsRequestSecretConfig, CreateSecretsRequest, + CreateTriggerRequestCronConfig, + CreateTriggerRequest, StartJobDefinitionRequest, UpdateJobDefinitionRequestCronScheduleConfig, UpdateJobDefinitionRequest, UpdateSecretRequest, + UpdateTriggerRequestCronConfig, + UpdateTriggerRequest, ) @@ -187,19 +196,19 @@ def unmarshal_JobDefinition(data: Any) -> JobDefinition: if field is not None: args["cpu_limit"] = field else: - args["cpu_limit"] = None + args["cpu_limit"] = 0 field = data.get("memory_limit", None) if field is not None: args["memory_limit"] = field else: - args["memory_limit"] = None + args["memory_limit"] = 0 field = data.get("local_storage_capacity", None) if field is not None: args["local_storage_capacity"] = field else: - args["local_storage_capacity"] = None + args["local_storage_capacity"] = 0 field = data.get("image_uri", None) if field is not None: @@ -207,11 +216,17 @@ def unmarshal_JobDefinition(data: Any) -> JobDefinition: else: args["image_uri"] = None + field = data.get("command", None) + if field is not None: + args["command"] = field + else: + args["command"] = None + field = data.get("environment_variables", None) if field is not None: args["environment_variables"] = field else: - args["environment_variables"] = None + args["environment_variables"] = {} field = data.get("created_at", None) if field is not None: @@ -225,12 +240,6 @@ def unmarshal_JobDefinition(data: Any) -> JobDefinition: else: args["updated_at"] = None - field = data.get("command", None) - if field is not None: - args["command"] = field - else: - args["command"] = None - field = data.get("job_timeout", None) if field is not None: args["job_timeout"] = field @@ -247,13 +256,13 @@ def unmarshal_JobDefinition(data: Any) -> JobDefinition: if field is not None: args["startup_command"] = field else: - args["startup_command"] = None + args["startup_command"] = [] field = data.get("args", None) if field is not None: args["args"] = field else: - args["args"] = None + args["args"] = [] field = data.get("region", None) if field is not None: @@ -300,13 +309,7 @@ def unmarshal_JobRun(data: Any) -> JobRun: if field is not None: args["state"] = field else: - args["state"] = None - - field = data.get("cpu_limit", None) - if field is not None: - args["cpu_limit"] = field - else: - args["cpu_limit"] = None + args["state"] = JobRunState.UNKNOWN_STATE field = data.get("created_at", None) if field is not None: @@ -326,35 +329,47 @@ def unmarshal_JobRun(data: Any) -> JobRun: else: args["started_at"] = None + field = data.get("cpu_limit", None) + if field is not None: + args["cpu_limit"] = field + else: + args["cpu_limit"] = 0 + field = data.get("memory_limit", None) if field is not None: args["memory_limit"] = field else: - args["memory_limit"] = None + args["memory_limit"] = 0 field = data.get("local_storage_capacity", None) if field is not None: args["local_storage_capacity"] = field else: - args["local_storage_capacity"] = None + args["local_storage_capacity"] = 0 + + field = data.get("command", None) + if field is not None: + args["command"] = field + else: + args["command"] = None field = data.get("environment_variables", None) if field is not None: args["environment_variables"] = field else: - args["environment_variables"] = None + args["environment_variables"] = {} field = data.get("startup_command", None) if field is not None: args["startup_command"] = field else: - args["startup_command"] = None + args["startup_command"] = [] field = data.get("args", None) if field is not None: args["args"] = field else: - args["args"] = None + args["args"] = [] field = data.get("region", None) if field is not None: @@ -380,13 +395,13 @@ def unmarshal_JobRun(data: Any) -> JobRun: if field is not None: args["reason"] = field else: - args["reason"] = None + args["reason"] = JobRunReason.UNKNOWN_REASON field = data.get("exit_code", None) if field is not None: args["exit_code"] = field else: - args["exit_code"] = None + args["exit_code"] = 0 field = data.get("error_message", None) if field is not None: @@ -394,21 +409,97 @@ def unmarshal_JobRun(data: Any) -> JobRun: else: args["error_message"] = None - field = data.get("command", None) - if field is not None: - args["command"] = field - else: - args["command"] = None - field = data.get("attempts", None) if field is not None: args["attempts"] = field else: - args["attempts"] = None + args["attempts"] = 0 return JobRun(**args) +def unmarshal_TriggerCronConfig(data: Any) -> TriggerCronConfig: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'TriggerCronConfig' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("schedule", None) + if field is not None: + args["schedule"] = field + else: + args["schedule"] = None + + field = data.get("timezone", None) + if field is not None: + args["timezone"] = field + else: + args["timezone"] = None + + field = data.get("startup_command", None) + if field is not None: + args["startup_command"] = field + else: + args["startup_command"] = [] + + field = data.get("args", None) + if field is not None: + args["args"] = field + else: + args["args"] = [] + + return TriggerCronConfig(**args) + + +def unmarshal_Trigger(data: Any) -> Trigger: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'Trigger' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("id", None) + if field is not None: + args["id"] = field + else: + args["id"] = None + + field = data.get("job_definition_id", None) + if field is not None: + args["job_definition_id"] = field + else: + args["job_definition_id"] = None + + field = data.get("name", None) + if field is not None: + args["name"] = field + else: + args["name"] = None + + field = data.get("created_at", None) + if field is not None: + args["created_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["created_at"] = None + + field = data.get("updated_at", None) + if field is not None: + args["updated_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["updated_at"] = None + + field = data.get("cron_config", None) + if field is not None: + args["cron_config"] = unmarshal_TriggerCronConfig(field) + else: + args["cron_config"] = None + + return Trigger(**args) + + def unmarshal_CreateSecretsResponse(data: Any) -> CreateSecretsResponse: if not isinstance(data, dict): raise TypeError( @@ -562,6 +653,31 @@ def unmarshal_ListSecretsResponse(data: Any) -> ListSecretsResponse: return ListSecretsResponse(**args) +def unmarshal_ListTriggersResponse(data: Any) -> ListTriggersResponse: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'ListTriggersResponse' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("triggers", None) + if field is not None: + args["triggers"] = ( + [unmarshal_Trigger(v) for v in field] if field is not None else None + ) + else: + args["triggers"] = [] + + field = data.get("total_count", None) + if field is not None: + args["total_count"] = field + else: + args["total_count"] = 0 + + return ListTriggersResponse(**args) + + def unmarshal_StartJobDefinitionResponse(data: Any) -> StartJobDefinitionResponse: if not isinstance(data, dict): raise TypeError( @@ -629,12 +745,12 @@ def marshal_CreateJobDefinitionRequest( if request.name is not None: output["name"] = request.name - if request.description is not None: - output["description"] = request.description - if request.command is not None: output["command"] = request.command + if request.description is not None: + output["description"] = request.description + if request.startup_command is not None: output["startup_command"] = request.startup_command @@ -708,6 +824,53 @@ def marshal_CreateSecretsRequest( return output +def marshal_CreateTriggerRequestCronConfig( + request: CreateTriggerRequestCronConfig, + defaults: ProfileDefaults, +) -> dict[str, Any]: + output: dict[str, Any] = {} + + if request.schedule is not None: + output["schedule"] = request.schedule + + if request.timezone is not None: + output["timezone"] = request.timezone + + if request.startup_command is not None: + output["startup_command"] = request.startup_command + + if request.args is not None: + output["args"] = request.args + + return output + + +def marshal_CreateTriggerRequest( + request: CreateTriggerRequest, + defaults: ProfileDefaults, +) -> dict[str, Any]: + output: dict[str, Any] = {} + output.update( + resolve_one_of( + [ + OneOfPossibility( + param="cron_config", + value=request.cron_config, + marshal_func=marshal_CreateTriggerRequestCronConfig, + ), + ] + ), + ) + + if request.job_definition_id is not None: + output["job_definition_id"] = request.job_definition_id + + if request.name is not None: + output["name"] = request.name + + return output + + def marshal_StartJobDefinitionRequest( request: StartJobDefinitionRequest, defaults: ProfileDefaults, @@ -817,3 +980,47 @@ def marshal_UpdateSecretRequest( output["secret_manager_version"] = request.secret_manager_version return output + + +def marshal_UpdateTriggerRequestCronConfig( + request: UpdateTriggerRequestCronConfig, + defaults: ProfileDefaults, +) -> dict[str, Any]: + output: dict[str, Any] = {} + + if request.schedule is not None: + output["schedule"] = request.schedule + + if request.timezone is not None: + output["timezone"] = request.timezone + + if request.startup_command is not None: + output["startup_command"] = request.startup_command + + if request.args is not None: + output["args"] = request.args + + return output + + +def marshal_UpdateTriggerRequest( + request: UpdateTriggerRequest, + defaults: ProfileDefaults, +) -> dict[str, Any]: + output: dict[str, Any] = {} + output.update( + resolve_one_of( + [ + OneOfPossibility( + param="cron_config", + value=request.cron_config, + marshal_func=marshal_UpdateTriggerRequestCronConfig, + ), + ] + ), + ) + + if request.name is not None: + output["name"] = request.name + + return output diff --git a/scaleway/scaleway/jobs/v1alpha2/types.py b/scaleway/scaleway/jobs/v1alpha2/types.py index 1f13dc4f4..5dcf6b2ce 100644 --- a/scaleway/scaleway/jobs/v1alpha2/types.py +++ b/scaleway/scaleway/jobs/v1alpha2/types.py @@ -66,6 +66,14 @@ def __str__(self) -> str: return str(self.value) +class ListTriggersRequestOrderBy(str, Enum, metaclass=StrEnumMeta): + CREATED_AT_ASC = "created_at_asc" + CREATED_AT_DESC = "created_at_desc" + + def __str__(self) -> str: + return str(self.value) + + @dataclass class SecretEnvVar: name: str @@ -97,6 +105,29 @@ class RetryPolicy: """ +@dataclass +class TriggerCronConfig: + schedule: str + """ + CRON schedule in UNIX format. + """ + + timezone: str + """ + Time zone for the CRON schedule. + """ + + startup_command: list[str] + """ + Startup command that will be used by the triggered job. + """ + + args: list[str] + """ + Arguments passed to the startup command used by the triggered job. + """ + + @dataclass class CreateJobDefinitionRequestCronScheduleConfig: schedule: str @@ -139,30 +170,120 @@ class Secret: env_var: Optional[SecretEnvVar] = None +@dataclass +class CreateTriggerRequestCronConfig: + schedule: str + """ + CRON schedule in UNIX format. + """ + + timezone: str + """ + Time zone for the CRON schedule. + """ + + startup_command: list[str] + """ + Startup command that will be used by the triggered job. + """ + + args: list[str] + """ + Arguments passed to the startup command used by the triggered job. + """ + + @dataclass class JobDefinition: id: str + """ + UUID of the job definition. + """ + name: str + """ + Name of the job definition. + """ + project_id: str + """ + UUID of the Scaleway Project containing the job. + """ + cpu_limit: int + """ + CPU limit of the job (in mvCPU). + """ + memory_limit: int + """ + Memory limit of the job (in MiB). + """ + local_storage_capacity: int + """ + Local storage capacity of the job (in MiB). + """ + image_uri: str + """ + Image to use for the job. + """ + + command: str + """ + Deprecated, please use startup_command instead. + """ + environment_variables: dict[str, str] + """ + Environment variables of the job. + """ + description: str + """ + Description of the job. + """ + startup_command: list[str] + """ + Job startup command. + """ + args: list[str] + """ + Job arguments passed to the startup command at runtime. + """ + region: ScwRegion """ Region to target. If none is passed will use default region from the config. """ created_at: Optional[datetime] = None + """ + Creation date of the job definition. + """ + updated_at: Optional[datetime] = None - command: Optional[str] = None + """ + Last update date of the job definition. + """ + job_timeout: Optional[str] = None + """ + Timeout of the job in seconds. + """ + cron_schedule: Optional[CronSchedule] = None + """ + Configure a cron for the job. + """ + retry_policy: Optional[RetryPolicy] = None + """ + Retry behaviour in case of job failure. + """ @dataclass @@ -174,29 +295,134 @@ class Resource: @dataclass class JobRun: id: str + """ + UUID of the job run. + """ + job_definition_id: str + """ + UUID of the job definition. + """ + state: JobRunState + """ + State of the job run. + """ + cpu_limit: int + """ + CPU limit of the job (in mvCPU). + """ + memory_limit: int + """ + Memory limit of the job (in MiB). + """ + local_storage_capacity: int + """ + Local storage capacity of the job (in MiB). + """ + + command: str + """ + Deprecated, please use startup_command instead. + """ + environment_variables: dict[str, str] + """ + Environment variables of the job run. + """ + startup_command: list[str] + """ + Job startup command. + """ + args: list[str] + """ + Job arguments passed to the startup command at runtime. + """ + region: ScwRegion """ Region to target. If none is passed will use default region from the config. """ created_at: Optional[datetime] = None + """ + Creation date of the job run. + """ + updated_at: Optional[datetime] = None + """ + Last update date of the job run. + """ + started_at: Optional[datetime] = None + """ + Start date of the job run. + """ + terminated_at: Optional[datetime] = None + """ + Termination date of the job run. + """ + run_duration: Optional[str] = None - reason: Optional[JobRunReason] = None - exit_code: Optional[int] = None + """ + Duration of the job run. + """ + + reason: Optional[JobRunReason] = JobRunReason.UNKNOWN_REASON + """ + Reason for failure if the job failed. + """ + + exit_code: Optional[int] = 0 + """ + Exit code of the job. + """ + error_message: Optional[str] = None - command: Optional[str] = None - attempts: Optional[int] = None + """ + Error message if the job failed. + """ + + attempts: Optional[int] = 0 + """ + Number of retry attempts. + """ + + +@dataclass +class Trigger: + id: str + """ + UUID of the trigger. + """ + + job_definition_id: str + """ + UUID of the job definition. + """ + + name: str + """ + Human readable name of the trigger. + """ + + created_at: Optional[datetime] = None + """ + Creation time of the trigger. + """ + + updated_at: Optional[datetime] = None + """ + Last update time of the trigger. + """ + + cron_config: Optional[TriggerCronConfig] = None @dataclass @@ -205,6 +431,29 @@ class UpdateJobDefinitionRequestCronScheduleConfig: timezone: Optional[str] = None +@dataclass +class UpdateTriggerRequestCronConfig: + schedule: Optional[str] = None + """ + CRON schedule in UNIX format. + """ + + timezone: Optional[str] = None + """ + Time zone for the CRON schedule. + """ + + startup_command: Optional[list[str]] = field(default_factory=list) + """ + Startup command that will be used by the triggered job. + """ + + args: Optional[list[str]] = field(default_factory=list) + """ + Arguments passed to the startup command used by the triggered job. + """ + + @dataclass class CreateJobDefinitionRequest: cpu_limit: int @@ -227,6 +476,11 @@ class CreateJobDefinitionRequest: Image to use for the job. """ + command: str + """ + Deprecated: please use startup_command instead. + """ + description: str """ Description of the job. @@ -242,11 +496,6 @@ class CreateJobDefinitionRequest: Name of the job definition. """ - command: Optional[str] = None - """ - Deprecated: please use startup_command instead. - """ - startup_command: Optional[list[str]] = field(default_factory=list) """ The main executable or entrypoint script to run. @@ -311,6 +560,26 @@ class CreateSecretsResponse: """ +@dataclass +class CreateTriggerRequest: + job_definition_id: str + """ + UUID of the job definition. + """ + + name: str + """ + Name of the trigger. + """ + + region: Optional[ScwRegion] = None + """ + Region to target. If none is passed will use default region from the config. + """ + + cron_config: Optional[CreateTriggerRequestCronConfig] = None + + @dataclass class DeleteJobDefinitionRequest: job_definition_id: str @@ -337,6 +606,19 @@ class DeleteSecretRequest: """ +@dataclass +class DeleteTriggerRequest: + trigger_id: str + """ + UUID of the trigger. + """ + + region: Optional[ScwRegion] = None + """ + Region to target. If none is passed will use default region from the config. + """ + + @dataclass class GetJobDefinitionRequest: job_definition_id: str @@ -384,6 +666,19 @@ class GetSecretRequest: """ +@dataclass +class GetTriggerRequest: + trigger_id: str + """ + UUID of the trigger. + """ + + region: Optional[ScwRegion] = None + """ + Region to target. If none is passed will use default region from the config. + """ + + @dataclass class JobLimits: secrets_per_job_definition: int @@ -472,6 +767,49 @@ class ListSecretsResponse: """ +@dataclass +class ListTriggersRequest: + job_definition_id: str + """ + UUID of the job definition. + """ + + region: Optional[ScwRegion] = None + """ + Region to target. If none is passed will use default region from the config. + """ + + page: Optional[int] = 0 + """ + Page number from paginated list of triggers. + """ + + page_size: Optional[int] = 0 + """ + Number of triggers per page. + """ + + order_by: Optional[ListTriggersRequestOrderBy] = ( + ListTriggersRequestOrderBy.CREATED_AT_ASC + ) + """ + Sorting order of triggers. + """ + + +@dataclass +class ListTriggersResponse: + triggers: list[Trigger] + """ + List of triggers. + """ + + total_count: int + """ + Total count of triggers. + """ + + @dataclass class StartJobDefinitionRequest: job_definition_id: str @@ -636,3 +974,23 @@ class UpdateSecretRequest: path: Optional[str] = None env_var_name: Optional[str] = None + + +@dataclass +class UpdateTriggerRequest: + trigger_id: str + """ + UUID of the trigger. + """ + + region: Optional[ScwRegion] = None + """ + Region to target. If none is passed will use default region from the config. + """ + + name: Optional[str] = None + """ + Name of the trigger. + """ + + cron_config: Optional[UpdateTriggerRequestCronConfig] = None diff --git a/scaleway/scaleway/lb/v1/api.py b/scaleway/scaleway/lb/v1/api.py index 11e607f11..be4b09f44 100644 --- a/scaleway/scaleway/lb/v1/api.py +++ b/scaleway/scaleway/lb/v1/api.py @@ -939,7 +939,7 @@ def create_backend( server_ip: list[str], zone: Optional[ScwZone] = None, name: Optional[str] = None, - send_proxy_v2: Optional[bool] = None, + send_proxy_v2: bool, timeout_server: Optional[str] = None, timeout_connect: Optional[str] = None, timeout_tunnel: Optional[str] = None, @@ -993,6 +993,7 @@ def create_backend( lb_id="example", health_check=HealthCheck(), server_ip=[], + send_proxy_v2=False, ) """ @@ -1077,8 +1078,8 @@ def update_backend( forward_port_algorithm: ForwardPortAlgorithm, sticky_sessions: StickySessionsType, sticky_sessions_cookie_name: str, + send_proxy_v2: bool, zone: Optional[ScwZone] = None, - send_proxy_v2: Optional[bool] = None, timeout_server: Optional[str] = None, timeout_connect: Optional[str] = None, timeout_tunnel: Optional[str] = None, @@ -1102,8 +1103,8 @@ def update_backend( :param forward_port_algorithm: Load balancing algorithm to be used when determining which backend server to forward new traffic to. :param sticky_sessions: Defines whether to activate sticky sessions (binding a particular session to a particular backend server) and the method to use if so. None disables sticky sessions. Cookie-based uses an HTTP cookie to stick a session to a backend server. Table-based uses the source (client) IP address to stick a session to a backend server. :param sticky_sessions_cookie_name: Cookie name for cookie-based sticky sessions. - :param zone: Zone to target. If none is passed will use default zone from the config. :param send_proxy_v2: Deprecated in favor of proxy_protocol field. + :param zone: Zone to target. If none is passed will use default zone from the config. :param timeout_server: Maximum allowed time for a backend server to process a request. :param timeout_connect: Maximum allowed time for establishing a connection to a backend server. :param timeout_tunnel: Maximum allowed tunnel inactivity time after Websocket is established (takes precedence over client and server timeout). @@ -1129,6 +1130,7 @@ def update_backend( forward_port_algorithm=ForwardPortAlgorithm.roundrobin, sticky_sessions=StickySessionsType.none, sticky_sessions_cookie_name="example", + send_proxy_v2=False, ) """ @@ -1147,8 +1149,8 @@ def update_backend( forward_port_algorithm=forward_port_algorithm, sticky_sessions=sticky_sessions, sticky_sessions_cookie_name=sticky_sessions_cookie_name, - zone=zone, send_proxy_v2=send_proxy_v2, + zone=zone, timeout_server=timeout_server, timeout_connect=timeout_connect, timeout_tunnel=timeout_tunnel, @@ -3977,7 +3979,7 @@ def create_backend( server_ip: list[str], region: Optional[ScwRegion] = None, name: Optional[str] = None, - send_proxy_v2: Optional[bool] = None, + send_proxy_v2: bool, timeout_server: Optional[str] = None, timeout_connect: Optional[str] = None, timeout_tunnel: Optional[str] = None, @@ -4030,6 +4032,7 @@ def create_backend( lb_id="example", health_check=HealthCheck(), server_ip=[], + send_proxy_v2=False, ) """ @@ -4117,8 +4120,8 @@ def update_backend( forward_port_algorithm: ForwardPortAlgorithm, sticky_sessions: StickySessionsType, sticky_sessions_cookie_name: str, + send_proxy_v2: bool, region: Optional[ScwRegion] = None, - send_proxy_v2: Optional[bool] = None, timeout_server: Optional[str] = None, timeout_connect: Optional[str] = None, timeout_tunnel: Optional[str] = None, @@ -4141,8 +4144,8 @@ def update_backend( :param forward_port_algorithm: Load balancing algorithm to be used when determining which backend server to forward new traffic to. :param sticky_sessions: Defines whether to activate sticky sessions (binding a particular session to a particular backend server) and the method to use if so. None disables sticky sessions. Cookie-based uses an HTTP cookie to stick a session to a backend server. Table-based uses the source (client) IP address to stick a session to a backend server. :param sticky_sessions_cookie_name: Cookie name for cookie-based sticky sessions. - :param region: Region to target. If none is passed will use default region from the config. :param send_proxy_v2: Deprecated in favor of proxy_protocol field. + :param region: Region to target. If none is passed will use default region from the config. :param timeout_server: Maximum allowed time for a backend server to process a request. :param timeout_connect: Maximum allowed time for establishing a connection to a backend server. :param timeout_tunnel: Maximum allowed tunnel inactivity time after Websocket is established (takes precedence over client and server timeout). @@ -4168,6 +4171,7 @@ def update_backend( forward_port_algorithm=ForwardPortAlgorithm.roundrobin, sticky_sessions=StickySessionsType.none, sticky_sessions_cookie_name="example", + send_proxy_v2=False, ) """ @@ -4188,8 +4192,8 @@ def update_backend( forward_port_algorithm=forward_port_algorithm, sticky_sessions=sticky_sessions, sticky_sessions_cookie_name=sticky_sessions_cookie_name, - region=region, send_proxy_v2=send_proxy_v2, + region=region, timeout_server=timeout_server, timeout_connect=timeout_connect, timeout_tunnel=timeout_tunnel, diff --git a/scaleway/scaleway/lb/v1/marshalling.py b/scaleway/scaleway/lb/v1/marshalling.py index a1d2aef14..13215d66e 100644 --- a/scaleway/scaleway/lb/v1/marshalling.py +++ b/scaleway/scaleway/lb/v1/marshalling.py @@ -167,6 +167,12 @@ def unmarshal_Ip(data: Any) -> Ip: else: args["tags"] = [] + field = data.get("region", None) + if field is not None: + args["region"] = field + else: + args["region"] = None + field = data.get("zone", None) if field is not None: args["zone"] = field @@ -179,12 +185,6 @@ def unmarshal_Ip(data: Any) -> Ip: else: args["lb_id"] = None - field = data.get("region", None) - if field is not None: - args["region"] = field - else: - args["region"] = None - return Ip(**args) @@ -515,6 +515,12 @@ def unmarshal_Instance(data: Any) -> Instance: else: args["ip_address"] = None + field = data.get("region", None) + if field is not None: + args["region"] = field + else: + args["region"] = None + field = data.get("zone", None) if field is not None: args["zone"] = field @@ -533,12 +539,6 @@ def unmarshal_Instance(data: Any) -> Instance: else: args["updated_at"] = None - field = data.get("region", None) - if field is not None: - args["region"] = field - else: - args["region"] = None - return Instance(**args) @@ -644,6 +644,12 @@ def unmarshal_Lb(data: Any) -> Lb: else: args["route_count"] = 0 + field = data.get("region", None) + if field is not None: + args["region"] = field + else: + args["region"] = None + field = data.get("zone", None) if field is not None: args["zone"] = field @@ -668,12 +674,6 @@ def unmarshal_Lb(data: Any) -> Lb: else: args["updated_at"] = None - field = data.get("region", None) - if field is not None: - args["region"] = field - else: - args["region"] = None - return Lb(**args) @@ -733,6 +733,12 @@ def unmarshal_Backend(data: Any) -> Backend: else: args["pool"] = [] + field = data.get("send_proxy_v2", None) + if field is not None: + args["send_proxy_v2"] = field + else: + args["send_proxy_v2"] = False + field = data.get("on_marked_down_action", None) if field is not None: args["on_marked_down_action"] = field @@ -757,12 +763,6 @@ def unmarshal_Backend(data: Any) -> Backend: else: args["lb"] = None - field = data.get("send_proxy_v2", None) - if field is not None: - args["send_proxy_v2"] = field - else: - args["send_proxy_v2"] = False - field = data.get("timeout_server", None) if field is not None: args["timeout_server"] = field @@ -1645,18 +1645,18 @@ def unmarshal_LbType(data: Any) -> LbType: else: args["description"] = None - field = data.get("zone", None) - if field is not None: - args["zone"] = field - else: - args["zone"] = None - field = data.get("region", None) if field is not None: args["region"] = field else: args["region"] = None + field = data.get("zone", None) + if field is not None: + args["zone"] = field + else: + args["zone"] = None + return LbType(**args) diff --git a/scaleway/scaleway/lb/v1/types.py b/scaleway/scaleway/lb/v1/types.py index f6ab10591..81d8f7e08 100644 --- a/scaleway/scaleway/lb/v1/types.py +++ b/scaleway/scaleway/lb/v1/types.py @@ -393,6 +393,11 @@ class Instance: Instance IP address. """ + region: ScwRegion + """ + The region the Instance is in. + """ + zone: ScwZone """ The zone the Instance is in. @@ -408,11 +413,6 @@ class Instance: Date on which the Instance was last updated. """ - region: Optional[ScwRegion] = None - """ - The region the Instance is in. - """ - @dataclass class Ip: @@ -446,6 +446,11 @@ class Ip: IP tags. """ + region: ScwRegion + """ + The region the IP address is in. + """ + zone: ScwZone """ The zone the IP address is in. @@ -456,11 +461,6 @@ class Ip: Load Balancer ID. """ - region: Optional[ScwRegion] = None - """ - The region the IP address is in. - """ - @dataclass class Subscriber: @@ -607,6 +607,11 @@ class Lb: Number of routes configured on the Load Balancer. """ + region: ScwRegion + """ + The region the Load Balancer is in. + """ + zone: ScwZone """ The zone the Load Balancer is in. @@ -627,11 +632,6 @@ class Lb: Date on which the Load Balancer was last updated. """ - region: Optional[ScwRegion] = None - """ - The region the Load Balancer is in. - """ - @dataclass class AclActionRedirect: @@ -693,6 +693,11 @@ class Backend: List of IP addresses of backend servers attached to this backend. """ + send_proxy_v2: bool + """ + Deprecated in favor of proxy_protocol field. + """ + on_marked_down_action: OnMarkedDownAction """ Action to take when a backend server is marked as down. @@ -713,11 +718,6 @@ class Backend: Load Balancer the backend is attached to. """ - send_proxy_v2: Optional[bool] = False - """ - Deprecated in favor of proxy_protocol field. - """ - timeout_server: Optional[str] = None """ Maximum allowed time for a backend server to process a request. @@ -973,7 +973,7 @@ class PrivateNetworkIpamConfig: @dataclass class PrivateNetworkStaticConfig: - ip_address: Optional[list[str]] = field(default_factory=list) + ip_address: list[str] """ Array of a local IP address for the Load Balancer on this Private Network. """ @@ -1151,14 +1151,14 @@ class LbType: Load Balancer commercial offer type description. """ - zone: ScwZone + region: ScwRegion """ - The zone the Load Balancer stock is in. + The region the Load Balancer stock is in. """ - region: Optional[ScwRegion] = None + zone: ScwZone """ - The region the Load Balancer stock is in. + The zone the Load Balancer stock is in. """ @@ -1354,6 +1354,11 @@ class CreateBackendRequest: List of backend server IP addresses (IPv4 or IPv6) the backend should forward traffic to. """ + send_proxy_v2: bool + """ + Deprecated in favor of proxy_protocol field. + """ + region: Optional[ScwRegion] = None """ Region to target. If none is passed will use default region from the config. @@ -1364,11 +1369,6 @@ class CreateBackendRequest: Name for the backend. """ - send_proxy_v2: Optional[bool] = False - """ - Deprecated in favor of proxy_protocol field. - """ - timeout_server: Optional[str] = None """ Maximum allowed time for a backend server to process a request. @@ -2593,14 +2593,14 @@ class UpdateBackendRequest: Cookie name for cookie-based sticky sessions. """ - region: Optional[ScwRegion] = None + send_proxy_v2: bool """ - Region to target. If none is passed will use default region from the config. + Deprecated in favor of proxy_protocol field. """ - send_proxy_v2: Optional[bool] = False + region: Optional[ScwRegion] = None """ - Deprecated in favor of proxy_protocol field. + Region to target. If none is passed will use default region from the config. """ timeout_server: Optional[str] = None @@ -3038,6 +3038,11 @@ class ZonedApiCreateBackendRequest: List of backend server IP addresses (IPv4 or IPv6) the backend should forward traffic to. """ + send_proxy_v2: bool + """ + Deprecated in favor of proxy_protocol field. + """ + zone: Optional[ScwZone] = None """ Zone to target. If none is passed will use default zone from the config. @@ -3048,11 +3053,6 @@ class ZonedApiCreateBackendRequest: Name for the backend. """ - send_proxy_v2: Optional[bool] = False - """ - Deprecated in favor of proxy_protocol field. - """ - timeout_server: Optional[str] = None """ Maximum allowed time for a backend server to process a request. @@ -4131,14 +4131,14 @@ class ZonedApiUpdateBackendRequest: Cookie name for cookie-based sticky sessions. """ - zone: Optional[ScwZone] = None + send_proxy_v2: bool """ - Zone to target. If none is passed will use default zone from the config. + Deprecated in favor of proxy_protocol field. """ - send_proxy_v2: Optional[bool] = False + zone: Optional[ScwZone] = None """ - Deprecated in favor of proxy_protocol field. + Zone to target. If none is passed will use default zone from the config. """ timeout_server: Optional[str] = None diff --git a/scaleway/scaleway/partner/__init__.py b/scaleway/scaleway/partner/__init__.py new file mode 100644 index 000000000..8b74a5ed7 --- /dev/null +++ b/scaleway/scaleway/partner/__init__.py @@ -0,0 +1,2 @@ +# This file was automatically generated. DO NOT EDIT. +# If you have any remark or suggestion do not hesitate to open an issue. diff --git a/scaleway/scaleway/partner/v1/__init__.py b/scaleway/scaleway/partner/v1/__init__.py new file mode 100644 index 000000000..13de5e968 --- /dev/null +++ b/scaleway/scaleway/partner/v1/__init__.py @@ -0,0 +1,31 @@ +# This file was automatically generated. DO NOT EDIT. +# If you have any remark or suggestion do not hesitate to open an issue. +from .types import ListOrganizationsRequestOrderBy +from .types import OrganizationLockedBy +from .types import OrganizationStatus +from .types import Organization +from .types import CreateOrganizationRequest +from .types import GetOrganizationRequest +from .types import ListOrganizationsRequest +from .types import ListOrganizationsResponse +from .types import LockOrganizationRequest +from .types import RequestAdminRoleRequest +from .types import UnlockOrganizationRequest +from .types import UpdateOrganizationRequest +from .api import PartnerV1API + +__all__ = [ + "ListOrganizationsRequestOrderBy", + "OrganizationLockedBy", + "OrganizationStatus", + "Organization", + "CreateOrganizationRequest", + "GetOrganizationRequest", + "ListOrganizationsRequest", + "ListOrganizationsResponse", + "LockOrganizationRequest", + "RequestAdminRoleRequest", + "UnlockOrganizationRequest", + "UpdateOrganizationRequest", + "PartnerV1API", +] diff --git a/scaleway/scaleway/partner/v1/api.py b/scaleway/scaleway/partner/v1/api.py new file mode 100644 index 000000000..d896b9722 --- /dev/null +++ b/scaleway/scaleway/partner/v1/api.py @@ -0,0 +1,369 @@ +# This file was automatically generated. DO NOT EDIT. +# If you have any remark or suggestion do not hesitate to open an issue. + +from typing import Optional + +from scaleway_core.api import API +from scaleway_core.utils import ( + validate_path_param, + fetch_all_pages, +) +from .types import ( + ListOrganizationsRequestOrderBy, + OrganizationLockedBy, + OrganizationStatus, + CreateOrganizationRequest, + ListOrganizationsResponse, + Organization, + RequestAdminRoleRequest, + UpdateOrganizationRequest, +) +from .marshalling import ( + unmarshal_Organization, + unmarshal_ListOrganizationsResponse, + marshal_CreateOrganizationRequest, + marshal_RequestAdminRoleRequest, + marshal_UpdateOrganizationRequest, +) + + +class PartnerV1API(API): + """ + Scaleway Partner API ( for partner only ). + """ + + def request_admin_role( + self, + *, + username: str, + email: str, + password: str, + organization_id: Optional[str] = None, + ) -> None: + """ + Invite a partner user in the customer organization. + :param username: The member username. + :param email: The member email. + :param password: The member password. + :param organization_id: The ID of the organization you want to be invited to. + + Usage: + :: + + result = api.request_admin_role( + username="example", + email="example", + password="example", + ) + """ + + param_organization_id = validate_path_param( + "organization_id", organization_id or self.client.default_organization_id + ) + + res = self._request( + "POST", + f"/partner/v1/organizations/{param_organization_id}/request-admin-role", + body=marshal_RequestAdminRoleRequest( + RequestAdminRoleRequest( + username=username, + email=email, + password=password, + organization_id=organization_id, + ), + self.client, + ), + ) + + self._throw_on_error(res) + + def create_organization( + self, + *, + partner_id: str, + email: str, + organization_name: str, + owner_firstname: str, + owner_lastname: str, + customer_id: str, + phone_number: Optional[str] = None, + siren_number: Optional[str] = None, + ) -> Organization: + """ + Create a new organization. + :param partner_id: Your personal `partner_id`. This is the same as your Organization ID. + :param email: The email of the new organization owner. + :param organization_name: The name of the organization you want to create. Usually the company name. + :param owner_firstname: The first name of the new organization owner. + :param owner_lastname: The last name of the new organization owner. + :param customer_id: A custom ID for the customer in your own infrastructure. + :param phone_number: The phone number of the new organization owner. + :param siren_number: A SIREN number for the customer. + :return: :class:`Organization ` + + Usage: + :: + + result = api.create_organization( + partner_id="example", + email="example", + organization_name="example", + owner_firstname="example", + owner_lastname="example", + customer_id="example", + ) + """ + + res = self._request( + "POST", + "/partner/v1/organizations", + body=marshal_CreateOrganizationRequest( + CreateOrganizationRequest( + partner_id=partner_id, + email=email, + organization_name=organization_name, + owner_firstname=owner_firstname, + owner_lastname=owner_lastname, + customer_id=customer_id, + phone_number=phone_number, + siren_number=siren_number, + ), + self.client, + ), + ) + + self._throw_on_error(res) + return unmarshal_Organization(res.json()) + + def get_organization( + self, + *, + organization_id: Optional[str] = None, + ) -> Organization: + """ + Get an organization. + :param organization_id: The ID of the organization you want to GET. + :return: :class:`Organization ` + + Usage: + :: + + result = api.get_organization() + """ + + param_organization_id = validate_path_param( + "organization_id", organization_id or self.client.default_organization_id + ) + + res = self._request( + "GET", + f"/partner/v1/organizations/{param_organization_id}", + ) + + self._throw_on_error(res) + return unmarshal_Organization(res.json()) + + def list_organizations( + self, + *, + page_size: Optional[int] = None, + page: Optional[int] = None, + order_by: Optional[ListOrganizationsRequestOrderBy] = None, + status: Optional[OrganizationStatus] = None, + email: Optional[str] = None, + customer_id: Optional[str] = None, + locked_by: Optional[OrganizationLockedBy] = None, + ) -> ListOrganizationsResponse: + """ + List Organizations. + :param page_size: + :param page: + :param order_by: + :param status: Only list organizations with this status. + :param email: Only list organizations created with this email. + :param customer_id: Only list organizations attached to this Customer ID. + If the customer ID was changed only the last one can be used. + :param locked_by: Only list organizations locked by a certain entity. + :return: :class:`ListOrganizationsResponse ` + + Usage: + :: + + result = api.list_organizations() + """ + + res = self._request( + "GET", + "/partner/v1/organizations", + params={ + "customer_id": customer_id, + "email": email, + "locked_by": locked_by, + "order_by": order_by, + "page": page, + "page_size": page_size or self.client.default_page_size, + "status": status, + }, + ) + + self._throw_on_error(res) + return unmarshal_ListOrganizationsResponse(res.json()) + + def list_organizations_all( + self, + *, + page_size: Optional[int] = None, + page: Optional[int] = None, + order_by: Optional[ListOrganizationsRequestOrderBy] = None, + status: Optional[OrganizationStatus] = None, + email: Optional[str] = None, + customer_id: Optional[str] = None, + locked_by: Optional[OrganizationLockedBy] = None, + ) -> list[Organization]: + """ + List Organizations. + :param page_size: + :param page: + :param order_by: + :param status: Only list organizations with this status. + :param email: Only list organizations created with this email. + :param customer_id: Only list organizations attached to this Customer ID. + If the customer ID was changed only the last one can be used. + :param locked_by: Only list organizations locked by a certain entity. + :return: :class:`list[Organization] ` + + Usage: + :: + + result = api.list_organizations_all() + """ + + return fetch_all_pages( + type=ListOrganizationsResponse, + key="organizations", + fetcher=self.list_organizations, + args={ + "page_size": page_size, + "page": page, + "order_by": order_by, + "status": status, + "email": email, + "customer_id": customer_id, + "locked_by": locked_by, + }, + ) + + def lock_organization( + self, + *, + organization_id: Optional[str] = None, + ) -> Organization: + """ + Lock an organization. + :param organization_id: The ID of the organization you want to lock. + :return: :class:`Organization ` + + Usage: + :: + + result = api.lock_organization() + """ + + param_organization_id = validate_path_param( + "organization_id", organization_id or self.client.default_organization_id + ) + + res = self._request( + "POST", + f"/partner/v1/organizations/{param_organization_id}/lock", + body={}, + ) + + self._throw_on_error(res) + return unmarshal_Organization(res.json()) + + def unlock_organization( + self, + *, + organization_id: Optional[str] = None, + ) -> Organization: + """ + Unlock an organization. + :param organization_id: The ID of the organization you want to unlock. + :return: :class:`Organization ` + + Usage: + :: + + result = api.unlock_organization() + """ + + param_organization_id = validate_path_param( + "organization_id", organization_id or self.client.default_organization_id + ) + + res = self._request( + "POST", + f"/partner/v1/organizations/{param_organization_id}/unlock", + body={}, + ) + + self._throw_on_error(res) + return unmarshal_Organization(res.json()) + + def update_organization( + self, + *, + organization_id: Optional[str] = None, + email: Optional[str] = None, + name: Optional[str] = None, + owner_firstname: Optional[str] = None, + owner_lastname: Optional[str] = None, + phone_number: Optional[str] = None, + customer_id: Optional[str] = None, + comment: Optional[str] = None, + ) -> Organization: + """ + Update an organization. + :param organization_id: The ID of the organization you want to update. + :param email: The new email. + :param name: The new name. + :param owner_firstname: The first name of the new owner. + :param owner_lastname: The last name of the new owner. + :param phone_number: The phone number of the new owner. + :param customer_id: Customer ID associated with this organization. + Warning: Changing this value will only affect future invoices. + If you try to change this value after the 25th of the month, we cannot guarantee that this will take effect on the invoice issued for the current month. + :param comment: A comment about the organization. + :return: :class:`Organization ` + + Usage: + :: + + result = api.update_organization() + """ + + param_organization_id = validate_path_param( + "organization_id", organization_id or self.client.default_organization_id + ) + + res = self._request( + "PATCH", + f"/partner/v1/organizations/{param_organization_id}", + body=marshal_UpdateOrganizationRequest( + UpdateOrganizationRequest( + organization_id=organization_id, + email=email, + name=name, + owner_firstname=owner_firstname, + owner_lastname=owner_lastname, + phone_number=phone_number, + customer_id=customer_id, + comment=comment, + ), + self.client, + ), + ) + + self._throw_on_error(res) + return unmarshal_Organization(res.json()) diff --git a/scaleway/scaleway/partner/v1/marshalling.py b/scaleway/scaleway/partner/v1/marshalling.py new file mode 100644 index 000000000..976bc4151 --- /dev/null +++ b/scaleway/scaleway/partner/v1/marshalling.py @@ -0,0 +1,223 @@ +# This file was automatically generated. DO NOT EDIT. +# If you have any remark or suggestion do not hesitate to open an issue. + +from typing import Any +from dateutil import parser + +from scaleway_core.profile import ProfileDefaults +from .types import ( + OrganizationLockedBy, + OrganizationStatus, + Organization, + ListOrganizationsResponse, + CreateOrganizationRequest, + RequestAdminRoleRequest, + UpdateOrganizationRequest, +) + + +def unmarshal_Organization(data: Any) -> Organization: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'Organization' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("id", None) + if field is not None: + args["id"] = field + else: + args["id"] = None + + field = data.get("name", None) + if field is not None: + args["name"] = field + else: + args["name"] = None + + field = data.get("email", None) + if field is not None: + args["email"] = field + else: + args["email"] = None + + field = data.get("status", None) + if field is not None: + args["status"] = field + else: + args["status"] = OrganizationStatus.UNKNOWN_STATUS + + field = data.get("owner_firstname", None) + if field is not None: + args["owner_firstname"] = field + else: + args["owner_firstname"] = None + + field = data.get("owner_lastname", None) + if field is not None: + args["owner_lastname"] = field + else: + args["owner_lastname"] = None + + field = data.get("created_at", None) + if field is not None: + args["created_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["created_at"] = None + + field = data.get("phone_number", None) + if field is not None: + args["phone_number"] = field + else: + args["phone_number"] = None + + field = data.get("siren_number", None) + if field is not None: + args["siren_number"] = field + else: + args["siren_number"] = None + + field = data.get("customer_id", None) + if field is not None: + args["customer_id"] = field + else: + args["customer_id"] = None + + field = data.get("lock_reason_message", None) + if field is not None: + args["lock_reason_message"] = field + else: + args["lock_reason_message"] = None + + field = data.get("locked_by", None) + if field is not None: + args["locked_by"] = field + else: + args["locked_by"] = OrganizationLockedBy.UNKNOWN_LOCKED_BY + + field = data.get("comment", None) + if field is not None: + args["comment"] = field + else: + args["comment"] = None + + field = data.get("locked_at", None) + if field is not None: + args["locked_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["locked_at"] = None + + field = data.get("picture_link", None) + if field is not None: + args["picture_link"] = field + else: + args["picture_link"] = None + + return Organization(**args) + + +def unmarshal_ListOrganizationsResponse(data: Any) -> ListOrganizationsResponse: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'ListOrganizationsResponse' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("organizations", None) + if field is not None: + args["organizations"] = ( + [unmarshal_Organization(v) for v in field] if field is not None else None + ) + else: + args["organizations"] = [] + + field = data.get("total_count", None) + if field is not None: + args["total_count"] = field + else: + args["total_count"] = 0 + + return ListOrganizationsResponse(**args) + + +def marshal_CreateOrganizationRequest( + request: CreateOrganizationRequest, + defaults: ProfileDefaults, +) -> dict[str, Any]: + output: dict[str, Any] = {} + + if request.partner_id is not None: + output["partner_id"] = request.partner_id + + if request.email is not None: + output["email"] = request.email + + if request.organization_name is not None: + output["organization_name"] = request.organization_name + + if request.owner_firstname is not None: + output["owner_firstname"] = request.owner_firstname + + if request.owner_lastname is not None: + output["owner_lastname"] = request.owner_lastname + + if request.customer_id is not None: + output["customer_id"] = request.customer_id + + if request.phone_number is not None: + output["phone_number"] = request.phone_number + + if request.siren_number is not None: + output["siren_number"] = request.siren_number + + return output + + +def marshal_RequestAdminRoleRequest( + request: RequestAdminRoleRequest, + defaults: ProfileDefaults, +) -> dict[str, Any]: + output: dict[str, Any] = {} + + if request.username is not None: + output["username"] = request.username + + if request.email is not None: + output["email"] = request.email + + if request.password is not None: + output["password"] = request.password + + return output + + +def marshal_UpdateOrganizationRequest( + request: UpdateOrganizationRequest, + defaults: ProfileDefaults, +) -> dict[str, Any]: + output: dict[str, Any] = {} + + if request.email is not None: + output["email"] = request.email + + if request.name is not None: + output["name"] = request.name + + if request.owner_firstname is not None: + output["owner_firstname"] = request.owner_firstname + + if request.owner_lastname is not None: + output["owner_lastname"] = request.owner_lastname + + if request.phone_number is not None: + output["phone_number"] = request.phone_number + + if request.customer_id is not None: + output["customer_id"] = request.customer_id + + if request.comment is not None: + output["comment"] = request.comment + + return output diff --git a/scaleway/scaleway/partner/v1/types.py b/scaleway/scaleway/partner/v1/types.py new file mode 100644 index 000000000..65f805613 --- /dev/null +++ b/scaleway/scaleway/partner/v1/types.py @@ -0,0 +1,294 @@ +# This file was automatically generated. DO NOT EDIT. +# If you have any remark or suggestion do not hesitate to open an issue. +from __future__ import annotations + +from dataclasses import dataclass +from datetime import datetime +from enum import Enum +from typing import Optional + +from scaleway_core.utils import ( + StrEnumMeta, +) + + +class ListOrganizationsRequestOrderBy(str, Enum, metaclass=StrEnumMeta): + CREATED_AT_ASC = "created_at_asc" + CREATED_AT_DESC = "created_at_desc" + + def __str__(self) -> str: + return str(self.value) + + +class OrganizationLockedBy(str, Enum, metaclass=StrEnumMeta): + UNKNOWN_LOCKED_BY = "unknown_locked_by" + PARTNER = "partner" + SCALEWAY = "scaleway" + + def __str__(self) -> str: + return str(self.value) + + +class OrganizationStatus(str, Enum, metaclass=StrEnumMeta): + UNKNOWN_STATUS = "unknown_status" + OPENED = "opened" + LOCKED = "locked" + CLOSED = "closed" + + def __str__(self) -> str: + return str(self.value) + + +@dataclass +class Organization: + id: str + """ + ID of the organization. + """ + + name: str + """ + Name of the organization. + """ + + email: str + """ + Organization owner's email. + """ + + status: OrganizationStatus + """ + The current status of the organization. + """ + + owner_firstname: str + """ + Organization owner's first name. + """ + + owner_lastname: str + """ + Organization owner's last name. + """ + + customer_id: str + """ + Customer ID associated with this organization. + """ + + lock_reason_message: str + """ + If the organization is locked, this field will contain a human-readable reason. + """ + + locked_by: OrganizationLockedBy + """ + Originator of the lock. Can be one of "partner" or "scaleway". + """ + + comment: str + """ + A comment about the organization. + """ + + created_at: Optional[datetime] = None + """ + Date of organization creation. + """ + + phone_number: Optional[str] = None + """ + Organization owner's phone number. + """ + + siren_number: Optional[str] = None + """ + Siren number of the organization. + """ + + locked_at: Optional[datetime] = None + """ + Date of lock. + """ + + picture_link: Optional[str] = None + """ + Link to the Organization's picture. + """ + + +@dataclass +class CreateOrganizationRequest: + partner_id: str + """ + Your personal `partner_id`. This is the same as your Organization ID. + """ + + email: str + """ + The email of the new organization owner. + """ + + organization_name: str + """ + The name of the organization you want to create. Usually the company name. + """ + + owner_firstname: str + """ + The first name of the new organization owner. + """ + + owner_lastname: str + """ + The last name of the new organization owner. + """ + + customer_id: str + """ + A custom ID for the customer in your own infrastructure. + """ + + phone_number: Optional[str] = None + """ + The phone number of the new organization owner. + """ + + siren_number: Optional[str] = None + """ + A SIREN number for the customer. + """ + + +@dataclass +class GetOrganizationRequest: + organization_id: Optional[str] = None + """ + The ID of the organization you want to GET. + """ + + +@dataclass +class ListOrganizationsRequest: + page_size: Optional[int] = 0 + page: Optional[int] = 0 + order_by: Optional[ListOrganizationsRequestOrderBy] = ( + ListOrganizationsRequestOrderBy.CREATED_AT_ASC + ) + status: Optional[OrganizationStatus] = OrganizationStatus.UNKNOWN_STATUS + """ + Only list organizations with this status. + """ + + email: Optional[str] = None + """ + Only list organizations created with this email. + """ + + customer_id: Optional[str] = None + """ + Only list organizations attached to this Customer ID. +If the customer ID was changed only the last one can be used. + """ + + locked_by: Optional[OrganizationLockedBy] = OrganizationLockedBy.UNKNOWN_LOCKED_BY + """ + Only list organizations locked by a certain entity. + """ + + +@dataclass +class ListOrganizationsResponse: + organizations: list[Organization] + """ + List of organizations. + """ + + total_count: int + """ + Total number of organizations. + """ + + +@dataclass +class LockOrganizationRequest: + organization_id: Optional[str] = None + """ + The ID of the organization you want to lock. + """ + + +@dataclass +class RequestAdminRoleRequest: + username: str + """ + The member username. + """ + + email: str + """ + The member email. + """ + + password: str + """ + The member password. + """ + + organization_id: Optional[str] = None + """ + The ID of the organization you want to be invited to. + """ + + +@dataclass +class UnlockOrganizationRequest: + organization_id: Optional[str] = None + """ + The ID of the organization you want to unlock. + """ + + +@dataclass +class UpdateOrganizationRequest: + organization_id: Optional[str] = None + """ + The ID of the organization you want to update. + """ + + email: Optional[str] = None + """ + The new email. + """ + + name: Optional[str] = None + """ + The new name. + """ + + owner_firstname: Optional[str] = None + """ + The first name of the new owner. + """ + + owner_lastname: Optional[str] = None + """ + The last name of the new owner. + """ + + phone_number: Optional[str] = None + """ + The phone number of the new owner. + """ + + customer_id: Optional[str] = None + """ + Customer ID associated with this organization. +Warning: Changing this value will only affect future invoices. +If you try to change this value after the 25th of the month, we cannot guarantee that this will take effect on the invoice issued for the current month. + """ + + comment: Optional[str] = None + """ + A comment about the organization. + """ diff --git a/scaleway/scaleway/rdb/v1/api.py b/scaleway/scaleway/rdb/v1/api.py index 3632cb7ac..451d21173 100644 --- a/scaleway/scaleway/rdb/v1/api.py +++ b/scaleway/scaleway/rdb/v1/api.py @@ -536,8 +536,8 @@ def wait_for_database_backup( options = WaitForOptions() if not options.stop: - options.stop = ( - lambda res: res.status not in DATABASE_BACKUP_TRANSIENT_STATUSES + options.stop = lambda res: ( + res.status not in DATABASE_BACKUP_TRANSIENT_STATUSES ) return wait_for_resource( diff --git a/scaleway/scaleway/rdb/v1/marshalling.py b/scaleway/scaleway/rdb/v1/marshalling.py index 1b3c0ab92..0ca045b2c 100644 --- a/scaleway/scaleway/rdb/v1/marshalling.py +++ b/scaleway/scaleway/rdb/v1/marshalling.py @@ -13,6 +13,9 @@ resolve_one_of, ) from .types import ( + ACLRuleAction, + ACLRuleDirection, + ACLRuleProtocol, DatabaseBackupStatus, EndpointPrivateNetworkDetailsProvisioningMode, EngineSettingPropertyType, @@ -1018,19 +1021,19 @@ def unmarshal_ACLRule(data: Any) -> ACLRule: if field is not None: args["protocol"] = field else: - args["protocol"] = None + args["protocol"] = ACLRuleProtocol.TCP field = data.get("direction", None) if field is not None: args["direction"] = field else: - args["direction"] = None + args["direction"] = ACLRuleDirection.INBOUND field = data.get("action", None) if field is not None: args["action"] = field else: - args["action"] = None + args["action"] = ACLRuleAction.ALLOW field = data.get("description", None) if field is not None: @@ -1042,7 +1045,7 @@ def unmarshal_ACLRule(data: Any) -> ACLRule: if field is not None: args["port"] = field else: - args["port"] = None + args["port"] = 0 return ACLRule(**args) @@ -1622,18 +1625,6 @@ def unmarshal_NodeType(data: Any) -> NodeType: else: args["memory"] = 0 - field = data.get("disabled", None) - if field is not None: - args["disabled"] = field - else: - args["disabled"] = False - - field = data.get("beta", None) - if field is not None: - args["beta"] = field - else: - args["beta"] = False - field = data.get("volume_constraint", None) if field is not None: args["volume_constraint"] = unmarshal_NodeTypeVolumeConstraintSizes(field) @@ -1646,6 +1637,18 @@ def unmarshal_NodeType(data: Any) -> NodeType: else: args["is_bssd_compatible"] = False + field = data.get("disabled", None) + if field is not None: + args["disabled"] = field + else: + args["disabled"] = False + + field = data.get("beta", None) + if field is not None: + args["beta"] = field + else: + args["beta"] = False + field = data.get("available_volume_types", None) if field is not None: args["available_volume_types"] = ( diff --git a/scaleway/scaleway/rdb/v1/types.py b/scaleway/scaleway/rdb/v1/types.py index 046a2b107..0c6b7d6fa 100644 --- a/scaleway/scaleway/rdb/v1/types.py +++ b/scaleway/scaleway/rdb/v1/types.py @@ -666,7 +666,7 @@ class ACLRule: direction: ACLRuleDirection action: ACLRuleAction description: str - port: Optional[int] = None + port: int @dataclass @@ -991,6 +991,11 @@ class NodeType: Quantity of RAM. """ + is_bssd_compatible: bool + """ + The Node Type is compliant with Block Storage. + """ + disabled: bool """ The Node Type is currently disabled. @@ -1031,11 +1036,6 @@ class NodeType: [deprecated] Node Type volume constraints. """ - is_bssd_compatible: Optional[bool] = False - """ - The Node Type is compliant with Block Storage. - """ - @dataclass class Privilege: diff --git a/scaleway/scaleway/registry/v1/api.py b/scaleway/scaleway/registry/v1/api.py index 721f072e6..1f13b1478 100644 --- a/scaleway/scaleway/registry/v1/api.py +++ b/scaleway/scaleway/registry/v1/api.py @@ -768,15 +768,15 @@ def delete_tag( self, *, tag_id: str, + force: bool, region: Optional[ScwRegion] = None, - force: Optional[bool] = None, ) -> Tag: """ Delete a tag. Delete a given image tag. You must specify, in the endpoint, the `region` and `tag_id` parameters of the tag you want to delete. :param tag_id: UUID of the tag. - :param region: Region to target. If none is passed will use default region from the config. :param force: If two tags share the same digest the deletion will fail unless this parameter is set to true (deprecated). + :param region: Region to target. If none is passed will use default region from the config. :return: :class:`Tag ` Usage: @@ -784,6 +784,7 @@ def delete_tag( result = api.delete_tag( tag_id="example", + force=False, ) """ diff --git a/scaleway/scaleway/registry/v1/types.py b/scaleway/scaleway/registry/v1/types.py index 2c46e2521..ac263fac3 100644 --- a/scaleway/scaleway/registry/v1/types.py +++ b/scaleway/scaleway/registry/v1/types.py @@ -314,14 +314,14 @@ class DeleteTagRequest: UUID of the tag. """ - region: Optional[ScwRegion] = None + force: bool """ - Region to target. If none is passed will use default region from the config. + If two tags share the same digest the deletion will fail unless this parameter is set to true (deprecated). """ - force: Optional[bool] = False + region: Optional[ScwRegion] = None """ - If two tags share the same digest the deletion will fail unless this parameter is set to true (deprecated). + Region to target. If none is passed will use default region from the config. """ diff --git a/scaleway/scaleway/searchdb/v1alpha1/marshalling.py b/scaleway/scaleway/searchdb/v1alpha1/marshalling.py index 3e2de3e49..0103c40e2 100644 --- a/scaleway/scaleway/searchdb/v1alpha1/marshalling.py +++ b/scaleway/scaleway/searchdb/v1alpha1/marshalling.py @@ -110,6 +110,12 @@ def unmarshal_Endpoint(data: Any) -> Endpoint: else: args["id"] = None + field = data.get("dns_record", None) + if field is not None: + args["dns_record"] = field + else: + args["dns_record"] = None + field = data.get("services", None) if field is not None: args["services"] = ( @@ -118,12 +124,6 @@ def unmarshal_Endpoint(data: Any) -> Endpoint: else: args["services"] = [] - field = data.get("dns_record", None) - if field is not None: - args["dns_record"] = field - else: - args["dns_record"] = None - field = data.get("public", None) if field is not None: args["public"] = unmarshal_EndpointPublicDetails(field) diff --git a/scaleway/scaleway/searchdb/v1alpha1/types.py b/scaleway/scaleway/searchdb/v1alpha1/types.py index 6cb8184c2..ef52096f6 100644 --- a/scaleway/scaleway/searchdb/v1alpha1/types.py +++ b/scaleway/scaleway/searchdb/v1alpha1/types.py @@ -128,14 +128,14 @@ class Endpoint: Unique identifier of the Endpoint. """ - services: list[EndpointService] + dns_record: str """ - List of available services, their ports and URLs. + DNS entry to access to the service. Now deprecated. Use the `url` field from `services` field instead. """ - dns_record: Optional[str] = None + services: list[EndpointService] """ - DNS entry to access to the service. Now deprecated. Use the `url` field from `services` field instead. + List of available services, their ports and URLs. """ public: Optional[EndpointPublicDetails] = None diff --git a/scaleway/scaleway/tem/v1alpha1/api.py b/scaleway/scaleway/tem/v1alpha1/api.py index 9785787c2..8cf232ece 100644 --- a/scaleway/scaleway/tem/v1alpha1/api.py +++ b/scaleway/scaleway/tem/v1alpha1/api.py @@ -475,19 +475,19 @@ def create_domain( self, *, domain_name: str, + accept_tos: bool, autoconfig: bool, region: Optional[ScwRegion] = None, project_id: Optional[str] = None, - accept_tos: Optional[bool] = None, ) -> Domain: """ Register a domain in a project. You must specify the `region`, `project_id` and `domain_name` to register a domain in a specific Project. :param domain_name: Fully qualified domain dame. + :param accept_tos: Deprecated. Accept Scaleway's Terms of Service. :param autoconfig: Activate auto-configuration of the domain's DNS zone. :param region: Region to target. If none is passed will use default region from the config. :param project_id: ID of the project to which the domain belongs. - :param accept_tos: Deprecated. Accept Scaleway's Terms of Service. :return: :class:`Domain ` Usage: @@ -495,6 +495,7 @@ def create_domain( result = api.create_domain( domain_name="example", + accept_tos=False, autoconfig=False, ) """ @@ -509,10 +510,10 @@ def create_domain( body=marshal_CreateDomainRequest( CreateDomainRequest( domain_name=domain_name, + accept_tos=accept_tos, autoconfig=autoconfig, region=region, project_id=project_id, - accept_tos=accept_tos, ), self.client, ), diff --git a/scaleway/scaleway/tem/v1alpha1/marshalling.py b/scaleway/scaleway/tem/v1alpha1/marshalling.py index 491d43ee2..91a274dc4 100644 --- a/scaleway/scaleway/tem/v1alpha1/marshalling.py +++ b/scaleway/scaleway/tem/v1alpha1/marshalling.py @@ -137,18 +137,18 @@ def unmarshal_Email(data: Any) -> Email: else: args["mail_from"] = None - field = data.get("mail_rcpt", None) - if field is not None: - args["mail_rcpt"] = field - else: - args["mail_rcpt"] = None - field = data.get("rcpt_to", None) if field is not None: args["rcpt_to"] = field else: args["rcpt_to"] = None + field = data.get("mail_rcpt", None) + if field is not None: + args["mail_rcpt"] = field + else: + args["mail_rcpt"] = None + field = data.get("rcpt_type", None) if field is not None: args["rcpt_type"] = field @@ -1558,6 +1558,9 @@ def marshal_CreateDomainRequest( if request.domain_name is not None: output["domain_name"] = request.domain_name + if request.accept_tos is not None: + output["accept_tos"] = request.accept_tos + if request.autoconfig is not None: output["autoconfig"] = request.autoconfig @@ -1566,9 +1569,6 @@ def marshal_CreateDomainRequest( else: output["project_id"] = defaults.default_project_id - if request.accept_tos is not None: - output["accept_tos"] = request.accept_tos - return output diff --git a/scaleway/scaleway/tem/v1alpha1/types.py b/scaleway/scaleway/tem/v1alpha1/types.py index f1cfe51bb..717b6deb5 100644 --- a/scaleway/scaleway/tem/v1alpha1/types.py +++ b/scaleway/scaleway/tem/v1alpha1/types.py @@ -453,6 +453,11 @@ class Email: Email address of the sender. """ + rcpt_to: str + """ + Deprecated. Email address of the recipient. + """ + mail_rcpt: str """ Email address of the recipient. @@ -488,11 +493,6 @@ class Email: Flags categorize emails. They allow you to obtain more information about recurring errors, for example. """ - rcpt_to: Optional[str] = None - """ - Deprecated. Email address of the recipient. - """ - created_at: Optional[datetime] = None """ Creation date of the email object. @@ -1051,6 +1051,11 @@ class CreateDomainRequest: Fully qualified domain dame. """ + accept_tos: bool + """ + Deprecated. Accept Scaleway's Terms of Service. + """ + autoconfig: bool """ Activate auto-configuration of the domain's DNS zone. @@ -1066,11 +1071,6 @@ class CreateDomainRequest: ID of the project to which the domain belongs. """ - accept_tos: Optional[bool] = False - """ - Deprecated. Accept Scaleway's Terms of Service. - """ - @dataclass class CreateEmailRequest: diff --git a/scaleway/scaleway/vpcgw/v1/api.py b/scaleway/scaleway/vpcgw/v1/api.py index b04c7a0c1..7fa509d97 100644 --- a/scaleway/scaleway/vpcgw/v1/api.py +++ b/scaleway/scaleway/vpcgw/v1/api.py @@ -694,8 +694,8 @@ def wait_for_gateway_network( options = WaitForOptions() if not options.stop: - options.stop = ( - lambda res: res.status not in GATEWAY_NETWORK_TRANSIENT_STATUSES + options.stop = lambda res: ( + res.status not in GATEWAY_NETWORK_TRANSIENT_STATUSES ) return wait_for_resource( diff --git a/scaleway/scaleway/vpcgw/v2/api.py b/scaleway/scaleway/vpcgw/v2/api.py index 29ee499ca..102253a73 100644 --- a/scaleway/scaleway/vpcgw/v2/api.py +++ b/scaleway/scaleway/vpcgw/v2/api.py @@ -628,8 +628,8 @@ def wait_for_gateway_network( options = WaitForOptions() if not options.stop: - options.stop = ( - lambda res: res.status not in GATEWAY_NETWORK_TRANSIENT_STATUSES + options.stop = lambda res: ( + res.status not in GATEWAY_NETWORK_TRANSIENT_STATUSES ) return wait_for_resource(