From 0d9e189e8a5af7497d5ad3bf60708867e97875d9 Mon Sep 17 00:00:00 2001
From: Stefan Majer
Date: Mon, 19 Jan 2026 08:05:41 +0100
Subject: [PATCH] VPN Authkey with all details
---
doc/index.html | 21 ++++++++
go/metalstack/admin/v2/vpn.pb.go | 66 ++++++++++++++++++++------
proto/metalstack/admin/v2/vpn.proto | 7 +++
python/metalstack/admin/v2/vpn_pb2.py | 23 ++++-----
python/metalstack/admin/v2/vpn_pb2.pyi | 11 ++++-
5 files changed, 100 insertions(+), 28 deletions(-)
diff --git a/doc/index.html b/doc/index.html
index 11985ea4..3433184f 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -14851,6 +14851,27 @@
+
+ | ephemeral |
+ bool |
+ |
+ Ephemeral defines if the authkey should be ephemeral. |
+
+
+
+ | expires_at |
+ google.protobuf.Timestamp |
+ |
+ ExpiresAt this key cannot be used after this timestamp. |
+
+
+
+ | created_at |
+ google.protobuf.Timestamp |
+ |
+ CreatedAt this key was created at this timestamp. |
+
+
diff --git a/go/metalstack/admin/v2/vpn.pb.go b/go/metalstack/admin/v2/vpn.pb.go
index d2761f2d..87f9ea43 100644
--- a/go/metalstack/admin/v2/vpn.pb.go
+++ b/go/metalstack/admin/v2/vpn.pb.go
@@ -12,6 +12,7 @@ import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
durationpb "google.golang.org/protobuf/types/known/durationpb"
+ timestamppb "google.golang.org/protobuf/types/known/timestamppb"
reflect "reflect"
sync "sync"
unsafe "unsafe"
@@ -95,7 +96,13 @@ type VPNServiceAuthKeyResponse struct {
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
// AuthKey is the key to connect to the vpn at the given address.
// This key can only be seen once.
- AuthKey string `protobuf:"bytes,2,opt,name=auth_key,json=authKey,proto3" json:"auth_key,omitempty"`
+ AuthKey string `protobuf:"bytes,2,opt,name=auth_key,json=authKey,proto3" json:"auth_key,omitempty"`
+ // Ephemeral defines if the authkey should be ephemeral.
+ Ephemeral bool `protobuf:"varint,3,opt,name=ephemeral,proto3" json:"ephemeral,omitempty"`
+ // ExpiresAt this key cannot be used after this timestamp.
+ ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"`
+ // CreatedAt this key was created at this timestamp.
+ CreatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@@ -144,6 +151,27 @@ func (x *VPNServiceAuthKeyResponse) GetAuthKey() string {
return ""
}
+func (x *VPNServiceAuthKeyResponse) GetEphemeral() bool {
+ if x != nil {
+ return x.Ephemeral
+ }
+ return false
+}
+
+func (x *VPNServiceAuthKeyResponse) GetExpiresAt() *timestamppb.Timestamp {
+ if x != nil {
+ return x.ExpiresAt
+ }
+ return nil
+}
+
+func (x *VPNServiceAuthKeyResponse) GetCreatedAt() *timestamppb.Timestamp {
+ if x != nil {
+ return x.CreatedAt
+ }
+ return nil
+}
+
// VPNServiceListNodesRequest is the request payload for a vpn list nodes request
type VPNServiceListNodesRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
@@ -240,14 +268,19 @@ var File_metalstack_admin_v2_vpn_proto protoreflect.FileDescriptor
const file_metalstack_admin_v2_vpn_proto_rawDesc = "" +
"\n" +
- "\x1dmetalstack/admin/v2/vpn.proto\x12\x13metalstack.admin.v2\x1a\x1bbuf/validate/validate.proto\x1a\x1egoogle/protobuf/duration.proto\x1a\x1emetalstack/api/v2/common.proto\x1a\x1bmetalstack/api/v2/vpn.proto\"\x91\x01\n" +
+ "\x1dmetalstack/admin/v2/vpn.proto\x12\x13metalstack.admin.v2\x1a\x1bbuf/validate/validate.proto\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1emetalstack/api/v2/common.proto\x1a\x1bmetalstack/api/v2/vpn.proto\"\x91\x01\n" +
"\x18VPNServiceAuthKeyRequest\x12\"\n" +
"\aproject\x18\x01 \x01(\tB\b\xbaH\x05r\x03\xb0\x01\x01R\aproject\x12\x1c\n" +
"\tephemeral\x18\x02 \x01(\bR\tephemeral\x123\n" +
- "\aexpires\x18\x03 \x01(\v2\x19.google.protobuf.DurationR\aexpires\"P\n" +
+ "\aexpires\x18\x03 \x01(\v2\x19.google.protobuf.DurationR\aexpires\"\xe4\x01\n" +
"\x19VPNServiceAuthKeyResponse\x12\x18\n" +
"\aaddress\x18\x01 \x01(\tR\aaddress\x12\x19\n" +
- "\bauth_key\x18\x02 \x01(\tR\aauthKey\"G\n" +
+ "\bauth_key\x18\x02 \x01(\tR\aauthKey\x12\x1c\n" +
+ "\tephemeral\x18\x03 \x01(\bR\tephemeral\x129\n" +
+ "\n" +
+ "expires_at\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\texpiresAt\x129\n" +
+ "\n" +
+ "created_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\"G\n" +
"\x1aVPNServiceListNodesRequest\x12\x1d\n" +
"\aproject\x18\x01 \x01(\tH\x00R\aproject\x88\x01\x01B\n" +
"\n" +
@@ -279,20 +312,23 @@ var file_metalstack_admin_v2_vpn_proto_goTypes = []any{
(*VPNServiceListNodesRequest)(nil), // 2: metalstack.admin.v2.VPNServiceListNodesRequest
(*VPNServiceListNodesResponse)(nil), // 3: metalstack.admin.v2.VPNServiceListNodesResponse
(*durationpb.Duration)(nil), // 4: google.protobuf.Duration
- (*v2.VPNNode)(nil), // 5: metalstack.api.v2.VPNNode
+ (*timestamppb.Timestamp)(nil), // 5: google.protobuf.Timestamp
+ (*v2.VPNNode)(nil), // 6: metalstack.api.v2.VPNNode
}
var file_metalstack_admin_v2_vpn_proto_depIdxs = []int32{
4, // 0: metalstack.admin.v2.VPNServiceAuthKeyRequest.expires:type_name -> google.protobuf.Duration
- 5, // 1: metalstack.admin.v2.VPNServiceListNodesResponse.nodes:type_name -> metalstack.api.v2.VPNNode
- 0, // 2: metalstack.admin.v2.VPNService.AuthKey:input_type -> metalstack.admin.v2.VPNServiceAuthKeyRequest
- 2, // 3: metalstack.admin.v2.VPNService.ListNodes:input_type -> metalstack.admin.v2.VPNServiceListNodesRequest
- 1, // 4: metalstack.admin.v2.VPNService.AuthKey:output_type -> metalstack.admin.v2.VPNServiceAuthKeyResponse
- 3, // 5: metalstack.admin.v2.VPNService.ListNodes:output_type -> metalstack.admin.v2.VPNServiceListNodesResponse
- 4, // [4:6] is the sub-list for method output_type
- 2, // [2:4] is the sub-list for method input_type
- 2, // [2:2] is the sub-list for extension type_name
- 2, // [2:2] is the sub-list for extension extendee
- 0, // [0:2] is the sub-list for field type_name
+ 5, // 1: metalstack.admin.v2.VPNServiceAuthKeyResponse.expires_at:type_name -> google.protobuf.Timestamp
+ 5, // 2: metalstack.admin.v2.VPNServiceAuthKeyResponse.created_at:type_name -> google.protobuf.Timestamp
+ 6, // 3: metalstack.admin.v2.VPNServiceListNodesResponse.nodes:type_name -> metalstack.api.v2.VPNNode
+ 0, // 4: metalstack.admin.v2.VPNService.AuthKey:input_type -> metalstack.admin.v2.VPNServiceAuthKeyRequest
+ 2, // 5: metalstack.admin.v2.VPNService.ListNodes:input_type -> metalstack.admin.v2.VPNServiceListNodesRequest
+ 1, // 6: metalstack.admin.v2.VPNService.AuthKey:output_type -> metalstack.admin.v2.VPNServiceAuthKeyResponse
+ 3, // 7: metalstack.admin.v2.VPNService.ListNodes:output_type -> metalstack.admin.v2.VPNServiceListNodesResponse
+ 6, // [6:8] is the sub-list for method output_type
+ 4, // [4:6] is the sub-list for method input_type
+ 4, // [4:4] is the sub-list for extension type_name
+ 4, // [4:4] is the sub-list for extension extendee
+ 0, // [0:4] is the sub-list for field type_name
}
func init() { file_metalstack_admin_v2_vpn_proto_init() }
diff --git a/proto/metalstack/admin/v2/vpn.proto b/proto/metalstack/admin/v2/vpn.proto
index 5738d16e..2427b448 100644
--- a/proto/metalstack/admin/v2/vpn.proto
+++ b/proto/metalstack/admin/v2/vpn.proto
@@ -4,6 +4,7 @@ package metalstack.admin.v2;
import "buf/validate/validate.proto";
import "google/protobuf/duration.proto";
+import "google/protobuf/timestamp.proto";
import "metalstack/api/v2/common.proto";
import "metalstack/api/v2/vpn.proto";
@@ -39,6 +40,12 @@ message VPNServiceAuthKeyResponse {
// AuthKey is the key to connect to the vpn at the given address.
// This key can only be seen once.
string auth_key = 2;
+ // Ephemeral defines if the authkey should be ephemeral.
+ bool ephemeral = 3;
+ // ExpiresAt this key cannot be used after this timestamp.
+ google.protobuf.Timestamp expires_at = 4;
+ // CreatedAt this key was created at this timestamp.
+ google.protobuf.Timestamp created_at = 5;
}
// VPNServiceListNodesRequest is the request payload for a vpn list nodes request
diff --git a/python/metalstack/admin/v2/vpn_pb2.py b/python/metalstack/admin/v2/vpn_pb2.py
index ddb3929b..2068d549 100644
--- a/python/metalstack/admin/v2/vpn_pb2.py
+++ b/python/metalstack/admin/v2/vpn_pb2.py
@@ -24,11 +24,12 @@
from buf.validate import validate_pb2 as buf_dot_validate_dot_validate__pb2
from google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2
+from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
from metalstack.api.v2 import common_pb2 as metalstack_dot_api_dot_v2_dot_common__pb2
from metalstack.api.v2 import vpn_pb2 as metalstack_dot_api_dot_v2_dot_vpn__pb2
-DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1dmetalstack/admin/v2/vpn.proto\x12\x13metalstack.admin.v2\x1a\x1b\x62uf/validate/validate.proto\x1a\x1egoogle/protobuf/duration.proto\x1a\x1emetalstack/api/v2/common.proto\x1a\x1bmetalstack/api/v2/vpn.proto\"\x91\x01\n\x18VPNServiceAuthKeyRequest\x12\"\n\x07project\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x07project\x12\x1c\n\tephemeral\x18\x02 \x01(\x08R\tephemeral\x12\x33\n\x07\x65xpires\x18\x03 \x01(\x0b\x32\x19.google.protobuf.DurationR\x07\x65xpires\"P\n\x19VPNServiceAuthKeyResponse\x12\x18\n\x07\x61\x64\x64ress\x18\x01 \x01(\tR\x07\x61\x64\x64ress\x12\x19\n\x08\x61uth_key\x18\x02 \x01(\tR\x07\x61uthKey\"G\n\x1aVPNServiceListNodesRequest\x12\x1d\n\x07project\x18\x01 \x01(\tH\x00R\x07project\x88\x01\x01\x42\n\n\x08_project\"O\n\x1bVPNServiceListNodesResponse\x12\x30\n\x05nodes\x18\x01 \x03(\x0b\x32\x1a.metalstack.api.v2.VPNNodeR\x05nodes2\xf5\x01\n\nVPNService\x12o\n\x07\x41uthKey\x12-.metalstack.admin.v2.VPNServiceAuthKeyRequest\x1a..metalstack.admin.v2.VPNServiceAuthKeyResponse\"\x05\xd2\xf3\x18\x01\x01\x12v\n\tListNodes\x12/.metalstack.admin.v2.VPNServiceListNodesRequest\x1a\x30.metalstack.admin.v2.VPNServiceListNodesResponse\"\x06\xd2\xf3\x18\x02\x01\x02\x42\xcc\x01\n\x17\x63om.metalstack.admin.v2B\x08VpnProtoP\x01Z9github.com/metal-stack/api/go/metalstack/admin/v2;adminv2\xa2\x02\x03MAX\xaa\x02\x13Metalstack.Admin.V2\xca\x02\x13Metalstack\\Admin\\V2\xe2\x02\x1fMetalstack\\Admin\\V2\\GPBMetadata\xea\x02\x15Metalstack::Admin::V2b\x06proto3')
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1dmetalstack/admin/v2/vpn.proto\x12\x13metalstack.admin.v2\x1a\x1b\x62uf/validate/validate.proto\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1emetalstack/api/v2/common.proto\x1a\x1bmetalstack/api/v2/vpn.proto\"\x91\x01\n\x18VPNServiceAuthKeyRequest\x12\"\n\x07project\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x07project\x12\x1c\n\tephemeral\x18\x02 \x01(\x08R\tephemeral\x12\x33\n\x07\x65xpires\x18\x03 \x01(\x0b\x32\x19.google.protobuf.DurationR\x07\x65xpires\"\xe4\x01\n\x19VPNServiceAuthKeyResponse\x12\x18\n\x07\x61\x64\x64ress\x18\x01 \x01(\tR\x07\x61\x64\x64ress\x12\x19\n\x08\x61uth_key\x18\x02 \x01(\tR\x07\x61uthKey\x12\x1c\n\tephemeral\x18\x03 \x01(\x08R\tephemeral\x12\x39\n\nexpires_at\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\texpiresAt\x12\x39\n\ncreated_at\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\tcreatedAt\"G\n\x1aVPNServiceListNodesRequest\x12\x1d\n\x07project\x18\x01 \x01(\tH\x00R\x07project\x88\x01\x01\x42\n\n\x08_project\"O\n\x1bVPNServiceListNodesResponse\x12\x30\n\x05nodes\x18\x01 \x03(\x0b\x32\x1a.metalstack.api.v2.VPNNodeR\x05nodes2\xf5\x01\n\nVPNService\x12o\n\x07\x41uthKey\x12-.metalstack.admin.v2.VPNServiceAuthKeyRequest\x1a..metalstack.admin.v2.VPNServiceAuthKeyResponse\"\x05\xd2\xf3\x18\x01\x01\x12v\n\tListNodes\x12/.metalstack.admin.v2.VPNServiceListNodesRequest\x1a\x30.metalstack.admin.v2.VPNServiceListNodesResponse\"\x06\xd2\xf3\x18\x02\x01\x02\x42\xcc\x01\n\x17\x63om.metalstack.admin.v2B\x08VpnProtoP\x01Z9github.com/metal-stack/api/go/metalstack/admin/v2;adminv2\xa2\x02\x03MAX\xaa\x02\x13Metalstack.Admin.V2\xca\x02\x13Metalstack\\Admin\\V2\xe2\x02\x1fMetalstack\\Admin\\V2\\GPBMetadata\xea\x02\x15Metalstack::Admin::V2b\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -42,14 +43,14 @@
_globals['_VPNSERVICE'].methods_by_name['AuthKey']._serialized_options = b'\322\363\030\001\001'
_globals['_VPNSERVICE'].methods_by_name['ListNodes']._loaded_options = None
_globals['_VPNSERVICE'].methods_by_name['ListNodes']._serialized_options = b'\322\363\030\002\001\002'
- _globals['_VPNSERVICEAUTHKEYREQUEST']._serialized_start=177
- _globals['_VPNSERVICEAUTHKEYREQUEST']._serialized_end=322
- _globals['_VPNSERVICEAUTHKEYRESPONSE']._serialized_start=324
- _globals['_VPNSERVICEAUTHKEYRESPONSE']._serialized_end=404
- _globals['_VPNSERVICELISTNODESREQUEST']._serialized_start=406
- _globals['_VPNSERVICELISTNODESREQUEST']._serialized_end=477
- _globals['_VPNSERVICELISTNODESRESPONSE']._serialized_start=479
- _globals['_VPNSERVICELISTNODESRESPONSE']._serialized_end=558
- _globals['_VPNSERVICE']._serialized_start=561
- _globals['_VPNSERVICE']._serialized_end=806
+ _globals['_VPNSERVICEAUTHKEYREQUEST']._serialized_start=210
+ _globals['_VPNSERVICEAUTHKEYREQUEST']._serialized_end=355
+ _globals['_VPNSERVICEAUTHKEYRESPONSE']._serialized_start=358
+ _globals['_VPNSERVICEAUTHKEYRESPONSE']._serialized_end=586
+ _globals['_VPNSERVICELISTNODESREQUEST']._serialized_start=588
+ _globals['_VPNSERVICELISTNODESREQUEST']._serialized_end=659
+ _globals['_VPNSERVICELISTNODESRESPONSE']._serialized_start=661
+ _globals['_VPNSERVICELISTNODESRESPONSE']._serialized_end=740
+ _globals['_VPNSERVICE']._serialized_start=743
+ _globals['_VPNSERVICE']._serialized_end=988
# @@protoc_insertion_point(module_scope)
diff --git a/python/metalstack/admin/v2/vpn_pb2.pyi b/python/metalstack/admin/v2/vpn_pb2.pyi
index 27187814..4488a9f2 100644
--- a/python/metalstack/admin/v2/vpn_pb2.pyi
+++ b/python/metalstack/admin/v2/vpn_pb2.pyi
@@ -2,6 +2,7 @@ import datetime
from buf.validate import validate_pb2 as _validate_pb2
from google.protobuf import duration_pb2 as _duration_pb2
+from google.protobuf import timestamp_pb2 as _timestamp_pb2
from metalstack.api.v2 import common_pb2 as _common_pb2
from metalstack.api.v2 import vpn_pb2 as _vpn_pb2
from google.protobuf.internal import containers as _containers
@@ -23,12 +24,18 @@ class VPNServiceAuthKeyRequest(_message.Message):
def __init__(self, project: _Optional[str] = ..., ephemeral: _Optional[bool] = ..., expires: _Optional[_Union[datetime.timedelta, _duration_pb2.Duration, _Mapping]] = ...) -> None: ...
class VPNServiceAuthKeyResponse(_message.Message):
- __slots__ = ("address", "auth_key")
+ __slots__ = ("address", "auth_key", "ephemeral", "expires_at", "created_at")
ADDRESS_FIELD_NUMBER: _ClassVar[int]
AUTH_KEY_FIELD_NUMBER: _ClassVar[int]
+ EPHEMERAL_FIELD_NUMBER: _ClassVar[int]
+ EXPIRES_AT_FIELD_NUMBER: _ClassVar[int]
+ CREATED_AT_FIELD_NUMBER: _ClassVar[int]
address: str
auth_key: str
- def __init__(self, address: _Optional[str] = ..., auth_key: _Optional[str] = ...) -> None: ...
+ ephemeral: bool
+ expires_at: _timestamp_pb2.Timestamp
+ created_at: _timestamp_pb2.Timestamp
+ def __init__(self, address: _Optional[str] = ..., auth_key: _Optional[str] = ..., ephemeral: _Optional[bool] = ..., expires_at: _Optional[_Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping]] = ..., created_at: _Optional[_Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping]] = ...) -> None: ...
class VPNServiceListNodesRequest(_message.Message):
__slots__ = ("project",)