Skip to content

Commit 8d64e20

Browse files
authored
Merge pull request #252 from jumpstarter-dev/metadata
Add ObjectMeta to config
2 parents 4049bf8 + e5e41e7 commit 8d64e20

File tree

18 files changed

+226
-33
lines changed

18 files changed

+226
-33
lines changed

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
ClientConfigV1Alpha1,
1919
ClientConfigV1Alpha1Drivers,
2020
ExporterConfigV1Alpha1,
21+
ObjectMeta,
2122
)
2223

2324
# Generate a random client name
@@ -32,19 +33,21 @@
3233
CLIENT_OBJECT = V1Alpha1Client(
3334
api_version="jumpstarter.dev/v1alpha1",
3435
kind="Client",
35-
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"),
3637
status=V1Alpha1ClientStatus(endpoint=CLIENT_ENDPOINT, credential=None),
3738
)
3839

3940
UNSAFE_CLIENT_CONFIG = ClientConfigV1Alpha1(
4041
name=CLIENT_NAME,
42+
metadata=ObjectMeta(namespace="default", name=CLIENT_NAME),
4143
endpoint=CLIENT_ENDPOINT,
4244
token=CLIENT_TOKEN,
4345
drivers=ClientConfigV1Alpha1Drivers(allow=[], unsafe=True),
4446
)
4547

