Skip to content

Commit 5bb915c

Browse files
committed
Add ObjectMeta field to client configuration
1 parent ff6d9a4 commit 5bb915c

File tree

11 files changed

+132
-21
lines changed

11 files changed

+132
-21
lines changed

packages/jumpstarter-cli-admin/jumpstarter_cli_admin/create_test.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,21 @@
3333
CLIENT_OBJECT = V1Alpha1Client(
3434
api_version="jumpstarter.dev/v1alpha1",
3535
kind="Client",
36-
metadata=V1ObjectMeta(name=CLIENT_NAME, namespace="default", creation_timestamp="2024-01-01T21:00:00Z"),
36+
metadata=V1ObjectMeta(namespace="default", name=CLIENT_NAME, creation_timestamp="2024-01-01T21:00:00Z"),
3737
status=V1Alpha1ClientStatus(endpoint=CLIENT_ENDPOINT, credential=None),
3838
)
3939

4040
UNSAFE_CLIENT_CONFIG = ClientConfigV1Alpha1(
4141
name=CLIENT_NAME,
42+
metadata=ObjectMeta(namespace="default", name=CLIENT_NAME),
4243
endpoint=CLIENT_ENDPOINT,
4344
token=CLIENT_TOKEN,
4445
drivers=ClientConfigV1Alpha1Drivers(allow=[], unsafe=True),
4546
)
4647

