Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:__
Expand Down
2 changes: 1 addition & 1 deletion src/pybritive/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '2.2.1'
__version__ = '2.2.2'
72 changes: 34 additions & 38 deletions src/pybritive/britive_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:
Expand All @@ -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
Expand Down Expand Up @@ -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'],
}
)

Expand Down Expand Up @@ -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,
Expand Down
12 changes: 8 additions & 4 deletions src/pybritive/helpers/kube_config_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'])
Expand All @@ -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]
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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]
Expand Down