diff --git a/examples/test_iam_identity_v1_examples.py b/examples/test_iam_identity_v1_examples.py index d6b78d9..4490e7c 100644 --- a/examples/test_iam_identity_v1_examples.py +++ b/examples/test_iam_identity_v1_examples.py @@ -38,6 +38,7 @@ # IAM_IDENTITY_IAM_ID_MEMBER= # IAM_IDENTITY_ENTERPRISE_ACCOUNT_ID= # IAM_IDENTITY_ENTERPRISE_SUBACCOUNT_ID= +# IAM_IDENTITY_IAM_ID_FOR_PREFERENCES= # # These configuration properties can be exported as environment variables, or stored # in a configuration file and then: @@ -51,6 +52,9 @@ apikey_name = 'Example-ApiKey' serviceid_name = 'Example-ServiceId' +service = 'console' +value_string = '/billing' +preference_id1 = 'landing_page' # config property values account_id = None @@ -91,6 +95,8 @@ account_settings_template_assignment_id = None account_settings_template_assignment_etag = None +iam_id_for_preferences = None + ############################################################################## # Start of Examples for Service: IamIdentityV1 @@ -136,6 +142,9 @@ def setup_class(cls): global enterprise_subaccount_id enterprise_subaccount_id = config['ENTERPRISE_SUBACCOUNT_ID'] + global iam_id_for_preferences + iam_id_for_preferences = config['IAM_ID_FOR_PREFERENCES'] + print('Setup complete.') needscredentials = pytest.mark.skipif( @@ -1775,6 +1784,82 @@ def test_delete_account_settings_template(self): except ApiException as e: pytest.fail(str(e)) + @needscredentials + def test_update_preference_on_scope_account(self): + """ + update_preference_on_scope_account request example + """ + try: + print('\nupdate_preference_on_scope_account() result:') + # begin-update_preference_on_scope_account + + preference = iam_identity_service.update_preference_on_scope_account( + iam_id=iam_id_for_preferences, service=service, preference_id=preference_id1, value_string=value_string + ).get_result() + print(json.dumps(preference, indent=2)) + + # end-update_preference_on_scope_account + + except ApiException as e: + pytest.fail(str(e)) + + @needscredentials + def test_get_preferences_on_scope_account(self): + """ + get_preferences_on_scope_account request example + """ + try: + print('\nget_preferences_on_scope_account() result:') + # begin-get_preferences_on_scope_account + + preference = iam_identity_service.get_preferences_on_scope_account( + iam_id=iam_id_for_preferences, service=service, preference_id=preference_id1 + ).get_result() + print(json.dumps(preference, indent=2)) + + # end-get_preferences_on_scope_account + + except ApiException as e: + pytest.fail(str(e)) + + @needscredentials + def test_get_all_preferences_on_scope_account(self): + """ + get_all_preferences_on_scope_account request example + """ + try: + print('\nget_all_preferences_on_scope_account() result:') + # begin-get_all_preferences_on_scope_account + + preference = iam_identity_service.get_all_preferences_on_scope_account( + iam_id=iam_id_for_preferences + ).get_result() + print(json.dumps(preference, indent=2)) + + # end-get_all_preferences_on_scope_account + + except ApiException as e: + pytest.fail(str(e)) + + @needscredentials + def test_delete_preferences_on_scope_account(self): + """ + delete_preferences_on_scope_account request example + """ + try: + # begin-delete_preferences_on_scope_account + + response = iam_identity_service.delete_preferences_on_scope_account( + iam_id=iam_id_for_preferences, service=service, preference_id=preference_id1 + ) + + # end-delete_preferences_on_scope_account + + print('\ndelete_preferences_on_scope_account() response status code: ', response.get_status_code()) + + except ApiException as e: + pytest.fail(str(e)) + # endregion ############################################################################## diff --git a/ibm_platform_services/iam_identity_v1.py b/ibm_platform_services/iam_identity_v1.py index 70795fd..22241e8 100644 --- a/ibm_platform_services/iam_identity_v1.py +++ b/ibm_platform_services/iam_identity_v1.py @@ -1,6 +1,6 @@ # coding: utf-8 -# (C) Copyright IBM Corp. 2024. +# (C) Copyright IBM Corp. 2025. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# IBM OpenAPI SDK Code Generator Version: 3.93.0-c40121e6-20240729-182103 +# IBM OpenAPI SDK Code Generator Version: 3.98.0-8be2046a-20241205-162752 """ The IAM Identity Service API allows for the management of Account Settings and Identities @@ -96,9 +96,7 @@ def list_api_keys( Returns the list of API key details for a given service or user IAM ID and account ID. Users can manage user API keys for themself, or service ID API keys for - service IDs that are bound to an entity they have access to. In case of service - IDs and their API keys, a user must be either an account owner, a IBM Cloud org - manager or IBM Cloud space developer in order to manage service IDs of the entity. + service IDs they have access to. :param str account_id: (optional) Account ID of the API keys to query. If a service IAM ID is specified in iam_id then account_id must match the @@ -182,8 +180,7 @@ def create_api_key( Create an API key. Creates an API key for a UserID or service ID. Users can manage user API keys for - themself, or service ID API keys for service IDs that are bound to an entity they - have access to. + themself, or service ID API keys for service IDs they have access to. :param str name: Name of the API key. The name is not checked for uniqueness. Therefore multiple names with the same value can exist. Access @@ -204,8 +201,10 @@ def create_api_key( API key value is retrievable in the future by using the Get details of an API key request. If you create an API key for a user, you must specify `false` or omit the value. We don't allow storing of API keys for users. - :param bool support_sessions: (optional) Defines if the API key supports - sessions. Sessions are only supported for user apikeys. + :param bool support_sessions: (optional) Defines whether you can manage CLI + login sessions for the API key. When `true`, sessions are created and can + be reviewed or revoked. When `false`, no sessions are tracked. To block + access, delete or rotate the API key. Available only for user API keys. :param str action_when_leaked: (optional) Defines the action to take when API key is leaked, valid values are 'none', 'disable' and 'delete'. :param str entity_lock: (optional) Indicates if the API key is locked for @@ -273,8 +272,7 @@ def get_api_keys_details( Get details of an API key by its value. Returns the details of an API key by its value. Users can manage user API keys for - themself, or service ID API keys for service IDs that are bound to an entity they - have access to. + themself, or service ID API keys for service IDs they have access to. :param str iam_api_key: (optional) API key value. :param bool include_history: (optional) Defines if the entity history is @@ -326,10 +324,7 @@ def get_api_key( Get details of an API key. Returns the details of an API key. Users can manage user API keys for themself, or - service ID API keys for service IDs that are bound to an entity they have access - to. In case of service IDs and their API keys, a user must be either an account - owner, a IBM Cloud org manager or IBM Cloud space developer in order to manage - service IDs of the entity. + service ID API keys for service IDs they have access to. :param str id: Unique ID of the API key. :param bool include_history: (optional) Defines if the entity history is @@ -393,9 +388,8 @@ def update_api_key( Updates properties of an API key. This does NOT affect existing access tokens. Their token content will stay unchanged until the access token is refreshed. To update an API key, pass the property to be modified. To delete one property's - value, pass the property with an empty value "".Users can manage user API keys for - themself, or service ID API keys for service IDs that are bound to an entity they - have access to. + value, pass the property with an empty value "". Users can manage user API keys + for themself, or service ID API keys for service IDs they have access to. :param str id: Unique ID of the API key to be updated. :param str if_match: Version of the API key to be updated. Specify the @@ -408,8 +402,10 @@ def update_api_key( :param str description: (optional) The description of the API key to update. If specified an empty description will clear the description of the API key. If a non empty value is provided the API key will be updated. - :param bool support_sessions: (optional) Defines if the API key supports - sessions. Sessions are only supported for user apikeys. + :param bool support_sessions: (optional) Defines whether you can manage CLI + login sessions for the API key. When `true`, sessions are created and can + be reviewed or revoked. When `false`, no sessions are tracked. To block + access, delete or rotate the API key. Available only for user API keys. :param str action_when_leaked: (optional) Defines the action to take when API key is leaked, valid values are 'none', 'disable' and 'delete'. :param dict headers: A `dict` containing the request headers @@ -469,8 +465,8 @@ def delete_api_key( Deletes an API key. Deletes an API key. Existing tokens will remain valid until expired. Users can - manage user API keys for themself, or service ID API keys for service IDs that are - bound to an entity they have access to. + manage user API keys for themself, or service ID API keys for service IDs they + have access to. :param str id: Unique ID of the API key. :param dict headers: A `dict` containing the request headers @@ -558,10 +554,7 @@ def unlock_api_key( Unlock the API key. Unlocks an API key by ID. Users can manage user API keys for themself, or service - ID API keys for service IDs that are bound to an entity they have access to. In - case of service IDs and their API keys, a user must be either an account owner, a - IBM Cloud org manager or IBM Cloud space developer in order to manage service IDs - of the entity. + ID API keys for service IDs they have access to. :param str id: Unique ID of the API key. :param dict headers: A `dict` containing the request headers @@ -602,10 +595,10 @@ def disable_api_key( **kwargs, ) -> DetailedResponse: """ - disable the API key. + Disable the API key. Disable an API key. Users can manage user API keys for themself, or service ID API - keys for service IDs that are bound to an entity they have access to. + keys for service IDs they have access to. :param str id: Unique ID of the API key. :param dict headers: A `dict` containing the request headers @@ -649,7 +642,7 @@ def enable_api_key( Enable the API key. Enable an API key. Users can manage user API keys for themself, or service ID API - keys for service IDs that are bound to an entity they have access to. + keys for service IDs they have access to. :param str id: Unique ID of the API key. :param dict headers: A `dict` containing the request headers @@ -704,9 +697,8 @@ def list_service_ids( List service IDs. Returns a list of service IDs. Users can manage user API keys for themself, or - service ID API keys for service IDs that are bound to an entity they have access - to. Note: apikey details are only included in the response when creating a Service - ID with an api key. + service ID API keys for service IDs they have access to. Note: apikey details are + only included in the response when creating a Service ID with an api key. :param str account_id: (optional) Account ID of the service ID(s) to query. This parameter is required (unless using a pagetoken). @@ -777,8 +769,7 @@ def create_service_id( Create a service ID. Creates a service ID for an IBM Cloud account. Users can manage user API keys for - themself, or service ID API keys for service IDs that are bound to an entity they - have access to. + themself, or service ID API keys for service IDs they have access to. :param str account_id: ID of the account the service ID belongs to. :param str name: Name of the Service Id. The name is not checked for @@ -853,9 +844,8 @@ def get_service_id( Get details of a service ID. Returns the details of a service ID. Users can manage user API keys for themself, - or service ID API keys for service IDs that are bound to an entity they have - access to. Note: apikey details are only included in the response when creating a - Service ID with an api key. + or service ID API keys for service IDs they have access to. Note: apikey details + are only included in the response when creating a Service ID with an api key. :param str id: Unique ID of the service ID. :param bool include_history: (optional) Defines if the entity history is @@ -919,9 +909,9 @@ def update_service_id( Their token content will stay unchanged until the access token is refreshed. To update a service ID, pass the property to be modified. To delete one property's value, pass the property with an empty value "".Users can manage user API keys for - themself, or service ID API keys for service IDs that are bound to an entity they - have access to. Note: apikey details are only included in the response when - creating a Service ID with an apikey. + themself, or service ID API keys for service IDs they have access to. Note: apikey + details are only included in the response when creating a Service ID with an + apikey. :param str id: Unique ID of the service ID to be updated. :param str if_match: Version of the service ID to be updated. Specify the @@ -998,8 +988,7 @@ def delete_service_id( service ID, all associated API keys are deleted. In case a Delete Conflict (status code 409) a retry of the request may help as the service ID is only deleted if the associated API keys were successfully deleted before. Users can manage user API - keys for themself, or service ID API keys for service IDs that are bound to an - entity they have access to. + keys for themself, or service ID API keys for service IDs they have access to. :param str id: Unique ID of the service ID. :param dict headers: A `dict` containing the request headers @@ -1043,10 +1032,7 @@ def lock_service_id( Lock the service ID. Locks a service ID by ID. Users can manage user API keys for themself, or service - ID API keys for service IDs that are bound to an entity they have access to. In - case of service IDs and their API keys, a user must be either an account owner, a - IBM Cloud org manager or IBM Cloud space developer in order to manage service IDs - of the entity. + ID API keys for service IDs they have access to. :param str id: Unique ID of the service ID. :param dict headers: A `dict` containing the request headers @@ -1090,10 +1076,7 @@ def unlock_service_id( Unlock the service ID. Unlocks a service ID by ID. Users can manage user API keys for themself, or - service ID API keys for service IDs that are bound to an entity they have access - to. In case of service IDs and their API keys, a user must be either an account - owner, a IBM Cloud org manager or IBM Cloud space developer in order to manage - service IDs of the entity. + service ID API keys for service IDs they have access to. :param str id: Unique ID of the service ID. :param dict headers: A `dict` containing the request headers @@ -3721,6 +3704,271 @@ def get_effective_account_settings( response = self.send(request, **kwargs) return response + ######################### + # identityPreferences + ######################### + + def update_preference_on_scope_account( + self, + account_id: str, + iam_id: str, + service: str, + preference_id: str, + value_string: str, + *, + value_list_of_strings: Optional[List[str]] = None, + **kwargs, + ) -> DetailedResponse: + """ + Update Identity Preference on scope account. + + Update one Identity Preference on scope 'account'. supported preferences: + The following preferences are storing values for identities inside an account, + i.e. for each account that an identity is member of, the value stored might be + different. + This means, users who might be member of multiple accounts can have multiple + preferences, one per account. + Identities like Service Ids or Trusted Profiles can only exist in one account, + therefore they can only have one preference inside their related account. + preference: console/landing_page + service: console + preferenceId: landing_page + supportedIdentityType: Trusted Profiles, Users + type: string + validation: valid URL (without host part), e.g. /billing or /iam + preference: console/global_left_navigation + service: console + preferenceId: global_left_navigation + supportedIdentityType: Trusted Profiles, Users + type: list of strings + validation: each entry in the list of strings must match the identifier of one + navigation entry in the console. + + :param str account_id: Account id to update preference for. + :param str iam_id: IAM id to update the preference for. + :param str service: Service of the preference to be updated. + :param str preference_id: Identifier of preference to be updated. + :param str value_string: contains a string value of the preference. only + one value property is set, either 'value_string' or 'value_list_of_strings' + is present. + :param List[str] value_list_of_strings: (optional) contains a list of + string values of the preference. only one value property is set, either + 'value_string' or 'value_list_of_strings' is present. + :param dict headers: A `dict` containing the request headers + :return: A `DetailedResponse` containing the result, headers and HTTP status code. + :rtype: DetailedResponse with `dict` result representing a `IdentityPreferenceResponse` object + """ + + if not account_id: + raise ValueError('account_id must be provided') + if not iam_id: + raise ValueError('iam_id must be provided') + if not service: + raise ValueError('service must be provided') + if not preference_id: + raise ValueError('preference_id must be provided') + if value_string is None: + raise ValueError('value_string must be provided') + headers = {} + sdk_headers = get_sdk_headers( + service_name=self.DEFAULT_SERVICE_NAME, + service_version='V1', + operation_id='update_preference_on_scope_account', + ) + headers.update(sdk_headers) + + data = { + 'value_string': value_string, + 'value_list_of_strings': value_list_of_strings, + } + data = {k: v for (k, v) in data.items() if v is not None} + data = json.dumps(data) + headers['content-type'] = 'application/json' + + if 'headers' in kwargs: + headers.update(kwargs.get('headers')) + del kwargs['headers'] + headers['Accept'] = 'application/json' + + path_param_keys = ['account_id', 'iam_id', 'service', 'preference_id'] + path_param_values = self.encode_path_vars(account_id, iam_id, service, preference_id) + path_param_dict = dict(zip(path_param_keys, path_param_values)) + url = '/v1/preferences/accounts/{account_id}/identities/{iam_id}/{service}/{preference_id}'.format( + **path_param_dict + ) + request = self.prepare_request( + method='PUT', + url=url, + headers=headers, + data=data, + ) + + response = self.send(request, **kwargs) + return response + + def delete_preferences_on_scope_account( + self, + account_id: str, + iam_id: str, + service: str, + preference_id: str, + **kwargs, + ) -> DetailedResponse: + """ + Delete Identity Preference on scope account. + + Delete one Identity Preference on scope 'account'. + + :param str account_id: Account id to delete preference for. + :param str iam_id: IAM id to delete the preference for. + :param str service: Service of the preference to be deleted. + :param str preference_id: Identifier of preference to be deleted. + :param dict headers: A `dict` containing the request headers + :return: A `DetailedResponse` containing the result, headers and HTTP status code. + :rtype: DetailedResponse + """ + + if not account_id: + raise ValueError('account_id must be provided') + if not iam_id: + raise ValueError('iam_id must be provided') + if not service: + raise ValueError('service must be provided') + if not preference_id: + raise ValueError('preference_id must be provided') + headers = {} + sdk_headers = get_sdk_headers( + service_name=self.DEFAULT_SERVICE_NAME, + service_version='V1', + operation_id='delete_preferences_on_scope_account', + ) + headers.update(sdk_headers) + + if 'headers' in kwargs: + headers.update(kwargs.get('headers')) + del kwargs['headers'] + + path_param_keys = ['account_id', 'iam_id', 'service', 'preference_id'] + path_param_values = self.encode_path_vars(account_id, iam_id, service, preference_id) + path_param_dict = dict(zip(path_param_keys, path_param_values)) + url = '/v1/preferences/accounts/{account_id}/identities/{iam_id}/{service}/{preference_id}'.format( + **path_param_dict + ) + request = self.prepare_request( + method='DELETE', + url=url, + headers=headers, + ) + + response = self.send(request, **kwargs) + return response + + def get_preferences_on_scope_account( + self, + account_id: str, + iam_id: str, + service: str, + preference_id: str, + **kwargs, + ) -> DetailedResponse: + """ + Get Identity Preference on scope account. + + Get one Identity Preference on scope 'account'. + + :param str account_id: Account id to get preference for. + :param str iam_id: IAM id to get the preference for. + :param str service: Service of the preference to be fetched. + :param str preference_id: Identifier of preference to be fetched. + :param dict headers: A `dict` containing the request headers + :return: A `DetailedResponse` containing the result, headers and HTTP status code. + :rtype: DetailedResponse with `dict` result representing a `IdentityPreferenceResponse` object + """ + + if not account_id: + raise ValueError('account_id must be provided') + if not iam_id: + raise ValueError('iam_id must be provided') + if not service: + raise ValueError('service must be provided') + if not preference_id: + raise ValueError('preference_id must be provided') + headers = {} + sdk_headers = get_sdk_headers( + service_name=self.DEFAULT_SERVICE_NAME, + service_version='V1', + operation_id='get_preferences_on_scope_account', + ) + headers.update(sdk_headers) + + if 'headers' in kwargs: + headers.update(kwargs.get('headers')) + del kwargs['headers'] + headers['Accept'] = 'application/json' + + path_param_keys = ['account_id', 'iam_id', 'service', 'preference_id'] + path_param_values = self.encode_path_vars(account_id, iam_id, service, preference_id) + path_param_dict = dict(zip(path_param_keys, path_param_values)) + url = '/v1/preferences/accounts/{account_id}/identities/{iam_id}/{service}/{preference_id}'.format( + **path_param_dict + ) + request = self.prepare_request( + method='GET', + url=url, + headers=headers, + ) + + response = self.send(request, **kwargs) + return response + + def get_all_preferences_on_scope_account( + self, + account_id: str, + iam_id: str, + **kwargs, + ) -> DetailedResponse: + """ + Get all Identity Preferences for one account. + + Get all Identity Preferences for one account / user combination. + + :param str account_id: Account id to get preferences for. + :param str iam_id: IAM id to get the preferences for. + :param dict headers: A `dict` containing the request headers + :return: A `DetailedResponse` containing the result, headers and HTTP status code. + :rtype: DetailedResponse with `dict` result representing a `IdentityPreferencesResponse` object + """ + + if not account_id: + raise ValueError('account_id must be provided') + if not iam_id: + raise ValueError('iam_id must be provided') + headers = {} + sdk_headers = get_sdk_headers( + service_name=self.DEFAULT_SERVICE_NAME, + service_version='V1', + operation_id='get_all_preferences_on_scope_account', + ) + headers.update(sdk_headers) + + if 'headers' in kwargs: + headers.update(kwargs.get('headers')) + del kwargs['headers'] + headers['Accept'] = 'application/json' + + path_param_keys = ['account_id', 'iam_id'] + path_param_values = self.encode_path_vars(account_id, iam_id) + path_param_dict = dict(zip(path_param_keys, path_param_values)) + url = '/v1/preferences/accounts/{account_id}/identities/{iam_id}'.format(**path_param_dict) + request = self.prepare_request( + method='GET', + url=url, + headers=headers, + ) + + response = self.send(request, **kwargs) + return response + ######################### # trustedProfileAssignments ######################### @@ -7305,8 +7553,10 @@ class ApiKey: :param str name: Name of the API key. The name is not checked for uniqueness. Therefore multiple names with the same value can exist. Access is done via the UUID of the API key. - :param bool support_sessions: (optional) Defines if the API key supports - sessions. Sessions are only supported for user apikeys. + :param bool support_sessions: (optional) Defines whether you can manage CLI + login sessions for the API key. When `true`, sessions are created and can be + reviewed or revoked. When `false`, no sessions are tracked. To block access, + delete or rotate the API key. Available only for user API keys. :param str action_when_leaked: (optional) Defines the action to take when API key is leaked, valid values are 'none', 'disable' and 'delete'. :param str description: (optional) The optional description of the API key. The @@ -7379,8 +7629,10 @@ def __init__( of the creation date in ISO format. :param datetime modified_at: (optional) If set contains a date time string of the last modification date in ISO format. - :param bool support_sessions: (optional) Defines if the API key supports - sessions. Sessions are only supported for user apikeys. + :param bool support_sessions: (optional) Defines whether you can manage CLI + login sessions for the API key. When `true`, sessions are created and can + be reviewed or revoked. When `false`, no sessions are tracked. To block + access, delete or rotate the API key. Available only for user API keys. :param str action_when_leaked: (optional) Defines the action to take when API key is leaked, valid values are 'none', 'disable' and 'delete'. :param str description: (optional) The optional description of the API key. @@ -8988,6 +9240,182 @@ class ComplyStateEnum(str, Enum): CROSS_ACCOUNT = 'CROSS_ACCOUNT' +class IdentityPreferenceResponse: + """ + IdentityPreferenceResponse. + + :param str service: (optional) Service of the preference. + :param str id: (optional) Unique ID of the preference. + :param str account_id: (optional) Account ID of the preference, only present for + scope 'account'. + :param str scope: (optional) Scope of the preference, 'global' or 'account'. + :param str value_string: (optional) String value of the preference, only one + value property is set, either 'value_string' or 'value_list_of_strings' is + present. + :param List[str] value_list_of_strings: (optional) List of value of the + preference, only one value property is set, either 'value_string' or + 'value_list_of_strings' is present. + """ + + def __init__( + self, + *, + service: Optional[str] = None, + id: Optional[str] = None, + account_id: Optional[str] = None, + scope: Optional[str] = None, + value_string: Optional[str] = None, + value_list_of_strings: Optional[List[str]] = None, + ) -> None: + """ + Initialize a IdentityPreferenceResponse object. + + :param str service: (optional) Service of the preference. + :param str id: (optional) Unique ID of the preference. + :param str account_id: (optional) Account ID of the preference, only + present for scope 'account'. + :param str scope: (optional) Scope of the preference, 'global' or + 'account'. + :param str value_string: (optional) String value of the preference, only + one value property is set, either 'value_string' or 'value_list_of_strings' + is present. + :param List[str] value_list_of_strings: (optional) List of value of the + preference, only one value property is set, either 'value_string' or + 'value_list_of_strings' is present. + """ + self.service = service + self.id = id + self.account_id = account_id + self.scope = scope + self.value_string = value_string + self.value_list_of_strings = value_list_of_strings + + @classmethod + def from_dict(cls, _dict: Dict) -> 'IdentityPreferenceResponse': + """Initialize a IdentityPreferenceResponse object from a json dictionary.""" + args = {} + if (service := _dict.get('service')) is not None: + args['service'] = service + if (id := _dict.get('id')) is not None: + args['id'] = id + if (account_id := _dict.get('account_id')) is not None: + args['account_id'] = account_id + if (scope := _dict.get('scope')) is not None: + args['scope'] = scope + if (value_string := _dict.get('value_string')) is not None: + args['value_string'] = value_string + if (value_list_of_strings := _dict.get('value_list_of_strings')) is not None: + args['value_list_of_strings'] = value_list_of_strings + return cls(**args) + + @classmethod + def _from_dict(cls, _dict): + """Initialize a IdentityPreferenceResponse object from a json dictionary.""" + return cls.from_dict(_dict) + + def to_dict(self) -> Dict: + """Return a json dictionary representing this model.""" + _dict = {} + if hasattr(self, 'service') and self.service is not None: + _dict['service'] = self.service + if hasattr(self, 'id') and self.id is not None: + _dict['id'] = self.id + if hasattr(self, 'account_id') and self.account_id is not None: + _dict['account_id'] = self.account_id + if hasattr(self, 'scope') and self.scope is not None: + _dict['scope'] = self.scope + if hasattr(self, 'value_string') and self.value_string is not None: + _dict['value_string'] = self.value_string + if hasattr(self, 'value_list_of_strings') and self.value_list_of_strings is not None: + _dict['value_list_of_strings'] = self.value_list_of_strings + return _dict + + def _to_dict(self): + """Return a json dictionary representing this model.""" + return self.to_dict() + + def __str__(self) -> str: + """Return a `str` version of this IdentityPreferenceResponse object.""" + return json.dumps(self.to_dict(), indent=2) + + def __eq__(self, other: 'IdentityPreferenceResponse') -> bool: + """Return `true` when self and other are equal, false otherwise.""" + if not isinstance(other, self.__class__): + return False + return self.__dict__ == other.__dict__ + + def __ne__(self, other: 'IdentityPreferenceResponse') -> bool: + """Return `true` when self and other are not equal, false otherwise.""" + return not self == other + + +class IdentityPreferencesResponse: + """ + IdentityPreferencesResponse. + + :param List[IdentityPreferenceResponse] preferences: List of Identity + Preferences. + """ + + def __init__( + self, + preferences: List['IdentityPreferenceResponse'], + ) -> None: + """ + Initialize a IdentityPreferencesResponse object. + + :param List[IdentityPreferenceResponse] preferences: List of Identity + Preferences. + """ + self.preferences = preferences + + @classmethod + def from_dict(cls, _dict: Dict) -> 'IdentityPreferencesResponse': + """Initialize a IdentityPreferencesResponse object from a json dictionary.""" + args = {} + if (preferences := _dict.get('preferences')) is not None: + args['preferences'] = [IdentityPreferenceResponse.from_dict(v) for v in preferences] + else: + raise ValueError('Required property \'preferences\' not present in IdentityPreferencesResponse JSON') + return cls(**args) + + @classmethod + def _from_dict(cls, _dict): + """Initialize a IdentityPreferencesResponse object from a json dictionary.""" + return cls.from_dict(_dict) + + def to_dict(self) -> Dict: + """Return a json dictionary representing this model.""" + _dict = {} + if hasattr(self, 'preferences') and self.preferences is not None: + preferences_list = [] + for v in self.preferences: + if isinstance(v, dict): + preferences_list.append(v) + else: + preferences_list.append(v.to_dict()) + _dict['preferences'] = preferences_list + return _dict + + def _to_dict(self): + """Return a json dictionary representing this model.""" + return self.to_dict() + + def __str__(self) -> str: + """Return a `str` version of this IdentityPreferencesResponse object.""" + return json.dumps(self.to_dict(), indent=2) + + def __eq__(self, other: 'IdentityPreferencesResponse') -> bool: + """Return `true` when self and other are equal, false otherwise.""" + if not isinstance(other, self.__class__): + return False + return self.__dict__ == other.__dict__ + + def __ne__(self, other: 'IdentityPreferencesResponse') -> bool: + """Return `true` when self and other are not equal, false otherwise.""" + return not self == other + + class MfaEnrollmentTypeStatus: """ MfaEnrollmentTypeStatus. diff --git a/test/integration/test_iam_identity_v1.py b/test/integration/test_iam_identity_v1.py index f0c9e30..2aceb1d 100644 --- a/test/integration/test_iam_identity_v1.py +++ b/test/integration/test_iam_identity_v1.py @@ -66,6 +66,8 @@ account_settings_template_assignment_id = None account_settings_template_assignment_etag = None +iam_id_for_preferences = None + class TestIamIdentityV1: """ @@ -91,6 +93,7 @@ def setup_class(cls): cls.apikey = cls.config['APIKEY'] cls.enterprise_account_id = cls.config['ENTERPRISE_ACCOUNT_ID'] cls.enterprise_subaccount_id = cls.config['ENTERPRISE_SUBACCOUNT_ID'] + cls.iam_id_for_preferences = cls.config['IAM_ID_FOR_PREFERENCES'] assert cls.account_id is not None assert cls.iam_id is not None @@ -106,6 +109,9 @@ def setup_class(cls): cls.profile_template_name = 'Python-SDK-IT-TrustedProfileTemplate' cls.profile_template_profile_name = 'Python-SDK-IT-TrustedProfile-FromTemplate' cls.account_settings_template_name = 'Python-SDK-IT-TrustedProfileTemplate' + cls.service = 'console' + cls.value_string = '/billing' + cls.preference_id1 = 'landing_page' cls.cleanup_resources() @@ -1819,3 +1825,62 @@ def test_delete_account_settings_template(self): template_id=account_settings_template_id ) assert delete_response.get_status_code() == 204 + + @needscredentials + def test_update_api_key(self): + assert apikey_id1 is not None + assert apikey_etag1 is not None + + new_description = 'This is an updated description' + update_api_key_response = self.iam_identity_service.update_api_key( + id=apikey_id1, if_match=apikey_etag1, description=new_description + ) + + assert update_api_key_response.get_status_code() == 200 + api_key = update_api_key_response.get_result() + print('\nupdate_api_key() response: ', json.dumps(api_key, indent=2)) + assert api_key is not None + assert api_key['description'] == new_description + + @needscredentials + def test_update_preference_on_scope_account(self): + assert iam_id_for_preferences is not None + assert self.preference_id1 is not None + + preference = self.iam_identity_service.update_preference_on_scope_account( + iam_id=iam_id_for_preferences, + service=self.service, + preference_id=self.preference_id1, + value_string=self.value_string, + ).get_result() + print('\nupdate_preference_on_scope_account() response: ', json.dumps(preference, indent=2)) + preference is not None + + @needscredentials + def test_get_preferences_on_scope_account(self): + assert iam_id_for_preferences is not None + assert self.preference_id1 is not None + preference = self.iam_identity_service.get_preferences_on_scope_account( + iam_id=iam_id_for_preferences, service=self.service, preference_id=self.preference_id1 + ).get_result() + print('\nget_preference_on_scope_account() response: ', json.dumps(preference, indent=2)) + preference is not None + + @needscredentials + def test_get_all_preferences_on_scope_account(self): + assert iam_id_for_preferences is not None + assert self.preference_id1 is not None + preference = self.iam_identity_service.get_all_preferences_on_scope_account( + iam_id=iam_id_for_preferences + ).get_result() + print('\nget_all_preference_on_scope_account() response: ', json.dumps(preference, indent=2)) + preference is not None + + @needscredentials + def test_delete_preferences_on_scope_account(self): + assert iam_id_for_preferences is not None + assert self.preference_id1 is not None + preference = self.iam_identity_service.delete_preferences_on_scope_account( + iam_id=iam_id_for_preferences, service=self.service, preference_id=self.preference_id1 + ) + assert preference.get_status_code() == 204 diff --git a/test/unit/test_iam_identity_v1.py b/test/unit/test_iam_identity_v1.py index 5d0ba37..457e5cc 100644 --- a/test/unit/test_iam_identity_v1.py +++ b/test/unit/test_iam_identity_v1.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# (C) Copyright IBM Corp. 2024. +# (C) Copyright IBM Corp. 2025. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -33,7 +33,7 @@ _service = IamIdentityV1(authenticator=NoAuthAuthenticator()) -_base_url = 'https://iam.cloud.ibm.com' +_base_url = 'https://iam.test.cloud.ibm.com' _service.set_service_url(_base_url) @@ -44,15 +44,8 @@ def preprocess_url(operation_path: str): The returned request URL is used to register the mock response so it needs to match the request URL that is formed by the requests library. """ - # First, unquote the path since it might have some quoted/escaped characters in it - # due to how the generator inserts the operation paths into the unit test code. - operation_path = urllib.parse.unquote(operation_path) - # Next, quote the path using urllib so that we approximate what will - # happen during request processing. - operation_path = urllib.parse.quote(operation_path, safe='/') - - # Finally, form the request URL from the base URL and operation path. + # Form the request URL from the base URL and operation path. request_url = _base_url + operation_path # If the request url does NOT end with a /, then just return it as-is. @@ -6499,6 +6492,414 @@ def test_get_effective_account_settings_value_error_with_retries(self): # End of Service: EffectiveAccountSettings ############################################################################## +############################################################################## +# Start of Service: IdentityPreferences +############################################################################## +# region + + +class TestNewInstance: + """ + Test Class for new_instance + """ + + def test_new_instance(self): + """ + new_instance() + """ + os.environ['TEST_SERVICE_AUTH_TYPE'] = 'noAuth' + + service = IamIdentityV1.new_instance( + service_name='TEST_SERVICE', + ) + + assert service is not None + assert isinstance(service, IamIdentityV1) + + def test_new_instance_without_authenticator(self): + """ + new_instance_without_authenticator() + """ + with pytest.raises(ValueError, match='authenticator must be provided'): + service = IamIdentityV1.new_instance( + service_name='TEST_SERVICE_NOT_FOUND', + ) + + +class TestUpdatePreferenceOnScopeAccount: + """ + Test Class for update_preference_on_scope_account + """ + + @responses.activate + def test_update_preference_on_scope_account_all_params(self): + """ + update_preference_on_scope_account() + """ + # Set up mock + url = preprocess_url('/v1/preferences/accounts/testString/identities/testString/testString/testString') + mock_response = '{"service": "service", "id": "id", "account_id": "account_id", "scope": "scope", "value_string": "value_string", "value_list_of_strings": ["value_list_of_strings"]}' + responses.add( + responses.PUT, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Set up parameter values + account_id = 'testString' + iam_id = 'testString' + service = 'testString' + preference_id = 'testString' + value_string = 'testString' + value_list_of_strings = ['testString'] + + # Invoke method + response = _service.update_preference_on_scope_account( + account_id, + iam_id, + service, + preference_id, + value_string, + value_list_of_strings=value_list_of_strings, + headers={}, + ) + + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + # Validate body params + req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) + assert req_body['value_string'] == 'testString' + assert req_body['value_list_of_strings'] == ['testString'] + + def test_update_preference_on_scope_account_all_params_with_retries(self): + # Enable retries and run test_update_preference_on_scope_account_all_params. + _service.enable_retries() + self.test_update_preference_on_scope_account_all_params() + + # Disable retries and run test_update_preference_on_scope_account_all_params. + _service.disable_retries() + self.test_update_preference_on_scope_account_all_params() + + @responses.activate + def test_update_preference_on_scope_account_value_error(self): + """ + test_update_preference_on_scope_account_value_error() + """ + # Set up mock + url = preprocess_url('/v1/preferences/accounts/testString/identities/testString/testString/testString') + mock_response = '{"service": "service", "id": "id", "account_id": "account_id", "scope": "scope", "value_string": "value_string", "value_list_of_strings": ["value_list_of_strings"]}' + responses.add( + responses.PUT, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Set up parameter values + account_id = 'testString' + iam_id = 'testString' + service = 'testString' + preference_id = 'testString' + value_string = 'testString' + value_list_of_strings = ['testString'] + + # Pass in all but one required param and check for a ValueError + req_param_dict = { + "account_id": account_id, + "iam_id": iam_id, + "service": service, + "preference_id": preference_id, + "value_string": value_string, + } + for param in req_param_dict.keys(): + req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} + with pytest.raises(ValueError): + _service.update_preference_on_scope_account(**req_copy) + + def test_update_preference_on_scope_account_value_error_with_retries(self): + # Enable retries and run test_update_preference_on_scope_account_value_error. + _service.enable_retries() + self.test_update_preference_on_scope_account_value_error() + + # Disable retries and run test_update_preference_on_scope_account_value_error. + _service.disable_retries() + self.test_update_preference_on_scope_account_value_error() + + +class TestDeletePreferencesOnScopeAccount: + """ + Test Class for delete_preferences_on_scope_account + """ + + @responses.activate + def test_delete_preferences_on_scope_account_all_params(self): + """ + delete_preferences_on_scope_account() + """ + # Set up mock + url = preprocess_url('/v1/preferences/accounts/testString/identities/testString/testString/testString') + responses.add( + responses.DELETE, + url, + status=204, + ) + + # Set up parameter values + account_id = 'testString' + iam_id = 'testString' + service = 'testString' + preference_id = 'testString' + + # Invoke method + response = _service.delete_preferences_on_scope_account( + account_id, + iam_id, + service, + preference_id, + headers={}, + ) + + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 204 + + def test_delete_preferences_on_scope_account_all_params_with_retries(self): + # Enable retries and run test_delete_preferences_on_scope_account_all_params. + _service.enable_retries() + self.test_delete_preferences_on_scope_account_all_params() + + # Disable retries and run test_delete_preferences_on_scope_account_all_params. + _service.disable_retries() + self.test_delete_preferences_on_scope_account_all_params() + + @responses.activate + def test_delete_preferences_on_scope_account_value_error(self): + """ + test_delete_preferences_on_scope_account_value_error() + """ + # Set up mock + url = preprocess_url('/v1/preferences/accounts/testString/identities/testString/testString/testString') + responses.add( + responses.DELETE, + url, + status=204, + ) + + # Set up parameter values + account_id = 'testString' + iam_id = 'testString' + service = 'testString' + preference_id = 'testString' + + # Pass in all but one required param and check for a ValueError + req_param_dict = { + "account_id": account_id, + "iam_id": iam_id, + "service": service, + "preference_id": preference_id, + } + for param in req_param_dict.keys(): + req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} + with pytest.raises(ValueError): + _service.delete_preferences_on_scope_account(**req_copy) + + def test_delete_preferences_on_scope_account_value_error_with_retries(self): + # Enable retries and run test_delete_preferences_on_scope_account_value_error. + _service.enable_retries() + self.test_delete_preferences_on_scope_account_value_error() + + # Disable retries and run test_delete_preferences_on_scope_account_value_error. + _service.disable_retries() + self.test_delete_preferences_on_scope_account_value_error() + + +class TestGetPreferencesOnScopeAccount: + """ + Test Class for get_preferences_on_scope_account + """ + + @responses.activate + def test_get_preferences_on_scope_account_all_params(self): + """ + get_preferences_on_scope_account() + """ + # Set up mock + url = preprocess_url('/v1/preferences/accounts/testString/identities/testString/testString/testString') + mock_response = '{"service": "service", "id": "id", "account_id": "account_id", "scope": "scope", "value_string": "value_string", "value_list_of_strings": ["value_list_of_strings"]}' + responses.add( + responses.GET, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Set up parameter values + account_id = 'testString' + iam_id = 'testString' + service = 'testString' + preference_id = 'testString' + + # Invoke method + response = _service.get_preferences_on_scope_account( + account_id, + iam_id, + service, + preference_id, + headers={}, + ) + + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + + def test_get_preferences_on_scope_account_all_params_with_retries(self): + # Enable retries and run test_get_preferences_on_scope_account_all_params. + _service.enable_retries() + self.test_get_preferences_on_scope_account_all_params() + + # Disable retries and run test_get_preferences_on_scope_account_all_params. + _service.disable_retries() + self.test_get_preferences_on_scope_account_all_params() + + @responses.activate + def test_get_preferences_on_scope_account_value_error(self): + """ + test_get_preferences_on_scope_account_value_error() + """ + # Set up mock + url = preprocess_url('/v1/preferences/accounts/testString/identities/testString/testString/testString') + mock_response = '{"service": "service", "id": "id", "account_id": "account_id", "scope": "scope", "value_string": "value_string", "value_list_of_strings": ["value_list_of_strings"]}' + responses.add( + responses.GET, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Set up parameter values + account_id = 'testString' + iam_id = 'testString' + service = 'testString' + preference_id = 'testString' + + # Pass in all but one required param and check for a ValueError + req_param_dict = { + "account_id": account_id, + "iam_id": iam_id, + "service": service, + "preference_id": preference_id, + } + for param in req_param_dict.keys(): + req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} + with pytest.raises(ValueError): + _service.get_preferences_on_scope_account(**req_copy) + + def test_get_preferences_on_scope_account_value_error_with_retries(self): + # Enable retries and run test_get_preferences_on_scope_account_value_error. + _service.enable_retries() + self.test_get_preferences_on_scope_account_value_error() + + # Disable retries and run test_get_preferences_on_scope_account_value_error. + _service.disable_retries() + self.test_get_preferences_on_scope_account_value_error() + + +class TestGetAllPreferencesOnScopeAccount: + """ + Test Class for get_all_preferences_on_scope_account + """ + + @responses.activate + def test_get_all_preferences_on_scope_account_all_params(self): + """ + get_all_preferences_on_scope_account() + """ + # Set up mock + url = preprocess_url('/v1/preferences/accounts/testString/identities/testString') + mock_response = '{"preferences": [{"service": "service", "id": "id", "account_id": "account_id", "scope": "scope", "value_string": "value_string", "value_list_of_strings": ["value_list_of_strings"]}]}' + responses.add( + responses.GET, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Set up parameter values + account_id = 'testString' + iam_id = 'testString' + + # Invoke method + response = _service.get_all_preferences_on_scope_account( + account_id, + iam_id, + headers={}, + ) + + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + + def test_get_all_preferences_on_scope_account_all_params_with_retries(self): + # Enable retries and run test_get_all_preferences_on_scope_account_all_params. + _service.enable_retries() + self.test_get_all_preferences_on_scope_account_all_params() + + # Disable retries and run test_get_all_preferences_on_scope_account_all_params. + _service.disable_retries() + self.test_get_all_preferences_on_scope_account_all_params() + + @responses.activate + def test_get_all_preferences_on_scope_account_value_error(self): + """ + test_get_all_preferences_on_scope_account_value_error() + """ + # Set up mock + url = preprocess_url('/v1/preferences/accounts/testString/identities/testString') + mock_response = '{"preferences": [{"service": "service", "id": "id", "account_id": "account_id", "scope": "scope", "value_string": "value_string", "value_list_of_strings": ["value_list_of_strings"]}]}' + responses.add( + responses.GET, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Set up parameter values + account_id = 'testString' + iam_id = 'testString' + + # Pass in all but one required param and check for a ValueError + req_param_dict = { + "account_id": account_id, + "iam_id": iam_id, + } + for param in req_param_dict.keys(): + req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} + with pytest.raises(ValueError): + _service.get_all_preferences_on_scope_account(**req_copy) + + def test_get_all_preferences_on_scope_account_value_error_with_retries(self): + # Enable retries and run test_get_all_preferences_on_scope_account_value_error. + _service.enable_retries() + self.test_get_all_preferences_on_scope_account_value_error() + + # Disable retries and run test_get_all_preferences_on_scope_account_value_error. + _service.disable_retries() + self.test_get_all_preferences_on_scope_account_value_error() + + +# endregion +############################################################################## +# End of Service: IdentityPreferences +############################################################################## + ############################################################################## # Start of Service: TrustedProfileAssignments ############################################################################## @@ -9779,6 +10180,89 @@ def test_id_based_mfa_enrollment_serialization(self): assert id_based_mfa_enrollment_model_json2 == id_based_mfa_enrollment_model_json +class TestModel_IdentityPreferenceResponse: + """ + Test Class for IdentityPreferenceResponse + """ + + def test_identity_preference_response_serialization(self): + """ + Test serialization/deserialization for IdentityPreferenceResponse + """ + + # Construct a json representation of a IdentityPreferenceResponse model + identity_preference_response_model_json = {} + identity_preference_response_model_json['service'] = 'testString' + identity_preference_response_model_json['id'] = 'testString' + identity_preference_response_model_json['account_id'] = 'testString' + identity_preference_response_model_json['scope'] = 'testString' + identity_preference_response_model_json['value_string'] = 'testString' + identity_preference_response_model_json['value_list_of_strings'] = ['testString'] + + # Construct a model instance of IdentityPreferenceResponse by calling from_dict on the json representation + identity_preference_response_model = IdentityPreferenceResponse.from_dict( + identity_preference_response_model_json + ) + assert identity_preference_response_model != False + + # Construct a model instance of IdentityPreferenceResponse by calling from_dict on the json representation + identity_preference_response_model_dict = IdentityPreferenceResponse.from_dict( + identity_preference_response_model_json + ).__dict__ + identity_preference_response_model2 = IdentityPreferenceResponse(**identity_preference_response_model_dict) + + # Verify the model instances are equivalent + assert identity_preference_response_model == identity_preference_response_model2 + + # Convert model instance back to dict and verify no loss of data + identity_preference_response_model_json2 = identity_preference_response_model.to_dict() + assert identity_preference_response_model_json2 == identity_preference_response_model_json + + +class TestModel_IdentityPreferencesResponse: + """ + Test Class for IdentityPreferencesResponse + """ + + def test_identity_preferences_response_serialization(self): + """ + Test serialization/deserialization for IdentityPreferencesResponse + """ + + # Construct dict forms of any model objects needed in order to build this model. + + identity_preference_response_model = {} # IdentityPreferenceResponse + identity_preference_response_model['service'] = 'testString' + identity_preference_response_model['id'] = 'testString' + identity_preference_response_model['account_id'] = 'testString' + identity_preference_response_model['scope'] = 'testString' + identity_preference_response_model['value_string'] = 'testString' + identity_preference_response_model['value_list_of_strings'] = ['testString'] + + # Construct a json representation of a IdentityPreferencesResponse model + identity_preferences_response_model_json = {} + identity_preferences_response_model_json['preferences'] = [identity_preference_response_model] + + # Construct a model instance of IdentityPreferencesResponse by calling from_dict on the json representation + identity_preferences_response_model = IdentityPreferencesResponse.from_dict( + identity_preferences_response_model_json + ) + assert identity_preferences_response_model != False + + # Construct a model instance of IdentityPreferencesResponse by calling from_dict on the json representation + identity_preferences_response_model_dict = IdentityPreferencesResponse.from_dict( + identity_preferences_response_model_json + ).__dict__ + identity_preferences_response_model2 = IdentityPreferencesResponse(**identity_preferences_response_model_dict) + + # Verify the model instances are equivalent + assert identity_preferences_response_model == identity_preferences_response_model2 + + # Convert model instance back to dict and verify no loss of data + identity_preferences_response_model_json2 = identity_preferences_response_model.to_dict() + assert identity_preferences_response_model_json2 == identity_preferences_response_model_json + + class TestModel_MfaEnrollmentTypeStatus: """ Test Class for MfaEnrollmentTypeStatus