4748
CLIENT_CONFIG = ClientConfigV1Alpha1(
4849
name=CLIENT_NAME,
50+
metadata=ObjectMeta(namespace="default", name=CLIENT_NAME),
4951
endpoint=CLIENT_ENDPOINT,
5052
token=CLIENT_TOKEN,
5153
drivers=ClientConfigV1Alpha1Drivers(allow=[], unsafe=True),

packages/jumpstarter-cli-admin/jumpstarter_cli_admin/delete_test.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
CLIENT_CONFIG = ClientConfigV1Alpha1(
3232
name=CLIENT_NAME,
33+
metadata=ObjectMeta(namespace="default", name=CLIENT_NAME),
3334
endpoint=CLIENT_ENDPOINT,
3435
token=CLIENT_TOKEN,
3536
drivers=ClientConfigV1Alpha1Drivers(allow=[], unsafe=True),

packages/jumpstarter-cli-admin/jumpstarter_cli_admin/import_res_test.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@
2424
# Create a test client config
2525
UNSAFE_CLIENT_CONFIG = ClientConfigV1Alpha1(
2626
name=CLIENT_NAME,
27+
metadata=ObjectMeta(namespace="default", name=CLIENT_NAME),
2728
endpoint=CLIENT_ENDPOINT,
2829
token=CLIENT_TOKEN,
2930
drivers=ClientConfigV1Alpha1Drivers(allow=[], unsafe=True),
3031
)
3132
CLIENT_CONFIG = ClientConfigV1Alpha1(
3233
name=CLIENT_NAME,
34+
metadata=ObjectMeta(namespace="default", name=CLIENT_NAME),
3335
endpoint=CLIENT_ENDPOINT,
3436
token=CLIENT_TOKEN,
3537
drivers=ClientConfigV1Alpha1Drivers(allow=[DRIVER_NAME], unsafe=False),

packages/jumpstarter-cli-client/jumpstarter_cli_client/client_config.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,29 @@
33
import asyncclick as click
44
from jumpstarter_cli_common import make_table
55

6-
from jumpstarter.config import ClientConfigV1Alpha1, ClientConfigV1Alpha1Drivers, UserConfigV1Alpha1
6+
from jumpstarter.config import ClientConfigV1Alpha1, ClientConfigV1Alpha1Drivers, ObjectMeta, UserConfigV1Alpha1
77

88

99
@click.command("create-config", short_help="Create a client config.")
10-
@click.argument("name")
10+
@click.argument("alias")
1111
@click.option(
1212
"-o",
1313
"--out",
1414
type=click.Path(dir_okay=False, resolve_path=True, writable=True),
1515
help="Specify an output file for the client config.",
1616
)
17+
@click.option(
18+
"--namespace",
19+
type=str,
20+
help="Enter the Jumpstarter client namespace.",
21+
prompt="Enter a valid Jumpstarter client nespace",
22+
)
23+
@click.option(
24+
"--name",
25+
type=str,
26+
help="Enter the Jumpstarter client name.",
27+
prompt="Enter a valid Jumpstarter client name",
28+
)
1729
@click.option(
1830
"-e",
1931
"--endpoint",
@@ -39,6 +51,8 @@
3951
)
4052
@click.option("--unsafe", is_flag=True, help="Should all driver client packages be allowed to load (UNSAFE!).")
4153
def create_client_config(
54+
alias: str,
55+
namespace: str,
4256
name: str,
4357
endpoint: str,
4458
token: str,
@@ -47,11 +61,12 @@ def create_client_config(
4761
out: Optional[str],
4862
):
4963
"""Create a Jumpstarter client configuration."""
50-
if out is None and ClientConfigV1Alpha1.exists(name):
51-
raise click.ClickException(f"A client with the name '{name}' already exists.")
64+
if out is None and ClientConfigV1Alpha1.exists(alias):
65+
raise click.ClickException(f"A client with the name '{alias}' already exists.")
5266

5367
config = ClientConfigV1Alpha1(
54-
name=name,
68+
name=alias,
69+
metadata=ObjectMeta(namespace=namespace, name=name),
5570
endpoint=endpoint,
5671
token=token,
5772
drivers=ClientConfigV1Alpha1Drivers(allow=allow.split(","), unsafe=unsafe),

packages/jumpstarter-cli-client/jumpstarter_cli_client/client_test.py

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,48 @@ async def test_client(tmp_config_path):
1818
# create client non-interactively
1919
result = await runner.invoke(
2020
client,
21-
["create-config", "test1", "--endpoint", "example.com:443", "--token", "dummy", "--allow", "jumpstarter.*"],
21+
[
22+
"create-config",
23+
"test1",
24+
"--namespace",
25+
"default",
26+
"--name",
27+
"test1",
28+
"--endpoint",
29+
"example.com:443",
30+
"--token",
31+
"dummy",
32+
"--allow",
33+
"jumpstarter.*",
34+
],
2235
)
2336
assert result.exit_code == 0
2437

2538
# create duplicate client
2639
result = await runner.invoke(
2740
client,
28-
["create-config", "test1", "--endpoint", "example.com:443", "--token", "dummy", "--allow", "jumpstarter.*"],
41+
[
42+
"create-config",
43+
"test1",
44+
"--namespace",
45+
"default",
46+
"--name",
47+
"test1",
48+
"--endpoint",
49+
"example.com:443",
50+
"--token",
51+
"dummy",
52+
"--allow",
53+
"jumpstarter.*",
54+
],
2955
)
3056
assert result.exit_code != 0
3157

3258
# create client interactively
3359
result = await runner.invoke(
3460
client,
3561
["create-config", "test2"],
36-
input="example.org:443\ndummytoken\njumpstarter.*,com.example.*\n",
62+
input="default\ntest2\nexample.org:443\ndummytoken\njumpstarter.*,com.example.*\n",
3763
)
3864
assert result.exit_code == 0
3965

packages/jumpstarter-kubernetes/jumpstarter_kubernetes/clients.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from kubernetes_asyncio.client.models import V1ObjectMeta, V1ObjectReference
88

99
from .util import AbstractAsyncCustomObjectApi
10-
from jumpstarter.config import ClientConfigV1Alpha1, ClientConfigV1Alpha1Drivers
10+
from jumpstarter.config import ClientConfigV1Alpha1, ClientConfigV1Alpha1Drivers, ObjectMeta
1111

1212
logger = logging.getLogger(__name__)
1313

@@ -105,6 +105,10 @@ async def get_client_config(self, name: str, allow: list[str], unsafe=False) ->
105105
token = base64.b64decode(secret.data["token"]).decode("utf8")
106106
return ClientConfigV1Alpha1(
107107
name=name,
108+
metadata=ObjectMeta(
109+
namespace=client.metadata.namespace,
110+
name=client.metadata.name,
111+
),
108112
endpoint=endpoint,
109113
token=token,
110114
drivers=ClientConfigV1Alpha1Drivers(allow=allow, unsafe=unsafe),

packages/jumpstarter/jumpstarter/config/client.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
from jumpstarter_protocol import jumpstarter_pb2, jumpstarter_pb2_grpc
1010
from pydantic import BaseModel, Field, ValidationError
1111

12-
from .common import CONFIG_PATH
13-
from .env import JMP_DRIVERS_ALLOW, JMP_ENDPOINT, JMP_LEASE, JMP_TOKEN
12+
from .common import CONFIG_PATH, ObjectMeta
13+
from .env import JMP_DRIVERS_ALLOW, JMP_ENDPOINT, JMP_LEASE, JMP_NAME, JMP_NAMESPACE, JMP_TOKEN
1414
from .tls import TLSConfigV1Alpha1
1515
from jumpstarter.common import MetadataFilter
1616
from jumpstarter.common.grpc import aio_secure_channel, ssl_channel_credentials
@@ -41,6 +41,8 @@ class ClientConfigV1Alpha1(BaseModel):
4141
apiVersion: Literal["jumpstarter.dev/v1alpha1"] = Field(default="jumpstarter.dev/v1alpha1")
4242
kind: Literal["ClientConfig"] = Field(default="ClientConfig")
4343

44+
metadata: ObjectMeta
45+
4446
endpoint: str
4547
tls: TLSConfigV1Alpha1 = Field(default_factory=TLSConfigV1Alpha1)
4648
token: str
@@ -141,6 +143,10 @@ def try_from_env(cls):
141143
def from_env(cls):
142144
allow, unsafe = _allow_from_env()
143145
return cls(
146+
metadata=ObjectMeta(
147+
namespace=os.environ.get(JMP_NAMESPACE),
148+
name=os.environ.get(JMP_NAME),
149+
),
144150
endpoint=os.environ.get(JMP_ENDPOINT),
145151
token=os.environ.get(JMP_TOKEN),
146152
drivers=ClientConfigV1Alpha1Drivers(

packages/jumpstarter/jumpstarter/config/client_config_test.py

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,8 @@
77
import yaml
88
from pydantic import ValidationError
99

10-
from jumpstarter.config import (
11-
ClientConfigV1Alpha1,
12-
ClientConfigV1Alpha1Drivers,
13-
)
14-
from jumpstarter.config.env import JMP_DRIVERS_ALLOW, JMP_ENDPOINT, JMP_TOKEN
10+
from jumpstarter.config import ClientConfigV1Alpha1, ClientConfigV1Alpha1Drivers, ObjectMeta
11+
from jumpstarter.config.env import JMP_DRIVERS_ALLOW, JMP_ENDPOINT, JMP_NAME, JMP_NAMESPACE, JMP_TOKEN
1512

1613

1714
def test_client_ensure_exists_makes_dir(monkeypatch: pytest.MonkeyPatch):
@@ -22,12 +19,16 @@ def test_client_ensure_exists_makes_dir(monkeypatch: pytest.MonkeyPatch):
2219

2320

2421
def test_client_config_try_from_env(monkeypatch: pytest.MonkeyPatch):
22+
monkeypatch.setenv(JMP_NAMESPACE, "default")
23+
monkeypatch.setenv(JMP_NAME, "testclient")
2524
monkeypatch.setenv(JMP_TOKEN, "dGhpc2lzYXRva2VuLTEyMzQxMjM0MTIzNEyMzQtc2Rxd3Jxd2VycXdlcnF3ZXJxd2VyLTEyMzQxMjM0MTIz")
2625
monkeypatch.setenv(JMP_ENDPOINT, "jumpstarter.my-lab.com:1443")
2726
monkeypatch.setenv(JMP_DRIVERS_ALLOW, "jumpstarter.drivers.*,vendorpackage.*")
2827

2928
config = ClientConfigV1Alpha1.try_from_env()
3029
assert config.name == "default"
30+
assert config.metadata.namespace == "default"
31+
assert config.metadata.name == "testclient"
3132
assert config.token == "dGhpc2lzYXRva2VuLTEyMzQxMjM0MTIzNEyMzQtc2Rxd3Jxd2VycXdlcnF3ZXJxd2VyLTEyMzQxMjM0MTIz"
3233
assert config.endpoint == "jumpstarter.my-lab.com:1443"
3334
assert config.drivers.allow == ["jumpstarter.drivers.*", "vendorpackage.*"]
@@ -40,25 +41,33 @@ def test_client_config_try_from_env_not_set():
4041

4142

4243
def test_client_config_from_env(monkeypatch: pytest.MonkeyPatch):
44+
monkeypatch.setenv(JMP_NAMESPACE, "default")
45+
monkeypatch.setenv(JMP_NAME, "testclient")
4346
monkeypatch.setenv(JMP_TOKEN, "dGhpc2lzYXRva2VuLTEyMzQxMjM0MTIzNEyMzQtc2Rxd3Jxd2VycXdlcnF3ZXJxd2VyLTEyMzQxMjM0MTIz")
4447
monkeypatch.setenv(JMP_ENDPOINT, "jumpstarter.my-lab.com:1443")
4548
monkeypatch.setenv(JMP_DRIVERS_ALLOW, "jumpstarter.drivers.*,vendorpackage.*")
4649

4750
config = ClientConfigV1Alpha1.from_env()
4851
assert config.name == "default"
52+
assert config.metadata.namespace == "default"
53+
assert config.metadata.name == "testclient"
4954
assert config.token == "dGhpc2lzYXRva2VuLTEyMzQxMjM0MTIzNEyMzQtc2Rxd3Jxd2VycXdlcnF3ZXJxd2VyLTEyMzQxMjM0MTIz"
5055
assert config.endpoint == "jumpstarter.my-lab.com:1443"
5156
assert config.drivers.allow == ["jumpstarter.drivers.*", "vendorpackage.*"]
5257
assert config.drivers.unsafe is False
5358

5459

5560
def test_client_config_from_env_allow_unsafe(monkeypatch: pytest.MonkeyPatch):
61+
monkeypatch.setenv(JMP_NAMESPACE, "default")
62+
monkeypatch.setenv(JMP_NAME, "testclient")
5663
monkeypatch.setenv(JMP_TOKEN, "dGhpc2lzYXRva2VuLTEyMzQxMjM0MTIzNEyMzQtc2Rxd3Jxd2VycXdlcnF3ZXJxd2VyLTEyMzQxMjM0MTIz")
5764
monkeypatch.setenv(JMP_ENDPOINT, "jumpstarter.my-lab.com:1443")
5865
monkeypatch.setenv(JMP_DRIVERS_ALLOW, "UNSAFE")
5966

6067
config = ClientConfigV1Alpha1.from_env()
6168
assert config.name == "default"
69+
assert config.metadata.namespace == "default"
70+
assert config.metadata.name == "testclient"
6271
assert config.token == "dGhpc2lzYXRva2VuLTEyMzQxMjM0MTIzNEyMzQtc2Rxd3Jxd2VycXdlcnF3ZXJxd2VyLTEyMzQxMjM0MTIz"
6372
assert config.endpoint == "jumpstarter.my-lab.com:1443"
6473
assert config.drivers.allow == []
@@ -67,6 +76,8 @@ def test_client_config_from_env_allow_unsafe(monkeypatch: pytest.MonkeyPatch):
6776

6877
@pytest.mark.parametrize("missing_field", [JMP_TOKEN, JMP_ENDPOINT])
6978
def test_client_config_from_env_missing_field_raises(monkeypatch: pytest.MonkeyPatch, missing_field):
79+
monkeypatch.setenv(JMP_NAMESPACE, "default")
80+
monkeypatch.setenv(JMP_NAME, "testclient")
7081
monkeypatch.setenv(JMP_TOKEN, "dGhpc2lzYXRva2VuLTEyMzQxMjM0MTIzNEyMzQtc2Rxd3Jxd2VycXdlcnF3ZXJxd2VyLTEyMzQxMjM0MTIz")
7182
monkeypatch.setenv(JMP_ENDPOINT, "jumpstarter.my-lab.com:1443")
7283
monkeypatch.setenv(JMP_DRIVERS_ALLOW, "jumpstarter.drivers.*,vendorpackage.*")
@@ -80,6 +91,9 @@ def test_client_config_from_env_missing_field_raises(monkeypatch: pytest.MonkeyP
8091
def test_client_config_from_file():
8192
CLIENT_CONFIG = """apiVersion: jumpstarter.dev/v1alpha1
8293
kind: ClientConfig
94+
metadata:
95+
namespace: default
96+
name: testclient
8397
endpoint: jumpstarter.my-lab.com:1443
8498
token: dGhpc2lzYXRva2VuLTEyMzQxMjM0MTIzNEyMzQtc2Rxd3Jxd2VycXdlcnF3ZXJxd2VyLTEyMzQxMjM0MTIz
8599
drivers:
@@ -92,6 +106,8 @@ def test_client_config_from_file():
92106
f.close()
93107
config = ClientConfigV1Alpha1.from_file(f.name)
94108
assert config.name == f.name.split("/")[-1]
109+
assert config.metadata.namespace == "default"
110+
assert config.metadata.name == "testclient"
95111
assert config.endpoint == "jumpstarter.my-lab.com:1443"
96112
assert config.token == "dGhpc2lzYXRva2VuLTEyMzQxMjM0MTIzNEyMzQtc2Rxd3Jxd2VycXdlcnF3ZXJxd2VyLTEyMzQxMjM0MTIz"
97113
assert config.drivers.allow == ["jumpstarter.drivers.*", "vendorpackage.*"]
@@ -160,6 +176,7 @@ def test_client_config_load():
160176
"from_file",
161177
return_value=ClientConfigV1Alpha1(
162178
name="another",
179+
metadata=ObjectMeta(namespace="default", name="another"),
163180
endpoint="abc",
164181
token="123",
165182
drivers=ClientConfigV1Alpha1Drivers(allow=[], unsafe=False),
@@ -180,6 +197,9 @@ def test_client_config_load_not_found_raises():
180197
def test_client_config_save(monkeypatch: pytest.MonkeyPatch):
181198
CLIENT_CONFIG = """apiVersion: jumpstarter.dev/v1alpha1
182199
kind: ClientConfig
200+
metadata:
201+
namespace: default
202+
name: testclient
183203
endpoint: jumpstarter.my-lab.com:1443
184204
tls:
185205
ca: ''
@@ -193,6 +213,7 @@ def test_client_config_save(monkeypatch: pytest.MonkeyPatch):
193213
"""
194214
config = ClientConfigV1Alpha1(
195215
name="testclient",
216+
metadata=ObjectMeta(namespace="default", name="testclient"),
196217
endpoint="jumpstarter.my-lab.com:1443",
197218
token="dGhpc2lzYXRva2VuLTEyMzQxMjM0MTIzNEyMzQtc2Rxd3Jxd2VycXdlcnF3ZXJxd2VyLTEyMzQxMjM0MTIz",
198219
drivers=ClientConfigV1Alpha1Drivers(allow=["jumpstarter.drivers.*", "vendorpackage.*"], unsafe=False),
@@ -211,6 +232,9 @@ def test_client_config_save(monkeypatch: pytest.MonkeyPatch):
211232
def test_client_config_save_explicit_path():
212233
CLIENT_CONFIG = """apiVersion: jumpstarter.dev/v1alpha1
213234
kind: ClientConfig
235+
metadata:
236+
namespace: default
237+
name: testclient
214238
endpoint: jumpstarter.my-lab.com:1443
215239
tls:
216240
ca: ''
@@ -224,6 +248,7 @@ def test_client_config_save_explicit_path():
224248
"""
225249
config = ClientConfigV1Alpha1(
226250
name="testclient",
251+
metadata=ObjectMeta(namespace="default", name="testclient"),
227252
endpoint="jumpstarter.my-lab.com:1443",
228253
token="dGhpc2lzYXRva2VuLTEyMzQxMjM0MTIzNEyMzQtc2Rxd3Jxd2VycXdlcnF3ZXJxd2VyLTEyMzQxMjM0MTIz",
229254
drivers=ClientConfigV1Alpha1Drivers(allow=["jumpstarter.drivers.*", "vendorpackage.*"], unsafe=False),
@@ -240,6 +265,9 @@ def test_client_config_save_explicit_path():
240265
def test_client_config_save_unsafe_drivers():
241266
CLIENT_CONFIG = """apiVersion: jumpstarter.dev/v1alpha1
242267
kind: ClientConfig
268+
metadata:
269+
namespace: default
270+
name: testclient
243271
endpoint: jumpstarter.my-lab.com:1443
244272
tls:
245273
ca: ''
@@ -251,6 +279,7 @@ def test_client_config_save_unsafe_drivers():
251279
"""
252280
config = ClientConfigV1Alpha1(
253281
name="testclient",
282+
metadata=ObjectMeta(namespace="default", name="testclient"),
254283
endpoint="jumpstarter.my-lab.com:1443",
255284
token="dGhpc2lzYXRva2VuLTEyMzQxMjM0MTIzNEyMzQtc2Rxd3Jxd2VycXdlcnF3ZXJxd2VyLTEyMzQxMjM0MTIz",
256285
drivers=ClientConfigV1Alpha1Drivers(allow=[], unsafe=True),
@@ -275,6 +304,9 @@ def test_client_config_exists():
275304
def test_client_config_list(monkeypatch: pytest.MonkeyPatch):
276305
CLIENT_CONFIG = """apiVersion: jumpstarter.dev/v1alpha1
277306
kind: ClientConfig
307+
metadata:
308+
namespace: default
309+
name: testclient
278310
endpoint: jumpstarter.my-lab.com:1443
279311
token: dGhpc2lzYXRva2VuLTEyMzQxMjM0MTIzNEyMzQtc2Rxd3Jxd2VycXdlcnF3ZXJxd2VyLTEyMzQxMjM0MTIz
280312
drivers:

packages/jumpstarter/jumpstarter/config/env.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Common environment variables for client/exporter config
22
JMP_CLIENT_CONFIG = "JMP_CLIENT_CONFIG"
3+
JMP_NAMESPACE = "JMP_NAMESPACE"
4+
JMP_NAME = "JMP_NAME"
35
JMP_ENDPOINT = "JMP_ENDPOINT"
46
JMP_TOKEN = "JMP_TOKEN"
57
JMP_DRIVERS_ALLOW = "JMP_DRIVERS_ALLOW"

packages/jumpstarter/jumpstarter/config/exporter_test.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ async def test_exporter_serve(mock_controller):
4040

4141
client = ClientConfigV1Alpha1(
4242
name="testclient",
43+
metadata=ObjectMeta(namespace="default", name="testclient"),
4344
endpoint=mock_controller,
4445
token="dummy-client-token",
4546
drivers=ClientConfigV1Alpha1Drivers(allow=[], unsafe=True),

0 commit comments

Comments
 (0)