diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e696ea..d5681d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,28 @@ > As of v1.4.0, release candidates will be published in an effort to get new features out faster while still allowing > time for full QA testing before moving the release candidate to a full release. +## v2.2.2 [2025-07-25] + +__What's New:__ + +* None + +__Enhancements:__ + +* Added profile `sessionAttributes` to `context` when building `britive/kube/config`. + +__Bug Fixes:__ + +* Fixed issue with `console_fallback` when checking out a Resource profile with no console access. + +__Dependencies:__ + +* None + +__Other:__ + +* Dropped `_get_missing_env_properties` workaround. + ## v2.2.1 [2025-06-26] __What's New:__ diff --git a/src/pybritive/__init__.py b/src/pybritive/__init__.py index 36a511e..f1edb19 100644 --- a/src/pybritive/__init__.py +++ b/src/pybritive/__init__.py @@ -1 +1 @@ -__version__ = '2.2.1' +__version__ = '2.2.2' diff --git a/src/pybritive/britive_cli.py b/src/pybritive/britive_cli.py index dce1104..a96049b 100644 --- a/src/pybritive/britive_cli.py +++ b/src/pybritive/britive_cli.py @@ -465,26 +465,20 @@ def list_environments(self): data.append(row) self.print(data, ignore_silent=True) - # temporary fix till the new API is updated to return `profileEnvironmentProperties` - def _get_missing_env_properties( - self, app_id: str, app_type: str, env_id: str, profile_id: str, from_cache_command: bool - ) -> dict: - if app_type.lower() == 'kubernetes' and (from_cache_command or self.config.auto_refresh_kube_config()): - if not self.listed_profiles: - self.listed_profiles = self.b.my_access.list_profiles() - return next( - ( - env['profileEnvironmentProperties'] - for app in self.listed_profiles - if app['appContainerId'] == app_id - for profile in app.get('profiles', []) - if profile['profileId'] == profile_id - for env in profile.get('environments', []) - if env['environmentId'] == env_id - ), - {}, - ) - return {} + # temporary fix till the new API is updated to return `sessionAttributes` + def _get_missing_session_attributes(self, app_id: str, profile_id: str) -> dict: + if not self.listed_profiles: + self.listed_profiles = self.b.my_access.list_profiles() + return next( + ( + profile['sessionAttributes'] + for app in self.listed_profiles + if app['appContainerId'] == app_id + for profile in app.get('profiles', []) + if profile['profileId'] == profile_id + ), + [], + ) def _set_available_profiles(self, from_cache_command=False, profile_type: Optional[str] = None): if not self.available_profiles: @@ -509,23 +503,23 @@ def _set_available_profiles(self, from_cache_command=False, profile_type: Option env = envs[env_id] profile = profiles[profile_id] row = { - 'app_name': app['catalogAppDisplayName'], + '2_part_profile_format_allowed': app['requiresHierarchicalModel'], + 'app_description': app['appDescription'], 'app_id': app_id, + 'app_name': app['catalogAppDisplayName'], 'app_type': app['catalogAppName'], - 'app_description': app['appDescription'], - 'env_name': env['environmentName'], + 'env_description': env['environmentDescription'], 'env_id': env_id, + 'env_name': env['environmentName'], + 'env_properties': env['profileEnvironmentProperties'], 'env_short_name': env['alternateEnvironmentName'], - 'env_description': env['environmentDescription'], - 'profile_name': profile['papName'], - 'profile_id': profile_id, 'profile_allows_console': app.get('consoleAccess', False), 'profile_allows_programmatic': app.get('programmaticAccess', False), 'profile_description': profile['papDescription'], - '2_part_profile_format_allowed': app['requiresHierarchicalModel'], - 'env_properties': env['profileEnvironmentProperties'] - or self._get_missing_env_properties( - app_id, app['catalogAppName'], env_id, profile_id, from_cache_command + 'profile_id': profile_id, + 'profile_name': profile['papName'], + 'session_attributes': profile.get( + 'sessionAttributes', self._get_missing_session_attributes(app_id, profile_id) ), } if row not in access_output: @@ -539,21 +533,21 @@ def _set_available_profiles(self, from_cache_command=False, profile_type: Option profiles = profiles['data'] for item in profiles: row = { - 'app_name': None, + '2_part_profile_format_allowed': False, + 'app_description': None, 'app_id': None, + 'app_name': None, 'app_type': 'Resources', - 'app_description': None, - 'env_name': item['resourceName'], + 'env_description': None, 'env_id': item['resourceId'], + 'env_name': item['resourceName'], + 'env_properties': item.get('resourceLabels', {}), 'env_short_name': item['resourceName'], - 'env_description': None, - 'profile_name': item['profileName'], - 'profile_id': item['profileId'], 'profile_allows_console': False, 'profile_allows_programmatic': True, 'profile_description': None, - '2_part_profile_format_allowed': False, - 'env_properties': item.get('resourceLabels', {}), + 'profile_id': item['profileId'], + 'profile_name': item['profileName'], } data.append(row) self.available_profiles = data @@ -584,6 +578,7 @@ def construct_kube_config(self, from_cache_command=False): 'profile': p['profile_name'], 'url': url, 'cert': cert, + 'session_attributes': p['session_attributes'], } ) @@ -978,6 +973,7 @@ def checkout( if self._profile_is_for_resource(profile=profile, profile_type=profile_type): app_type = 'Resources' k8s_processor = None + console_fallback = False credentials = self._resource_checkout( blocktime=blocktime, justification=justification, diff --git a/src/pybritive/helpers/kube_config_builder.py b/src/pybritive/helpers/kube_config_builder.py index 30c4a0b..51710ee 100644 --- a/src/pybritive/helpers/kube_config_builder.py +++ b/src/pybritive/helpers/kube_config_builder.py @@ -69,7 +69,7 @@ def parse_profiles(profiles, aliases): cluster_names = {} assigned_aliases = [] for profile in profiles: - env_profile = f"{sanitize(profile['env'])}-{sanitize(profile['profile'].lower())}" + env_profile = f'{sanitize(profile["env"])}-{sanitize(profile["profile"].lower())}' if env_profile not in cluster_names: app = BritiveCli.escape_profile_element(profile['app']) env = BritiveCli.escape_profile_element(profile['env']) @@ -84,8 +84,9 @@ def parse_profiles(profiles, aliases): 'url': profile['url'], 'cert': profile['cert'], 'escaped_profile': escaped_profile_str, - 'profile': f"{profile['app']}/{profile['env']}/{profile['profile']}".lower(), + 'profile': f'{profile["app"]}/{profile["env"]}/{profile["profile"]}'.lower(), 'alias': alias, + 'session_attributes': profile['session_attributes'], } cluster_names[env_profile]['apps'].append(sanitize(profile['app'])) return [cluster_names, assigned_aliases] @@ -129,7 +130,6 @@ def build_tenant_config(tenant, cluster_names, username, cli: BritiveCli): ) contexts = [] clusters = [] - for env_profile, details in cluster_names.items(): if len(details['apps']) == 1: names = [env_profile] @@ -162,7 +162,11 @@ def build_tenant_config(tenant, cluster_names, username, cli: BritiveCli): contexts.append( { 'name': details.get('alias') or f'{tenant}-{name}', - 'context': {'cluster': f'{tenant}-{name}', 'user': username}, + 'context': { + 'cluster': f'{tenant}-{name}', + 'user': username, + **{attr['mappingName']: attr['attributeValue'] for attr in details['session_attributes']}, + }, } ) return [clusters, contexts, users]