Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workload identity #2460

Merged
merged 151 commits into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from 147 commits
Commits
Show all changes
151 commits
Select commit Hold shift + click to select a range
14125a3
upgrade pydantic
fangchenli Aug 22, 2023
48f26ba
run bump-pydantic
fangchenli Aug 23, 2023
b57c75f
uncomment Werror
fangchenli Aug 23, 2023
250be86
Merge branch 'develop' into pydantic-v2
fangchenli Aug 23, 2023
7912e37
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Aug 23, 2023
4eb1e08
Merge branch 'develop' into pydantic-v2
fangchenli Aug 23, 2023
553d021
update dependency in pyproject
fangchenli Aug 23, 2023
9febc8a
Merge branch 'develop' into pydantic-v2
fangchenli Aug 23, 2023
8e33010
Merge remote-tracking branch 'upstream/develop' into pydantic-v2
fangchenli Aug 23, 2023
99cb520
Merge remote-tracking branch 'origin/pydantic-v2' into pydantic-v2
fangchenli Aug 23, 2023
8fb92ff
fix typo
fangchenli Aug 23, 2023
0967d52
fix cpu_guarantee type
fangchenli Aug 23, 2023
1692797
fix typo
fangchenli Aug 23, 2023
bd76c4d
Merge branch 'develop' into pydantic-v2
fangchenli Aug 24, 2023
708d165
Merge remote-tracking branch 'upstream/develop' into pydantic-v2
fangchenli Aug 24, 2023
2f99cac
Merge remote-tracking branch 'origin/pydantic-v2' into pydantic-v2
fangchenli Aug 24, 2023
82ec511
fix more validation errors
fangchenli Aug 24, 2023
aba88ec
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Aug 24, 2023
3e645b4
fix more validator errors
fangchenli Aug 24, 2023
ff0682e
Merge remote-tracking branch 'origin/pydantic-v2' into pydantic-v2
fangchenli Aug 24, 2023
eaab189
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Aug 24, 2023
fb90cc6
Merge remote-tracking branch 'upstream/develop' into pydantic-v2
fangchenli Aug 24, 2023
b085e49
resolve conflict
fangchenli Aug 24, 2023
e520dcc
resolve conflict
fangchenli Aug 24, 2023
91fb5b4
resolve conflict
fangchenli Aug 24, 2023
5d0fca4
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Aug 24, 2023
2935c1f
fix monkeypatch
fangchenli Aug 25, 2023
961a278
revert printout
fangchenli Aug 25, 2023
f725534
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Aug 25, 2023
c543bdd
fix validation error
fangchenli Aug 25, 2023
6b98638
set none
fangchenli Aug 25, 2023
2f3bbae
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Aug 25, 2023
ef8dfb4
revert change
fangchenli Aug 26, 2023
a9d8d71
Merge branch 'develop' into pydantic-v2
fangchenli Aug 29, 2023
e920e5b
rebase
fangchenli Aug 29, 2023
19af132
fix cli error test
fangchenli Aug 29, 2023
819abe9
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Aug 29, 2023
d0c07e8
Merge branch 'develop' into pydantic-v2
fangchenli Aug 30, 2023
f3c518e
Merge remote-tracking branch 'upstream/develop' into pydantic-v2
fangchenli Aug 30, 2023
bfba588
Merge remote-tracking branch 'origin/pydantic-v2' into pydantic-v2
fangchenli Aug 30, 2023
70a5803
Merge branch 'develop' into pydantic-v2
fangchenli Sep 5, 2023
afaf06a
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Sep 5, 2023
f6c8468
Merge branch 'develop' into pydantic-v2
fangchenli Sep 11, 2023
eb5afa7
resolve conflict
fangchenli Sep 11, 2023
292087a
resolve conflict
fangchenli Sep 11, 2023
ec2417c
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Sep 11, 2023
f4aeef2
Merge branch 'develop' into pydantic-v2
fangchenli Sep 11, 2023
41699ea
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Sep 11, 2023
27ca9ff
Merge branch 'develop' into pydantic-v2
fangchenli Sep 11, 2023
70c8f6c
Merge branch 'develop' into pydantic-v2
fangchenli Sep 24, 2023
7b695f0
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Sep 24, 2023
dbf5157
resolve conflict
fangchenli Sep 25, 2023
ac0b6ae
resolve conflict
fangchenli Sep 25, 2023
a770d2a
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Sep 25, 2023
5e57a3a
change varible name
fangchenli Sep 25, 2023
7481469
refactor model validation
fangchenli Sep 25, 2023
bc3f5f6
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Sep 25, 2023
4ff3236
Merge branch 'develop' into pydantic-v2
fangchenli Oct 9, 2023
22bef83
Merge branch 'develop' into pydantic-v2
fangchenli Oct 27, 2023
e41f3a7
resolve conflict, uddate pydantic
fangchenli Oct 29, 2023
2d0ee62
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Oct 29, 2023
7d42def
resolve conflict
fangchenli Oct 29, 2023
2f6cb7f
update
fangchenli Oct 30, 2023
bd50f0b
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Oct 30, 2023
a30760a
revert comment
fangchenli Oct 30, 2023
ba53843
update
fangchenli Nov 2, 2023
6532f6a
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Nov 2, 2023
8949cfe
update
fangchenli Nov 4, 2023
64d5943
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Nov 4, 2023
6c166cd
fix name
fangchenli Nov 4, 2023
acc7ebd
revert change
fangchenli Nov 4, 2023
4dfd46c
debug
fangchenli Nov 4, 2023
f3775d7
Merge remote-tracking branch 'upstream/develop' into pydantic-v2
fangchenli Nov 4, 2023
842de7b
update
fangchenli Nov 5, 2023
e4b458c
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Nov 5, 2023
a443deb
Merge branch 'develop' into pydantic-v2
fangchenli Nov 8, 2023
69ea483
resolve conflict
fangchenli Nov 8, 2023
bc79fd6
unskip test
fangchenli Nov 8, 2023
2da0b89
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Nov 8, 2023
ed1329d
uncomment
fangchenli Nov 9, 2023
9f648c0
Merge remote-tracking branch 'origin/pydantic-v2' into pydantic-v2
fangchenli Nov 9, 2023
8236673
remove fixture typing
fangchenli Nov 9, 2023
ae7d918
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Nov 9, 2023
b141ff3
resolve confilct
fangchenli Nov 9, 2023
deada6e
Merge remote-tracking branch 'origin/pydantic-v2' into pydantic-v2
fangchenli Nov 9, 2023
b3b5268
avoid import typing
fangchenli Nov 9, 2023
3831b51
use fixture for cli
fangchenli Nov 9, 2023
b77a59a
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Nov 9, 2023
f14529a
debug conda build
fangchenli Nov 9, 2023
3e46486
Merge remote-tracking branch 'upstream/develop' into pydantic-v2
fangchenli Nov 11, 2023
33fde03
fix typing import in init
fangchenli Nov 11, 2023
ec07870
Merge remote-tracking branch 'upstream/develop' into pydantic-v2
fangchenli Nov 13, 2023
5c50185
refactor env variable check
fangchenli Nov 13, 2023
47b86eb
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Nov 13, 2023
5cef9ce
Merge branch 'develop' into pydantic-v2
fangchenli Dec 26, 2023
7c5b5cc
Merge branch 'develop' into pydantic-v2
aktech Feb 14, 2024
d74d69d
render all config before writing
Adam-D-Lewis Mar 6, 2024
44c9f71
update
Adam-D-Lewis Mar 6, 2024
12f5288
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Mar 6, 2024
88d8bc4
split certs into different pydantic models
Adam-D-Lewis Mar 7, 2024
bbdf6f2
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Mar 7, 2024
b2891d1
allow each InputSchema to exclude certain parts of itself from the co…
Adam-D-Lewis Mar 9, 2024
0e4d7fd
allow each InputSchema to exclude certain parts of itself from the co…
Adam-D-Lewis Mar 9, 2024
845becb
import future annotations
Adam-D-Lewis Mar 11, 2024
b01446e
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Mar 11, 2024
0df2e64
switch typing annotation to fix tests
Adam-D-Lewis Mar 11, 2024
33f4712
switch typing annotation to fix tests
Adam-D-Lewis Mar 11, 2024
4a80f23
Merge branch 'develop' into explicit_config
viniciusdc Mar 11, 2024
4d824be
fix tests
Adam-D-Lewis Mar 12, 2024
6e330e5
[pre-commit.ci] Apply automatic pre-commit fixes
pre-commit-ci[bot] Mar 12, 2024
88b46a8
Merge branch 'develop' into pydantic2
Adam-D-Lewis Mar 19, 2024
924659d
merge develop
Adam-D-Lewis Mar 19, 2024
75d8e70
small fixes
Adam-D-Lewis Mar 19, 2024
a8bab5c
Merge branch 'develop' into pydantic2
Adam-D-Lewis Mar 27, 2024
35252ef
fix arg of classmethod
Adam-D-Lewis Mar 29, 2024
436dab7
fix req'd vars
Adam-D-Lewis Mar 29, 2024
283150f
fix availability zones
Adam-D-Lewis Mar 29, 2024
b2dbbd9
undo signature change
Adam-D-Lewis Mar 29, 2024
082cc41
fix fn call
Adam-D-Lewis Mar 29, 2024
3d6726f
remove unused var in fn signature
Adam-D-Lewis Mar 29, 2024
7e5891f
update cpu_limit dtype
Adam-D-Lewis Apr 1, 2024
32ee7ba
update cpu_limit dtype
Adam-D-Lewis Apr 1, 2024
e1030d8
revert test changes unrelated to pydantic v2
Adam-D-Lewis Apr 3, 2024
850de95
update for pydantic2
Adam-D-Lewis Apr 3, 2024
6b2b629
fix tests
Adam-D-Lewis Apr 3, 2024
473a1ee
Merge branch 'develop' into pydantic2
Adam-D-Lewis Apr 4, 2024
9d9fd49
replace .dict( with .model_dump(
Adam-D-Lewis Apr 4, 2024
c4b8c6e
Merge branch 'develop' into pydantic2
Adam-D-Lewis Apr 4, 2024
89e73aa
Merge branch 'develop' into pydantic2
Adam-D-Lewis Apr 10, 2024
680ce25
merge with pydantic2
Adam-D-Lewis Apr 11, 2024
c8feabc
reverse base class order
Adam-D-Lewis Apr 15, 2024
52b4ea8
merge with develop
Adam-D-Lewis Apr 15, 2024
2b38f46
make fields optional
Adam-D-Lewis Apr 15, 2024
a46cf1d
add default values
Adam-D-Lewis Apr 15, 2024
d4f301d
merge develop
Adam-D-Lewis May 6, 2024
8881d7c
merge develop
Adam-D-Lewis May 6, 2024
b88aa1b
remove validate default
Adam-D-Lewis May 6, 2024
992ae28
make verbose not the default
Adam-D-Lewis May 6, 2024
e904428
fix tests
Adam-D-Lewis May 6, 2024
261f43a
add workload identity
Adam-D-Lewis May 8, 2024
e48e3a4
add oidc-url outputs
Adam-D-Lewis May 8, 2024
e7faa3a
add needed env var
Adam-D-Lewis May 8, 2024
a0ab2a4
remove redundant comment
Adam-D-Lewis May 8, 2024
0e41fca
Merge branch 'explicit_config' into workload_identity
Adam-D-Lewis May 10, 2024
91f9e00
output main resource group name
Adam-D-Lewis May 13, 2024
92a27f7
add forward auth service and middleware as outputs
Adam-D-Lewis May 16, 2024
240b6dc
Merge branch 'develop' into workload_identity
Adam-D-Lewis May 17, 2024
f172e8b
revert commits from explicit schema branch
Adam-D-Lewis May 17, 2024
cbb82e0
revert commits from explicit schema branch
Adam-D-Lewis May 17, 2024
dc84aac
add missing outputs file
Adam-D-Lewis May 17, 2024
47b40ab
update forwardauth middleware for extensions and dask gateway
Adam-D-Lewis May 20, 2024
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
18 changes: 10 additions & 8 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -136,21 +136,23 @@ module = [
ignore_missing_imports = true

[tool.ruff]
extend-exclude = [
"src/_nebari/template",
"home",
"__pycache__"
]

[tool.ruff.lint]
select = [
"E",
"F",
"PTH",
"E", # E: pycodestyle rules
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

flyby: add helpful comments

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also select and ignore had to be moved to [tool.ruff.lint]. I was getting a warning saying the old location was deprectaed.

"F", # F: pyflakes rules
"PTH", # PTH: flake8-use-pathlib rules
]
ignore = [
"E501", # Line too long
"F821", # Undefined name
"PTH123", # open() should be replaced by Path.open()
]
extend-exclude = [
"src/_nebari/template",
"home",
"__pycache__"
]

[tool.coverage.run]
branch = true
Expand Down
3 changes: 2 additions & 1 deletion src/_nebari/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ def write_configuration(
"""Write the nebari configuration file to disk"""
with config_filename.open(mode) as f:
if isinstance(config, pydantic.BaseModel):
Adam-D-Lewis marked this conversation as resolved.
Show resolved Hide resolved
yaml.dump(config.model_dump(), f)
config_dict = config.write_config()
yaml.dump(config_dict, f)
else:
config = dump_nested_model(config)
yaml.dump(config, f)
Expand Down
5 changes: 2 additions & 3 deletions src/_nebari/initialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
DEFAULT_GCP_NODE_GROUPS,
node_groups_to_dict,
)
from _nebari.stages.kubernetes_ingress import CertificateEnum
from _nebari.stages.kubernetes_ingress import LetsEncryptCertificate
from _nebari.stages.kubernetes_keycloak import AuthenticationEnum
from _nebari.stages.terraform_state import TerraformStateEnum
from _nebari.utils import get_latest_kubernetes_version, random_secure_string
Expand Down Expand Up @@ -194,8 +194,7 @@ def render_config(
config["theme"]["jupyterhub"]["hub_subtitle"] = WELCOME_HEADER_TEXT

if ssl_cert_email:
config["certificate"] = {"type": CertificateEnum.letsencrypt.value}
Adam-D-Lewis marked this conversation as resolved.
Show resolved Hide resolved
config["certificate"]["acme_email"] = ssl_cert_email
config["certificate"] = LetsEncryptCertificate(acme_email=ssl_cert_email)

# validate configuration and convert to model
from nebari.plugins import nebari_plugin_manager
Expand Down
4 changes: 2 additions & 2 deletions src/_nebari/keycloak.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import requests
import rich
Adam-D-Lewis marked this conversation as resolved.
Show resolved Hide resolved

from _nebari.stages.kubernetes_ingress import CertificateEnum
from _nebari.stages.kubernetes_ingress import SelfSignedCertificate
from nebari import schema

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -91,7 +91,7 @@ def get_keycloak_admin_from_config(config: schema.Main):
"KEYCLOAK_ADMIN_PASSWORD", config.security.keycloak.initial_root_password
)

should_verify_tls = config.certificate.type != CertificateEnum.selfsigned
should_verify_tls = not isinstance(config.certificate, SelfSignedCertificate)

try:
keycloak_admin = keycloak.KeycloakAdmin(
Expand Down
10 changes: 10 additions & 0 deletions src/_nebari/stages/infrastructure/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ class AzureInputVars(schema.Base):
tags: Dict[str, str] = {}
max_pods: Optional[int] = None
network_profile: Optional[Dict[str, str]] = None
workload_identity_enabled: bool = False
Adam-D-Lewis marked this conversation as resolved.
Show resolved Hide resolved
Adam-D-Lewis marked this conversation as resolved.
Show resolved Hide resolved


class AWSNodeGroupInputVars(schema.Base):
Expand Down Expand Up @@ -380,6 +381,7 @@ class AzureProvider(schema.Base):
tags: Optional[Dict[str, str]] = {}
network_profile: Optional[Dict[str, str]] = None
max_pods: Optional[int] = None
workload_identity_enabled: bool = False
Adam-D-Lewis marked this conversation as resolved.
Show resolved Hide resolved
Adam-D-Lewis marked this conversation as resolved.
Show resolved Hide resolved

@model_validator(mode="before")
@classmethod
Expand Down Expand Up @@ -563,6 +565,13 @@ class InputSchema(schema.Base):
azure: Optional[AzureProvider] = None
digital_ocean: Optional[DigitalOceanProvider] = None

def exclude_from_config(self):
exclude = set()
for provider in InputSchema.model_fields:
if getattr(self, provider) is None:
exclude.add(provider)
return exclude

@model_validator(mode="before")
@classmethod
def check_provider(cls, data: Any) -> Any:
Expand Down Expand Up @@ -781,6 +790,7 @@ def input_vars(self, stage_outputs: Dict[str, Dict[str, Any]]):
tags=self.config.azure.tags,
network_profile=self.config.azure.network_profile,
max_pods=self.config.azure.max_pods,
workload_identity_enabled=self.config.azure.workload_identity_enabled,
Adam-D-Lewis marked this conversation as resolved.
Show resolved Hide resolved
).model_dump()
elif self.config.provider == schema.ProviderEnum.aws:
return AWSInputVars(
Expand Down
5 changes: 3 additions & 2 deletions src/_nebari/stages/infrastructure/template/azure/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ module "kubernetes" {
max_size = config.max_nodes
}
]
vnet_subnet_id = var.vnet_subnet_id
private_cluster_enabled = var.private_cluster_enabled
vnet_subnet_id = var.vnet_subnet_id
private_cluster_enabled = var.private_cluster_enabled
workload_identity_enabled = var.workload_identity_enabled
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ resource "azurerm_kubernetes_cluster" "main" {
resource_group_name = var.resource_group_name
tags = var.tags

# To enable Azure AD Workload Identity oidc_issuer_enabled must be set to true.
oidc_issuer_enabled = var.workload_identity_enabled
workload_identity_enabled = var.workload_identity_enabled

# DNS prefix specified when creating the managed cluster. Changing this forces a new resource to be created.
dns_prefix = "Nebari" # required

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,13 @@ output "kubeconfig" {
sensitive = true
value = azurerm_kubernetes_cluster.main.kube_config_raw
}

output "cluster_oidc_issuer_url" {
description = "The OpenID Connect issuer URL that is associated with the AKS cluster"
value = azurerm_kubernetes_cluster.main.oidc_issuer_url
}
Comment on lines +21 to +24
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When oidc_issuer_enabled is False, does this output return null, or does terraform raises an error?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It returns null


output "resource_group_name" {
description = "The name of the resource group in which the AKS cluster is created"
value = azurerm_kubernetes_cluster.main.resource_group_name
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,9 @@ variable "max_pods" {
type = number
default = 60
}

variable "workload_identity_enabled" {
description = "Enable Workload Identity"
type = bool
default = false
}
10 changes: 10 additions & 0 deletions src/_nebari/stages/infrastructure/template/azure/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,13 @@ output "kubeconfig_filename" {
description = "filename for nebari kubeconfig"
value = var.kubeconfig_filename
}

output "cluster_oidc_issuer_url" {
description = "The OpenID Connect issuer URL that is associated with the AKS cluster"
value = module.kubernetes.cluster_oidc_issuer_url
}

output "resource_group_name" {
description = "The name of the resource group in which the AKS cluster is created"
value = module.kubernetes.resource_group_name
}
6 changes: 6 additions & 0 deletions src/_nebari/stages/infrastructure/template/azure/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,9 @@ variable "max_pods" {
type = number
default = 60
}

variable "workload_identity_enabled" {
description = "Enable Workload Identity"
type = bool
default = false
Adam-D-Lewis marked this conversation as resolved.
Show resolved Hide resolved
}
47 changes: 28 additions & 19 deletions src/_nebari/stages/kubernetes_ingress/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import enum
from __future__ import annotations

import logging
import socket
import sys
import time
from typing import Any, Dict, List, Optional, Type
from typing import Any, Dict, List, Literal, Optional, Type, Union

from pydantic import Field

from _nebari import constants
from _nebari.provider.dns.cloudflare import update_record
Expand Down Expand Up @@ -112,27 +115,33 @@ def _attempt_dns_lookup(
sys.exit(1)


@schema.yaml_object(schema.yaml)
class CertificateEnum(str, enum.Enum):
letsencrypt = "lets-encrypt"
selfsigned = "self-signed"
existing = "existing"
disabled = "disabled"

@classmethod
def to_yaml(cls, representer, node):
return representer.represent_str(node.value)
class SelfSignedCertificate(schema.Base):
type: Literal["self-signed"] = Field("self-signed", validate_default=True)


class Certificate(schema.Base):
type: CertificateEnum = CertificateEnum.selfsigned
# existing
secret_name: Optional[str] = None
# lets-encrypt
acme_email: Optional[str] = None
class LetsEncryptCertificate(schema.Base):
type: Literal["lets-encrypt"] = Field("lets-encrypt", validate_default=True)
acme_email: str
acme_server: str = "https://acme-v02.api.letsencrypt.org/directory"


class ExistingCertificate(schema.Base):
type: Literal["existing"] = Field("existing", validate_default=True)
secret_name: str


class DisabledCertificate(schema.Base):
type: Literal["disabled"] = Field("disabled", validate_default=True)


Certificate = Union[
SelfSignedCertificate,
LetsEncryptCertificate,
ExistingCertificate,
DisabledCertificate,
]


class DnsProvider(schema.Base):
provider: Optional[str] = None
auto_provision: Optional[bool] = False
Expand All @@ -144,7 +153,7 @@ class Ingress(schema.Base):

class InputSchema(schema.Base):
domain: Optional[str] = None
certificate: Certificate = Certificate()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert changes to this file

certificate: Certificate = SelfSignedCertificate()
ingress: Ingress = Ingress()
dns: DnsProvider = DnsProvider()

Expand Down
10 changes: 10 additions & 0 deletions src/_nebari/stages/kubernetes_services/template/forward-auth.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,13 @@ module "forwardauth" {

node-group = var.node_groups.general
}

output "forward-auth-middleware" {
description = "middleware name for use with forward auth"
value = module.forwardauth.forward-auth-middleware
}

output "forward-auth-service" {
description = "middleware name for use with forward auth"
value = module.forwardauth.forward-auth-service
}
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ resource "kubernetes_manifest" "forwardauth-middleware" {
apiVersion = "traefik.containo.us/v1alpha1"
kind = "Middleware"
metadata = {
name = "traefik-forward-auth"
name = var.forwardauth_middleware_name
Copy link
Contributor

@viniciusdc viniciusdc May 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I got this correctly, you just created an output for the traefik-forward-auth and you are calling the components here onwards, right?

Copy link
Member Author

@Adam-D-Lewis Adam-D-Lewis May 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We previously hard coded the forward auth middleware name. I added a variable for it (not strictly necessary for what I needed with mlflow plugin). I also created an output for whatever name is chosen. This was necessary for an mlflow plugin. I needed to put authentication in front of the mlflow pod so I re-use the existing forward auth service, middleware, and pod.
See https://github.com/Quansight/nebari-mlflow-plugin/blob/0eeb522380e635ac4c5ac6d3ba843427acc6923f/src/nebari_plugin_mlflow_aws/__init__.py#L207-L221

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cool! The reason I asked was because DaskGateway also uses it, so I just wanted to make sure that the service would still work

namespace = var.namespace
}
spec = {
Expand Down Expand Up @@ -175,7 +175,7 @@ resource "kubernetes_manifest" "forwardauth-ingressroute" {

middlewares = [
{
name = "traefik-forward-auth"
name = kubernetes_manifest.forwardauth-middleware.manifest.metadata.name
namespace = var.namespace
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,9 @@ variable "node-group" {
value = string
})
}

variable "forwardauth_middleware_name" {
description = "Name of the traefik forward auth middleware"
type = string
default = "traefik-forward-auth"
}
18 changes: 17 additions & 1 deletion src/_nebari/subcommands/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class InitInputs(schema.Base):
ssl_cert_email: Optional[schema.email_pydantic] = None
disable_prompt: bool = False
Adam-D-Lewis marked this conversation as resolved.
Show resolved Hide resolved
output: pathlib.Path = pathlib.Path("nebari-config.yaml")
verbose: bool = False


def enum_to_list(enum_cls):
Expand Down Expand Up @@ -152,7 +153,7 @@ def handle_init(inputs: InitInputs, config_schema: BaseModel):
try:
write_configuration(
inputs.output,
config,
config if not inputs.verbose else config_schema(**config),
mode="x",
)
except FileExistsError:
Expand Down Expand Up @@ -565,6 +566,12 @@ def init(
"-o",
help="Output file path for the rendered config file.",
),
verbose: bool = typer.Option(
False,
"--verbose",
"-v",
help="Write verbose nebari config file.",
),
):
"""
Create and initialize your [purple]nebari-config.yaml[/purple] file.
Expand Down Expand Up @@ -604,6 +611,7 @@ def init(
inputs.ssl_cert_email = ssl_cert_email
inputs.disable_prompt = disable_prompt
inputs.output = output
inputs.verbose = verbose

from nebari.plugins import nebari_plugin_manager

Expand Down Expand Up @@ -894,6 +902,14 @@ def guided_init_wizard(ctx: typer.Context, guided_init: str):
)
inputs.kubernetes_version = kubernetes_version

# VERBOSE
inputs.verbose = questionary.confirm(
"Would you like the nebari config to show all available options? (recommended for advanced users only)",
default=False,
qmark=qmark,
auto_enter=False,
).unsafe_ask()

from nebari.plugins import nebari_plugin_manager

config_schema = nebari_plugin_manager.config_schema
Expand Down
27 changes: 24 additions & 3 deletions src/nebari/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,32 @@ def ordered_stages(self):
return self.get_available_stages()

@property
Adam-D-Lewis marked this conversation as resolved.
Show resolved Hide resolved
def config_schema(self):
classes = [schema.Main] + [
def ordered_schemas(self):
return [schema.Main] + [
_.input_schema for _ in self.ordered_stages if _.input_schema is not None
]
return type("ConfigSchema", tuple(classes), {})

@property
def config_schema(self):
ordered_schemas = self.ordered_schemas

def write_config(self):
config_exclude = set()
for cls in self._ordered_schemas:
if hasattr(cls, "exclude_from_config"):
new_exclude = cls.exclude_from_config(self)
config_exclude = config_exclude.union(new_exclude)
return self.model_dump(exclude=config_exclude)

ConfigSchema = type(
"ConfigSchema",
tuple(ordered_schemas[::-1]),
{
"_ordered_schemas": ordered_schemas,
"write_config": write_config,
},
)
return ConfigSchema


nebari_plugin_manager = NebariPluginManager()
Loading
Loading