4648
CLIENT_CONFIG = ClientConfigV1Alpha1(
4749
name=CLIENT_NAME,
50+
metadata=ObjectMeta(namespace="default", name=CLIENT_NAME),
4851
endpoint=CLIENT_ENDPOINT,
4952
token=CLIENT_TOKEN,
5053
drivers=ClientConfigV1Alpha1Drivers(allow=[], unsafe=True),
@@ -116,11 +119,12 @@ async def test_create_client(
116119
EXPORTER_OBJECT = V1Alpha1Exporter(
117120
api_version="jumpstarter.dev/v1alpha1",
118121
kind="Exporter",
119-
metadata=V1ObjectMeta(name=EXPORTER_NAME, namespace="default", creation_timestamp="2024-01-01T21:00:00Z"),
122+
metadata=V1ObjectMeta(namespace="default", name=EXPORTER_NAME, creation_timestamp="2024-01-01T21:00:00Z"),
120123
status=V1Alpha1ExporterStatus(endpoint=EXPORTER_ENDPOINT, credential=None, devices=[]),
121124
)
122125
EXPORTER_CONFIG = ExporterConfigV1Alpha1(
123126
alias=EXPORTER_NAME,
127+
metadata=ObjectMeta(namespace="default", name=EXPORTER_NAME),
124128
endpoint=EXPORTER_ENDPOINT,
125129
token=EXPORTER_TOKEN,
126130
)

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
ClientConfigV1Alpha1,
1616
ClientConfigV1Alpha1Drivers,
1717
ExporterConfigV1Alpha1,
18+
ObjectMeta,
1819
UserConfigV1Alpha1,
1920
UserConfigV1Alpha1Config,
2021
)
@@ -29,6 +30,7 @@
2930

3031
CLIENT_CONFIG = ClientConfigV1Alpha1(
3132
name=CLIENT_NAME,
33+
metadata=ObjectMeta(namespace="default", name=CLIENT_NAME),
3234
endpoint=CLIENT_ENDPOINT,
3335
token=CLIENT_TOKEN,
3436
drivers=ClientConfigV1Alpha1Drivers(allow=[], unsafe=True),
@@ -133,11 +135,12 @@ async def test_delete_client(
133135
EXPORTER_OBJECT = V1Alpha1Exporter(
134136
api_version="jumpstarter.dev/v1alpha1",
135137
kind="Exporter",
136-
metadata=V1ObjectMeta(name=EXPORTER_NAME, namespace="default", creation_timestamp="2024-01-01T21:00:00Z"),
138+
metadata=V1ObjectMeta(namespace="default", name=EXPORTER_NAME, creation_timestamp="2024-01-01T21:00:00Z"),
137139
status=V1Alpha1ExporterStatus(endpoint=EXPORTER_ENDPOINT, credential=None, devices=[]),
138140
)
139141
EXPORTER_CONFIG = ExporterConfigV1Alpha1(
140142
alias=EXPORTER_NAME,
143+
metadata=ObjectMeta(namespace="default", name=EXPORTER_NAME),
141144
endpoint=EXPORTER_ENDPOINT,
142145
token=EXPORTER_TOKEN,
143146
)

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
ClientConfigV1Alpha1,
1414
ClientConfigV1Alpha1Drivers,
1515
ExporterConfigV1Alpha1,
16+
ObjectMeta,
1617
)
1718

1819
# Generate a random client name
@@ -23,12 +24,14 @@
2324
# Create a test client config
2425
UNSAFE_CLIENT_CONFIG = ClientConfigV1Alpha1(
2526
name=CLIENT_NAME,
27+
metadata=ObjectMeta(namespace="default", name=CLIENT_NAME),
2628
endpoint=CLIENT_ENDPOINT,
2729
token=CLIENT_TOKEN,
2830
drivers=ClientConfigV1Alpha1Drivers(allow=[], unsafe=True),
2931
)
3032
CLIENT_CONFIG = ClientConfigV1Alpha1(
3133
name=CLIENT_NAME,
34+
metadata=ObjectMeta(namespace="default", name=CLIENT_NAME),
3235
endpoint=CLIENT_ENDPOINT,
3336
token=CLIENT_TOKEN,
3437
drivers=ClientConfigV1Alpha1Drivers(allow=[DRIVER_NAME], unsafe=False),
@@ -85,6 +88,7 @@ async def test_import_client(_load_kube_config_mock, get_client_config_mock: Asy
8588
# Create a test exporter config
8689
EXPORTER_CONFIG = ExporterConfigV1Alpha1(
8790
alias=EXPORTER_NAME,
91+
metadata=ObjectMeta(namespace="default", name=EXPORTER_NAME),
8892
endpoint=EXPORTER_ENDPOINT,
8993
token=EXPORTER_TOKEN,
9094
)

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-cli-exporter/jumpstarter_cli_exporter/exporter_config.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
import asyncclick as click
22
from jumpstarter_cli_common import make_table
33

4-
from jumpstarter.config.exporter import ExporterConfigV1Alpha1
4+
from jumpstarter.config.exporter import ExporterConfigV1Alpha1, ObjectMeta
55

66
arg_alias = click.argument("alias", default="default")
77

88

99
@click.command("create-config")
10+
@click.option("--namespace", prompt=True)
11+
@click.option("--name", prompt=True)
1012
@click.option("--endpoint", prompt=True)
1113
@click.option("--token", prompt=True)
1214
@arg_alias
13-
def create_exporter_config(alias, endpoint, token):
15+
def create_exporter_config(alias, namespace, name, endpoint, token):
1416
"""Create an exporter config."""
1517
try:
1618
ExporterConfigV1Alpha1.load(alias)
@@ -21,6 +23,7 @@ def create_exporter_config(alias, endpoint, token):
2123

2224
config = ExporterConfigV1Alpha1(
2325
alias=alias,
26+
metadata=ObjectMeta(namespace=namespace, name=name),
2427
endpoint=endpoint,
2528
token=token,
2629
)

packages/jumpstarter-cli-exporter/jumpstarter_cli_exporter/exporter_test.py

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,44 @@ async def test_exporter(tmp_config_path):
1616

1717
# create exporter non-interactively
1818
result = await runner.invoke(
19-
exporter, ["create-config", "test1", "--endpoint", "example.com:443", "--token", "dummy"]
19+
exporter,
20+
[
21+
"create-config",
22+
"test1",
23+
"--namespace",
24+
"default",
25+
"--name",
26+
"test1",
27+
"--endpoint",
28+
"example.com:443",
29+
"--token",
30+
"dummy",
31+
],
2032
)
2133
assert result.exit_code == 0
2234

2335
# create duplicate exporter
2436
result = await runner.invoke(
25-
exporter, ["create-config", "test1", "--endpoint", "example.com:443", "--token", "dummy"]
37+
exporter,
38+
[
39+
"create-config",
40+
"test1",
41+
"--namespace",
42+
"default",
43+
"--name",
44+
"test1",
45+
"--endpoint",
46+
"example.com:443",
47+
"--token",
48+
"dummy",
49+
],
2650
)
2751
assert result.exit_code != 0
2852

2953
# create exporter interactively
30-
result = await runner.invoke(exporter, ["create-config", "test2"], input="example.org:443\ndummytoken\n")
54+
result = await runner.invoke(
55+
exporter, ["create-config", "test2"], input="default\ntest2\nexample.org:443\ndummytoken\n"
56+
)
3157
assert result.exit_code == 0
3258

3359
# list exporters

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-kubernetes/jumpstarter_kubernetes/exporters.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from kubernetes_asyncio.client.models import V1ObjectMeta, V1ObjectReference
77

88
from .util import AbstractAsyncCustomObjectApi
9-
from jumpstarter.config import ExporterConfigV1Alpha1
9+
from jumpstarter.config import ExporterConfigV1Alpha1, ObjectMeta
1010

1111
CREATE_EXPORTER_DELAY = 1
1212
CREATE_EXPORTER_COUNT = 10
@@ -110,7 +110,16 @@ async def get_exporter_config(self, name: str) -> ExporterConfigV1Alpha1:
110110
secret = await self.core_api.read_namespaced_secret(exporter.status.credential.name, self.namespace)
111111
endpoint = exporter.status.endpoint
112112
token = base64.b64decode(secret.data["token"]).decode("utf8")
113-
return ExporterConfigV1Alpha1(alias=name, endpoint=endpoint, token=token, export={})
113+
return ExporterConfigV1Alpha1(
114+
alias=name,
115+
metadata=ObjectMeta(
116+
namespace=exporter.metadata.namespace,
117+
name=exporter.metadata.name,
118+
),
119+
endpoint=endpoint,
120+
token=token,
121+
export={},
122+
)
114123

115124
async def delete_exporter(self, name: str):
116125
"""Delete an exporter object"""

packages/jumpstarter/jumpstarter/config/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
ClientConfigV1Alpha1,
33
ClientConfigV1Alpha1Drivers,
44
)
5-
from .common import CONFIG_API_VERSION, CONFIG_PATH
5+
from .common import CONFIG_API_VERSION, CONFIG_PATH, ObjectMeta
66
from .env import JMP_CLIENT_CONFIG, JMP_DRIVERS_ALLOW, JMP_ENDPOINT, JMP_TOKEN
77
from .exporter import ExporterConfigV1Alpha1, ExporterConfigV1Alpha1DriverInstance
88
from .user import UserConfigV1Alpha1, UserConfigV1Alpha1Config
@@ -15,6 +15,7 @@
1515
"JMP_TOKEN",
1616
"JMP_DRIVERS_ALLOW",
1717
"JMP_DRIVERS_ALLOW_UNSAFE",
18+
"ObjectMeta",
1819
"UserConfigV1Alpha1",
1920
"UserConfigV1Alpha1Config",
2021
"ClientConfigV1Alpha1",

packages/jumpstarter/jumpstarter/config/client.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
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
14+
from .grpc import call_credentials
1415
from .tls import TLSConfigV1Alpha1
1516
from jumpstarter.common import MetadataFilter
1617
from jumpstarter.common.grpc import aio_secure_channel, ssl_channel_credentials
@@ -41,6 +42,8 @@ class ClientConfigV1Alpha1(BaseModel):
4142
apiVersion: Literal["jumpstarter.dev/v1alpha1"] = Field(default="jumpstarter.dev/v1alpha1")
4243
kind: Literal["ClientConfig"] = Field(default="ClientConfig")
4344

45+
metadata: ObjectMeta
46+
4447
endpoint: str
4548
tls: TLSConfigV1Alpha1 = Field(default_factory=TLSConfigV1Alpha1)
4649
token: str
@@ -50,7 +53,7 @@ class ClientConfigV1Alpha1(BaseModel):
5053
async def channel(self):
5154
credentials = grpc.composite_channel_credentials(
5255
ssl_channel_credentials(self.endpoint, self.tls),
53-
grpc.access_token_call_credentials(self.token),
56+
call_credentials("Client", self.metadata, self.token),
5457
)
5558

5659
return aio_secure_channel(self.endpoint, credentials)
@@ -141,6 +144,10 @@ def try_from_env(cls):
141144
def from_env(cls):
142145
allow, unsafe = _allow_from_env()
143146
return cls(
147+
metadata=ObjectMeta(
148+
namespace=os.environ.get(JMP_NAMESPACE),
149+
name=os.environ.get(JMP_NAME),
150+
),
144151
endpoint=os.environ.get(JMP_ENDPOINT),
145152
token=os.environ.get(JMP_TOKEN),
146153
drivers=ClientConfigV1Alpha1Drivers(

0 commit comments

Comments
 (0)