From 416db8cfeeacb5b3381e9a3e5243f931ed94b5cf Mon Sep 17 00:00:00 2001 From: Marcelo Villa Date: Fri, 1 Nov 2024 10:55:13 +0100 Subject: [PATCH 01/12] Bump conda-store tag to 2024.10.1 --- src/_nebari/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_nebari/constants.py b/src/_nebari/constants.py index 6e57519fee..013764da6a 100644 --- a/src/_nebari/constants.py +++ b/src/_nebari/constants.py @@ -19,7 +19,7 @@ DEFAULT_NEBARI_IMAGE_TAG = CURRENT_RELEASE DEFAULT_NEBARI_WORKFLOW_CONTROLLER_IMAGE_TAG = CURRENT_RELEASE -DEFAULT_CONDA_STORE_IMAGE_TAG = "2024.3.1" +DEFAULT_CONDA_STORE_IMAGE_TAG = "2024.10.1" LATEST_SUPPORTED_PYTHON_VERSION = "3.10" From cf3bfcef6161a3909a66a4ba8329b73cd30b6115 Mon Sep 17 00:00:00 2001 From: Marcelo Villa Date: Thu, 7 Nov 2024 16:41:16 +0100 Subject: [PATCH 02/12] Update imports given conda-store refactor --- .../services/conda-store/config/conda_store_config.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py index ad9b79843a..b41f29d250 100644 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py +++ b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py @@ -10,7 +10,8 @@ from pathlib import Path import requests -from conda_store_server import api, orm, schema +from conda_store_server import api +from conda_store_server._internal import orm, schema from conda_store_server.server.auth import GenericOAuthAuthentication from conda_store_server.server.dependencies import get_conda_store from conda_store_server.storage import S3Storage From 93d4c11655cb5bb568b8b0990aadd938c7961dbc Mon Sep 17 00:00:00 2001 From: Marcelo Villa Date: Tue, 12 Nov 2024 14:26:33 +0100 Subject: [PATCH 03/12] Vendor conda-store schema --- .../conda-store/config/conda_store_config.py | 55 +++++++++++++------ 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py index b41f29d250..cc946de5cf 100644 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py +++ b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py @@ -1,20 +1,44 @@ import dataclasses +import datetime +import functools import json import logging import re import tempfile -import typing import urllib import urllib.parse import urllib.request from pathlib import Path +from typing import Dict, List, Optional, TypeAlias import requests from conda_store_server import api -from conda_store_server._internal import orm, schema from conda_store_server.server.auth import GenericOAuthAuthentication from conda_store_server.server.dependencies import get_conda_store from conda_store_server.storage import S3Storage +from pydantic import BaseModel, Field, constr + +# The following definitions (from line 24 to line 40) have been copied over +# from conda-store source code in order to avoid accessing a "private" schema +# that does not follow a backwards compatibility policy. +ALLOWED_CHARACTERS = "A-Za-z0-9-+_@$&?^~.=" +ARN_ALLOWED = f"^([{ALLOWED_CHARACTERS}*]+)/([{ALLOWED_CHARACTERS}*]+)$" + + +def _datetime_factory(offset: datetime.timedelta): + """utcnow datetime + timezone as string""" + return datetime.datetime.utcnow() + offset + + +RoleBindings: TypeAlias = Dict[constr(regex=ARN_ALLOWED), List[str]] + + +class AuthenticationToken(BaseModel): + exp: datetime.datetime = Field( + default_factory=functools.partial(_datetime_factory, datetime.timedelta(days=1)) + ) + primary_namespace: str = "default" + role_bindings: RoleBindings = {} def conda_store_config(path="/var/lib/conda-store/config.json"): @@ -111,9 +135,7 @@ def _validate_role(self, role): self.log.info(f"role: {role} is {'valid' if valid else 'invalid'}") return valid - def parse_role_and_namespace( - self, text - ) -> typing.Optional[CondaStoreNamespaceRole]: + def parse_role_and_namespace(self, text) -> Optional[CondaStoreNamespaceRole]: # The regex pattern pattern = r"^(\w+)!namespace=([^!]+)$" @@ -128,7 +150,7 @@ def parse_role_and_namespace( else: return None - def parse_scope(self) -> typing.List[CondaStoreNamespaceRole]: + def parse_scope(self) -> List[CondaStoreNamespaceRole]: """Parsed scopes from keycloak role's attribute and returns a list of role/namespace if scopes' syntax is valid otherwise return [] @@ -249,7 +271,7 @@ async def _apply_roles_from_keycloak(self, request, user_data): ) def _filter_duplicate_namespace_roles_with_max_permissions( - self, namespace_roles: typing.List[CondaStoreNamespaceRole] + self, namespace_roles: List[CondaStoreNamespaceRole] ): """Filter duplicate roles in keycloak such that to apply only the one with the highest permissions. @@ -260,7 +282,7 @@ def _filter_duplicate_namespace_roles_with_max_permissions( We need to apply only the role 2 as that one has higher permissions. """ self.log.info("Filtering duplicate roles for same namespace") - namespace_role_mapping: typing.Dict[str:CondaStoreNamespaceRole] = {} + namespace_role_mapping: Dict[str:CondaStoreNamespaceRole] = {} for namespace_role in namespace_roles: namespace = namespace_role.namespace new_role = namespace_role.role @@ -283,7 +305,7 @@ def _filter_duplicate_namespace_roles_with_max_permissions( def _get_permissions_from_keycloak_role( self, keycloak_role - ) -> typing.List[CondaStoreNamespaceRole]: + ) -> List[CondaStoreNamespaceRole]: self.log.info(f"Getting permissions from keycloak role: {keycloak_role}") role_attributes = keycloak_role["attributes"] # scopes returns a list with a value say ["viewer!namespace=pycon,developer!namespace=scipy"] @@ -297,14 +319,14 @@ async def _apply_conda_store_roles_from_keycloak( self.log.info( f"Apply conda store roles from keycloak roles: {conda_store_client_roles}, user: {username}" ) - role_permissions: typing.List[CondaStoreNamespaceRole] = [] + role_permissions: List[CondaStoreNamespaceRole] = [] for conda_store_client_role in conda_store_client_roles: role_permissions += self._get_permissions_from_keycloak_role( conda_store_client_role ) self.log.info("Filtering duplicate namespace role for max permissions") - filtered_namespace_role: typing.List[CondaStoreNamespaceRole] = ( + filtered_namespace_role: List[CondaStoreNamespaceRole] = ( self._filter_duplicate_namespace_roles_with_max_permissions( role_permissions ) @@ -357,9 +379,7 @@ def _get_conda_store_client_roles_for_user( return client_roles_rich def _get_current_entity_bindings(self, username): - entity = schema.AuthenticationToken( - primary_namespace=username, role_bindings={} - ) + entity = AuthenticationToken(primary_namespace=username, role_bindings={}) self.log.info(f"entity: {entity}") entity_bindings = self.authorization.get_entity_bindings(entity) self.log.info(f"current entity_bindings: {entity_bindings}") @@ -387,7 +407,7 @@ async def authenticate(self, request): # superadmin gets access to everything if "conda_store_superadmin" in user_data.get("roles", []): - return schema.AuthenticationToken( + return AuthenticationToken( primary_namespace=username, role_bindings={"*/*": {"admin"}}, ) @@ -423,10 +443,9 @@ async def authenticate(self, request): for namespace in namespaces: _namespace = api.get_namespace(db, name=namespace) if _namespace is None: - db.add(orm.Namespace(name=namespace)) - db.commit() + api.create_namespace(db, name=namespace) - return schema.AuthenticationToken( + return AuthenticationToken( primary_namespace=username, role_bindings=role_bindings, ) From 05d80a27a0a2f60b4c4de16dff21c9ab8ef1fa23 Mon Sep 17 00:00:00 2001 From: Marcelo Villa Date: Tue, 12 Nov 2024 18:31:26 +0100 Subject: [PATCH 04/12] Revert vendoring conda-store schema --- .../conda-store/config/conda_store_config.py | 55 ++++++------------- 1 file changed, 18 insertions(+), 37 deletions(-) diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py index cc946de5cf..b41f29d250 100644 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py +++ b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py @@ -1,44 +1,20 @@ import dataclasses -import datetime -import functools import json import logging import re import tempfile +import typing import urllib import urllib.parse import urllib.request from pathlib import Path -from typing import Dict, List, Optional, TypeAlias import requests from conda_store_server import api +from conda_store_server._internal import orm, schema from conda_store_server.server.auth import GenericOAuthAuthentication from conda_store_server.server.dependencies import get_conda_store from conda_store_server.storage import S3Storage -from pydantic import BaseModel, Field, constr - -# The following definitions (from line 24 to line 40) have been copied over -# from conda-store source code in order to avoid accessing a "private" schema -# that does not follow a backwards compatibility policy. -ALLOWED_CHARACTERS = "A-Za-z0-9-+_@$&?^~.=" -ARN_ALLOWED = f"^([{ALLOWED_CHARACTERS}*]+)/([{ALLOWED_CHARACTERS}*]+)$" - - -def _datetime_factory(offset: datetime.timedelta): - """utcnow datetime + timezone as string""" - return datetime.datetime.utcnow() + offset - - -RoleBindings: TypeAlias = Dict[constr(regex=ARN_ALLOWED), List[str]] - - -class AuthenticationToken(BaseModel): - exp: datetime.datetime = Field( - default_factory=functools.partial(_datetime_factory, datetime.timedelta(days=1)) - ) - primary_namespace: str = "default" - role_bindings: RoleBindings = {} def conda_store_config(path="/var/lib/conda-store/config.json"): @@ -135,7 +111,9 @@ def _validate_role(self, role): self.log.info(f"role: {role} is {'valid' if valid else 'invalid'}") return valid - def parse_role_and_namespace(self, text) -> Optional[CondaStoreNamespaceRole]: + def parse_role_and_namespace( + self, text + ) -> typing.Optional[CondaStoreNamespaceRole]: # The regex pattern pattern = r"^(\w+)!namespace=([^!]+)$" @@ -150,7 +128,7 @@ def parse_role_and_namespace(self, text) -> Optional[CondaStoreNamespaceRole]: else: return None - def parse_scope(self) -> List[CondaStoreNamespaceRole]: + def parse_scope(self) -> typing.List[CondaStoreNamespaceRole]: """Parsed scopes from keycloak role's attribute and returns a list of role/namespace if scopes' syntax is valid otherwise return [] @@ -271,7 +249,7 @@ async def _apply_roles_from_keycloak(self, request, user_data): ) def _filter_duplicate_namespace_roles_with_max_permissions( - self, namespace_roles: List[CondaStoreNamespaceRole] + self, namespace_roles: typing.List[CondaStoreNamespaceRole] ): """Filter duplicate roles in keycloak such that to apply only the one with the highest permissions. @@ -282,7 +260,7 @@ def _filter_duplicate_namespace_roles_with_max_permissions( We need to apply only the role 2 as that one has higher permissions. """ self.log.info("Filtering duplicate roles for same namespace") - namespace_role_mapping: Dict[str:CondaStoreNamespaceRole] = {} + namespace_role_mapping: typing.Dict[str:CondaStoreNamespaceRole] = {} for namespace_role in namespace_roles: namespace = namespace_role.namespace new_role = namespace_role.role @@ -305,7 +283,7 @@ def _filter_duplicate_namespace_roles_with_max_permissions( def _get_permissions_from_keycloak_role( self, keycloak_role - ) -> List[CondaStoreNamespaceRole]: + ) -> typing.List[CondaStoreNamespaceRole]: self.log.info(f"Getting permissions from keycloak role: {keycloak_role}") role_attributes = keycloak_role["attributes"] # scopes returns a list with a value say ["viewer!namespace=pycon,developer!namespace=scipy"] @@ -319,14 +297,14 @@ async def _apply_conda_store_roles_from_keycloak( self.log.info( f"Apply conda store roles from keycloak roles: {conda_store_client_roles}, user: {username}" ) - role_permissions: List[CondaStoreNamespaceRole] = [] + role_permissions: typing.List[CondaStoreNamespaceRole] = [] for conda_store_client_role in conda_store_client_roles: role_permissions += self._get_permissions_from_keycloak_role( conda_store_client_role ) self.log.info("Filtering duplicate namespace role for max permissions") - filtered_namespace_role: List[CondaStoreNamespaceRole] = ( + filtered_namespace_role: typing.List[CondaStoreNamespaceRole] = ( self._filter_duplicate_namespace_roles_with_max_permissions( role_permissions ) @@ -379,7 +357,9 @@ def _get_conda_store_client_roles_for_user( return client_roles_rich def _get_current_entity_bindings(self, username): - entity = AuthenticationToken(primary_namespace=username, role_bindings={}) + entity = schema.AuthenticationToken( + primary_namespace=username, role_bindings={} + ) self.log.info(f"entity: {entity}") entity_bindings = self.authorization.get_entity_bindings(entity) self.log.info(f"current entity_bindings: {entity_bindings}") @@ -407,7 +387,7 @@ async def authenticate(self, request): # superadmin gets access to everything if "conda_store_superadmin" in user_data.get("roles", []): - return AuthenticationToken( + return schema.AuthenticationToken( primary_namespace=username, role_bindings={"*/*": {"admin"}}, ) @@ -443,9 +423,10 @@ async def authenticate(self, request): for namespace in namespaces: _namespace = api.get_namespace(db, name=namespace) if _namespace is None: - api.create_namespace(db, name=namespace) + db.add(orm.Namespace(name=namespace)) + db.commit() - return AuthenticationToken( + return schema.AuthenticationToken( primary_namespace=username, role_bindings=role_bindings, ) From a4e331ad724959238c95782d79a12086dde5e908 Mon Sep 17 00:00:00 2001 From: Marcelo Villa Date: Tue, 12 Nov 2024 18:51:03 +0100 Subject: [PATCH 05/12] Replace orm call with api call --- .../services/conda-store/config/conda_store_config.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py index b41f29d250..fe97514374 100644 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py +++ b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py @@ -11,7 +11,7 @@ import requests from conda_store_server import api -from conda_store_server._internal import orm, schema +from conda_store_server._internal import schema from conda_store_server.server.auth import GenericOAuthAuthentication from conda_store_server.server.dependencies import get_conda_store from conda_store_server.storage import S3Storage @@ -423,8 +423,7 @@ async def authenticate(self, request): for namespace in namespaces: _namespace = api.get_namespace(db, name=namespace) if _namespace is None: - db.add(orm.Namespace(name=namespace)) - db.commit() + api.create_namespace(db, name=namespace) return schema.AuthenticationToken( primary_namespace=username, From 887a3f3e3bfdf5c544a023168c6da12bb1ffc89b Mon Sep 17 00:00:00 2001 From: Marcelo Villa Date: Tue, 17 Dec 2024 11:18:23 -0500 Subject: [PATCH 06/12] Upgrade conda-store to 2024.11.2 --- src/_nebari/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_nebari/constants.py b/src/_nebari/constants.py index b5a17c878d..f30da0f870 100644 --- a/src/_nebari/constants.py +++ b/src/_nebari/constants.py @@ -16,7 +16,7 @@ DEFAULT_NEBARI_IMAGE_TAG = CURRENT_RELEASE DEFAULT_NEBARI_WORKFLOW_CONTROLLER_IMAGE_TAG = CURRENT_RELEASE -DEFAULT_CONDA_STORE_IMAGE_TAG = "2024.10.1" +DEFAULT_CONDA_STORE_IMAGE_TAG = "2024.11.2" LATEST_SUPPORTED_PYTHON_VERSION = "3.10" From 195789d4673dd09dd90f7b26ce203ebde66f3660 Mon Sep 17 00:00:00 2001 From: Marcelo Villa Date: Tue, 17 Dec 2024 11:44:04 -0500 Subject: [PATCH 07/12] Update get_conda_store import --- .../services/conda-store/config/conda_store_config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py index fe97514374..0c1ed45004 100644 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py +++ b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py @@ -12,8 +12,8 @@ import requests from conda_store_server import api from conda_store_server._internal import schema +from conda_store_server._internal.server.dependencies import get_conda_store from conda_store_server.server.auth import GenericOAuthAuthentication -from conda_store_server.server.dependencies import get_conda_store from conda_store_server.storage import S3Storage From 903808885fe1e2d0f176074ab103025a48de1189 Mon Sep 17 00:00:00 2001 From: Marcelo Villa Date: Tue, 17 Dec 2024 17:08:51 -0500 Subject: [PATCH 08/12] Add explicit db.commit --- .../kubernetes/services/conda-store/config/conda_store_config.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py index 0c1ed45004..3e33fe40ea 100644 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py +++ b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py @@ -424,6 +424,7 @@ async def authenticate(self, request): _namespace = api.get_namespace(db, name=namespace) if _namespace is None: api.create_namespace(db, name=namespace) + db.commit() return schema.AuthenticationToken( primary_namespace=username, From 67e739aa0356494490fffbfd78c85a504f7ca7f8 Mon Sep 17 00:00:00 2001 From: Marcelo Villa Date: Tue, 7 Jan 2025 18:53:52 +0100 Subject: [PATCH 09/12] Use ensure_namespace function to create new namespace --- .../services/conda-store/config/conda_store_config.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py index 3e33fe40ea..f14c352973 100644 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py +++ b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/conda-store/config/conda_store_config.py @@ -423,8 +423,7 @@ async def authenticate(self, request): for namespace in namespaces: _namespace = api.get_namespace(db, name=namespace) if _namespace is None: - api.create_namespace(db, name=namespace) - db.commit() + api.ensure_namespace(db, name=namespace) return schema.AuthenticationToken( primary_namespace=username, From 6ef8cff1787083cc21922b28c7041f9546c829f0 Mon Sep 17 00:00:00 2001 From: Chuck McAndrew <6248903+dcmcand@users.noreply.github.com> Date: Fri, 10 Jan 2025 00:42:58 +0100 Subject: [PATCH 10/12] add authorized ip range variable for azure (#2880) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- src/_nebari/stages/infrastructure/__init__.py | 3 +++ src/_nebari/stages/infrastructure/template/azure/main.tf | 1 + .../template/azure/modules/kubernetes/main.tf | 3 +++ .../template/azure/modules/kubernetes/variables.tf | 6 ++++++ .../stages/infrastructure/template/azure/variables.tf | 6 ++++++ 5 files changed, 19 insertions(+) diff --git a/src/_nebari/stages/infrastructure/__init__.py b/src/_nebari/stages/infrastructure/__init__.py index 067161f6a4..0c5a60a06c 100644 --- a/src/_nebari/stages/infrastructure/__init__.py +++ b/src/_nebari/stages/infrastructure/__init__.py @@ -95,6 +95,7 @@ class AzureInputVars(schema.Base): name: str environment: str region: str + authorized_ip_ranges: List[str] = ["0.0.0.0/0"] kubeconfig_filename: str = get_kubeconfig_filename() kubernetes_version: str node_groups: Dict[str, AzureNodeGroupInputVars] @@ -362,6 +363,7 @@ class AzureProvider(schema.Base): region: str kubernetes_version: Optional[str] = None storage_account_postfix: str + authorized_ip_ranges: Optional[List[str]] = ["0.0.0.0/0"] resource_group_name: Optional[str] = None node_groups: Dict[str, AzureNodeGroup] = DEFAULT_AZURE_NODE_GROUPS storage_account_postfix: str @@ -799,6 +801,7 @@ def input_vars(self, stage_outputs: Dict[str, Dict[str, Any]]): environment=self.config.namespace, region=self.config.azure.region, kubernetes_version=self.config.azure.kubernetes_version, + authorized_ip_ranges=self.config.azure.authorized_ip_ranges, node_groups={ name: AzureNodeGroupInputVars( instance=node_group.instance, diff --git a/src/_nebari/stages/infrastructure/template/azure/main.tf b/src/_nebari/stages/infrastructure/template/azure/main.tf index 594a6a4aa2..960b755f8c 100644 --- a/src/_nebari/stages/infrastructure/template/azure/main.tf +++ b/src/_nebari/stages/infrastructure/template/azure/main.tf @@ -28,6 +28,7 @@ module "kubernetes" { kubernetes_version = var.kubernetes_version tags = var.tags max_pods = var.max_pods + authorized_ip_ranges = var.authorized_ip_ranges network_profile = var.network_profile diff --git a/src/_nebari/stages/infrastructure/template/azure/modules/kubernetes/main.tf b/src/_nebari/stages/infrastructure/template/azure/modules/kubernetes/main.tf index 66b46e13eb..f97f1f6383 100644 --- a/src/_nebari/stages/infrastructure/template/azure/modules/kubernetes/main.tf +++ b/src/_nebari/stages/infrastructure/template/azure/modules/kubernetes/main.tf @@ -4,6 +4,9 @@ resource "azurerm_kubernetes_cluster" "main" { location = var.location resource_group_name = var.resource_group_name tags = var.tags + api_server_access_profile { + authorized_ip_ranges = var.authorized_ip_ranges + } # To enable Azure AD Workload Identity oidc_issuer_enabled must be set to true. oidc_issuer_enabled = var.workload_identity_enabled diff --git a/src/_nebari/stages/infrastructure/template/azure/modules/kubernetes/variables.tf b/src/_nebari/stages/infrastructure/template/azure/modules/kubernetes/variables.tf index 355b284ba0..95d2045420 100644 --- a/src/_nebari/stages/infrastructure/template/azure/modules/kubernetes/variables.tf +++ b/src/_nebari/stages/infrastructure/template/azure/modules/kubernetes/variables.tf @@ -77,6 +77,12 @@ variable "workload_identity_enabled" { default = false } +variable "authorized_ip_ranges" { + description = "The ip range allowed to access the Kubernetes API server, defaults to 0.0.0.0/0" + type = list(string) + default = ["0.0.0.0/0"] +} + variable "azure_policy_enabled" { description = "Enable Azure Policy" type = bool diff --git a/src/_nebari/stages/infrastructure/template/azure/variables.tf b/src/_nebari/stages/infrastructure/template/azure/variables.tf index 657435c7da..ac36f42fd6 100644 --- a/src/_nebari/stages/infrastructure/template/azure/variables.tf +++ b/src/_nebari/stages/infrastructure/template/azure/variables.tf @@ -83,6 +83,12 @@ variable "workload_identity_enabled" { default = false } +variable "authorized_ip_ranges" { + description = "The ip range allowed to access the Kubernetes API server, defaults to 0.0.0.0/0" + type = list(string) + default = ["0.0.0.0/0"] +} + variable "azure_policy_enabled" { description = "Enable Azure Policy" type = bool From ed494e0a3aa4150147640d328ffa9be6281bc2cd Mon Sep 17 00:00:00 2001 From: vinicius douglas cerutti Date: Thu, 9 Jan 2025 20:57:28 -0300 Subject: [PATCH 11/12] handle default value for azure addon policy --- src/_nebari/stages/infrastructure/__init__.py | 3 ++- src/_nebari/stages/infrastructure/template/azure/variables.tf | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/_nebari/stages/infrastructure/__init__.py b/src/_nebari/stages/infrastructure/__init__.py index 0c5a60a06c..553e520e3a 100644 --- a/src/_nebari/stages/infrastructure/__init__.py +++ b/src/_nebari/stages/infrastructure/__init__.py @@ -106,7 +106,7 @@ class AzureInputVars(schema.Base): tags: Dict[str, str] = {} max_pods: Optional[int] = None network_profile: Optional[Dict[str, str]] = None - azure_policy_enabled: bool = None + azure_policy_enabled: Optional[bool] = None workload_identity_enabled: bool = False @@ -374,6 +374,7 @@ class AzureProvider(schema.Base): network_profile: Optional[Dict[str, str]] = None max_pods: Optional[int] = None workload_identity_enabled: bool = False + azure_policy_enabled: Optional[bool] = None @model_validator(mode="before") @classmethod diff --git a/src/_nebari/stages/infrastructure/template/azure/variables.tf b/src/_nebari/stages/infrastructure/template/azure/variables.tf index ac36f42fd6..44ef90463f 100644 --- a/src/_nebari/stages/infrastructure/template/azure/variables.tf +++ b/src/_nebari/stages/infrastructure/template/azure/variables.tf @@ -92,4 +92,5 @@ variable "authorized_ip_ranges" { variable "azure_policy_enabled" { description = "Enable Azure Policy" type = bool + default = false } From 22de521bfa9bd7cd4662b92b4a7ac81cef04f215 Mon Sep 17 00:00:00 2001 From: sophia Date: Tue, 14 Jan 2025 10:25:35 -0800 Subject: [PATCH 12/12] Update conda-store-ui tests for updated page verbage --- tests/common/handlers.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/common/handlers.py b/tests/common/handlers.py index 51964d3ac5..761a6efd88 100644 --- a/tests/common/handlers.py +++ b/tests/common/handlers.py @@ -298,7 +298,9 @@ def _open_conda_store_service(self): def _open_new_environment_tab(self): self.page.get_by_label("Create a new environment in").click() - expect(self.page.get_by_text("Create Environment")).to_be_visible() + expect( + self.page.get_by_role("button", name="Create", exact=True) + ).to_be_visible() def _assert_user_namespace(self): expect(