@@ -7290,6 +7336,13 @@
Labels for which this machine allocation should get filtered |
+
+ | vpn |
+ MachineVPN |
+ optional |
+ VPN query if this machine has a vpn configuration |
+
+
@@ -8615,9 +8668,14 @@
connected |
bool |
|
- Connected indicate if this machine is connected to the VPN
-
-TODO add machine ips |
+ Connected indicate if this machine is connected to the VPN |
+
+
+
+ | ips |
+ string |
+ repeated |
+ IPs of the machine connected to the vpn |
@@ -14598,6 +14656,237 @@
+
+
+
+
+
+ VPNNode is a machine connected to the vpn
+
+
+
+
+ | Field | Type | Label | Description |
+
+
+
+
+ | id |
+ uint64 |
+ |
+ Id of this node |
+
+
+
+ | name |
+ string |
+ |
+ Name of this node |
+
+
+
+ | user |
+ string |
+ optional |
+ User of this node, maps to a project |
+
+
+
+ | ip_addresses |
+ string |
+ repeated |
+ IPAddresses of this node in the vpn |
+
+
+
+ | last_seen |
+ google.protobuf.Timestamp |
+ |
+ LastSeen timestamp when this node reached out the the control plane |
+
+
+
+ | online |
+ bool |
+ |
+ Online indicates if this node is online |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ VPNServiceAuthkeyRequest is the request payload for a vpn authkey request.
+
+
+
+
+ | Field | Type | Label | Description |
+
+
+
+
+ | project |
+ string |
+ |
+ Project for which a vpn authkey should be generated. |
+
+
+
+ | ephemeral |
+ bool |
+ |
+ Ephemeral defines if the authkey should be ephemeral. |
+
+
+
+ | expires |
+ google.protobuf.Duration |
+ |
+ Expires defines the duration after which the authkey expires. |
+
+
+
+
+
+
+
+
+
+
+ VPNServiceAuthkeyResponse is the request payload for a authkey response
+
+
+
+
+ | Field | Type | Label | Description |
+
+
+
+
+ | address |
+ string |
+ |
+ Address is the address of the vpn control plane. |
+
+
+
+ | authkey |
+ string |
+ |
+ Authkey is the key to connect to the vpn at the given address.
+This key can only be seen once. |
+
+
+
+
+
+
+
+
+
+
+ VPNServiceListNodesRequest is the request payload for a vpn list nodes request
+
+
+
+
+ | Field | Type | Label | Description |
+
+
+
+
+ | user |
+ string |
+ optional |
+ User if given only nodes of this user are returned |
+
+
+
+
+
+
+
+
+
+
+ VPNServiceListNodesResponse is the response payload for a vpn list nodes request
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ VPNService serves vpn related functions
+
+
+
+
+
diff --git a/go.mod b/go.mod
index b0f7bdb8..b0c5974f 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@ module github.com/metal-stack/api
go 1.25
require (
- buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.10-20251209175733-2a1774d88802.1
+ buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20251209175733-2a1774d88802.1
buf.build/go/protovalidate v1.1.0
connectrpc.com/connect v1.19.1
github.com/bufbuild/protocompile v0.14.1
@@ -12,7 +12,7 @@ require (
github.com/google/go-cmp v0.7.0
github.com/klauspost/connect-compress/v2 v2.1.0
github.com/stretchr/testify v1.11.1
- google.golang.org/protobuf v1.36.10
+ google.golang.org/protobuf v1.36.11
)
require (
@@ -28,8 +28,8 @@ require (
github.com/stretchr/objx v0.5.3 // indirect
golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 // indirect
golang.org/x/text v0.32.0 // indirect
- google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect
+ google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff --git a/go.sum b/go.sum
index 17f2eb64..faa47374 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,5 @@
-buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.10-20251209175733-2a1774d88802.1 h1:ZnX3qpF/pDiYrf+Q3p+/zCzZ5ELSpszy5hdVarDMSV4=
-buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.10-20251209175733-2a1774d88802.1/go.mod h1:fUl8CEN/6ZAMk6bP8ahBJPUJw7rbp+j4x+wCcYi2IG4=
+buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20251209175733-2a1774d88802.1 h1:j9yeqTWEFrtimt8Nng2MIeRrpoCvQzM9/g25XTvqUGg=
+buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20251209175733-2a1774d88802.1/go.mod h1:tvtbpgaVXZX4g6Pn+AnzFycuRK3MOz5HJfEGeEllXYM=
buf.build/go/protovalidate v1.1.0 h1:pQqEQRpOo4SqS60qkvmhLTTQU9JwzEvdyiqAtXa5SeY=
buf.build/go/protovalidate v1.1.0/go.mod h1:bGZcPiAQDC3ErCHK3t74jSoJDFOs2JH3d7LWuTEIdss=
cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4=
@@ -60,12 +60,12 @@ golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 h1:MDfG8Cvcqlt9XXrmEiD4epKn7
golang.org/x/exp v0.0.0-20251209150349-8475f28825e9/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU=
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
-google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls=
-google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
-google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
-google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
+google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 h1:7LRqPCEdE4TP4/9psdaB7F2nhZFfBiGJomA5sojLWdU=
+google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
+google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
+google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
diff --git a/go/client/client.go b/go/client/client.go
index a28cb156..ff4d4730 100755
--- a/go/client/client.go
+++ b/go/client/client.go
@@ -38,6 +38,7 @@ type (
Switch() adminv2connect.SwitchServiceClient
Tenant() adminv2connect.TenantServiceClient
Token() adminv2connect.TokenServiceClient
+ VPN() adminv2connect.VPNServiceClient
}
adminv2 struct {
@@ -52,6 +53,7 @@ type (
switchservice adminv2connect.SwitchServiceClient
tenantservice adminv2connect.TenantServiceClient
tokenservice adminv2connect.TokenServiceClient
+ vpnservice adminv2connect.VPNServiceClient
}
Apiv2 interface {
@@ -212,6 +214,12 @@ func (c *client) Adminv2() Adminv2 {
connect.WithInterceptors(c.interceptors...),
compress.WithAll(compress.LevelBalanced),
),
+ vpnservice: adminv2connect.NewVPNServiceClient(
+ c.config.HttpClient(),
+ c.config.BaseURL,
+ connect.WithInterceptors(c.interceptors...),
+ compress.WithAll(compress.LevelBalanced),
+ ),
}
return a
}
@@ -249,6 +257,9 @@ func (c *adminv2) Tenant() adminv2connect.TenantServiceClient {
func (c *adminv2) Token() adminv2connect.TokenServiceClient {
return c.tokenservice
}
+func (c *adminv2) VPN() adminv2connect.VPNServiceClient {
+ return c.vpnservice
+}
func (c *client) Apiv2() Apiv2 {
a := &apiv2{
diff --git a/go/metalstack/admin/v2/adminv2connect/vpn.connect.go b/go/metalstack/admin/v2/adminv2connect/vpn.connect.go
new file mode 100644
index 00000000..714f7526
--- /dev/null
+++ b/go/metalstack/admin/v2/adminv2connect/vpn.connect.go
@@ -0,0 +1,148 @@
+// Code generated by protoc-gen-connect-go. DO NOT EDIT.
+//
+// Source: metalstack/admin/v2/vpn.proto
+
+package adminv2connect
+
+import (
+ connect "connectrpc.com/connect"
+ context "context"
+ errors "errors"
+ v2 "github.com/metal-stack/api/go/metalstack/admin/v2"
+ http "net/http"
+ strings "strings"
+)
+
+// This is a compile-time assertion to ensure that this generated file and the connect package are
+// compatible. If you get a compiler error that this constant is not defined, this code was
+// generated with a version of connect newer than the one compiled into your binary. You can fix the
+// problem by either regenerating this code with an older version of connect or updating the connect
+// version compiled into your binary.
+const _ = connect.IsAtLeastVersion1_13_0
+
+const (
+ // VPNServiceName is the fully-qualified name of the VPNService service.
+ VPNServiceName = "metalstack.admin.v2.VPNService"
+)
+
+// These constants are the fully-qualified names of the RPCs defined in this package. They're
+// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route.
+//
+// Note that these are different from the fully-qualified method names used by
+// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
+// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
+// period.
+const (
+ // VPNServiceAuthkeyProcedure is the fully-qualified name of the VPNService's Authkey RPC.
+ VPNServiceAuthkeyProcedure = "/metalstack.admin.v2.VPNService/Authkey"
+ // VPNServiceListNodesProcedure is the fully-qualified name of the VPNService's ListNodes RPC.
+ VPNServiceListNodesProcedure = "/metalstack.admin.v2.VPNService/ListNodes"
+)
+
+// VPNServiceClient is a client for the metalstack.admin.v2.VPNService service.
+type VPNServiceClient interface {
+ // AuthKey generates a authkey for a project to join a machine to the project vpn
+ Authkey(context.Context, *v2.VPNServiceAuthkeyRequest) (*v2.VPNServiceAuthkeyResponse, error)
+ // ListNodes returns a list of machines actually connected to the vpn
+ ListNodes(context.Context, *v2.VPNServiceListNodesRequest) (*v2.VPNServiceListNodesResponse, error)
+}
+
+// NewVPNServiceClient constructs a client for the metalstack.admin.v2.VPNService service. By
+// default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses,
+// and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the
+// connect.WithGRPC() or connect.WithGRPCWeb() options.
+//
+// The URL supplied here should be the base URL for the Connect or gRPC server (for example,
+// http://api.acme.com or https://acme.com/grpc).
+func NewVPNServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) VPNServiceClient {
+ baseURL = strings.TrimRight(baseURL, "/")
+ vPNServiceMethods := v2.File_metalstack_admin_v2_vpn_proto.Services().ByName("VPNService").Methods()
+ return &vPNServiceClient{
+ authkey: connect.NewClient[v2.VPNServiceAuthkeyRequest, v2.VPNServiceAuthkeyResponse](
+ httpClient,
+ baseURL+VPNServiceAuthkeyProcedure,
+ connect.WithSchema(vPNServiceMethods.ByName("Authkey")),
+ connect.WithClientOptions(opts...),
+ ),
+ listNodes: connect.NewClient[v2.VPNServiceListNodesRequest, v2.VPNServiceListNodesResponse](
+ httpClient,
+ baseURL+VPNServiceListNodesProcedure,
+ connect.WithSchema(vPNServiceMethods.ByName("ListNodes")),
+ connect.WithClientOptions(opts...),
+ ),
+ }
+}
+
+// vPNServiceClient implements VPNServiceClient.
+type vPNServiceClient struct {
+ authkey *connect.Client[v2.VPNServiceAuthkeyRequest, v2.VPNServiceAuthkeyResponse]
+ listNodes *connect.Client[v2.VPNServiceListNodesRequest, v2.VPNServiceListNodesResponse]
+}
+
+// Authkey calls metalstack.admin.v2.VPNService.Authkey.
+func (c *vPNServiceClient) Authkey(ctx context.Context, req *v2.VPNServiceAuthkeyRequest) (*v2.VPNServiceAuthkeyResponse, error) {
+ response, err := c.authkey.CallUnary(ctx, connect.NewRequest(req))
+ if response != nil {
+ return response.Msg, err
+ }
+ return nil, err
+}
+
+// ListNodes calls metalstack.admin.v2.VPNService.ListNodes.
+func (c *vPNServiceClient) ListNodes(ctx context.Context, req *v2.VPNServiceListNodesRequest) (*v2.VPNServiceListNodesResponse, error) {
+ response, err := c.listNodes.CallUnary(ctx, connect.NewRequest(req))
+ if response != nil {
+ return response.Msg, err
+ }
+ return nil, err
+}
+
+// VPNServiceHandler is an implementation of the metalstack.admin.v2.VPNService service.
+type VPNServiceHandler interface {
+ // AuthKey generates a authkey for a project to join a machine to the project vpn
+ Authkey(context.Context, *v2.VPNServiceAuthkeyRequest) (*v2.VPNServiceAuthkeyResponse, error)
+ // ListNodes returns a list of machines actually connected to the vpn
+ ListNodes(context.Context, *v2.VPNServiceListNodesRequest) (*v2.VPNServiceListNodesResponse, error)
+}
+
+// NewVPNServiceHandler builds an HTTP handler from the service implementation. It returns the path
+// on which to mount the handler and the handler itself.
+//
+// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf
+// and JSON codecs. They also support gzip compression.
+func NewVPNServiceHandler(svc VPNServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) {
+ vPNServiceMethods := v2.File_metalstack_admin_v2_vpn_proto.Services().ByName("VPNService").Methods()
+ vPNServiceAuthkeyHandler := connect.NewUnaryHandlerSimple(
+ VPNServiceAuthkeyProcedure,
+ svc.Authkey,
+ connect.WithSchema(vPNServiceMethods.ByName("Authkey")),
+ connect.WithHandlerOptions(opts...),
+ )
+ vPNServiceListNodesHandler := connect.NewUnaryHandlerSimple(
+ VPNServiceListNodesProcedure,
+ svc.ListNodes,
+ connect.WithSchema(vPNServiceMethods.ByName("ListNodes")),
+ connect.WithHandlerOptions(opts...),
+ )
+ return "/metalstack.admin.v2.VPNService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ switch r.URL.Path {
+ case VPNServiceAuthkeyProcedure:
+ vPNServiceAuthkeyHandler.ServeHTTP(w, r)
+ case VPNServiceListNodesProcedure:
+ vPNServiceListNodesHandler.ServeHTTP(w, r)
+ default:
+ http.NotFound(w, r)
+ }
+ })
+}
+
+// UnimplementedVPNServiceHandler returns CodeUnimplemented from all methods.
+type UnimplementedVPNServiceHandler struct{}
+
+func (UnimplementedVPNServiceHandler) Authkey(context.Context, *v2.VPNServiceAuthkeyRequest) (*v2.VPNServiceAuthkeyResponse, error) {
+ return nil, connect.NewError(connect.CodeUnimplemented, errors.New("metalstack.admin.v2.VPNService.Authkey is not implemented"))
+}
+
+func (UnimplementedVPNServiceHandler) ListNodes(context.Context, *v2.VPNServiceListNodesRequest) (*v2.VPNServiceListNodesResponse, error) {
+ return nil, connect.NewError(connect.CodeUnimplemented, errors.New("metalstack.admin.v2.VPNService.ListNodes is not implemented"))
+}
diff --git a/go/metalstack/admin/v2/filesystem.pb.go b/go/metalstack/admin/v2/filesystem.pb.go
index c395d53f..750ae226 100644
--- a/go/metalstack/admin/v2/filesystem.pb.go
+++ b/go/metalstack/admin/v2/filesystem.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/admin/v2/filesystem.proto
diff --git a/go/metalstack/admin/v2/image.pb.go b/go/metalstack/admin/v2/image.pb.go
index caf74e15..58202dbf 100644
--- a/go/metalstack/admin/v2/image.pb.go
+++ b/go/metalstack/admin/v2/image.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/admin/v2/image.proto
diff --git a/go/metalstack/admin/v2/ip.pb.go b/go/metalstack/admin/v2/ip.pb.go
index fcbb7cc3..ab24e077 100644
--- a/go/metalstack/admin/v2/ip.pb.go
+++ b/go/metalstack/admin/v2/ip.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/admin/v2/ip.proto
diff --git a/go/metalstack/admin/v2/machine.pb.go b/go/metalstack/admin/v2/machine.pb.go
index 76419332..df02b8b1 100644
--- a/go/metalstack/admin/v2/machine.pb.go
+++ b/go/metalstack/admin/v2/machine.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/admin/v2/machine.proto
diff --git a/go/metalstack/admin/v2/network.pb.go b/go/metalstack/admin/v2/network.pb.go
index 6b1cffe2..96395c5f 100644
--- a/go/metalstack/admin/v2/network.pb.go
+++ b/go/metalstack/admin/v2/network.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/admin/v2/network.proto
diff --git a/go/metalstack/admin/v2/partition.pb.go b/go/metalstack/admin/v2/partition.pb.go
index d30482da..7d9266da 100644
--- a/go/metalstack/admin/v2/partition.pb.go
+++ b/go/metalstack/admin/v2/partition.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/admin/v2/partition.proto
diff --git a/go/metalstack/admin/v2/project.pb.go b/go/metalstack/admin/v2/project.pb.go
index a9a57b6b..76465046 100644
--- a/go/metalstack/admin/v2/project.pb.go
+++ b/go/metalstack/admin/v2/project.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/admin/v2/project.proto
diff --git a/go/metalstack/admin/v2/size.pb.go b/go/metalstack/admin/v2/size.pb.go
index 71d1f39f..b17594a7 100644
--- a/go/metalstack/admin/v2/size.pb.go
+++ b/go/metalstack/admin/v2/size.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/admin/v2/size.proto
diff --git a/go/metalstack/admin/v2/switch.pb.go b/go/metalstack/admin/v2/switch.pb.go
index 80daaaf2..cf56cf61 100644
--- a/go/metalstack/admin/v2/switch.pb.go
+++ b/go/metalstack/admin/v2/switch.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/admin/v2/switch.proto
diff --git a/go/metalstack/admin/v2/tenant.pb.go b/go/metalstack/admin/v2/tenant.pb.go
index 0973d1b5..1015efcd 100644
--- a/go/metalstack/admin/v2/tenant.pb.go
+++ b/go/metalstack/admin/v2/tenant.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/admin/v2/tenant.proto
diff --git a/go/metalstack/admin/v2/token.pb.go b/go/metalstack/admin/v2/token.pb.go
index b48f9b07..feb7991b 100644
--- a/go/metalstack/admin/v2/token.pb.go
+++ b/go/metalstack/admin/v2/token.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/admin/v2/token.proto
diff --git a/go/metalstack/admin/v2/vpn.pb.go b/go/metalstack/admin/v2/vpn.pb.go
new file mode 100644
index 00000000..2862c688
--- /dev/null
+++ b/go/metalstack/admin/v2/vpn.pb.go
@@ -0,0 +1,320 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.36.11
+// protoc (unknown)
+// source: metalstack/admin/v2/vpn.proto
+
+package adminv2
+
+import (
+ _ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate"
+ v2 "github.com/metal-stack/api/go/metalstack/api/v2"
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ durationpb "google.golang.org/protobuf/types/known/durationpb"
+ reflect "reflect"
+ sync "sync"
+ unsafe "unsafe"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// VPNServiceAuthkeyRequest is the request payload for a vpn authkey request.
+type VPNServiceAuthkeyRequest struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ // Project for which a vpn authkey should be generated.
+ Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+ // Ephemeral defines if the authkey should be ephemeral.
+ Ephemeral bool `protobuf:"varint,2,opt,name=ephemeral,proto3" json:"ephemeral,omitempty"`
+ // Expires defines the duration after which the authkey expires.
+ Expires *durationpb.Duration `protobuf:"bytes,3,opt,name=expires,proto3" json:"expires,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *VPNServiceAuthkeyRequest) Reset() {
+ *x = VPNServiceAuthkeyRequest{}
+ mi := &file_metalstack_admin_v2_vpn_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *VPNServiceAuthkeyRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*VPNServiceAuthkeyRequest) ProtoMessage() {}
+
+func (x *VPNServiceAuthkeyRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_metalstack_admin_v2_vpn_proto_msgTypes[0]
+ if x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use VPNServiceAuthkeyRequest.ProtoReflect.Descriptor instead.
+func (*VPNServiceAuthkeyRequest) Descriptor() ([]byte, []int) {
+ return file_metalstack_admin_v2_vpn_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *VPNServiceAuthkeyRequest) GetProject() string {
+ if x != nil {
+ return x.Project
+ }
+ return ""
+}
+
+func (x *VPNServiceAuthkeyRequest) GetEphemeral() bool {
+ if x != nil {
+ return x.Ephemeral
+ }
+ return false
+}
+
+func (x *VPNServiceAuthkeyRequest) GetExpires() *durationpb.Duration {
+ if x != nil {
+ return x.Expires
+ }
+ return nil
+}
+
+// VPNServiceAuthkeyResponse is the request payload for a authkey response
+type VPNServiceAuthkeyResponse struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ // Address is the address of the vpn control plane.
+ 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=authkey,proto3" json:"authkey,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *VPNServiceAuthkeyResponse) Reset() {
+ *x = VPNServiceAuthkeyResponse{}
+ mi := &file_metalstack_admin_v2_vpn_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *VPNServiceAuthkeyResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*VPNServiceAuthkeyResponse) ProtoMessage() {}
+
+func (x *VPNServiceAuthkeyResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_metalstack_admin_v2_vpn_proto_msgTypes[1]
+ if x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use VPNServiceAuthkeyResponse.ProtoReflect.Descriptor instead.
+func (*VPNServiceAuthkeyResponse) Descriptor() ([]byte, []int) {
+ return file_metalstack_admin_v2_vpn_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *VPNServiceAuthkeyResponse) GetAddress() string {
+ if x != nil {
+ return x.Address
+ }
+ return ""
+}
+
+func (x *VPNServiceAuthkeyResponse) GetAuthkey() string {
+ if x != nil {
+ return x.Authkey
+ }
+ return ""
+}
+
+// VPNServiceListNodesRequest is the request payload for a vpn list nodes request
+type VPNServiceListNodesRequest struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ // User if given only nodes of this user are returned
+ User *string `protobuf:"bytes,1,opt,name=user,proto3,oneof" json:"user,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *VPNServiceListNodesRequest) Reset() {
+ *x = VPNServiceListNodesRequest{}
+ mi := &file_metalstack_admin_v2_vpn_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *VPNServiceListNodesRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*VPNServiceListNodesRequest) ProtoMessage() {}
+
+func (x *VPNServiceListNodesRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_metalstack_admin_v2_vpn_proto_msgTypes[2]
+ if x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use VPNServiceListNodesRequest.ProtoReflect.Descriptor instead.
+func (*VPNServiceListNodesRequest) Descriptor() ([]byte, []int) {
+ return file_metalstack_admin_v2_vpn_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *VPNServiceListNodesRequest) GetUser() string {
+ if x != nil && x.User != nil {
+ return *x.User
+ }
+ return ""
+}
+
+// VPNServiceListNodesResponse is the response payload for a vpn list nodes request
+type VPNServiceListNodesResponse struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ // Nodes connected to the vpn
+ Nodes []*v2.VPNNode `protobuf:"bytes,1,rep,name=nodes,proto3" json:"nodes,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *VPNServiceListNodesResponse) Reset() {
+ *x = VPNServiceListNodesResponse{}
+ mi := &file_metalstack_admin_v2_vpn_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *VPNServiceListNodesResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*VPNServiceListNodesResponse) ProtoMessage() {}
+
+func (x *VPNServiceListNodesResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_metalstack_admin_v2_vpn_proto_msgTypes[3]
+ if x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use VPNServiceListNodesResponse.ProtoReflect.Descriptor instead.
+func (*VPNServiceListNodesResponse) Descriptor() ([]byte, []int) {
+ return file_metalstack_admin_v2_vpn_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *VPNServiceListNodesResponse) GetNodes() []*v2.VPNNode {
+ if x != nil {
+ return x.Nodes
+ }
+ return nil
+}
+
+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" +
+ "\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\"O\n" +
+ "\x19VPNServiceAuthkeyResponse\x12\x18\n" +
+ "\aaddress\x18\x01 \x01(\tR\aaddress\x12\x18\n" +
+ "\aauthkey\x18\x02 \x01(\tR\aauthkey\">\n" +
+ "\x1aVPNServiceListNodesRequest\x12\x17\n" +
+ "\x04user\x18\x01 \x01(\tH\x00R\x04user\x88\x01\x01B\a\n" +
+ "\x05_user\"O\n" +
+ "\x1bVPNServiceListNodesResponse\x120\n" +
+ "\x05nodes\x18\x01 \x03(\v2\x1a.metalstack.api.v2.VPNNodeR\x05nodes2\xf4\x01\n" +
+ "\n" +
+ "VPNService\x12o\n" +
+ "\aAuthkey\x12-.metalstack.admin.v2.VPNServiceAuthkeyRequest\x1a..metalstack.admin.v2.VPNServiceAuthkeyResponse\"\x05\xd2\xf3\x18\x01\x01\x12u\n" +
+ "\tListNodes\x12/.metalstack.admin.v2.VPNServiceListNodesRequest\x1a0.metalstack.admin.v2.VPNServiceListNodesResponse\"\x05\xd2\xf3\x18\x01\x01B\xcc\x01\n" +
+ "\x17com.metalstack.admin.v2B\bVpnProtoP\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"
+
+var (
+ file_metalstack_admin_v2_vpn_proto_rawDescOnce sync.Once
+ file_metalstack_admin_v2_vpn_proto_rawDescData []byte
+)
+
+func file_metalstack_admin_v2_vpn_proto_rawDescGZIP() []byte {
+ file_metalstack_admin_v2_vpn_proto_rawDescOnce.Do(func() {
+ file_metalstack_admin_v2_vpn_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_metalstack_admin_v2_vpn_proto_rawDesc), len(file_metalstack_admin_v2_vpn_proto_rawDesc)))
+ })
+ return file_metalstack_admin_v2_vpn_proto_rawDescData
+}
+
+var file_metalstack_admin_v2_vpn_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
+var file_metalstack_admin_v2_vpn_proto_goTypes = []any{
+ (*VPNServiceAuthkeyRequest)(nil), // 0: metalstack.admin.v2.VPNServiceAuthkeyRequest
+ (*VPNServiceAuthkeyResponse)(nil), // 1: metalstack.admin.v2.VPNServiceAuthkeyResponse
+ (*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
+}
+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
+}
+
+func init() { file_metalstack_admin_v2_vpn_proto_init() }
+func file_metalstack_admin_v2_vpn_proto_init() {
+ if File_metalstack_admin_v2_vpn_proto != nil {
+ return
+ }
+ file_metalstack_admin_v2_vpn_proto_msgTypes[2].OneofWrappers = []any{}
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: unsafe.Slice(unsafe.StringData(file_metalstack_admin_v2_vpn_proto_rawDesc), len(file_metalstack_admin_v2_vpn_proto_rawDesc)),
+ NumEnums: 0,
+ NumMessages: 4,
+ NumExtensions: 0,
+ NumServices: 1,
+ },
+ GoTypes: file_metalstack_admin_v2_vpn_proto_goTypes,
+ DependencyIndexes: file_metalstack_admin_v2_vpn_proto_depIdxs,
+ MessageInfos: file_metalstack_admin_v2_vpn_proto_msgTypes,
+ }.Build()
+ File_metalstack_admin_v2_vpn_proto = out.File
+ file_metalstack_admin_v2_vpn_proto_goTypes = nil
+ file_metalstack_admin_v2_vpn_proto_depIdxs = nil
+}
diff --git a/go/metalstack/api/v2/common.pb.go b/go/metalstack/api/v2/common.pb.go
index 0b77a426..627a8379 100644
--- a/go/metalstack/api/v2/common.pb.go
+++ b/go/metalstack/api/v2/common.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/api/v2/common.proto
diff --git a/go/metalstack/api/v2/filesystem.pb.go b/go/metalstack/api/v2/filesystem.pb.go
index b613337e..ffeb547c 100644
--- a/go/metalstack/api/v2/filesystem.pb.go
+++ b/go/metalstack/api/v2/filesystem.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/api/v2/filesystem.proto
diff --git a/go/metalstack/api/v2/health.pb.go b/go/metalstack/api/v2/health.pb.go
index ee526adc..b05a6c59 100644
--- a/go/metalstack/api/v2/health.pb.go
+++ b/go/metalstack/api/v2/health.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/api/v2/health.proto
diff --git a/go/metalstack/api/v2/image.pb.go b/go/metalstack/api/v2/image.pb.go
index d9c152d6..baf8fdea 100644
--- a/go/metalstack/api/v2/image.pb.go
+++ b/go/metalstack/api/v2/image.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/api/v2/image.proto
diff --git a/go/metalstack/api/v2/ip.pb.go b/go/metalstack/api/v2/ip.pb.go
index 0a5315e4..cf4645b1 100644
--- a/go/metalstack/api/v2/ip.pb.go
+++ b/go/metalstack/api/v2/ip.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/api/v2/ip.proto
diff --git a/go/metalstack/api/v2/machine.pb.go b/go/metalstack/api/v2/machine.pb.go
index 511c227b..d3b06d10 100644
--- a/go/metalstack/api/v2/machine.pb.go
+++ b/go/metalstack/api/v2/machine.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/api/v2/machine.proto
@@ -2598,7 +2598,9 @@ type MachineVPN struct {
// Auth key used to connect to VPN
AuthKey string `protobuf:"bytes,2,opt,name=auth_key,json=authKey,proto3" json:"auth_key,omitempty"`
// Connected indicate if this machine is connected to the VPN
- Connected bool `protobuf:"varint,3,opt,name=connected,proto3" json:"connected,omitempty"` // TODO add machine ips
+ Connected bool `protobuf:"varint,3,opt,name=connected,proto3" json:"connected,omitempty"`
+ // IPs of the machine connected to the vpn
+ Ips []string `protobuf:"bytes,5,rep,name=ips,proto3" json:"ips,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@@ -2654,6 +2656,13 @@ func (x *MachineVPN) GetConnected() bool {
return false
}
+func (x *MachineVPN) GetIps() []string {
+ if x != nil {
+ return x.Ips
+ }
+ return nil
+}
+
// MachineQuery contains fields which can be specified to list specific machines.
type MachineQuery struct {
state protoimpl.MessageState `protogen:"open.v1"`
@@ -2835,7 +2844,9 @@ type MachineAllocationQuery struct {
// AllocationType of this machine
AllocationType *MachineAllocationType `protobuf:"varint,7,opt,name=allocation_type,json=allocationType,proto3,enum=metalstack.api.v2.MachineAllocationType,oneof" json:"allocation_type,omitempty"`
// Labels for which this machine allocation should get filtered
- Labels *Labels `protobuf:"bytes,8,opt,name=labels,proto3,oneof" json:"labels,omitempty"`
+ Labels *Labels `protobuf:"bytes,8,opt,name=labels,proto3,oneof" json:"labels,omitempty"`
+ // VPN query if this machine has a vpn configuration
+ Vpn *MachineVPN `protobuf:"bytes,9,opt,name=vpn,proto3,oneof" json:"vpn,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@@ -2926,6 +2937,13 @@ func (x *MachineAllocationQuery) GetLabels() *Labels {
return nil
}
+func (x *MachineAllocationQuery) GetVpn() *MachineVPN {
+ if x != nil {
+ return x.Vpn
+ }
+ return nil
+}
+
// MachineNetworkQuery network specific machine queries
type MachineNetworkQuery struct {
state protoimpl.MessageState `protogen:"open.v1"`
@@ -3566,12 +3584,13 @@ const file_metalstack_api_v2_machine_proto_rawDesc = "" +
"\x18MachineProvisioningEvent\x12.\n" +
"\x04time\x18\x01 \x01(\v2\x1a.google.protobuf.TimestampR\x04time\x12E\n" +
"\x05event\x18\x02 \x01(\x0e2/.metalstack.api.v2.MachineProvisioningEventTypeR\x05event\x12\x18\n" +
- "\amessage\x18\x03 \x01(\tR\amessage\"y\n" +
+ "\amessage\x18\x03 \x01(\tR\amessage\"\x99\x01\n" +
"\n" +
"MachineVPN\x122\n" +
"\x15control_plane_address\x18\x01 \x01(\tR\x13controlPlaneAddress\x12\x19\n" +
"\bauth_key\x18\x02 \x01(\tR\aauthKey\x12\x1c\n" +
- "\tconnected\x18\x03 \x01(\bR\tconnected\"\xa8\a\n" +
+ "\tconnected\x18\x03 \x01(\bR\tconnected\x12\x1e\n" +
+ "\x03ips\x18\x05 \x03(\tB\f\xbaH\t\x92\x01\x06賮\xb1\x02\x01R\x03ips\"\xa8\a\n" +
"\fMachineQuery\x12!\n" +
"\x04uuid\x18\x01 \x01(\tB\b\xbaH\x05r\x03\xb0\x01\x01H\x00R\x04uuid\x88\x01\x01\x12$\n" +
"\x04name\x18\x02 \x01(\tB\v\xbaH\br\x06\xc0\xb3\xae\xb1\x02\x01H\x01R\x04name\x88\x01\x01\x12-\n" +
@@ -3609,7 +3628,7 @@ const file_metalstack_api_v2_machine_proto_rawDesc = "" +
"\x05_ipmiB\x06\n" +
"\x04_fruB\v\n" +
"\t_hardwareB\b\n" +
- "\x06_state\"\xa0\x04\n" +
+ "\x06_state\"\xde\x04\n" +
"\x16MachineAllocationQuery\x12!\n" +
"\x04uuid\x18\x01 \x01(\tB\b\xbaH\x05r\x03\xb0\x01\x01H\x00R\x04uuid\x88\x01\x01\x12$\n" +
"\x04name\x18\x02 \x01(\tB\v\xbaH\br\x06\xc0\xb3\xae\xb1\x02\x01H\x01R\x04name\x88\x01\x01\x12'\n" +
@@ -3621,7 +3640,8 @@ const file_metalstack_api_v2_machine_proto_rawDesc = "" +
"\bhostname\x18\x06 \x01(\tB\n" +
"\xbaH\ar\x05\x10\x02\x18\x80\x01H\x05R\bhostname\x88\x01\x01\x12`\n" +
"\x0fallocation_type\x18\a \x01(\x0e2(.metalstack.api.v2.MachineAllocationTypeB\b\xbaH\x05\x82\x01\x02\x10\x01H\x06R\x0eallocationType\x88\x01\x01\x126\n" +
- "\x06labels\x18\b \x01(\v2\x19.metalstack.api.v2.LabelsH\aR\x06labels\x88\x01\x01B\a\n" +
+ "\x06labels\x18\b \x01(\v2\x19.metalstack.api.v2.LabelsH\aR\x06labels\x88\x01\x01\x124\n" +
+ "\x03vpn\x18\t \x01(\v2\x1d.metalstack.api.v2.MachineVPNH\bR\x03vpn\x88\x01\x01B\a\n" +
"\x05_uuidB\a\n" +
"\x05_nameB\n" +
"\n" +
@@ -3630,7 +3650,8 @@ const file_metalstack_api_v2_machine_proto_rawDesc = "" +
"\x12_filesystem_layoutB\v\n" +
"\t_hostnameB\x12\n" +
"\x10_allocation_typeB\t\n" +
- "\a_labels\"\xe4\x01\n" +
+ "\a_labelsB\x06\n" +
+ "\x04_vpn\"\xe4\x01\n" +
"\x13MachineNetworkQuery\x12\x1a\n" +
"\bnetworks\x18\x01 \x03(\tR\bnetworks\x12(\n" +
"\bprefixes\x18\x02 \x03(\tB\f\xbaH\t\x92\x01\x06೮\xb1\x02\x01R\bprefixes\x12?\n" +
@@ -3866,21 +3887,22 @@ var file_metalstack_api_v2_machine_proto_depIdxs = []int32{
1, // 61: metalstack.api.v2.MachineQuery.state:type_name -> metalstack.api.v2.MachineState
5, // 62: metalstack.api.v2.MachineAllocationQuery.allocation_type:type_name -> metalstack.api.v2.MachineAllocationType
44, // 63: metalstack.api.v2.MachineAllocationQuery.labels:type_name -> metalstack.api.v2.Labels
- 6, // 64: metalstack.api.v2.MachineService.Get:input_type -> metalstack.api.v2.MachineServiceGetRequest
- 8, // 65: metalstack.api.v2.MachineService.Create:input_type -> metalstack.api.v2.MachineServiceCreateRequest
- 11, // 66: metalstack.api.v2.MachineService.Update:input_type -> metalstack.api.v2.MachineServiceUpdateRequest
- 13, // 67: metalstack.api.v2.MachineService.List:input_type -> metalstack.api.v2.MachineServiceListRequest
- 15, // 68: metalstack.api.v2.MachineService.Delete:input_type -> metalstack.api.v2.MachineServiceDeleteRequest
- 7, // 69: metalstack.api.v2.MachineService.Get:output_type -> metalstack.api.v2.MachineServiceGetResponse
- 10, // 70: metalstack.api.v2.MachineService.Create:output_type -> metalstack.api.v2.MachineServiceCreateResponse
- 12, // 71: metalstack.api.v2.MachineService.Update:output_type -> metalstack.api.v2.MachineServiceUpdateResponse
- 14, // 72: metalstack.api.v2.MachineService.List:output_type -> metalstack.api.v2.MachineServiceListResponse
- 16, // 73: metalstack.api.v2.MachineService.Delete:output_type -> metalstack.api.v2.MachineServiceDeleteResponse
- 69, // [69:74] is the sub-list for method output_type
- 64, // [64:69] is the sub-list for method input_type
- 64, // [64:64] is the sub-list for extension type_name
- 64, // [64:64] is the sub-list for extension extendee
- 0, // [0:64] is the sub-list for field type_name
+ 35, // 64: metalstack.api.v2.MachineAllocationQuery.vpn:type_name -> metalstack.api.v2.MachineVPN
+ 6, // 65: metalstack.api.v2.MachineService.Get:input_type -> metalstack.api.v2.MachineServiceGetRequest
+ 8, // 66: metalstack.api.v2.MachineService.Create:input_type -> metalstack.api.v2.MachineServiceCreateRequest
+ 11, // 67: metalstack.api.v2.MachineService.Update:input_type -> metalstack.api.v2.MachineServiceUpdateRequest
+ 13, // 68: metalstack.api.v2.MachineService.List:input_type -> metalstack.api.v2.MachineServiceListRequest
+ 15, // 69: metalstack.api.v2.MachineService.Delete:input_type -> metalstack.api.v2.MachineServiceDeleteRequest
+ 7, // 70: metalstack.api.v2.MachineService.Get:output_type -> metalstack.api.v2.MachineServiceGetResponse
+ 10, // 71: metalstack.api.v2.MachineService.Create:output_type -> metalstack.api.v2.MachineServiceCreateResponse
+ 12, // 72: metalstack.api.v2.MachineService.Update:output_type -> metalstack.api.v2.MachineServiceUpdateResponse
+ 14, // 73: metalstack.api.v2.MachineService.List:output_type -> metalstack.api.v2.MachineServiceListResponse
+ 16, // 74: metalstack.api.v2.MachineService.Delete:output_type -> metalstack.api.v2.MachineServiceDeleteResponse
+ 70, // [70:75] is the sub-list for method output_type
+ 65, // [65:70] is the sub-list for method input_type
+ 65, // [65:65] is the sub-list for extension type_name
+ 65, // [65:65] is the sub-list for extension extendee
+ 0, // [0:65] is the sub-list for field type_name
}
func init() { file_metalstack_api_v2_machine_proto_init() }
diff --git a/go/metalstack/api/v2/method.pb.go b/go/metalstack/api/v2/method.pb.go
index 952f4f7f..3376502a 100644
--- a/go/metalstack/api/v2/method.pb.go
+++ b/go/metalstack/api/v2/method.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/api/v2/method.proto
diff --git a/go/metalstack/api/v2/network.pb.go b/go/metalstack/api/v2/network.pb.go
index 959fd091..132b1685 100644
--- a/go/metalstack/api/v2/network.pb.go
+++ b/go/metalstack/api/v2/network.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/api/v2/network.proto
diff --git a/go/metalstack/api/v2/partition.pb.go b/go/metalstack/api/v2/partition.pb.go
index fc64c003..2b6656d2 100644
--- a/go/metalstack/api/v2/partition.pb.go
+++ b/go/metalstack/api/v2/partition.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/api/v2/partition.proto
diff --git a/go/metalstack/api/v2/predefined_rules.pb.go b/go/metalstack/api/v2/predefined_rules.pb.go
index 7b755cc3..decc252e 100644
--- a/go/metalstack/api/v2/predefined_rules.pb.go
+++ b/go/metalstack/api/v2/predefined_rules.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/api/v2/predefined_rules.proto
diff --git a/go/metalstack/api/v2/project.pb.go b/go/metalstack/api/v2/project.pb.go
index 50d7a4d4..6a185273 100644
--- a/go/metalstack/api/v2/project.pb.go
+++ b/go/metalstack/api/v2/project.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/api/v2/project.proto
diff --git a/go/metalstack/api/v2/size.pb.go b/go/metalstack/api/v2/size.pb.go
index e2303302..2f6c9070 100644
--- a/go/metalstack/api/v2/size.pb.go
+++ b/go/metalstack/api/v2/size.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/api/v2/size.proto
diff --git a/go/metalstack/api/v2/switch.pb.go b/go/metalstack/api/v2/switch.pb.go
index fab16a35..b5c92c55 100644
--- a/go/metalstack/api/v2/switch.pb.go
+++ b/go/metalstack/api/v2/switch.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/api/v2/switch.proto
diff --git a/go/metalstack/api/v2/tenant.pb.go b/go/metalstack/api/v2/tenant.pb.go
index 087f13b0..7cd317ec 100644
--- a/go/metalstack/api/v2/tenant.pb.go
+++ b/go/metalstack/api/v2/tenant.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/api/v2/tenant.proto
diff --git a/go/metalstack/api/v2/token.pb.go b/go/metalstack/api/v2/token.pb.go
index 7d2cc683..4f09e3f3 100644
--- a/go/metalstack/api/v2/token.pb.go
+++ b/go/metalstack/api/v2/token.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/api/v2/token.proto
diff --git a/go/metalstack/api/v2/user.pb.go b/go/metalstack/api/v2/user.pb.go
index fe5ee97b..05db8018 100644
--- a/go/metalstack/api/v2/user.pb.go
+++ b/go/metalstack/api/v2/user.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/api/v2/user.proto
diff --git a/go/metalstack/api/v2/version.pb.go b/go/metalstack/api/v2/version.pb.go
index d963a4d4..846b3fe9 100644
--- a/go/metalstack/api/v2/version.pb.go
+++ b/go/metalstack/api/v2/version.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/api/v2/version.proto
diff --git a/go/metalstack/api/v2/vpn.pb.go b/go/metalstack/api/v2/vpn.pb.go
new file mode 100644
index 00000000..d0fc7563
--- /dev/null
+++ b/go/metalstack/api/v2/vpn.pb.go
@@ -0,0 +1,180 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.36.11
+// protoc (unknown)
+// source: metalstack/api/v2/vpn.proto
+
+package apiv2
+
+import (
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ timestamppb "google.golang.org/protobuf/types/known/timestamppb"
+ reflect "reflect"
+ sync "sync"
+ unsafe "unsafe"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// VPNNode is a machine connected to the vpn
+type VPNNode struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ // Id of this node
+ Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
+ // Name of this node
+ Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+ // User of this node, maps to a project
+ User *string `protobuf:"bytes,3,opt,name=user,proto3,oneof" json:"user,omitempty"`
+ // IPAddresses of this node in the vpn
+ IpAddresses []string `protobuf:"bytes,4,rep,name=ip_addresses,json=ipAddresses,proto3" json:"ip_addresses,omitempty"`
+ // LastSeen timestamp when this node reached out the the control plane
+ LastSeen *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=last_seen,json=lastSeen,proto3" json:"last_seen,omitempty"`
+ // Online indicates if this node is online
+ Online bool `protobuf:"varint,6,opt,name=online,proto3" json:"online,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *VPNNode) Reset() {
+ *x = VPNNode{}
+ mi := &file_metalstack_api_v2_vpn_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *VPNNode) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*VPNNode) ProtoMessage() {}
+
+func (x *VPNNode) ProtoReflect() protoreflect.Message {
+ mi := &file_metalstack_api_v2_vpn_proto_msgTypes[0]
+ if x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use VPNNode.ProtoReflect.Descriptor instead.
+func (*VPNNode) Descriptor() ([]byte, []int) {
+ return file_metalstack_api_v2_vpn_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *VPNNode) GetId() uint64 {
+ if x != nil {
+ return x.Id
+ }
+ return 0
+}
+
+func (x *VPNNode) GetName() string {
+ if x != nil {
+ return x.Name
+ }
+ return ""
+}
+
+func (x *VPNNode) GetUser() string {
+ if x != nil && x.User != nil {
+ return *x.User
+ }
+ return ""
+}
+
+func (x *VPNNode) GetIpAddresses() []string {
+ if x != nil {
+ return x.IpAddresses
+ }
+ return nil
+}
+
+func (x *VPNNode) GetLastSeen() *timestamppb.Timestamp {
+ if x != nil {
+ return x.LastSeen
+ }
+ return nil
+}
+
+func (x *VPNNode) GetOnline() bool {
+ if x != nil {
+ return x.Online
+ }
+ return false
+}
+
+var File_metalstack_api_v2_vpn_proto protoreflect.FileDescriptor
+
+const file_metalstack_api_v2_vpn_proto_rawDesc = "" +
+ "\n" +
+ "\x1bmetalstack/api/v2/vpn.proto\x12\x11metalstack.api.v2\x1a\x1fgoogle/protobuf/timestamp.proto\"\xc3\x01\n" +
+ "\aVPNNode\x12\x0e\n" +
+ "\x02id\x18\x01 \x01(\x04R\x02id\x12\x12\n" +
+ "\x04name\x18\x02 \x01(\tR\x04name\x12\x17\n" +
+ "\x04user\x18\x03 \x01(\tH\x00R\x04user\x88\x01\x01\x12!\n" +
+ "\fip_addresses\x18\x04 \x03(\tR\vipAddresses\x127\n" +
+ "\tlast_seen\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\blastSeen\x12\x16\n" +
+ "\x06online\x18\x06 \x01(\bR\x06onlineB\a\n" +
+ "\x05_userB\xbe\x01\n" +
+ "\x15com.metalstack.api.v2B\bVpnProtoP\x01Z5github.com/metal-stack/api/go/metalstack/api/v2;apiv2\xa2\x02\x03MAX\xaa\x02\x11Metalstack.Api.V2\xca\x02\x11Metalstack\\Api\\V2\xe2\x02\x1dMetalstack\\Api\\V2\\GPBMetadata\xea\x02\x13Metalstack::Api::V2b\x06proto3"
+
+var (
+ file_metalstack_api_v2_vpn_proto_rawDescOnce sync.Once
+ file_metalstack_api_v2_vpn_proto_rawDescData []byte
+)
+
+func file_metalstack_api_v2_vpn_proto_rawDescGZIP() []byte {
+ file_metalstack_api_v2_vpn_proto_rawDescOnce.Do(func() {
+ file_metalstack_api_v2_vpn_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_metalstack_api_v2_vpn_proto_rawDesc), len(file_metalstack_api_v2_vpn_proto_rawDesc)))
+ })
+ return file_metalstack_api_v2_vpn_proto_rawDescData
+}
+
+var file_metalstack_api_v2_vpn_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_metalstack_api_v2_vpn_proto_goTypes = []any{
+ (*VPNNode)(nil), // 0: metalstack.api.v2.VPNNode
+ (*timestamppb.Timestamp)(nil), // 1: google.protobuf.Timestamp
+}
+var file_metalstack_api_v2_vpn_proto_depIdxs = []int32{
+ 1, // 0: metalstack.api.v2.VPNNode.last_seen:type_name -> google.protobuf.Timestamp
+ 1, // [1:1] is the sub-list for method output_type
+ 1, // [1:1] is the sub-list for method input_type
+ 1, // [1:1] is the sub-list for extension type_name
+ 1, // [1:1] is the sub-list for extension extendee
+ 0, // [0:1] is the sub-list for field type_name
+}
+
+func init() { file_metalstack_api_v2_vpn_proto_init() }
+func file_metalstack_api_v2_vpn_proto_init() {
+ if File_metalstack_api_v2_vpn_proto != nil {
+ return
+ }
+ file_metalstack_api_v2_vpn_proto_msgTypes[0].OneofWrappers = []any{}
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: unsafe.Slice(unsafe.StringData(file_metalstack_api_v2_vpn_proto_rawDesc), len(file_metalstack_api_v2_vpn_proto_rawDesc)),
+ NumEnums: 0,
+ NumMessages: 1,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_metalstack_api_v2_vpn_proto_goTypes,
+ DependencyIndexes: file_metalstack_api_v2_vpn_proto_depIdxs,
+ MessageInfos: file_metalstack_api_v2_vpn_proto_msgTypes,
+ }.Build()
+ File_metalstack_api_v2_vpn_proto = out.File
+ file_metalstack_api_v2_vpn_proto_goTypes = nil
+ file_metalstack_api_v2_vpn_proto_depIdxs = nil
+}
diff --git a/go/metalstack/infra/v2/bmc.pb.go b/go/metalstack/infra/v2/bmc.pb.go
index a9842bb5..f5457b09 100644
--- a/go/metalstack/infra/v2/bmc.pb.go
+++ b/go/metalstack/infra/v2/bmc.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/infra/v2/bmc.proto
diff --git a/go/metalstack/infra/v2/event.pb.go b/go/metalstack/infra/v2/event.pb.go
index 90118aeb..353e7029 100644
--- a/go/metalstack/infra/v2/event.pb.go
+++ b/go/metalstack/infra/v2/event.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/infra/v2/event.proto
diff --git a/go/metalstack/infra/v2/switch.pb.go b/go/metalstack/infra/v2/switch.pb.go
index 1fd9342a..a0d95820 100644
--- a/go/metalstack/infra/v2/switch.pb.go
+++ b/go/metalstack/infra/v2/switch.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc (unknown)
// source: metalstack/infra/v2/switch.proto
diff --git a/go/permissions/servicepermissions.go b/go/permissions/servicepermissions.go
index df3708e1..fd3f83db 100755
--- a/go/permissions/servicepermissions.go
+++ b/go/permissions/servicepermissions.go
@@ -18,6 +18,7 @@ func GetServices() []string {
"metalstack.admin.v2.SwitchService",
"metalstack.admin.v2.TenantService",
"metalstack.admin.v2.TokenService",
+ "metalstack.admin.v2.VPNService",
"metalstack.api.v2.FilesystemService",
"metalstack.api.v2.HealthService",
"metalstack.api.v2.IPService",
@@ -77,6 +78,8 @@ func GetServicePermissions() *ServicePermissions {
"/metalstack.admin.v2.TokenService/List",
"/metalstack.admin.v2.TokenService/Revoke",
"/metalstack.admin.v2.TokenService/Create",
+ "/metalstack.admin.v2.VPNService/Authkey",
+ "/metalstack.admin.v2.VPNService/ListNodes",
},
"ADMIN_ROLE_VIEWER": []string{
"/metalstack.admin.v2.ImageService/Usage",
@@ -228,6 +231,8 @@ func GetServicePermissions() *ServicePermissions {
"/metalstack.admin.v2.TokenService/Create": true,
"/metalstack.admin.v2.TokenService/List": true,
"/metalstack.admin.v2.TokenService/Revoke": true,
+ "/metalstack.admin.v2.VPNService/Authkey": true,
+ "/metalstack.admin.v2.VPNService/ListNodes": true,
"/metalstack.api.v2.FilesystemService/Get": true,
"/metalstack.api.v2.FilesystemService/List": true,
"/metalstack.api.v2.FilesystemService/Match": true,
@@ -367,6 +372,8 @@ func GetServicePermissions() *ServicePermissions {
"/metalstack.admin.v2.TokenService/Create": true,
"/metalstack.admin.v2.TokenService/List": true,
"/metalstack.admin.v2.TokenService/Revoke": true,
+ "/metalstack.admin.v2.VPNService/Authkey": true,
+ "/metalstack.admin.v2.VPNService/ListNodes": true,
},
Infra: map[string]bool{
"/metalstack.infra.v2.BMCService/UpdateBMCInfo": true,
@@ -450,6 +457,8 @@ func GetServicePermissions() *ServicePermissions {
"/metalstack.admin.v2.TokenService/Create": true,
"/metalstack.admin.v2.TokenService/List": true,
"/metalstack.admin.v2.TokenService/Revoke": true,
+ "/metalstack.admin.v2.VPNService/Authkey": true,
+ "/metalstack.admin.v2.VPNService/ListNodes": true,
"/metalstack.api.v2.FilesystemService/Get": false,
"/metalstack.api.v2.FilesystemService/List": false,
"/metalstack.api.v2.FilesystemService/Match": false,
diff --git a/go/tests/mock_clients.go b/go/tests/mock_clients.go
index df85cdfd..ee450de9 100755
--- a/go/tests/mock_clients.go
+++ b/go/tests/mock_clients.go
@@ -43,6 +43,7 @@ type (
switchservice *adminv2mocks.SwitchServiceClient
tenantservice *adminv2mocks.TenantServiceClient
tokenservice *adminv2mocks.TokenServiceClient
+ vpnservice *adminv2mocks.VPNServiceClient
}
Adminv2MockFns struct {
@@ -57,6 +58,7 @@ type (
Switch func(m *mock.Mock)
Tenant func(m *mock.Mock)
Token func(m *mock.Mock)
+ VPN func(m *mock.Mock)
}
apiv2 struct {
filesystemservice *apiv2mocks.FilesystemServiceClient
@@ -143,6 +145,7 @@ func newadminv2(t *testing.T, fns *Adminv2MockFns) *adminv2 {
switchservice: adminv2mocks.NewSwitchServiceClient(t),
tenantservice: adminv2mocks.NewTenantServiceClient(t),
tokenservice: adminv2mocks.NewTokenServiceClient(t),
+ vpnservice: adminv2mocks.NewVPNServiceClient(t),
}
if fns != nil {
@@ -179,6 +182,9 @@ func newadminv2(t *testing.T, fns *Adminv2MockFns) *adminv2 {
if fns.Token != nil {
fns.Token(&a.tokenservice.Mock)
}
+ if fns.VPN != nil {
+ fns.VPN(&a.vpnservice.Mock)
+ }
}
@@ -218,6 +224,9 @@ func (c *adminv2) Tenant() adminv2connect.TenantServiceClient {
func (c *adminv2) Token() adminv2connect.TokenServiceClient {
return c.tokenservice
}
+func (c *adminv2) VPN() adminv2connect.VPNServiceClient {
+ return c.vpnservice
+}
func (w wrapper) Apiv2(fns *Apiv2MockFns) *apiv2 {
return newapiv2(w.t, fns)
diff --git a/go/tests/mocks/client/Adminv2.go b/go/tests/mocks/client/Adminv2.go
index 8ebd1022..4da226a0 100644
--- a/go/tests/mocks/client/Adminv2.go
+++ b/go/tests/mocks/client/Adminv2.go
@@ -541,3 +541,49 @@ func (_c *Adminv2_Token_Call) RunAndReturn(run func() adminv2connect.TokenServic
_c.Call.Return(run)
return _c
}
+
+// VPN provides a mock function for the type Adminv2
+func (_mock *Adminv2) VPN() adminv2connect.VPNServiceClient {
+ ret := _mock.Called()
+
+ if len(ret) == 0 {
+ panic("no return value specified for VPN")
+ }
+
+ var r0 adminv2connect.VPNServiceClient
+ if returnFunc, ok := ret.Get(0).(func() adminv2connect.VPNServiceClient); ok {
+ r0 = returnFunc()
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(adminv2connect.VPNServiceClient)
+ }
+ }
+ return r0
+}
+
+// Adminv2_VPN_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'VPN'
+type Adminv2_VPN_Call struct {
+ *mock.Call
+}
+
+// VPN is a helper method to define mock.On call
+func (_e *Adminv2_Expecter) VPN() *Adminv2_VPN_Call {
+ return &Adminv2_VPN_Call{Call: _e.mock.On("VPN")}
+}
+
+func (_c *Adminv2_VPN_Call) Run(run func()) *Adminv2_VPN_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ run()
+ })
+ return _c
+}
+
+func (_c *Adminv2_VPN_Call) Return(vPNServiceClient adminv2connect.VPNServiceClient) *Adminv2_VPN_Call {
+ _c.Call.Return(vPNServiceClient)
+ return _c
+}
+
+func (_c *Adminv2_VPN_Call) RunAndReturn(run func() adminv2connect.VPNServiceClient) *Adminv2_VPN_Call {
+ _c.Call.Return(run)
+ return _c
+}
diff --git a/go/tests/mocks/metalstack/admin/v2/adminv2connect/VPNServiceClient.go b/go/tests/mocks/metalstack/admin/v2/adminv2connect/VPNServiceClient.go
new file mode 100644
index 00000000..1322ccaf
--- /dev/null
+++ b/go/tests/mocks/metalstack/admin/v2/adminv2connect/VPNServiceClient.go
@@ -0,0 +1,175 @@
+// Code generated by mockery; DO NOT EDIT.
+// github.com/vektra/mockery
+// template: testify
+
+package adminv2connect
+
+import (
+ "context"
+
+ "github.com/metal-stack/api/go/metalstack/admin/v2"
+ mock "github.com/stretchr/testify/mock"
+)
+
+// NewVPNServiceClient creates a new instance of VPNServiceClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewVPNServiceClient(t interface {
+ mock.TestingT
+ Cleanup(func())
+}) *VPNServiceClient {
+ mock := &VPNServiceClient{}
+ mock.Mock.Test(t)
+
+ t.Cleanup(func() { mock.AssertExpectations(t) })
+
+ return mock
+}
+
+// VPNServiceClient is an autogenerated mock type for the VPNServiceClient type
+type VPNServiceClient struct {
+ mock.Mock
+}
+
+type VPNServiceClient_Expecter struct {
+ mock *mock.Mock
+}
+
+func (_m *VPNServiceClient) EXPECT() *VPNServiceClient_Expecter {
+ return &VPNServiceClient_Expecter{mock: &_m.Mock}
+}
+
+// Authkey provides a mock function for the type VPNServiceClient
+func (_mock *VPNServiceClient) Authkey(context1 context.Context, vPNServiceAuthkeyRequest *adminv2.VPNServiceAuthkeyRequest) (*adminv2.VPNServiceAuthkeyResponse, error) {
+ ret := _mock.Called(context1, vPNServiceAuthkeyRequest)
+
+ if len(ret) == 0 {
+ panic("no return value specified for Authkey")
+ }
+
+ var r0 *adminv2.VPNServiceAuthkeyResponse
+ var r1 error
+ if returnFunc, ok := ret.Get(0).(func(context.Context, *adminv2.VPNServiceAuthkeyRequest) (*adminv2.VPNServiceAuthkeyResponse, error)); ok {
+ return returnFunc(context1, vPNServiceAuthkeyRequest)
+ }
+ if returnFunc, ok := ret.Get(0).(func(context.Context, *adminv2.VPNServiceAuthkeyRequest) *adminv2.VPNServiceAuthkeyResponse); ok {
+ r0 = returnFunc(context1, vPNServiceAuthkeyRequest)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(*adminv2.VPNServiceAuthkeyResponse)
+ }
+ }
+ if returnFunc, ok := ret.Get(1).(func(context.Context, *adminv2.VPNServiceAuthkeyRequest) error); ok {
+ r1 = returnFunc(context1, vPNServiceAuthkeyRequest)
+ } else {
+ r1 = ret.Error(1)
+ }
+ return r0, r1
+}
+
+// VPNServiceClient_Authkey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Authkey'
+type VPNServiceClient_Authkey_Call struct {
+ *mock.Call
+}
+
+// Authkey is a helper method to define mock.On call
+// - context1 context.Context
+// - vPNServiceAuthkeyRequest *adminv2.VPNServiceAuthkeyRequest
+func (_e *VPNServiceClient_Expecter) Authkey(context1 interface{}, vPNServiceAuthkeyRequest interface{}) *VPNServiceClient_Authkey_Call {
+ return &VPNServiceClient_Authkey_Call{Call: _e.mock.On("Authkey", context1, vPNServiceAuthkeyRequest)}
+}
+
+func (_c *VPNServiceClient_Authkey_Call) Run(run func(context1 context.Context, vPNServiceAuthkeyRequest *adminv2.VPNServiceAuthkeyRequest)) *VPNServiceClient_Authkey_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ var arg0 context.Context
+ if args[0] != nil {
+ arg0 = args[0].(context.Context)
+ }
+ var arg1 *adminv2.VPNServiceAuthkeyRequest
+ if args[1] != nil {
+ arg1 = args[1].(*adminv2.VPNServiceAuthkeyRequest)
+ }
+ run(
+ arg0,
+ arg1,
+ )
+ })
+ return _c
+}
+
+func (_c *VPNServiceClient_Authkey_Call) Return(vPNServiceAuthkeyResponse *adminv2.VPNServiceAuthkeyResponse, err error) *VPNServiceClient_Authkey_Call {
+ _c.Call.Return(vPNServiceAuthkeyResponse, err)
+ return _c
+}
+
+func (_c *VPNServiceClient_Authkey_Call) RunAndReturn(run func(context1 context.Context, vPNServiceAuthkeyRequest *adminv2.VPNServiceAuthkeyRequest) (*adminv2.VPNServiceAuthkeyResponse, error)) *VPNServiceClient_Authkey_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
+// ListNodes provides a mock function for the type VPNServiceClient
+func (_mock *VPNServiceClient) ListNodes(context1 context.Context, vPNServiceListNodesRequest *adminv2.VPNServiceListNodesRequest) (*adminv2.VPNServiceListNodesResponse, error) {
+ ret := _mock.Called(context1, vPNServiceListNodesRequest)
+
+ if len(ret) == 0 {
+ panic("no return value specified for ListNodes")
+ }
+
+ var r0 *adminv2.VPNServiceListNodesResponse
+ var r1 error
+ if returnFunc, ok := ret.Get(0).(func(context.Context, *adminv2.VPNServiceListNodesRequest) (*adminv2.VPNServiceListNodesResponse, error)); ok {
+ return returnFunc(context1, vPNServiceListNodesRequest)
+ }
+ if returnFunc, ok := ret.Get(0).(func(context.Context, *adminv2.VPNServiceListNodesRequest) *adminv2.VPNServiceListNodesResponse); ok {
+ r0 = returnFunc(context1, vPNServiceListNodesRequest)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(*adminv2.VPNServiceListNodesResponse)
+ }
+ }
+ if returnFunc, ok := ret.Get(1).(func(context.Context, *adminv2.VPNServiceListNodesRequest) error); ok {
+ r1 = returnFunc(context1, vPNServiceListNodesRequest)
+ } else {
+ r1 = ret.Error(1)
+ }
+ return r0, r1
+}
+
+// VPNServiceClient_ListNodes_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListNodes'
+type VPNServiceClient_ListNodes_Call struct {
+ *mock.Call
+}
+
+// ListNodes is a helper method to define mock.On call
+// - context1 context.Context
+// - vPNServiceListNodesRequest *adminv2.VPNServiceListNodesRequest
+func (_e *VPNServiceClient_Expecter) ListNodes(context1 interface{}, vPNServiceListNodesRequest interface{}) *VPNServiceClient_ListNodes_Call {
+ return &VPNServiceClient_ListNodes_Call{Call: _e.mock.On("ListNodes", context1, vPNServiceListNodesRequest)}
+}
+
+func (_c *VPNServiceClient_ListNodes_Call) Run(run func(context1 context.Context, vPNServiceListNodesRequest *adminv2.VPNServiceListNodesRequest)) *VPNServiceClient_ListNodes_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ var arg0 context.Context
+ if args[0] != nil {
+ arg0 = args[0].(context.Context)
+ }
+ var arg1 *adminv2.VPNServiceListNodesRequest
+ if args[1] != nil {
+ arg1 = args[1].(*adminv2.VPNServiceListNodesRequest)
+ }
+ run(
+ arg0,
+ arg1,
+ )
+ })
+ return _c
+}
+
+func (_c *VPNServiceClient_ListNodes_Call) Return(vPNServiceListNodesResponse *adminv2.VPNServiceListNodesResponse, err error) *VPNServiceClient_ListNodes_Call {
+ _c.Call.Return(vPNServiceListNodesResponse, err)
+ return _c
+}
+
+func (_c *VPNServiceClient_ListNodes_Call) RunAndReturn(run func(context1 context.Context, vPNServiceListNodesRequest *adminv2.VPNServiceListNodesRequest) (*adminv2.VPNServiceListNodesResponse, error)) *VPNServiceClient_ListNodes_Call {
+ _c.Call.Return(run)
+ return _c
+}
diff --git a/go/tests/mocks/metalstack/admin/v2/adminv2connect/VPNServiceHandler.go b/go/tests/mocks/metalstack/admin/v2/adminv2connect/VPNServiceHandler.go
new file mode 100644
index 00000000..73be9e73
--- /dev/null
+++ b/go/tests/mocks/metalstack/admin/v2/adminv2connect/VPNServiceHandler.go
@@ -0,0 +1,175 @@
+// Code generated by mockery; DO NOT EDIT.
+// github.com/vektra/mockery
+// template: testify
+
+package adminv2connect
+
+import (
+ "context"
+
+ "github.com/metal-stack/api/go/metalstack/admin/v2"
+ mock "github.com/stretchr/testify/mock"
+)
+
+// NewVPNServiceHandler creates a new instance of VPNServiceHandler. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewVPNServiceHandler(t interface {
+ mock.TestingT
+ Cleanup(func())
+}) *VPNServiceHandler {
+ mock := &VPNServiceHandler{}
+ mock.Mock.Test(t)
+
+ t.Cleanup(func() { mock.AssertExpectations(t) })
+
+ return mock
+}
+
+// VPNServiceHandler is an autogenerated mock type for the VPNServiceHandler type
+type VPNServiceHandler struct {
+ mock.Mock
+}
+
+type VPNServiceHandler_Expecter struct {
+ mock *mock.Mock
+}
+
+func (_m *VPNServiceHandler) EXPECT() *VPNServiceHandler_Expecter {
+ return &VPNServiceHandler_Expecter{mock: &_m.Mock}
+}
+
+// Authkey provides a mock function for the type VPNServiceHandler
+func (_mock *VPNServiceHandler) Authkey(context1 context.Context, vPNServiceAuthkeyRequest *adminv2.VPNServiceAuthkeyRequest) (*adminv2.VPNServiceAuthkeyResponse, error) {
+ ret := _mock.Called(context1, vPNServiceAuthkeyRequest)
+
+ if len(ret) == 0 {
+ panic("no return value specified for Authkey")
+ }
+
+ var r0 *adminv2.VPNServiceAuthkeyResponse
+ var r1 error
+ if returnFunc, ok := ret.Get(0).(func(context.Context, *adminv2.VPNServiceAuthkeyRequest) (*adminv2.VPNServiceAuthkeyResponse, error)); ok {
+ return returnFunc(context1, vPNServiceAuthkeyRequest)
+ }
+ if returnFunc, ok := ret.Get(0).(func(context.Context, *adminv2.VPNServiceAuthkeyRequest) *adminv2.VPNServiceAuthkeyResponse); ok {
+ r0 = returnFunc(context1, vPNServiceAuthkeyRequest)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(*adminv2.VPNServiceAuthkeyResponse)
+ }
+ }
+ if returnFunc, ok := ret.Get(1).(func(context.Context, *adminv2.VPNServiceAuthkeyRequest) error); ok {
+ r1 = returnFunc(context1, vPNServiceAuthkeyRequest)
+ } else {
+ r1 = ret.Error(1)
+ }
+ return r0, r1
+}
+
+// VPNServiceHandler_Authkey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Authkey'
+type VPNServiceHandler_Authkey_Call struct {
+ *mock.Call
+}
+
+// Authkey is a helper method to define mock.On call
+// - context1 context.Context
+// - vPNServiceAuthkeyRequest *adminv2.VPNServiceAuthkeyRequest
+func (_e *VPNServiceHandler_Expecter) Authkey(context1 interface{}, vPNServiceAuthkeyRequest interface{}) *VPNServiceHandler_Authkey_Call {
+ return &VPNServiceHandler_Authkey_Call{Call: _e.mock.On("Authkey", context1, vPNServiceAuthkeyRequest)}
+}
+
+func (_c *VPNServiceHandler_Authkey_Call) Run(run func(context1 context.Context, vPNServiceAuthkeyRequest *adminv2.VPNServiceAuthkeyRequest)) *VPNServiceHandler_Authkey_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ var arg0 context.Context
+ if args[0] != nil {
+ arg0 = args[0].(context.Context)
+ }
+ var arg1 *adminv2.VPNServiceAuthkeyRequest
+ if args[1] != nil {
+ arg1 = args[1].(*adminv2.VPNServiceAuthkeyRequest)
+ }
+ run(
+ arg0,
+ arg1,
+ )
+ })
+ return _c
+}
+
+func (_c *VPNServiceHandler_Authkey_Call) Return(vPNServiceAuthkeyResponse *adminv2.VPNServiceAuthkeyResponse, err error) *VPNServiceHandler_Authkey_Call {
+ _c.Call.Return(vPNServiceAuthkeyResponse, err)
+ return _c
+}
+
+func (_c *VPNServiceHandler_Authkey_Call) RunAndReturn(run func(context1 context.Context, vPNServiceAuthkeyRequest *adminv2.VPNServiceAuthkeyRequest) (*adminv2.VPNServiceAuthkeyResponse, error)) *VPNServiceHandler_Authkey_Call {
+ _c.Call.Return(run)
+ return _c
+}
+
+// ListNodes provides a mock function for the type VPNServiceHandler
+func (_mock *VPNServiceHandler) ListNodes(context1 context.Context, vPNServiceListNodesRequest *adminv2.VPNServiceListNodesRequest) (*adminv2.VPNServiceListNodesResponse, error) {
+ ret := _mock.Called(context1, vPNServiceListNodesRequest)
+
+ if len(ret) == 0 {
+ panic("no return value specified for ListNodes")
+ }
+
+ var r0 *adminv2.VPNServiceListNodesResponse
+ var r1 error
+ if returnFunc, ok := ret.Get(0).(func(context.Context, *adminv2.VPNServiceListNodesRequest) (*adminv2.VPNServiceListNodesResponse, error)); ok {
+ return returnFunc(context1, vPNServiceListNodesRequest)
+ }
+ if returnFunc, ok := ret.Get(0).(func(context.Context, *adminv2.VPNServiceListNodesRequest) *adminv2.VPNServiceListNodesResponse); ok {
+ r0 = returnFunc(context1, vPNServiceListNodesRequest)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(*adminv2.VPNServiceListNodesResponse)
+ }
+ }
+ if returnFunc, ok := ret.Get(1).(func(context.Context, *adminv2.VPNServiceListNodesRequest) error); ok {
+ r1 = returnFunc(context1, vPNServiceListNodesRequest)
+ } else {
+ r1 = ret.Error(1)
+ }
+ return r0, r1
+}
+
+// VPNServiceHandler_ListNodes_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListNodes'
+type VPNServiceHandler_ListNodes_Call struct {
+ *mock.Call
+}
+
+// ListNodes is a helper method to define mock.On call
+// - context1 context.Context
+// - vPNServiceListNodesRequest *adminv2.VPNServiceListNodesRequest
+func (_e *VPNServiceHandler_Expecter) ListNodes(context1 interface{}, vPNServiceListNodesRequest interface{}) *VPNServiceHandler_ListNodes_Call {
+ return &VPNServiceHandler_ListNodes_Call{Call: _e.mock.On("ListNodes", context1, vPNServiceListNodesRequest)}
+}
+
+func (_c *VPNServiceHandler_ListNodes_Call) Run(run func(context1 context.Context, vPNServiceListNodesRequest *adminv2.VPNServiceListNodesRequest)) *VPNServiceHandler_ListNodes_Call {
+ _c.Call.Run(func(args mock.Arguments) {
+ var arg0 context.Context
+ if args[0] != nil {
+ arg0 = args[0].(context.Context)
+ }
+ var arg1 *adminv2.VPNServiceListNodesRequest
+ if args[1] != nil {
+ arg1 = args[1].(*adminv2.VPNServiceListNodesRequest)
+ }
+ run(
+ arg0,
+ arg1,
+ )
+ })
+ return _c
+}
+
+func (_c *VPNServiceHandler_ListNodes_Call) Return(vPNServiceListNodesResponse *adminv2.VPNServiceListNodesResponse, err error) *VPNServiceHandler_ListNodes_Call {
+ _c.Call.Return(vPNServiceListNodesResponse, err)
+ return _c
+}
+
+func (_c *VPNServiceHandler_ListNodes_Call) RunAndReturn(run func(context1 context.Context, vPNServiceListNodesRequest *adminv2.VPNServiceListNodesRequest) (*adminv2.VPNServiceListNodesResponse, error)) *VPNServiceHandler_ListNodes_Call {
+ _c.Call.Return(run)
+ return _c
+}
diff --git a/proto/buf.gen.yaml b/proto/buf.gen.yaml
index 2b8a18e8..8b1c86e4 100644
--- a/proto/buf.gen.yaml
+++ b/proto/buf.gen.yaml
@@ -13,7 +13,7 @@ managed:
value: github.com/metal-stack/api/go
plugins:
# go
- - remote: buf.build/protocolbuffers/go:v1.36.10
+ - remote: buf.build/protocolbuffers/go:v1.36.11
out: ../go
opt: paths=source_relative
- remote: buf.build/connectrpc/go:v1.19.1
diff --git a/proto/buf.lock b/proto/buf.lock
index bb66131a..069cd88d 100644
--- a/proto/buf.lock
+++ b/proto/buf.lock
@@ -2,5 +2,5 @@
version: v2
deps:
- name: buf.build/bufbuild/protovalidate
- commit: 52f32327d4b045a79293a6ad4e7e1236
- digest: b5:cbabc98d4b7b7b0447c9b15f68eeb8a7a44ef8516cb386ac5f66e7fd4062cd6723ed3f452ad8c384b851f79e33d26e7f8a94e2b807282b3def1cd966c7eace97
+ commit: 2a1774d888024a9b93ce7eb4b59f6a83
+ digest: b5:6b7f9bc919b65e5b79d7b726ffc03d6f815a412d6b792970fa6f065cae162107bd0a9d47272c8ab1a2c9514e87b13d3fbf71df614374d62d2183afb64be2d30a
diff --git a/proto/metalstack/admin/v2/vpn.proto b/proto/metalstack/admin/v2/vpn.proto
new file mode 100644
index 00000000..a73730a8
--- /dev/null
+++ b/proto/metalstack/admin/v2/vpn.proto
@@ -0,0 +1,53 @@
+syntax = "proto3";
+
+package metalstack.admin.v2;
+
+import "buf/validate/validate.proto";
+import "google/protobuf/duration.proto";
+import "metalstack/api/v2/common.proto";
+import "metalstack/api/v2/vpn.proto";
+
+// VPNService serves vpn related functions
+service VPNService {
+ // AuthKey generates a authkey for a project to join a machine to the project vpn
+ rpc Authkey(VPNServiceAuthkeyRequest) returns (VPNServiceAuthkeyResponse) {
+ option (metalstack.api.v2.admin_roles) = ADMIN_ROLE_EDITOR;
+ }
+ // ListNodes returns a list of machines actually connected to the vpn
+ rpc ListNodes(VPNServiceListNodesRequest) returns (VPNServiceListNodesResponse) {
+ option (metalstack.api.v2.admin_roles) = ADMIN_ROLE_EDITOR;
+ }
+}
+
+// ------------------------ Service Messages ----------------------------------
+
+// VPNServiceAuthkeyRequest is the request payload for a vpn authkey request.
+message VPNServiceAuthkeyRequest {
+ // Project for which a vpn authkey should be generated.
+ string project = 1 [(buf.validate.field).string.uuid = true];
+ // Ephemeral defines if the authkey should be ephemeral.
+ bool ephemeral = 2;
+ // Expires defines the duration after which the authkey expires.
+ google.protobuf.Duration expires = 3;
+}
+
+// VPNServiceAuthkeyResponse is the request payload for a authkey response
+message VPNServiceAuthkeyResponse {
+ // Address is the address of the vpn control plane.
+ string address = 1;
+ // Authkey is the key to connect to the vpn at the given address.
+ // This key can only be seen once.
+ string authkey = 2;
+}
+
+// VPNServiceListNodesRequest is the request payload for a vpn list nodes request
+message VPNServiceListNodesRequest {
+ // User if given only nodes of this user are returned
+ optional string user = 1;
+}
+
+// VPNServiceListNodesResponse is the response payload for a vpn list nodes request
+message VPNServiceListNodesResponse {
+ // Nodes connected to the vpn
+ repeated metalstack.api.v2.VPNNode nodes = 1;
+}
diff --git a/proto/metalstack/api/v2/machine.proto b/proto/metalstack/api/v2/machine.proto
index 57a7c3d6..710d26f1 100644
--- a/proto/metalstack/api/v2/machine.proto
+++ b/proto/metalstack/api/v2/machine.proto
@@ -555,7 +555,8 @@ message MachineVPN {
string auth_key = 2;
// Connected indicate if this machine is connected to the VPN
bool connected = 3;
- // TODO add machine ips
+ // IPs of the machine connected to the vpn
+ repeated string ips = 5 [(buf.validate.field).repeated.(metalstack.api.v2.ips) = true];
}
// MachineLiveliness specifies the liveliness of a machine
@@ -648,6 +649,8 @@ message MachineAllocationQuery {
optional MachineAllocationType allocation_type = 7 [(buf.validate.field).enum.defined_only = true];
// Labels for which this machine allocation should get filtered
optional Labels labels = 8;
+ // VPN query if this machine has a vpn configuration
+ optional MachineVPN vpn = 9;
}
// MachineNetworkQuery network specific machine queries
diff --git a/proto/metalstack/api/v2/vpn.proto b/proto/metalstack/api/v2/vpn.proto
new file mode 100644
index 00000000..22cb03f9
--- /dev/null
+++ b/proto/metalstack/api/v2/vpn.proto
@@ -0,0 +1,21 @@
+syntax = "proto3";
+
+package metalstack.api.v2;
+
+import "google/protobuf/timestamp.proto";
+
+// VPNNode is a machine connected to the vpn
+message VPNNode {
+ // Id of this node
+ uint64 id = 1;
+ // Name of this node
+ string name = 2;
+ // User of this node, maps to a project
+ optional string user = 3;
+ // IPAddresses of this node in the vpn
+ repeated string ip_addresses = 4;
+ // LastSeen timestamp when this node reached out the the control plane
+ google.protobuf.Timestamp last_seen = 5;
+ // Online indicates if this node is online
+ bool online = 6;
+}
diff --git a/python/metalstack/admin/v2/vpn_connect.py b/python/metalstack/admin/v2/vpn_connect.py
new file mode 100644
index 00000000..7c518f0d
--- /dev/null
+++ b/python/metalstack/admin/v2/vpn_connect.py
@@ -0,0 +1,184 @@
+# -*- coding: utf-8 -*-
+# Generated by https://github.com/connectrpc/connect-python. DO NOT EDIT!
+# source: metalstack/admin/v2/vpn.proto
+
+from collections.abc import AsyncIterator, Iterable, Iterator, Mapping
+from typing import Protocol
+
+from connectrpc.client import ConnectClient, ConnectClientSync
+from connectrpc.code import Code
+from connectrpc.errors import ConnectError
+from connectrpc.interceptor import Interceptor, InterceptorSync
+from connectrpc.method import IdempotencyLevel, MethodInfo
+from connectrpc.request import Headers, RequestContext
+from connectrpc.server import ConnectASGIApplication, ConnectWSGIApplication, Endpoint, EndpointSync
+import metalstack.admin.v2.vpn_pb2 as metalstack_dot_admin_dot_v2_dot_vpn__pb2
+
+
+class VPNService(Protocol):
+ async def authkey(self, request: metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceAuthkeyRequest, ctx: RequestContext) -> metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceAuthkeyResponse:
+ raise ConnectError(Code.UNIMPLEMENTED, "Not implemented")
+
+ async def list_nodes(self, request: metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceListNodesRequest, ctx: RequestContext) -> metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceListNodesResponse:
+ raise ConnectError(Code.UNIMPLEMENTED, "Not implemented")
+
+
+class VPNServiceASGIApplication(ConnectASGIApplication):
+ def __init__(self, service: VPNService, *, interceptors: Iterable[Interceptor]=(), read_max_bytes: int | None = None) -> None:
+ super().__init__(
+ endpoints={
+ "/metalstack.admin.v2.VPNService/Authkey": Endpoint.unary(
+ method=MethodInfo(
+ name="Authkey",
+ service_name="metalstack.admin.v2.VPNService",
+ input=metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceAuthkeyRequest,
+ output=metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceAuthkeyResponse,
+ idempotency_level=IdempotencyLevel.UNKNOWN,
+ ),
+ function=service.authkey,
+ ),
+ "/metalstack.admin.v2.VPNService/ListNodes": Endpoint.unary(
+ method=MethodInfo(
+ name="ListNodes",
+ service_name="metalstack.admin.v2.VPNService",
+ input=metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceListNodesRequest,
+ output=metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceListNodesResponse,
+ idempotency_level=IdempotencyLevel.UNKNOWN,
+ ),
+ function=service.list_nodes,
+ ),
+ },
+ interceptors=interceptors,
+ read_max_bytes=read_max_bytes,
+ )
+
+ @property
+ def path(self) -> str:
+ """Returns the URL path to mount the application to when serving multiple applications."""
+ return "/metalstack.admin.v2.VPNService"
+
+
+class VPNServiceClient(ConnectClient):
+ async def authkey(
+ self,
+ request: metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceAuthkeyRequest,
+ *,
+ headers: Headers | Mapping[str, str] | None = None,
+ timeout_ms: int | None = None,
+ ) -> metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceAuthkeyResponse:
+ return await self.execute_unary(
+ request=request,
+ method=MethodInfo(
+ name="Authkey",
+ service_name="metalstack.admin.v2.VPNService",
+ input=metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceAuthkeyRequest,
+ output=metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceAuthkeyResponse,
+ idempotency_level=IdempotencyLevel.UNKNOWN,
+ ),
+ headers=headers,
+ timeout_ms=timeout_ms,
+ )
+
+ async def list_nodes(
+ self,
+ request: metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceListNodesRequest,
+ *,
+ headers: Headers | Mapping[str, str] | None = None,
+ timeout_ms: int | None = None,
+ ) -> metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceListNodesResponse:
+ return await self.execute_unary(
+ request=request,
+ method=MethodInfo(
+ name="ListNodes",
+ service_name="metalstack.admin.v2.VPNService",
+ input=metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceListNodesRequest,
+ output=metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceListNodesResponse,
+ idempotency_level=IdempotencyLevel.UNKNOWN,
+ ),
+ headers=headers,
+ timeout_ms=timeout_ms,
+ )
+
+
+class VPNServiceSync(Protocol):
+ def authkey(self, request: metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceAuthkeyRequest, ctx: RequestContext) -> metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceAuthkeyResponse:
+ raise ConnectError(Code.UNIMPLEMENTED, "Not implemented")
+ def list_nodes(self, request: metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceListNodesRequest, ctx: RequestContext) -> metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceListNodesResponse:
+ raise ConnectError(Code.UNIMPLEMENTED, "Not implemented")
+
+
+class VPNServiceWSGIApplication(ConnectWSGIApplication):
+ def __init__(self, service: VPNServiceSync, interceptors: Iterable[InterceptorSync]=(), read_max_bytes: int | None = None) -> None:
+ super().__init__(
+ endpoints={
+ "/metalstack.admin.v2.VPNService/Authkey": EndpointSync.unary(
+ method=MethodInfo(
+ name="Authkey",
+ service_name="metalstack.admin.v2.VPNService",
+ input=metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceAuthkeyRequest,
+ output=metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceAuthkeyResponse,
+ idempotency_level=IdempotencyLevel.UNKNOWN,
+ ),
+ function=service.authkey,
+ ),
+ "/metalstack.admin.v2.VPNService/ListNodes": EndpointSync.unary(
+ method=MethodInfo(
+ name="ListNodes",
+ service_name="metalstack.admin.v2.VPNService",
+ input=metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceListNodesRequest,
+ output=metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceListNodesResponse,
+ idempotency_level=IdempotencyLevel.UNKNOWN,
+ ),
+ function=service.list_nodes,
+ ),
+ },
+ interceptors=interceptors,
+ read_max_bytes=read_max_bytes,
+ )
+
+ @property
+ def path(self) -> str:
+ """Returns the URL path to mount the application to when serving multiple applications."""
+ return "/metalstack.admin.v2.VPNService"
+
+
+class VPNServiceClientSync(ConnectClientSync):
+ def authkey(
+ self,
+ request: metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceAuthkeyRequest,
+ *,
+ headers: Headers | Mapping[str, str] | None = None,
+ timeout_ms: int | None = None,
+ ) -> metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceAuthkeyResponse:
+ return self.execute_unary(
+ request=request,
+ method=MethodInfo(
+ name="Authkey",
+ service_name="metalstack.admin.v2.VPNService",
+ input=metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceAuthkeyRequest,
+ output=metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceAuthkeyResponse,
+ idempotency_level=IdempotencyLevel.UNKNOWN,
+ ),
+ headers=headers,
+ timeout_ms=timeout_ms,
+ )
+
+ def list_nodes(
+ self,
+ request: metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceListNodesRequest,
+ *,
+ headers: Headers | Mapping[str, str] | None = None,
+ timeout_ms: int | None = None,
+ ) -> metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceListNodesResponse:
+ return self.execute_unary(
+ request=request,
+ method=MethodInfo(
+ name="ListNodes",
+ service_name="metalstack.admin.v2.VPNService",
+ input=metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceListNodesRequest,
+ output=metalstack_dot_admin_dot_v2_dot_vpn__pb2.VPNServiceListNodesResponse,
+ idempotency_level=IdempotencyLevel.UNKNOWN,
+ ),
+ headers=headers,
+ timeout_ms=timeout_ms,
+ )
diff --git a/python/metalstack/admin/v2/vpn_pb2.py b/python/metalstack/admin/v2/vpn_pb2.py
new file mode 100644
index 00000000..4d07f80b
--- /dev/null
+++ b/python/metalstack/admin/v2/vpn_pb2.py
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: metalstack/admin/v2/vpn.proto
+# Protobuf Python Version: 6.32.1
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import descriptor_pool as _descriptor_pool
+from google.protobuf import runtime_version as _runtime_version
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf.internal import builder as _builder
+_runtime_version.ValidateProtobufRuntimeVersion(
+ _runtime_version.Domain.PUBLIC,
+ 6,
+ 32,
+ 1,
+ '',
+ 'metalstack/admin/v2/vpn.proto'
+)
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+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 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\"O\n\x19VPNServiceAuthkeyResponse\x12\x18\n\x07\x61\x64\x64ress\x18\x01 \x01(\tR\x07\x61\x64\x64ress\x12\x18\n\x07\x61uthkey\x18\x02 \x01(\tR\x07\x61uthkey\">\n\x1aVPNServiceListNodesRequest\x12\x17\n\x04user\x18\x01 \x01(\tH\x00R\x04user\x88\x01\x01\x42\x07\n\x05_user\"O\n\x1bVPNServiceListNodesResponse\x12\x30\n\x05nodes\x18\x01 \x03(\x0b\x32\x1a.metalstack.api.v2.VPNNodeR\x05nodes2\xf4\x01\n\nVPNService\x12o\n\x07\x41uthkey\x12-.metalstack.admin.v2.VPNServiceAuthkeyRequest\x1a..metalstack.admin.v2.VPNServiceAuthkeyResponse\"\x05\xd2\xf3\x18\x01\x01\x12u\n\tListNodes\x12/.metalstack.admin.v2.VPNServiceListNodesRequest\x1a\x30.metalstack.admin.v2.VPNServiceListNodesResponse\"\x05\xd2\xf3\x18\x01\x01\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)
+_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'metalstack.admin.v2.vpn_pb2', _globals)
+if not _descriptor._USE_C_DESCRIPTORS:
+ _globals['DESCRIPTOR']._loaded_options = None
+ _globals['DESCRIPTOR']._serialized_options = b'\n\027com.metalstack.admin.v2B\010VpnProtoP\001Z9github.com/metal-stack/api/go/metalstack/admin/v2;adminv2\242\002\003MAX\252\002\023Metalstack.Admin.V2\312\002\023Metalstack\\Admin\\V2\342\002\037Metalstack\\Admin\\V2\\GPBMetadata\352\002\025Metalstack::Admin::V2'
+ _globals['_VPNSERVICEAUTHKEYREQUEST'].fields_by_name['project']._loaded_options = None
+ _globals['_VPNSERVICEAUTHKEYREQUEST'].fields_by_name['project']._serialized_options = b'\272H\005r\003\260\001\001'
+ _globals['_VPNSERVICE'].methods_by_name['Authkey']._loaded_options = None
+ _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\001\001'
+ _globals['_VPNSERVICEAUTHKEYREQUEST']._serialized_start=177
+ _globals['_VPNSERVICEAUTHKEYREQUEST']._serialized_end=322
+ _globals['_VPNSERVICEAUTHKEYRESPONSE']._serialized_start=324
+ _globals['_VPNSERVICEAUTHKEYRESPONSE']._serialized_end=403
+ _globals['_VPNSERVICELISTNODESREQUEST']._serialized_start=405
+ _globals['_VPNSERVICELISTNODESREQUEST']._serialized_end=467
+ _globals['_VPNSERVICELISTNODESRESPONSE']._serialized_start=469
+ _globals['_VPNSERVICELISTNODESRESPONSE']._serialized_end=548
+ _globals['_VPNSERVICE']._serialized_start=551
+ _globals['_VPNSERVICE']._serialized_end=795
+# @@protoc_insertion_point(module_scope)
diff --git a/python/metalstack/admin/v2/vpn_pb2.pyi b/python/metalstack/admin/v2/vpn_pb2.pyi
new file mode 100644
index 00000000..f7dd9ed9
--- /dev/null
+++ b/python/metalstack/admin/v2/vpn_pb2.pyi
@@ -0,0 +1,43 @@
+import datetime
+
+from buf.validate import validate_pb2 as _validate_pb2
+from google.protobuf import duration_pb2 as _duration_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
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from collections.abc import Iterable as _Iterable, Mapping as _Mapping
+from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union
+
+DESCRIPTOR: _descriptor.FileDescriptor
+
+class VPNServiceAuthkeyRequest(_message.Message):
+ __slots__ = ("project", "ephemeral", "expires")
+ PROJECT_FIELD_NUMBER: _ClassVar[int]
+ EPHEMERAL_FIELD_NUMBER: _ClassVar[int]
+ EXPIRES_FIELD_NUMBER: _ClassVar[int]
+ project: str
+ ephemeral: bool
+ expires: _duration_pb2.Duration
+ 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", "authkey")
+ ADDRESS_FIELD_NUMBER: _ClassVar[int]
+ AUTHKEY_FIELD_NUMBER: _ClassVar[int]
+ address: str
+ authkey: str
+ def __init__(self, address: _Optional[str] = ..., authkey: _Optional[str] = ...) -> None: ...
+
+class VPNServiceListNodesRequest(_message.Message):
+ __slots__ = ("user",)
+ USER_FIELD_NUMBER: _ClassVar[int]
+ user: str
+ def __init__(self, user: _Optional[str] = ...) -> None: ...
+
+class VPNServiceListNodesResponse(_message.Message):
+ __slots__ = ("nodes",)
+ NODES_FIELD_NUMBER: _ClassVar[int]
+ nodes: _containers.RepeatedCompositeFieldContainer[_vpn_pb2.VPNNode]
+ def __init__(self, nodes: _Optional[_Iterable[_Union[_vpn_pb2.VPNNode, _Mapping]]] = ...) -> None: ...
diff --git a/python/metalstack/api/v2/machine_pb2.py b/python/metalstack/api/v2/machine_pb2.py
index ad3237a2..db71f836 100644
--- a/python/metalstack/api/v2/machine_pb2.py
+++ b/python/metalstack/api/v2/machine_pb2.py
@@ -33,7 +33,7 @@
from metalstack.api.v2 import size_pb2 as metalstack_dot_api_dot_v2_dot_size__pb2
-DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmetalstack/api/v2/machine.proto\x12\x11metalstack.api.v2\x1a\x1b\x62uf/validate/validate.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1emetalstack/api/v2/common.proto\x1a\"metalstack/api/v2/filesystem.proto\x1a\x1dmetalstack/api/v2/image.proto\x1a\x1fmetalstack/api/v2/network.proto\x1a!metalstack/api/v2/partition.proto\x1a(metalstack/api/v2/predefined_rules.proto\x1a\x1cmetalstack/api/v2/size.proto\"\\\n\x18MachineServiceGetRequest\x12\x1c\n\x04uuid\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x04uuid\x12\"\n\x07project\x18\x02 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x07project\"Q\n\x19MachineServiceGetResponse\x12\x34\n\x07machine\x18\x01 \x01(\x0b\x32\x1a.metalstack.api.v2.MachineR\x07machine\"\xa2\x08\n\x1bMachineServiceCreateRequest\x12\"\n\x07project\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x07project\x12!\n\x04uuid\x18\x02 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01H\x00R\x04uuid\x88\x01\x01\x12\x1f\n\x04name\x18\x03 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01R\x04name\x12\x32\n\x0b\x64\x65scription\x18\x04 \x01(\tB\x0b\xbaH\x08r\x06\xc8\xb3\xae\xb1\x02\x01H\x01R\x0b\x64\x65scription\x88\x01\x01\x12(\n\x08hostname\x18\x05 \x01(\tB\x07\xbaH\x04r\x02h\x01H\x02R\x08hostname\x88\x01\x01\x12)\n\tpartition\x18\x06 \x01(\tB\x0b\xbaH\x08r\x06\xd0\xb3\xae\xb1\x02\x01R\tpartition\x12\x1c\n\x04size\x18\x07 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01R\x04size\x12\x1e\n\x05image\x18\x08 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01R\x05image\x12\x30\n\x11\x66ilesystem_layout\x18\t \x01(\tH\x03R\x10\x66ilesystemLayout\x88\x01\x01\x12\x39\n\x0fssh_public_keys\x18\n \x03(\tB\x11\xbaH\x0e\x92\x01\x0b\x10\x32\"\x07r\x05\x10\x01\x18\x80@R\rsshPublicKeys\x12*\n\x08userdata\x18\x0b \x01(\tB\t\xbaH\x06r\x04\x18\x80\x80\x02H\x04R\x08userdata\x88\x01\x01\x12\x31\n\x06labels\x18\x0c \x01(\x0b\x32\x19.metalstack.api.v2.LabelsR\x06labels\x12G\n\x08networks\x18\r \x03(\x0b\x32+.metalstack.api.v2.MachineAllocationNetworkR\x08networks\x12\x1e\n\x03ips\x18\x0e \x03(\tB\x0c\xbaH\t\x92\x01\x06\xe8\xb3\xae\xb1\x02\x01R\x03ips\x12%\n\x0eplacement_tags\x18\x0f \x03(\tR\rplacementTags\x12\x45\n\ndns_server\x18\x10 \x03(\x0b\x32\x1c.metalstack.api.v2.DNSServerB\x08\xbaH\x05\x92\x01\x02\x10\x03R\tdnsServer\x12\x45\n\nntp_server\x18\x11 \x03(\x0b\x32\x1c.metalstack.api.v2.NTPServerB\x08\xbaH\x05\x92\x01\x02\x10\nR\tntpServer\x12[\n\x0f\x61llocation_type\x18\x12 \x01(\x0e\x32(.metalstack.api.v2.MachineAllocationTypeB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x0e\x61llocationType\x12\x44\n\rfirewall_spec\x18\x13 \x01(\x0b\x32\x1f.metalstack.api.v2.FirewallSpecR\x0c\x66irewallSpecB\x07\n\x05_uuidB\x0e\n\x0c_descriptionB\x0b\n\t_hostnameB\x14\n\x12_filesystem_layoutB\x0b\n\t_userdata\"W\n\x0c\x46irewallSpec\x12G\n\x0e\x66irewall_rules\x18\x13 \x01(\x0b\x32 .metalstack.api.v2.FirewallRulesR\rfirewallRules\"T\n\x1cMachineServiceCreateResponse\x12\x34\n\x07machine\x18\x01 \x01(\x0b\x32\x1a.metalstack.api.v2.MachineR\x07machine\"\xef\x02\n\x1bMachineServiceUpdateRequest\x12\x1c\n\x04uuid\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x04uuid\x12\x46\n\x0bupdate_meta\x18\x02 \x01(\x0b\x32\x1d.metalstack.api.v2.UpdateMetaB\x06\xbaH\x03\xc8\x01\x01R\nupdateMeta\x12\"\n\x07project\x18\x03 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x07project\x12\x32\n\x0b\x64\x65scription\x18\x04 \x01(\tB\x0b\xbaH\x08r\x06\xc8\xb3\xae\xb1\x02\x01H\x00R\x0b\x64\x65scription\x88\x01\x01\x12<\n\x06labels\x18\x05 \x01(\x0b\x32\x1f.metalstack.api.v2.UpdateLabelsH\x01R\x06labels\x88\x01\x01\x12\x39\n\x0fssh_public_keys\x18\x06 \x03(\tB\x11\xbaH\x0e\x92\x01\x0b\x10\x32\"\x07r\x05\x10\x01\x18\x80@R\rsshPublicKeysB\x0e\n\x0c_descriptionB\t\n\x07_labels\"T\n\x1cMachineServiceUpdateResponse\x12\x34\n\x07machine\x18\x01 \x01(\x0b\x32\x1a.metalstack.api.v2.MachineR\x07machine\"v\n\x19MachineServiceListRequest\x12\"\n\x07project\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x07project\x12\x35\n\x05query\x18\x02 \x01(\x0b\x32\x1f.metalstack.api.v2.MachineQueryR\x05query\"T\n\x1aMachineServiceListResponse\x12\x36\n\x08machines\x18\x01 \x03(\x0b\x32\x1a.metalstack.api.v2.MachineR\x08machines\"_\n\x1bMachineServiceDeleteRequest\x12\x1c\n\x04uuid\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x04uuid\x12\"\n\x07project\x18\x02 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x07project\"T\n\x1cMachineServiceDeleteResponse\x12\x34\n\x07machine\x18\x01 \x01(\x0b\x32\x1a.metalstack.api.v2.MachineR\x07machine\"\xc1\x04\n\x07Machine\x12\x1c\n\x04uuid\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x04uuid\x12+\n\x04meta\x18\x02 \x01(\x0b\x32\x17.metalstack.api.v2.MetaR\x04meta\x12:\n\tpartition\x18\x03 \x01(\x0b\x32\x1c.metalstack.api.v2.PartitionR\tpartition\x12\x1c\n\x04rack\x18\x04 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01R\x04rack\x12+\n\x04size\x18\x05 \x01(\x0b\x32\x17.metalstack.api.v2.SizeR\x04size\x12>\n\x08hardware\x18\x06 \x01(\x0b\x32\".metalstack.api.v2.MachineHardwareR\x08hardware\x12\x32\n\x04\x62ios\x18\x07 \x01(\x0b\x32\x1e.metalstack.api.v2.MachineBiosR\x04\x62ios\x12\x44\n\nallocation\x18\x08 \x01(\x0b\x32$.metalstack.api.v2.MachineAllocationR\nallocation\x12\x38\n\x06status\x18\t \x01(\x0b\x32 .metalstack.api.v2.MachineStatusR\x06status\x12p\n\x1arecent_provisioning_events\x18\n \x01(\x0b\x32\x32.metalstack.api.v2.MachineRecentProvisioningEventsR\x18recentProvisioningEvents\"\xa4\x02\n\rMachineStatus\x12\x41\n\tcondition\x18\x01 \x01(\x0b\x32#.metalstack.api.v2.MachineConditionR\tcondition\x12N\n\tled_state\x18\x02 \x01(\x0b\x32\x31.metalstack.api.v2.MachineChassisIdentifyLEDStateR\x08ledState\x12N\n\nliveliness\x18\x03 \x01(\x0e\x32$.metalstack.api.v2.MachineLivelinessB\x08\xbaH\x05\x82\x01\x02\x10\x01R\nliveliness\x12\x30\n\x14metal_hammer_version\x18\x04 \x01(\tR\x12metalHammerVersion\"\xa4\x01\n\x10MachineCondition\x12?\n\x05state\x18\x01 \x01(\x0e\x32\x1f.metalstack.api.v2.MachineStateB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x05state\x12-\n\x0b\x64\x65scription\x18\x02 \x01(\tB\x0b\xbaH\x08r\x06\xc8\xb3\xae\xb1\x02\x01R\x0b\x64\x65scription\x12 \n\x06issuer\x18\x03 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x02R\x06issuer\"\xa8\x07\n\x11MachineAllocation\x12\x1c\n\x04uuid\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x04uuid\x12+\n\x04meta\x18\x02 \x01(\x0b\x32\x17.metalstack.api.v2.MetaR\x04meta\x12\x1f\n\x04name\x18\x03 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01R\x04name\x12-\n\x0b\x64\x65scription\x18\x04 \x01(\tB\x0b\xbaH\x08r\x06\xc8\xb3\xae\xb1\x02\x01R\x0b\x64\x65scription\x12\'\n\ncreated_by\x18\x05 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01R\tcreatedBy\x12\"\n\x07project\x18\x06 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x07project\x12.\n\x05image\x18\x07 \x01(\x0b\x32\x18.metalstack.api.v2.ImageR\x05image\x12P\n\x11\x66ilesystem_layout\x18\x08 \x01(\x0b\x32#.metalstack.api.v2.FilesystemLayoutR\x10\x66ilesystemLayout\x12=\n\x08networks\x18\t \x03(\x0b\x32!.metalstack.api.v2.MachineNetworkR\x08networks\x12#\n\x08hostname\x18\n \x01(\tB\x07\xbaH\x04r\x02h\x01R\x08hostname\x12\x39\n\x0fssh_public_keys\x18\x0b \x03(\tB\x11\xbaH\x0e\x92\x01\x0b\x10\x32\"\x07r\x05\x10\x01\x18\x80@R\rsshPublicKeys\x12%\n\x08userdata\x18\x0c \x01(\tB\t\xbaH\x06r\x04\x18\x80\x80\x02R\x08userdata\x12[\n\x0f\x61llocation_type\x18\r \x01(\x0e\x32(.metalstack.api.v2.MachineAllocationTypeB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x0e\x61llocationType\x12G\n\x0e\x66irewall_rules\x18\x0e \x01(\x0b\x32 .metalstack.api.v2.FirewallRulesR\rfirewallRules\x12\x45\n\ndns_server\x18\x0f \x03(\x0b\x32\x1c.metalstack.api.v2.DNSServerB\x08\xbaH\x05\x92\x01\x02\x10\x03R\tdnsServer\x12\x45\n\nntp_server\x18\x10 \x03(\x0b\x32\x1c.metalstack.api.v2.NTPServerB\x08\xbaH\x05\x92\x01\x02\x10\nR\tntpServer\x12/\n\x03vpn\x18\x11 \x01(\x0b\x32\x1d.metalstack.api.v2.MachineVPNR\x03vpn\"}\n\x18MachineAllocationNetwork\x12\x18\n\x07network\x18\x01 \x01(\tR\x07network\x12\x30\n\x12no_auto_acquire_ip\x18\x02 \x01(\x08H\x00R\x0fnoAutoAcquireIp\x88\x01\x01\x42\x15\n\x13_no_auto_acquire_ip\"\x90\x01\n\rFirewallRules\x12=\n\x06\x65gress\x18\x01 \x03(\x0b\x32%.metalstack.api.v2.FirewallEgressRuleR\x06\x65gress\x12@\n\x07ingress\x18\x02 \x03(\x0b\x32&.metalstack.api.v2.FirewallIngressRuleR\x07ingress\"\xd0\x01\n\x12\x46irewallEgressRule\x12\x43\n\x08protocol\x18\x01 \x01(\x0e\x32\x1d.metalstack.api.v2.IPProtocolB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x08protocol\x12$\n\x05ports\x18\x02 \x03(\rB\x0e\xbaH\x0b\x92\x01\x08\"\x06*\x04\x18\xfc\xff\x03R\x05ports\x12\x1c\n\x02to\x18\x03 \x03(\tB\x0c\xbaH\t\x92\x01\x06\xe0\xb3\xae\xb1\x02\x01R\x02to\x12\x31\n\x07\x63omment\x18\x04 \x01(\tB\x17\xbaH\x14r\x0f\x18\x64\x32\x0b^[a-z_ -]*$\xd8\x01\x01R\x07\x63omment\"\xf3\x01\n\x13\x46irewallIngressRule\x12\x43\n\x08protocol\x18\x01 \x01(\x0e\x32\x1d.metalstack.api.v2.IPProtocolB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x08protocol\x12$\n\x05ports\x18\x02 \x03(\rB\x0e\xbaH\x0b\x92\x01\x08\"\x06*\x04\x18\xfc\xff\x03R\x05ports\x12\x1c\n\x02to\x18\x03 \x03(\tB\x0c\xbaH\t\x92\x01\x06\xe0\xb3\xae\xb1\x02\x01R\x02to\x12 \n\x04\x66rom\x18\x04 \x03(\tB\x0c\xbaH\t\x92\x01\x06\xe0\xb3\xae\xb1\x02\x01R\x04\x66rom\x12\x31\n\x07\x63omment\x18\x05 \x01(\tB\x17\xbaH\x14r\x0f\x18\x64\x32\x0b^[a-z_ -]*$\xd8\x01\x01R\x07\x63omment\"\xe7\x02\n\x0eMachineNetwork\x12\x18\n\x07network\x18\x01 \x01(\tR\x07network\x12(\n\x08prefixes\x18\x02 \x03(\tB\x0c\xbaH\t\x92\x01\x06\xe0\xb3\xae\xb1\x02\x01R\x08prefixes\x12?\n\x14\x64\x65stination_prefixes\x18\x03 \x03(\tB\x0c\xbaH\t\x92\x01\x06\xe0\xb3\xae\xb1\x02\x01R\x13\x64\x65stinationPrefixes\x12\x1e\n\x03ips\x18\x04 \x03(\tB\x0c\xbaH\t\x92\x01\x06\xe8\xb3\xae\xb1\x02\x01R\x03ips\x12K\n\x0cnetwork_type\x18\x05 \x01(\x0e\x32\x1e.metalstack.api.v2.NetworkTypeB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x0bnetworkType\x12?\n\x08nat_type\x18\x06 \x01(\x0e\x32\x1a.metalstack.api.v2.NATTypeB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x07natType\x12\x10\n\x03vrf\x18\x07 \x01(\x04R\x03vrf\x12\x10\n\x03\x61sn\x18\x08 \x01(\rR\x03\x61sn\"\xfb\x01\n\x0fMachineHardware\x12\x16\n\x06memory\x18\x01 \x01(\x04R\x06memory\x12;\n\x05\x64isks\x18\x03 \x03(\x0b\x32%.metalstack.api.v2.MachineBlockDeviceR\x05\x64isks\x12/\n\x04\x63pus\x18\x04 \x03(\x0b\x32\x1b.metalstack.api.v2.MetalCPUR\x04\x63pus\x12/\n\x04gpus\x18\x05 \x03(\x0b\x32\x1b.metalstack.api.v2.MetalGPUR\x04gpus\x12\x31\n\x04nics\x18\x06 \x03(\x0b\x32\x1d.metalstack.api.v2.MachineNicR\x04nics\"|\n\x08MetalCPU\x12 \n\x06vendor\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x02R\x06vendor\x12\x1e\n\x05model\x18\x02 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x02R\x05model\x12\x14\n\x05\x63ores\x18\x03 \x01(\rR\x05\x63ores\x12\x18\n\x07threads\x18\x04 \x01(\rR\x07threads\"L\n\x08MetalGPU\x12 \n\x06vendor\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x02R\x06vendor\x12\x1e\n\x05model\x18\x02 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x02R\x05model\"\xa7\x02\n\nMachineNic\x12\x1d\n\x03mac\x18\x01 \x01(\tB\x0b\xbaH\x08r\x06\xb8\xb3\xae\xb1\x02\x01R\x03mac\x12\x1f\n\x04name\x18\x02 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01R\x04name\x12(\n\nidentifier\x18\x03 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01R\nidentifier\x12 \n\x06vendor\x18\x04 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01R\x06vendor\x12\x1e\n\x05model\x18\x05 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01R\x05model\x12\x14\n\x05speed\x18\x06 \x01(\x04R\x05speed\x12;\n\tneighbors\x18\x07 \x03(\x0b\x32\x1d.metalstack.api.v2.MachineNicR\tneighbors\x12\x1a\n\x08hostname\x18\x08 \x01(\tR\x08hostname\"I\n\x12MachineBlockDevice\x12\x1f\n\x04name\x18\x01 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01R\x04name\x12\x12\n\x04size\x18\x02 \x01(\x04R\x04size\"o\n\x1eMachineChassisIdentifyLEDState\x12\x1e\n\x05value\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01R\x05value\x12-\n\x0b\x64\x65scription\x18\x02 \x01(\tB\x0b\xbaH\x08r\x06\xc8\xb3\xae\xb1\x02\x01R\x0b\x64\x65scription\"q\n\x0bMachineBios\x12\"\n\x07version\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x02R\x07version\x12 \n\x06vendor\x18\x02 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x02R\x06vendor\x12\x1c\n\x04\x64\x61te\x18\x03 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x02R\x04\x64\x61te\"\xd3\x02\n\x1fMachineRecentProvisioningEvents\x12\x43\n\x06\x65vents\x18\x01 \x03(\x0b\x32+.metalstack.api.v2.MachineProvisioningEventR\x06\x65vents\x12\x42\n\x0flast_event_time\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\rlastEventTime\x12U\n\x10last_error_event\x18\x03 \x01(\x0b\x32+.metalstack.api.v2.MachineProvisioningEventR\x0elastErrorEvent\x12P\n\x05state\x18\x04 \x01(\x0e\x32\x30.metalstack.api.v2.MachineProvisioningEventStateB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x05state\"\xab\x01\n\x18MachineProvisioningEvent\x12.\n\x04time\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x04time\x12\x45\n\x05\x65vent\x18\x02 \x01(\x0e\x32/.metalstack.api.v2.MachineProvisioningEventTypeR\x05\x65vent\x12\x18\n\x07message\x18\x03 \x01(\tR\x07message\"y\n\nMachineVPN\x12\x32\n\x15\x63ontrol_plane_address\x18\x01 \x01(\tR\x13\x63ontrolPlaneAddress\x12\x19\n\x08\x61uth_key\x18\x02 \x01(\tR\x07\x61uthKey\x12\x1c\n\tconnected\x18\x03 \x01(\x08R\tconnected\"\xa8\x07\n\x0cMachineQuery\x12!\n\x04uuid\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01H\x00R\x04uuid\x88\x01\x01\x12$\n\x04name\x18\x02 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01H\x01R\x04name\x88\x01\x01\x12-\n\tpartition\x18\x03 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01H\x02R\tpartition\x88\x01\x01\x12#\n\x04size\x18\x04 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01H\x03R\x04size\x88\x01\x01\x12#\n\x04rack\x18\x05 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01H\x04R\x04rack\x88\x01\x01\x12\x36\n\x06labels\x18\x06 \x01(\x0b\x32\x19.metalstack.api.v2.LabelsH\x05R\x06labels\x88\x01\x01\x12N\n\nallocation\x18\x07 \x01(\x0b\x32).metalstack.api.v2.MachineAllocationQueryH\x06R\nallocation\x88\x01\x01\x12\x45\n\x07network\x18\x08 \x01(\x0b\x32&.metalstack.api.v2.MachineNetworkQueryH\x07R\x07network\x88\x01\x01\x12\x39\n\x03nic\x18\t \x01(\x0b\x32\".metalstack.api.v2.MachineNicQueryH\x08R\x03nic\x88\x01\x01\x12<\n\x04\x64isk\x18\n \x01(\x0b\x32#.metalstack.api.v2.MachineDiskQueryH\tR\x04\x64isk\x88\x01\x01\x12<\n\x04ipmi\x18\x0b \x01(\x0b\x32#.metalstack.api.v2.MachineIPMIQueryH\nR\x04ipmi\x88\x01\x01\x12\x39\n\x03\x66ru\x18\x0c \x01(\x0b\x32\".metalstack.api.v2.MachineFRUQueryH\x0bR\x03\x66ru\x88\x01\x01\x12H\n\x08hardware\x18\r \x01(\x0b\x32\'.metalstack.api.v2.MachineHardwareQueryH\x0cR\x08hardware\x88\x01\x01\x12:\n\x05state\x18\x0e \x01(\x0e\x32\x1f.metalstack.api.v2.MachineStateH\rR\x05state\x88\x01\x01\x42\x07\n\x05_uuidB\x07\n\x05_nameB\x0c\n\n_partitionB\x07\n\x05_sizeB\x07\n\x05_rackB\t\n\x07_labelsB\r\n\x0b_allocationB\n\n\x08_networkB\x06\n\x04_nicB\x07\n\x05_diskB\x07\n\x05_ipmiB\x06\n\x04_fruB\x0b\n\t_hardwareB\x08\n\x06_state\"\xa0\x04\n\x16MachineAllocationQuery\x12!\n\x04uuid\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01H\x00R\x04uuid\x88\x01\x01\x12$\n\x04name\x18\x02 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01H\x01R\x04name\x88\x01\x01\x12\'\n\x07project\x18\x03 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01H\x02R\x07project\x88\x01\x01\x12%\n\x05image\x18\x04 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01H\x03R\x05image\x88\x01\x01\x12<\n\x11\x66ilesystem_layout\x18\x05 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01H\x04R\x10\x66ilesystemLayout\x88\x01\x01\x12+\n\x08hostname\x18\x06 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01H\x05R\x08hostname\x88\x01\x01\x12`\n\x0f\x61llocation_type\x18\x07 \x01(\x0e\x32(.metalstack.api.v2.MachineAllocationTypeB\x08\xbaH\x05\x82\x01\x02\x10\x01H\x06R\x0e\x61llocationType\x88\x01\x01\x12\x36\n\x06labels\x18\x08 \x01(\x0b\x32\x19.metalstack.api.v2.LabelsH\x07R\x06labels\x88\x01\x01\x42\x07\n\x05_uuidB\x07\n\x05_nameB\n\n\x08_projectB\x08\n\x06_imageB\x14\n\x12_filesystem_layoutB\x0b\n\t_hostnameB\x12\n\x10_allocation_typeB\t\n\x07_labels\"\xe4\x01\n\x13MachineNetworkQuery\x12\x1a\n\x08networks\x18\x01 \x03(\tR\x08networks\x12(\n\x08prefixes\x18\x02 \x03(\tB\x0c\xbaH\t\x92\x01\x06\xe0\xb3\xae\xb1\x02\x01R\x08prefixes\x12?\n\x14\x64\x65stination_prefixes\x18\x03 \x03(\tB\x0c\xbaH\t\x92\x01\x06\xe0\xb3\xae\xb1\x02\x01R\x13\x64\x65stinationPrefixes\x12\x1e\n\x03ips\x18\x04 \x03(\tB\x0c\xbaH\t\x92\x01\x06\xe8\xb3\xae\xb1\x02\x01R\x03ips\x12\x12\n\x04vrfs\x18\x05 \x03(\x04R\x04vrfs\x12\x12\n\x04\x61sns\x18\x06 \x03(\rR\x04\x61sns\"\xd9\x01\n\x0fMachineNicQuery\x12(\n\x04macs\x18\x01 \x03(\tB\x14\xbaH\x11\x92\x01\x0e\x10\x64\x18\x01\"\x08r\x06\xb8\xb3\xae\xb1\x02\x01R\x04macs\x12\'\n\x05names\x18\x02 \x03(\tB\x11\xbaH\x0e\x92\x01\x0b\x10\x64\x18\x01\"\x05r\x03\x18\x80\x01R\x05names\x12\x39\n\rneighbor_macs\x18\x03 \x03(\tB\x14\xbaH\x11\x92\x01\x0e\x10\x64\x18\x01\"\x08r\x06\xb8\xb3\xae\xb1\x02\x01R\x0cneighborMacs\x12\x38\n\x0eneighbor_names\x18\x04 \x03(\tB\x11\xbaH\x0e\x92\x01\x0b\x10\x64\x18\x01\"\x05r\x03\x18\x80\x01R\rneighborNames\"Y\n\x10MachineDiskQuery\x12%\n\x05names\x18\x01 \x03(\tB\x0f\xbaH\x0c\x92\x01\t\x10\x64\"\x05r\x03\x18\x80\x01R\x05names\x12\x1e\n\x05sizes\x18\x02 \x03(\x04\x42\x08\xbaH\x05\x92\x01\x02\x10\x64R\x05sizes\"\xd9\x01\n\x10MachineIPMIQuery\x12&\n\x07\x61\x64\x64ress\x18\x01 \x01(\tB\x07\xbaH\x04r\x02p\x01H\x00R\x07\x61\x64\x64ress\x88\x01\x01\x12\"\n\x03mac\x18\x02 \x01(\tB\x0b\xbaH\x08r\x06\xb8\xb3\xae\xb1\x02\x01H\x01R\x03mac\x88\x01\x01\x12!\n\x04user\x18\x03 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01H\x02R\x04user\x88\x01\x01\x12+\n\tinterface\x18\x04 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01H\x03R\tinterface\x88\x01\x01\x42\n\n\x08_addressB\x06\n\x04_macB\x07\n\x05_userB\x0c\n\n_interface\"\x88\x05\n\x0fMachineFRUQuery\x12=\n\x13\x63hassis_part_number\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01H\x00R\x11\x63hassisPartNumber\x88\x01\x01\x12=\n\x13\x63hassis_part_serial\x18\x02 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01H\x01R\x11\x63hassisPartSerial\x88\x01\x01\x12*\n\tboard_mfg\x18\x03 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01H\x02R\x08\x62oardMfg\x88\x01\x01\x12\x30\n\x0c\x62oard_serial\x18\x04 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01H\x03R\x0b\x62oardSerial\x88\x01\x01\x12\x39\n\x11\x62oard_part_number\x18\x05 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01H\x04R\x0f\x62oardPartNumber\x88\x01\x01\x12@\n\x14product_manufacturer\x18\x06 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01H\x05R\x13productManufacturer\x88\x01\x01\x12=\n\x13product_part_number\x18\x07 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01H\x06R\x11productPartNumber\x88\x01\x01\x12\x34\n\x0eproduct_serial\x18\x08 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01H\x07R\rproductSerial\x88\x01\x01\x42\x16\n\x14_chassis_part_numberB\x16\n\x14_chassis_part_serialB\x0c\n\n_board_mfgB\x0f\n\r_board_serialB\x14\n\x12_board_part_numberB\x17\n\x15_product_manufacturerB\x16\n\x14_product_part_numberB\x11\n\x0f_product_serial\"n\n\x14MachineHardwareQuery\x12\x1b\n\x06memory\x18\x01 \x01(\x04H\x00R\x06memory\x88\x01\x01\x12 \n\tcpu_cores\x18\x02 \x01(\rH\x01R\x08\x63puCores\x88\x01\x01\x42\t\n\x07_memoryB\x0c\n\n_cpu_cores*e\n\nIPProtocol\x12\x1b\n\x17IP_PROTOCOL_UNSPECIFIED\x10\x00\x12\x1c\n\x0fIP_PROTOCOL_TCP\x10\x01\x1a\x07\x82\xb2\x19\x03tcp\x12\x1c\n\x0fIP_PROTOCOL_UDP\x10\x02\x1a\x07\x82\xb2\x19\x03udp*\xaf\x01\n\x0cMachineState\x12#\n\x19MACHINE_STATE_UNSPECIFIED\x10\x00\x1a\x04\x82\xb2\x19\x00\x12(\n\x16MACHINE_STATE_RESERVED\x10\x01\x1a\x0c\x82\xb2\x19\x08reserved\x12$\n\x14MACHINE_STATE_LOCKED\x10\x02\x1a\n\x82\xb2\x19\x06locked\x12*\n\x17MACHINE_STATE_AVAILABLE\x10\x03\x1a\r\x82\xb2\x19\tavailable*\xdf\x01\n\x1dMachineProvisioningEventState\x12\x36\n,MACHINE_PROVISIONING_EVENT_STATE_UNSPECIFIED\x10\x00\x1a\x04\x82\xb2\x19\x00\x12=\n*MACHINE_PROVISIONING_EVENT_STATE_CRASHLOOP\x10\x01\x1a\r\x82\xb2\x19\tcrashloop\x12G\n/MACHINE_PROVISIONING_EVENT_STATE_FAILED_RECLAIM\x10\x02\x1a\x12\x82\xb2\x19\x0e\x66\x61iled-reclaim*\x9f\x06\n\x1cMachineProvisioningEventType\x12/\n+MACHINE_PROVISIONING_EVENT_TYPE_UNSPECIFIED\x10\x00\x12\x34\n%MACHINE_PROVISIONING_EVENT_TYPE_ALIVE\x10\x01\x1a\t\x82\xb2\x19\x05\x41live\x12\x38\n\'MACHINE_PROVISIONING_EVENT_TYPE_CRASHED\x10\x02\x1a\x0b\x82\xb2\x19\x07\x43rashed\x12@\n+MACHINE_PROVISIONING_EVENT_TYPE_PXE_BOOTING\x10\x03\x1a\x0f\x82\xb2\x19\x0bPXE Booting\x12\x46\n.MACHINE_PROVISIONING_EVENT_TYPE_PLANNED_REBOOT\x10\x04\x1a\x12\x82\xb2\x19\x0ePlanned Reboot\x12<\n)MACHINE_PROVISIONING_EVENT_TYPE_PREPARING\x10\x05\x1a\r\x82\xb2\x19\tPreparing\x12@\n+MACHINE_PROVISIONING_EVENT_TYPE_REGISTERING\x10\x06\x1a\x0f\x82\xb2\x19\x0bRegistering\x12\x38\n\'MACHINE_PROVISIONING_EVENT_TYPE_WAITING\x10\x07\x1a\x0b\x82\xb2\x19\x07Waiting\x12>\n*MACHINE_PROVISIONING_EVENT_TYPE_INSTALLING\x10\x08\x1a\x0e\x82\xb2\x19\nInstalling\x12N\n2MACHINE_PROVISIONING_EVENT_TYPE_BOOTING_NEW_KERNEL\x10\t\x1a\x16\x82\xb2\x19\x12\x42ooting New Kernel\x12@\n+MACHINE_PROVISIONING_EVENT_TYPE_PHONED_HOME\x10\n\x1a\x0f\x82\xb2\x19\x0bPhoned Home\x12H\n/MACHINE_PROVISIONING_EVENT_TYPE_MACHINE_RECLAIM\x10\x0b\x1a\x13\x82\xb2\x19\x0fMachine Reclaim*\xba\x01\n\x11MachineLiveliness\x12(\n\x1eMACHINE_LIVELINESS_UNSPECIFIED\x10\x00\x1a\x04\x82\xb2\x19\x00\x12\'\n\x18MACHINE_LIVELINESS_ALIVE\x10\x01\x1a\t\x82\xb2\x19\x05\x61live\x12%\n\x17MACHINE_LIVELINESS_DEAD\x10\x02\x1a\x08\x82\xb2\x19\x04\x64\x65\x61\x64\x12+\n\x1aMACHINE_LIVELINESS_UNKNOWN\x10\x03\x1a\x0b\x82\xb2\x19\x07unknown*\xac\x01\n\x15MachineAllocationType\x12-\n#MACHINE_ALLOCATION_TYPE_UNSPECIFIED\x10\x00\x1a\x04\x82\xb2\x19\x00\x12\x30\n\x1fMACHINE_ALLOCATION_TYPE_MACHINE\x10\x01\x1a\x0b\x82\xb2\x19\x07machine\x12\x32\n MACHINE_ALLOCATION_TYPE_FIREWALL\x10\x02\x1a\x0c\x82\xb2\x19\x08\x66irewall2\xca\x04\n\x0eMachineService\x12m\n\x03Get\x12+.metalstack.api.v2.MachineServiceGetRequest\x1a,.metalstack.api.v2.MachineServiceGetResponse\"\x0b\xca\xf3\x18\x03\x01\x02\x03\xe0\xf3\x18\x02\x12q\n\x06\x43reate\x12..metalstack.api.v2.MachineServiceCreateRequest\x1a/.metalstack.api.v2.MachineServiceCreateResponse\"\x06\xca\xf3\x18\x02\x01\x02\x12q\n\x06Update\x12..metalstack.api.v2.MachineServiceUpdateRequest\x1a/.metalstack.api.v2.MachineServiceUpdateResponse\"\x06\xca\xf3\x18\x02\x01\x02\x12p\n\x04List\x12,.metalstack.api.v2.MachineServiceListRequest\x1a-.metalstack.api.v2.MachineServiceListResponse\"\x0b\xca\xf3\x18\x03\x01\x02\x03\xe0\xf3\x18\x02\x12q\n\x06\x44\x65lete\x12..metalstack.api.v2.MachineServiceDeleteRequest\x1a/.metalstack.api.v2.MachineServiceDeleteResponse\"\x06\xca\xf3\x18\x02\x01\x02\x42\xc2\x01\n\x15\x63om.metalstack.api.v2B\x0cMachineProtoP\x01Z5github.com/metal-stack/api/go/metalstack/api/v2;apiv2\xa2\x02\x03MAX\xaa\x02\x11Metalstack.Api.V2\xca\x02\x11Metalstack\\Api\\V2\xe2\x02\x1dMetalstack\\Api\\V2\\GPBMetadata\xea\x02\x13Metalstack::Api::V2b\x06proto3')
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmetalstack/api/v2/machine.proto\x12\x11metalstack.api.v2\x1a\x1b\x62uf/validate/validate.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1emetalstack/api/v2/common.proto\x1a\"metalstack/api/v2/filesystem.proto\x1a\x1dmetalstack/api/v2/image.proto\x1a\x1fmetalstack/api/v2/network.proto\x1a!metalstack/api/v2/partition.proto\x1a(metalstack/api/v2/predefined_rules.proto\x1a\x1cmetalstack/api/v2/size.proto\"\\\n\x18MachineServiceGetRequest\x12\x1c\n\x04uuid\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x04uuid\x12\"\n\x07project\x18\x02 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x07project\"Q\n\x19MachineServiceGetResponse\x12\x34\n\x07machine\x18\x01 \x01(\x0b\x32\x1a.metalstack.api.v2.MachineR\x07machine\"\xa2\x08\n\x1bMachineServiceCreateRequest\x12\"\n\x07project\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x07project\x12!\n\x04uuid\x18\x02 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01H\x00R\x04uuid\x88\x01\x01\x12\x1f\n\x04name\x18\x03 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01R\x04name\x12\x32\n\x0b\x64\x65scription\x18\x04 \x01(\tB\x0b\xbaH\x08r\x06\xc8\xb3\xae\xb1\x02\x01H\x01R\x0b\x64\x65scription\x88\x01\x01\x12(\n\x08hostname\x18\x05 \x01(\tB\x07\xbaH\x04r\x02h\x01H\x02R\x08hostname\x88\x01\x01\x12)\n\tpartition\x18\x06 \x01(\tB\x0b\xbaH\x08r\x06\xd0\xb3\xae\xb1\x02\x01R\tpartition\x12\x1c\n\x04size\x18\x07 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01R\x04size\x12\x1e\n\x05image\x18\x08 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01R\x05image\x12\x30\n\x11\x66ilesystem_layout\x18\t \x01(\tH\x03R\x10\x66ilesystemLayout\x88\x01\x01\x12\x39\n\x0fssh_public_keys\x18\n \x03(\tB\x11\xbaH\x0e\x92\x01\x0b\x10\x32\"\x07r\x05\x10\x01\x18\x80@R\rsshPublicKeys\x12*\n\x08userdata\x18\x0b \x01(\tB\t\xbaH\x06r\x04\x18\x80\x80\x02H\x04R\x08userdata\x88\x01\x01\x12\x31\n\x06labels\x18\x0c \x01(\x0b\x32\x19.metalstack.api.v2.LabelsR\x06labels\x12G\n\x08networks\x18\r \x03(\x0b\x32+.metalstack.api.v2.MachineAllocationNetworkR\x08networks\x12\x1e\n\x03ips\x18\x0e \x03(\tB\x0c\xbaH\t\x92\x01\x06\xe8\xb3\xae\xb1\x02\x01R\x03ips\x12%\n\x0eplacement_tags\x18\x0f \x03(\tR\rplacementTags\x12\x45\n\ndns_server\x18\x10 \x03(\x0b\x32\x1c.metalstack.api.v2.DNSServerB\x08\xbaH\x05\x92\x01\x02\x10\x03R\tdnsServer\x12\x45\n\nntp_server\x18\x11 \x03(\x0b\x32\x1c.metalstack.api.v2.NTPServerB\x08\xbaH\x05\x92\x01\x02\x10\nR\tntpServer\x12[\n\x0f\x61llocation_type\x18\x12 \x01(\x0e\x32(.metalstack.api.v2.MachineAllocationTypeB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x0e\x61llocationType\x12\x44\n\rfirewall_spec\x18\x13 \x01(\x0b\x32\x1f.metalstack.api.v2.FirewallSpecR\x0c\x66irewallSpecB\x07\n\x05_uuidB\x0e\n\x0c_descriptionB\x0b\n\t_hostnameB\x14\n\x12_filesystem_layoutB\x0b\n\t_userdata\"W\n\x0c\x46irewallSpec\x12G\n\x0e\x66irewall_rules\x18\x13 \x01(\x0b\x32 .metalstack.api.v2.FirewallRulesR\rfirewallRules\"T\n\x1cMachineServiceCreateResponse\x12\x34\n\x07machine\x18\x01 \x01(\x0b\x32\x1a.metalstack.api.v2.MachineR\x07machine\"\xef\x02\n\x1bMachineServiceUpdateRequest\x12\x1c\n\x04uuid\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x04uuid\x12\x46\n\x0bupdate_meta\x18\x02 \x01(\x0b\x32\x1d.metalstack.api.v2.UpdateMetaB\x06\xbaH\x03\xc8\x01\x01R\nupdateMeta\x12\"\n\x07project\x18\x03 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x07project\x12\x32\n\x0b\x64\x65scription\x18\x04 \x01(\tB\x0b\xbaH\x08r\x06\xc8\xb3\xae\xb1\x02\x01H\x00R\x0b\x64\x65scription\x88\x01\x01\x12<\n\x06labels\x18\x05 \x01(\x0b\x32\x1f.metalstack.api.v2.UpdateLabelsH\x01R\x06labels\x88\x01\x01\x12\x39\n\x0fssh_public_keys\x18\x06 \x03(\tB\x11\xbaH\x0e\x92\x01\x0b\x10\x32\"\x07r\x05\x10\x01\x18\x80@R\rsshPublicKeysB\x0e\n\x0c_descriptionB\t\n\x07_labels\"T\n\x1cMachineServiceUpdateResponse\x12\x34\n\x07machine\x18\x01 \x01(\x0b\x32\x1a.metalstack.api.v2.MachineR\x07machine\"v\n\x19MachineServiceListRequest\x12\"\n\x07project\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x07project\x12\x35\n\x05query\x18\x02 \x01(\x0b\x32\x1f.metalstack.api.v2.MachineQueryR\x05query\"T\n\x1aMachineServiceListResponse\x12\x36\n\x08machines\x18\x01 \x03(\x0b\x32\x1a.metalstack.api.v2.MachineR\x08machines\"_\n\x1bMachineServiceDeleteRequest\x12\x1c\n\x04uuid\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x04uuid\x12\"\n\x07project\x18\x02 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x07project\"T\n\x1cMachineServiceDeleteResponse\x12\x34\n\x07machine\x18\x01 \x01(\x0b\x32\x1a.metalstack.api.v2.MachineR\x07machine\"\xc1\x04\n\x07Machine\x12\x1c\n\x04uuid\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x04uuid\x12+\n\x04meta\x18\x02 \x01(\x0b\x32\x17.metalstack.api.v2.MetaR\x04meta\x12:\n\tpartition\x18\x03 \x01(\x0b\x32\x1c.metalstack.api.v2.PartitionR\tpartition\x12\x1c\n\x04rack\x18\x04 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01R\x04rack\x12+\n\x04size\x18\x05 \x01(\x0b\x32\x17.metalstack.api.v2.SizeR\x04size\x12>\n\x08hardware\x18\x06 \x01(\x0b\x32\".metalstack.api.v2.MachineHardwareR\x08hardware\x12\x32\n\x04\x62ios\x18\x07 \x01(\x0b\x32\x1e.metalstack.api.v2.MachineBiosR\x04\x62ios\x12\x44\n\nallocation\x18\x08 \x01(\x0b\x32$.metalstack.api.v2.MachineAllocationR\nallocation\x12\x38\n\x06status\x18\t \x01(\x0b\x32 .metalstack.api.v2.MachineStatusR\x06status\x12p\n\x1arecent_provisioning_events\x18\n \x01(\x0b\x32\x32.metalstack.api.v2.MachineRecentProvisioningEventsR\x18recentProvisioningEvents\"\xa4\x02\n\rMachineStatus\x12\x41\n\tcondition\x18\x01 \x01(\x0b\x32#.metalstack.api.v2.MachineConditionR\tcondition\x12N\n\tled_state\x18\x02 \x01(\x0b\x32\x31.metalstack.api.v2.MachineChassisIdentifyLEDStateR\x08ledState\x12N\n\nliveliness\x18\x03 \x01(\x0e\x32$.metalstack.api.v2.MachineLivelinessB\x08\xbaH\x05\x82\x01\x02\x10\x01R\nliveliness\x12\x30\n\x14metal_hammer_version\x18\x04 \x01(\tR\x12metalHammerVersion\"\xa4\x01\n\x10MachineCondition\x12?\n\x05state\x18\x01 \x01(\x0e\x32\x1f.metalstack.api.v2.MachineStateB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x05state\x12-\n\x0b\x64\x65scription\x18\x02 \x01(\tB\x0b\xbaH\x08r\x06\xc8\xb3\xae\xb1\x02\x01R\x0b\x64\x65scription\x12 \n\x06issuer\x18\x03 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x02R\x06issuer\"\xa8\x07\n\x11MachineAllocation\x12\x1c\n\x04uuid\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x04uuid\x12+\n\x04meta\x18\x02 \x01(\x0b\x32\x17.metalstack.api.v2.MetaR\x04meta\x12\x1f\n\x04name\x18\x03 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01R\x04name\x12-\n\x0b\x64\x65scription\x18\x04 \x01(\tB\x0b\xbaH\x08r\x06\xc8\xb3\xae\xb1\x02\x01R\x0b\x64\x65scription\x12\'\n\ncreated_by\x18\x05 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01R\tcreatedBy\x12\"\n\x07project\x18\x06 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x07project\x12.\n\x05image\x18\x07 \x01(\x0b\x32\x18.metalstack.api.v2.ImageR\x05image\x12P\n\x11\x66ilesystem_layout\x18\x08 \x01(\x0b\x32#.metalstack.api.v2.FilesystemLayoutR\x10\x66ilesystemLayout\x12=\n\x08networks\x18\t \x03(\x0b\x32!.metalstack.api.v2.MachineNetworkR\x08networks\x12#\n\x08hostname\x18\n \x01(\tB\x07\xbaH\x04r\x02h\x01R\x08hostname\x12\x39\n\x0fssh_public_keys\x18\x0b \x03(\tB\x11\xbaH\x0e\x92\x01\x0b\x10\x32\"\x07r\x05\x10\x01\x18\x80@R\rsshPublicKeys\x12%\n\x08userdata\x18\x0c \x01(\tB\t\xbaH\x06r\x04\x18\x80\x80\x02R\x08userdata\x12[\n\x0f\x61llocation_type\x18\r \x01(\x0e\x32(.metalstack.api.v2.MachineAllocationTypeB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x0e\x61llocationType\x12G\n\x0e\x66irewall_rules\x18\x0e \x01(\x0b\x32 .metalstack.api.v2.FirewallRulesR\rfirewallRules\x12\x45\n\ndns_server\x18\x0f \x03(\x0b\x32\x1c.metalstack.api.v2.DNSServerB\x08\xbaH\x05\x92\x01\x02\x10\x03R\tdnsServer\x12\x45\n\nntp_server\x18\x10 \x03(\x0b\x32\x1c.metalstack.api.v2.NTPServerB\x08\xbaH\x05\x92\x01\x02\x10\nR\tntpServer\x12/\n\x03vpn\x18\x11 \x01(\x0b\x32\x1d.metalstack.api.v2.MachineVPNR\x03vpn\"}\n\x18MachineAllocationNetwork\x12\x18\n\x07network\x18\x01 \x01(\tR\x07network\x12\x30\n\x12no_auto_acquire_ip\x18\x02 \x01(\x08H\x00R\x0fnoAutoAcquireIp\x88\x01\x01\x42\x15\n\x13_no_auto_acquire_ip\"\x90\x01\n\rFirewallRules\x12=\n\x06\x65gress\x18\x01 \x03(\x0b\x32%.metalstack.api.v2.FirewallEgressRuleR\x06\x65gress\x12@\n\x07ingress\x18\x02 \x03(\x0b\x32&.metalstack.api.v2.FirewallIngressRuleR\x07ingress\"\xd0\x01\n\x12\x46irewallEgressRule\x12\x43\n\x08protocol\x18\x01 \x01(\x0e\x32\x1d.metalstack.api.v2.IPProtocolB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x08protocol\x12$\n\x05ports\x18\x02 \x03(\rB\x0e\xbaH\x0b\x92\x01\x08\"\x06*\x04\x18\xfc\xff\x03R\x05ports\x12\x1c\n\x02to\x18\x03 \x03(\tB\x0c\xbaH\t\x92\x01\x06\xe0\xb3\xae\xb1\x02\x01R\x02to\x12\x31\n\x07\x63omment\x18\x04 \x01(\tB\x17\xbaH\x14r\x0f\x18\x64\x32\x0b^[a-z_ -]*$\xd8\x01\x01R\x07\x63omment\"\xf3\x01\n\x13\x46irewallIngressRule\x12\x43\n\x08protocol\x18\x01 \x01(\x0e\x32\x1d.metalstack.api.v2.IPProtocolB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x08protocol\x12$\n\x05ports\x18\x02 \x03(\rB\x0e\xbaH\x0b\x92\x01\x08\"\x06*\x04\x18\xfc\xff\x03R\x05ports\x12\x1c\n\x02to\x18\x03 \x03(\tB\x0c\xbaH\t\x92\x01\x06\xe0\xb3\xae\xb1\x02\x01R\x02to\x12 \n\x04\x66rom\x18\x04 \x03(\tB\x0c\xbaH\t\x92\x01\x06\xe0\xb3\xae\xb1\x02\x01R\x04\x66rom\x12\x31\n\x07\x63omment\x18\x05 \x01(\tB\x17\xbaH\x14r\x0f\x18\x64\x32\x0b^[a-z_ -]*$\xd8\x01\x01R\x07\x63omment\"\xe7\x02\n\x0eMachineNetwork\x12\x18\n\x07network\x18\x01 \x01(\tR\x07network\x12(\n\x08prefixes\x18\x02 \x03(\tB\x0c\xbaH\t\x92\x01\x06\xe0\xb3\xae\xb1\x02\x01R\x08prefixes\x12?\n\x14\x64\x65stination_prefixes\x18\x03 \x03(\tB\x0c\xbaH\t\x92\x01\x06\xe0\xb3\xae\xb1\x02\x01R\x13\x64\x65stinationPrefixes\x12\x1e\n\x03ips\x18\x04 \x03(\tB\x0c\xbaH\t\x92\x01\x06\xe8\xb3\xae\xb1\x02\x01R\x03ips\x12K\n\x0cnetwork_type\x18\x05 \x01(\x0e\x32\x1e.metalstack.api.v2.NetworkTypeB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x0bnetworkType\x12?\n\x08nat_type\x18\x06 \x01(\x0e\x32\x1a.metalstack.api.v2.NATTypeB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x07natType\x12\x10\n\x03vrf\x18\x07 \x01(\x04R\x03vrf\x12\x10\n\x03\x61sn\x18\x08 \x01(\rR\x03\x61sn\"\xfb\x01\n\x0fMachineHardware\x12\x16\n\x06memory\x18\x01 \x01(\x04R\x06memory\x12;\n\x05\x64isks\x18\x03 \x03(\x0b\x32%.metalstack.api.v2.MachineBlockDeviceR\x05\x64isks\x12/\n\x04\x63pus\x18\x04 \x03(\x0b\x32\x1b.metalstack.api.v2.MetalCPUR\x04\x63pus\x12/\n\x04gpus\x18\x05 \x03(\x0b\x32\x1b.metalstack.api.v2.MetalGPUR\x04gpus\x12\x31\n\x04nics\x18\x06 \x03(\x0b\x32\x1d.metalstack.api.v2.MachineNicR\x04nics\"|\n\x08MetalCPU\x12 \n\x06vendor\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x02R\x06vendor\x12\x1e\n\x05model\x18\x02 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x02R\x05model\x12\x14\n\x05\x63ores\x18\x03 \x01(\rR\x05\x63ores\x12\x18\n\x07threads\x18\x04 \x01(\rR\x07threads\"L\n\x08MetalGPU\x12 \n\x06vendor\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x02R\x06vendor\x12\x1e\n\x05model\x18\x02 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x02R\x05model\"\xa7\x02\n\nMachineNic\x12\x1d\n\x03mac\x18\x01 \x01(\tB\x0b\xbaH\x08r\x06\xb8\xb3\xae\xb1\x02\x01R\x03mac\x12\x1f\n\x04name\x18\x02 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01R\x04name\x12(\n\nidentifier\x18\x03 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01R\nidentifier\x12 \n\x06vendor\x18\x04 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01R\x06vendor\x12\x1e\n\x05model\x18\x05 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01R\x05model\x12\x14\n\x05speed\x18\x06 \x01(\x04R\x05speed\x12;\n\tneighbors\x18\x07 \x03(\x0b\x32\x1d.metalstack.api.v2.MachineNicR\tneighbors\x12\x1a\n\x08hostname\x18\x08 \x01(\tR\x08hostname\"I\n\x12MachineBlockDevice\x12\x1f\n\x04name\x18\x01 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01R\x04name\x12\x12\n\x04size\x18\x02 \x01(\x04R\x04size\"o\n\x1eMachineChassisIdentifyLEDState\x12\x1e\n\x05value\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01R\x05value\x12-\n\x0b\x64\x65scription\x18\x02 \x01(\tB\x0b\xbaH\x08r\x06\xc8\xb3\xae\xb1\x02\x01R\x0b\x64\x65scription\"q\n\x0bMachineBios\x12\"\n\x07version\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x02R\x07version\x12 \n\x06vendor\x18\x02 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x02R\x06vendor\x12\x1c\n\x04\x64\x61te\x18\x03 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x02R\x04\x64\x61te\"\xd3\x02\n\x1fMachineRecentProvisioningEvents\x12\x43\n\x06\x65vents\x18\x01 \x03(\x0b\x32+.metalstack.api.v2.MachineProvisioningEventR\x06\x65vents\x12\x42\n\x0flast_event_time\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\rlastEventTime\x12U\n\x10last_error_event\x18\x03 \x01(\x0b\x32+.metalstack.api.v2.MachineProvisioningEventR\x0elastErrorEvent\x12P\n\x05state\x18\x04 \x01(\x0e\x32\x30.metalstack.api.v2.MachineProvisioningEventStateB\x08\xbaH\x05\x82\x01\x02\x10\x01R\x05state\"\xab\x01\n\x18MachineProvisioningEvent\x12.\n\x04time\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x04time\x12\x45\n\x05\x65vent\x18\x02 \x01(\x0e\x32/.metalstack.api.v2.MachineProvisioningEventTypeR\x05\x65vent\x12\x18\n\x07message\x18\x03 \x01(\tR\x07message\"\x99\x01\n\nMachineVPN\x12\x32\n\x15\x63ontrol_plane_address\x18\x01 \x01(\tR\x13\x63ontrolPlaneAddress\x12\x19\n\x08\x61uth_key\x18\x02 \x01(\tR\x07\x61uthKey\x12\x1c\n\tconnected\x18\x03 \x01(\x08R\tconnected\x12\x1e\n\x03ips\x18\x05 \x03(\tB\x0c\xbaH\t\x92\x01\x06\xe8\xb3\xae\xb1\x02\x01R\x03ips\"\xa8\x07\n\x0cMachineQuery\x12!\n\x04uuid\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01H\x00R\x04uuid\x88\x01\x01\x12$\n\x04name\x18\x02 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01H\x01R\x04name\x88\x01\x01\x12-\n\tpartition\x18\x03 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01H\x02R\tpartition\x88\x01\x01\x12#\n\x04size\x18\x04 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01H\x03R\x04size\x88\x01\x01\x12#\n\x04rack\x18\x05 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01H\x04R\x04rack\x88\x01\x01\x12\x36\n\x06labels\x18\x06 \x01(\x0b\x32\x19.metalstack.api.v2.LabelsH\x05R\x06labels\x88\x01\x01\x12N\n\nallocation\x18\x07 \x01(\x0b\x32).metalstack.api.v2.MachineAllocationQueryH\x06R\nallocation\x88\x01\x01\x12\x45\n\x07network\x18\x08 \x01(\x0b\x32&.metalstack.api.v2.MachineNetworkQueryH\x07R\x07network\x88\x01\x01\x12\x39\n\x03nic\x18\t \x01(\x0b\x32\".metalstack.api.v2.MachineNicQueryH\x08R\x03nic\x88\x01\x01\x12<\n\x04\x64isk\x18\n \x01(\x0b\x32#.metalstack.api.v2.MachineDiskQueryH\tR\x04\x64isk\x88\x01\x01\x12<\n\x04ipmi\x18\x0b \x01(\x0b\x32#.metalstack.api.v2.MachineIPMIQueryH\nR\x04ipmi\x88\x01\x01\x12\x39\n\x03\x66ru\x18\x0c \x01(\x0b\x32\".metalstack.api.v2.MachineFRUQueryH\x0bR\x03\x66ru\x88\x01\x01\x12H\n\x08hardware\x18\r \x01(\x0b\x32\'.metalstack.api.v2.MachineHardwareQueryH\x0cR\x08hardware\x88\x01\x01\x12:\n\x05state\x18\x0e \x01(\x0e\x32\x1f.metalstack.api.v2.MachineStateH\rR\x05state\x88\x01\x01\x42\x07\n\x05_uuidB\x07\n\x05_nameB\x0c\n\n_partitionB\x07\n\x05_sizeB\x07\n\x05_rackB\t\n\x07_labelsB\r\n\x0b_allocationB\n\n\x08_networkB\x06\n\x04_nicB\x07\n\x05_diskB\x07\n\x05_ipmiB\x06\n\x04_fruB\x0b\n\t_hardwareB\x08\n\x06_state\"\xde\x04\n\x16MachineAllocationQuery\x12!\n\x04uuid\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01H\x00R\x04uuid\x88\x01\x01\x12$\n\x04name\x18\x02 \x01(\tB\x0b\xbaH\x08r\x06\xc0\xb3\xae\xb1\x02\x01H\x01R\x04name\x88\x01\x01\x12\'\n\x07project\x18\x03 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01H\x02R\x07project\x88\x01\x01\x12%\n\x05image\x18\x04 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01H\x03R\x05image\x88\x01\x01\x12<\n\x11\x66ilesystem_layout\x18\x05 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01H\x04R\x10\x66ilesystemLayout\x88\x01\x01\x12+\n\x08hostname\x18\x06 \x01(\tB\n\xbaH\x07r\x05\x10\x02\x18\x80\x01H\x05R\x08hostname\x88\x01\x01\x12`\n\x0f\x61llocation_type\x18\x07 \x01(\x0e\x32(.metalstack.api.v2.MachineAllocationTypeB\x08\xbaH\x05\x82\x01\x02\x10\x01H\x06R\x0e\x61llocationType\x88\x01\x01\x12\x36\n\x06labels\x18\x08 \x01(\x0b\x32\x19.metalstack.api.v2.LabelsH\x07R\x06labels\x88\x01\x01\x12\x34\n\x03vpn\x18\t \x01(\x0b\x32\x1d.metalstack.api.v2.MachineVPNH\x08R\x03vpn\x88\x01\x01\x42\x07\n\x05_uuidB\x07\n\x05_nameB\n\n\x08_projectB\x08\n\x06_imageB\x14\n\x12_filesystem_layoutB\x0b\n\t_hostnameB\x12\n\x10_allocation_typeB\t\n\x07_labelsB\x06\n\x04_vpn\"\xe4\x01\n\x13MachineNetworkQuery\x12\x1a\n\x08networks\x18\x01 \x03(\tR\x08networks\x12(\n\x08prefixes\x18\x02 \x03(\tB\x0c\xbaH\t\x92\x01\x06\xe0\xb3\xae\xb1\x02\x01R\x08prefixes\x12?\n\x14\x64\x65stination_prefixes\x18\x03 \x03(\tB\x0c\xbaH\t\x92\x01\x06\xe0\xb3\xae\xb1\x02\x01R\x13\x64\x65stinationPrefixes\x12\x1e\n\x03ips\x18\x04 \x03(\tB\x0c\xbaH\t\x92\x01\x06\xe8\xb3\xae\xb1\x02\x01R\x03ips\x12\x12\n\x04vrfs\x18\x05 \x03(\x04R\x04vrfs\x12\x12\n\x04\x61sns\x18\x06 \x03(\rR\x04\x61sns\"\xd9\x01\n\x0fMachineNicQuery\x12(\n\x04macs\x18\x01 \x03(\tB\x14\xbaH\x11\x92\x01\x0e\x10\x64\x18\x01\"\x08r\x06\xb8\xb3\xae\xb1\x02\x01R\x04macs\x12\'\n\x05names\x18\x02 \x03(\tB\x11\xbaH\x0e\x92\x01\x0b\x10\x64\x18\x01\"\x05r\x03\x18\x80\x01R\x05names\x12\x39\n\rneighbor_macs\x18\x03 \x03(\tB\x14\xbaH\x11\x92\x01\x0e\x10\x64\x18\x01\"\x08r\x06\xb8\xb3\xae\xb1\x02\x01R\x0cneighborMacs\x12\x38\n\x0eneighbor_names\x18\x04 \x03(\tB\x11\xbaH\x0e\x92\x01\x0b\x10\x64\x18\x01\"\x05r\x03\x18\x80\x01R\rneighborNames\"Y\n\x10MachineDiskQuery\x12%\n\x05names\x18\x01 \x03(\tB\x0f\xbaH\x0c\x92\x01\t\x10\x64\"\x05r\x03\x18\x80\x01R\x05names\x12\x1e\n\x05sizes\x18\x02 \x03(\x04\x42\x08\xbaH\x05\x92\x01\x02\x10\x64R\x05sizes\"\xd9\x01\n\x10MachineIPMIQuery\x12&\n\x07\x61\x64\x64ress\x18\x01 \x01(\tB\x07\xbaH\x04r\x02p\x01H\x00R\x07\x61\x64\x64ress\x88\x01\x01\x12\"\n\x03mac\x18\x02 \x01(\tB\x0b\xbaH\x08r\x06\xb8\xb3\xae\xb1\x02\x01H\x01R\x03mac\x88\x01\x01\x12!\n\x04user\x18\x03 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01H\x02R\x04user\x88\x01\x01\x12+\n\tinterface\x18\x04 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01H\x03R\tinterface\x88\x01\x01\x42\n\n\x08_addressB\x06\n\x04_macB\x07\n\x05_userB\x0c\n\n_interface\"\x88\x05\n\x0fMachineFRUQuery\x12=\n\x13\x63hassis_part_number\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01H\x00R\x11\x63hassisPartNumber\x88\x01\x01\x12=\n\x13\x63hassis_part_serial\x18\x02 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01H\x01R\x11\x63hassisPartSerial\x88\x01\x01\x12*\n\tboard_mfg\x18\x03 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01H\x02R\x08\x62oardMfg\x88\x01\x01\x12\x30\n\x0c\x62oard_serial\x18\x04 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01H\x03R\x0b\x62oardSerial\x88\x01\x01\x12\x39\n\x11\x62oard_part_number\x18\x05 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01H\x04R\x0f\x62oardPartNumber\x88\x01\x01\x12@\n\x14product_manufacturer\x18\x06 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01H\x05R\x13productManufacturer\x88\x01\x01\x12=\n\x13product_part_number\x18\x07 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01H\x06R\x11productPartNumber\x88\x01\x01\x12\x34\n\x0eproduct_serial\x18\x08 \x01(\tB\x08\xbaH\x05r\x03\x18\x80\x01H\x07R\rproductSerial\x88\x01\x01\x42\x16\n\x14_chassis_part_numberB\x16\n\x14_chassis_part_serialB\x0c\n\n_board_mfgB\x0f\n\r_board_serialB\x14\n\x12_board_part_numberB\x17\n\x15_product_manufacturerB\x16\n\x14_product_part_numberB\x11\n\x0f_product_serial\"n\n\x14MachineHardwareQuery\x12\x1b\n\x06memory\x18\x01 \x01(\x04H\x00R\x06memory\x88\x01\x01\x12 \n\tcpu_cores\x18\x02 \x01(\rH\x01R\x08\x63puCores\x88\x01\x01\x42\t\n\x07_memoryB\x0c\n\n_cpu_cores*e\n\nIPProtocol\x12\x1b\n\x17IP_PROTOCOL_UNSPECIFIED\x10\x00\x12\x1c\n\x0fIP_PROTOCOL_TCP\x10\x01\x1a\x07\x82\xb2\x19\x03tcp\x12\x1c\n\x0fIP_PROTOCOL_UDP\x10\x02\x1a\x07\x82\xb2\x19\x03udp*\xaf\x01\n\x0cMachineState\x12#\n\x19MACHINE_STATE_UNSPECIFIED\x10\x00\x1a\x04\x82\xb2\x19\x00\x12(\n\x16MACHINE_STATE_RESERVED\x10\x01\x1a\x0c\x82\xb2\x19\x08reserved\x12$\n\x14MACHINE_STATE_LOCKED\x10\x02\x1a\n\x82\xb2\x19\x06locked\x12*\n\x17MACHINE_STATE_AVAILABLE\x10\x03\x1a\r\x82\xb2\x19\tavailable*\xdf\x01\n\x1dMachineProvisioningEventState\x12\x36\n,MACHINE_PROVISIONING_EVENT_STATE_UNSPECIFIED\x10\x00\x1a\x04\x82\xb2\x19\x00\x12=\n*MACHINE_PROVISIONING_EVENT_STATE_CRASHLOOP\x10\x01\x1a\r\x82\xb2\x19\tcrashloop\x12G\n/MACHINE_PROVISIONING_EVENT_STATE_FAILED_RECLAIM\x10\x02\x1a\x12\x82\xb2\x19\x0e\x66\x61iled-reclaim*\x9f\x06\n\x1cMachineProvisioningEventType\x12/\n+MACHINE_PROVISIONING_EVENT_TYPE_UNSPECIFIED\x10\x00\x12\x34\n%MACHINE_PROVISIONING_EVENT_TYPE_ALIVE\x10\x01\x1a\t\x82\xb2\x19\x05\x41live\x12\x38\n\'MACHINE_PROVISIONING_EVENT_TYPE_CRASHED\x10\x02\x1a\x0b\x82\xb2\x19\x07\x43rashed\x12@\n+MACHINE_PROVISIONING_EVENT_TYPE_PXE_BOOTING\x10\x03\x1a\x0f\x82\xb2\x19\x0bPXE Booting\x12\x46\n.MACHINE_PROVISIONING_EVENT_TYPE_PLANNED_REBOOT\x10\x04\x1a\x12\x82\xb2\x19\x0ePlanned Reboot\x12<\n)MACHINE_PROVISIONING_EVENT_TYPE_PREPARING\x10\x05\x1a\r\x82\xb2\x19\tPreparing\x12@\n+MACHINE_PROVISIONING_EVENT_TYPE_REGISTERING\x10\x06\x1a\x0f\x82\xb2\x19\x0bRegistering\x12\x38\n\'MACHINE_PROVISIONING_EVENT_TYPE_WAITING\x10\x07\x1a\x0b\x82\xb2\x19\x07Waiting\x12>\n*MACHINE_PROVISIONING_EVENT_TYPE_INSTALLING\x10\x08\x1a\x0e\x82\xb2\x19\nInstalling\x12N\n2MACHINE_PROVISIONING_EVENT_TYPE_BOOTING_NEW_KERNEL\x10\t\x1a\x16\x82\xb2\x19\x12\x42ooting New Kernel\x12@\n+MACHINE_PROVISIONING_EVENT_TYPE_PHONED_HOME\x10\n\x1a\x0f\x82\xb2\x19\x0bPhoned Home\x12H\n/MACHINE_PROVISIONING_EVENT_TYPE_MACHINE_RECLAIM\x10\x0b\x1a\x13\x82\xb2\x19\x0fMachine Reclaim*\xba\x01\n\x11MachineLiveliness\x12(\n\x1eMACHINE_LIVELINESS_UNSPECIFIED\x10\x00\x1a\x04\x82\xb2\x19\x00\x12\'\n\x18MACHINE_LIVELINESS_ALIVE\x10\x01\x1a\t\x82\xb2\x19\x05\x61live\x12%\n\x17MACHINE_LIVELINESS_DEAD\x10\x02\x1a\x08\x82\xb2\x19\x04\x64\x65\x61\x64\x12+\n\x1aMACHINE_LIVELINESS_UNKNOWN\x10\x03\x1a\x0b\x82\xb2\x19\x07unknown*\xac\x01\n\x15MachineAllocationType\x12-\n#MACHINE_ALLOCATION_TYPE_UNSPECIFIED\x10\x00\x1a\x04\x82\xb2\x19\x00\x12\x30\n\x1fMACHINE_ALLOCATION_TYPE_MACHINE\x10\x01\x1a\x0b\x82\xb2\x19\x07machine\x12\x32\n MACHINE_ALLOCATION_TYPE_FIREWALL\x10\x02\x1a\x0c\x82\xb2\x19\x08\x66irewall2\xca\x04\n\x0eMachineService\x12m\n\x03Get\x12+.metalstack.api.v2.MachineServiceGetRequest\x1a,.metalstack.api.v2.MachineServiceGetResponse\"\x0b\xca\xf3\x18\x03\x01\x02\x03\xe0\xf3\x18\x02\x12q\n\x06\x43reate\x12..metalstack.api.v2.MachineServiceCreateRequest\x1a/.metalstack.api.v2.MachineServiceCreateResponse\"\x06\xca\xf3\x18\x02\x01\x02\x12q\n\x06Update\x12..metalstack.api.v2.MachineServiceUpdateRequest\x1a/.metalstack.api.v2.MachineServiceUpdateResponse\"\x06\xca\xf3\x18\x02\x01\x02\x12p\n\x04List\x12,.metalstack.api.v2.MachineServiceListRequest\x1a-.metalstack.api.v2.MachineServiceListResponse\"\x0b\xca\xf3\x18\x03\x01\x02\x03\xe0\xf3\x18\x02\x12q\n\x06\x44\x65lete\x12..metalstack.api.v2.MachineServiceDeleteRequest\x1a/.metalstack.api.v2.MachineServiceDeleteResponse\"\x06\xca\xf3\x18\x02\x01\x02\x42\xc2\x01\n\x15\x63om.metalstack.api.v2B\x0cMachineProtoP\x01Z5github.com/metal-stack/api/go/metalstack/api/v2;apiv2\xa2\x02\x03MAX\xaa\x02\x11Metalstack.Api.V2\xca\x02\x11Metalstack\\Api\\V2\xe2\x02\x1dMetalstack\\Api\\V2\\GPBMetadata\xea\x02\x13Metalstack::Api::V2b\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -237,6 +237,8 @@
_globals['_MACHINEBIOS'].fields_by_name['date']._serialized_options = b'\272H\005r\003\030\200\002'
_globals['_MACHINERECENTPROVISIONINGEVENTS'].fields_by_name['state']._loaded_options = None
_globals['_MACHINERECENTPROVISIONINGEVENTS'].fields_by_name['state']._serialized_options = b'\272H\005\202\001\002\020\001'
+ _globals['_MACHINEVPN'].fields_by_name['ips']._loaded_options = None
+ _globals['_MACHINEVPN'].fields_by_name['ips']._serialized_options = b'\272H\t\222\001\006\350\263\256\261\002\001'
_globals['_MACHINEQUERY'].fields_by_name['uuid']._loaded_options = None
_globals['_MACHINEQUERY'].fields_by_name['uuid']._serialized_options = b'\272H\005r\003\260\001\001'
_globals['_MACHINEQUERY'].fields_by_name['name']._loaded_options = None
@@ -313,18 +315,18 @@
_globals['_MACHINESERVICE'].methods_by_name['List']._serialized_options = b'\312\363\030\003\001\002\003\340\363\030\002'
_globals['_MACHINESERVICE'].methods_by_name['Delete']._loaded_options = None
_globals['_MACHINESERVICE'].methods_by_name['Delete']._serialized_options = b'\312\363\030\002\001\002'
- _globals['_IPPROTOCOL']._serialized_start=10396
- _globals['_IPPROTOCOL']._serialized_end=10497
- _globals['_MACHINESTATE']._serialized_start=10500
- _globals['_MACHINESTATE']._serialized_end=10675
- _globals['_MACHINEPROVISIONINGEVENTSTATE']._serialized_start=10678
- _globals['_MACHINEPROVISIONINGEVENTSTATE']._serialized_end=10901
- _globals['_MACHINEPROVISIONINGEVENTTYPE']._serialized_start=10904
- _globals['_MACHINEPROVISIONINGEVENTTYPE']._serialized_end=11703
- _globals['_MACHINELIVELINESS']._serialized_start=11706
- _globals['_MACHINELIVELINESS']._serialized_end=11892
- _globals['_MACHINEALLOCATIONTYPE']._serialized_start=11895
- _globals['_MACHINEALLOCATIONTYPE']._serialized_end=12067
+ _globals['_IPPROTOCOL']._serialized_start=10491
+ _globals['_IPPROTOCOL']._serialized_end=10592
+ _globals['_MACHINESTATE']._serialized_start=10595
+ _globals['_MACHINESTATE']._serialized_end=10770
+ _globals['_MACHINEPROVISIONINGEVENTSTATE']._serialized_start=10773
+ _globals['_MACHINEPROVISIONINGEVENTSTATE']._serialized_end=10996
+ _globals['_MACHINEPROVISIONINGEVENTTYPE']._serialized_start=10999
+ _globals['_MACHINEPROVISIONINGEVENTTYPE']._serialized_end=11798
+ _globals['_MACHINELIVELINESS']._serialized_start=11801
+ _globals['_MACHINELIVELINESS']._serialized_end=11987
+ _globals['_MACHINEALLOCATIONTYPE']._serialized_start=11990
+ _globals['_MACHINEALLOCATIONTYPE']._serialized_end=12162
_globals['_MACHINESERVICEGETREQUEST']._serialized_start=355
_globals['_MACHINESERVICEGETREQUEST']._serialized_end=447
_globals['_MACHINESERVICEGETRESPONSE']._serialized_start=449
@@ -383,24 +385,24 @@
_globals['_MACHINERECENTPROVISIONINGEVENTS']._serialized_end=7086
_globals['_MACHINEPROVISIONINGEVENT']._serialized_start=7089
_globals['_MACHINEPROVISIONINGEVENT']._serialized_end=7260
- _globals['_MACHINEVPN']._serialized_start=7262
- _globals['_MACHINEVPN']._serialized_end=7383
- _globals['_MACHINEQUERY']._serialized_start=7386
- _globals['_MACHINEQUERY']._serialized_end=8322
- _globals['_MACHINEALLOCATIONQUERY']._serialized_start=8325
- _globals['_MACHINEALLOCATIONQUERY']._serialized_end=8869
- _globals['_MACHINENETWORKQUERY']._serialized_start=8872
- _globals['_MACHINENETWORKQUERY']._serialized_end=9100
- _globals['_MACHINENICQUERY']._serialized_start=9103
- _globals['_MACHINENICQUERY']._serialized_end=9320
- _globals['_MACHINEDISKQUERY']._serialized_start=9322
- _globals['_MACHINEDISKQUERY']._serialized_end=9411
- _globals['_MACHINEIPMIQUERY']._serialized_start=9414
- _globals['_MACHINEIPMIQUERY']._serialized_end=9631
- _globals['_MACHINEFRUQUERY']._serialized_start=9634
- _globals['_MACHINEFRUQUERY']._serialized_end=10282
- _globals['_MACHINEHARDWAREQUERY']._serialized_start=10284
- _globals['_MACHINEHARDWAREQUERY']._serialized_end=10394
- _globals['_MACHINESERVICE']._serialized_start=12070
- _globals['_MACHINESERVICE']._serialized_end=12656
+ _globals['_MACHINEVPN']._serialized_start=7263
+ _globals['_MACHINEVPN']._serialized_end=7416
+ _globals['_MACHINEQUERY']._serialized_start=7419
+ _globals['_MACHINEQUERY']._serialized_end=8355
+ _globals['_MACHINEALLOCATIONQUERY']._serialized_start=8358
+ _globals['_MACHINEALLOCATIONQUERY']._serialized_end=8964
+ _globals['_MACHINENETWORKQUERY']._serialized_start=8967
+ _globals['_MACHINENETWORKQUERY']._serialized_end=9195
+ _globals['_MACHINENICQUERY']._serialized_start=9198
+ _globals['_MACHINENICQUERY']._serialized_end=9415
+ _globals['_MACHINEDISKQUERY']._serialized_start=9417
+ _globals['_MACHINEDISKQUERY']._serialized_end=9506
+ _globals['_MACHINEIPMIQUERY']._serialized_start=9509
+ _globals['_MACHINEIPMIQUERY']._serialized_end=9726
+ _globals['_MACHINEFRUQUERY']._serialized_start=9729
+ _globals['_MACHINEFRUQUERY']._serialized_end=10377
+ _globals['_MACHINEHARDWAREQUERY']._serialized_start=10379
+ _globals['_MACHINEHARDWAREQUERY']._serialized_end=10489
+ _globals['_MACHINESERVICE']._serialized_start=12165
+ _globals['_MACHINESERVICE']._serialized_end=12751
# @@protoc_insertion_point(module_scope)
diff --git a/python/metalstack/api/v2/machine_pb2.pyi b/python/metalstack/api/v2/machine_pb2.pyi
index d459a136..128b3fdf 100644
--- a/python/metalstack/api/v2/machine_pb2.pyi
+++ b/python/metalstack/api/v2/machine_pb2.pyi
@@ -460,14 +460,16 @@ class MachineProvisioningEvent(_message.Message):
def __init__(self, time: _Optional[_Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping]] = ..., event: _Optional[_Union[MachineProvisioningEventType, str]] = ..., message: _Optional[str] = ...) -> None: ...
class MachineVPN(_message.Message):
- __slots__ = ("control_plane_address", "auth_key", "connected")
+ __slots__ = ("control_plane_address", "auth_key", "connected", "ips")
CONTROL_PLANE_ADDRESS_FIELD_NUMBER: _ClassVar[int]
AUTH_KEY_FIELD_NUMBER: _ClassVar[int]
CONNECTED_FIELD_NUMBER: _ClassVar[int]
+ IPS_FIELD_NUMBER: _ClassVar[int]
control_plane_address: str
auth_key: str
connected: bool
- def __init__(self, control_plane_address: _Optional[str] = ..., auth_key: _Optional[str] = ..., connected: _Optional[bool] = ...) -> None: ...
+ ips: _containers.RepeatedScalarFieldContainer[str]
+ def __init__(self, control_plane_address: _Optional[str] = ..., auth_key: _Optional[str] = ..., connected: _Optional[bool] = ..., ips: _Optional[_Iterable[str]] = ...) -> None: ...
class MachineQuery(_message.Message):
__slots__ = ("uuid", "name", "partition", "size", "rack", "labels", "allocation", "network", "nic", "disk", "ipmi", "fru", "hardware", "state")
@@ -502,7 +504,7 @@ class MachineQuery(_message.Message):
def __init__(self, uuid: _Optional[str] = ..., name: _Optional[str] = ..., partition: _Optional[str] = ..., size: _Optional[str] = ..., rack: _Optional[str] = ..., labels: _Optional[_Union[_common_pb2.Labels, _Mapping]] = ..., allocation: _Optional[_Union[MachineAllocationQuery, _Mapping]] = ..., network: _Optional[_Union[MachineNetworkQuery, _Mapping]] = ..., nic: _Optional[_Union[MachineNicQuery, _Mapping]] = ..., disk: _Optional[_Union[MachineDiskQuery, _Mapping]] = ..., ipmi: _Optional[_Union[MachineIPMIQuery, _Mapping]] = ..., fru: _Optional[_Union[MachineFRUQuery, _Mapping]] = ..., hardware: _Optional[_Union[MachineHardwareQuery, _Mapping]] = ..., state: _Optional[_Union[MachineState, str]] = ...) -> None: ...
class MachineAllocationQuery(_message.Message):
- __slots__ = ("uuid", "name", "project", "image", "filesystem_layout", "hostname", "allocation_type", "labels")
+ __slots__ = ("uuid", "name", "project", "image", "filesystem_layout", "hostname", "allocation_type", "labels", "vpn")
UUID_FIELD_NUMBER: _ClassVar[int]
NAME_FIELD_NUMBER: _ClassVar[int]
PROJECT_FIELD_NUMBER: _ClassVar[int]
@@ -511,6 +513,7 @@ class MachineAllocationQuery(_message.Message):
HOSTNAME_FIELD_NUMBER: _ClassVar[int]
ALLOCATION_TYPE_FIELD_NUMBER: _ClassVar[int]
LABELS_FIELD_NUMBER: _ClassVar[int]
+ VPN_FIELD_NUMBER: _ClassVar[int]
uuid: str
name: str
project: str
@@ -519,7 +522,8 @@ class MachineAllocationQuery(_message.Message):
hostname: str
allocation_type: MachineAllocationType
labels: _common_pb2.Labels
- def __init__(self, uuid: _Optional[str] = ..., name: _Optional[str] = ..., project: _Optional[str] = ..., image: _Optional[str] = ..., filesystem_layout: _Optional[str] = ..., hostname: _Optional[str] = ..., allocation_type: _Optional[_Union[MachineAllocationType, str]] = ..., labels: _Optional[_Union[_common_pb2.Labels, _Mapping]] = ...) -> None: ...
+ vpn: MachineVPN
+ def __init__(self, uuid: _Optional[str] = ..., name: _Optional[str] = ..., project: _Optional[str] = ..., image: _Optional[str] = ..., filesystem_layout: _Optional[str] = ..., hostname: _Optional[str] = ..., allocation_type: _Optional[_Union[MachineAllocationType, str]] = ..., labels: _Optional[_Union[_common_pb2.Labels, _Mapping]] = ..., vpn: _Optional[_Union[MachineVPN, _Mapping]] = ...) -> None: ...
class MachineNetworkQuery(_message.Message):
__slots__ = ("networks", "prefixes", "destination_prefixes", "ips", "vrfs", "asns")
diff --git a/python/metalstack/api/v2/vpn_pb2.py b/python/metalstack/api/v2/vpn_pb2.py
new file mode 100644
index 00000000..02ece3d8
--- /dev/null
+++ b/python/metalstack/api/v2/vpn_pb2.py
@@ -0,0 +1,38 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: metalstack/api/v2/vpn.proto
+# Protobuf Python Version: 6.32.1
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import descriptor_pool as _descriptor_pool
+from google.protobuf import runtime_version as _runtime_version
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf.internal import builder as _builder
+_runtime_version.ValidateProtobufRuntimeVersion(
+ _runtime_version.Domain.PUBLIC,
+ 6,
+ 32,
+ 1,
+ '',
+ 'metalstack/api/v2/vpn.proto'
+)
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
+
+
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1bmetalstack/api/v2/vpn.proto\x12\x11metalstack.api.v2\x1a\x1fgoogle/protobuf/timestamp.proto\"\xc3\x01\n\x07VPNNode\x12\x0e\n\x02id\x18\x01 \x01(\x04R\x02id\x12\x12\n\x04name\x18\x02 \x01(\tR\x04name\x12\x17\n\x04user\x18\x03 \x01(\tH\x00R\x04user\x88\x01\x01\x12!\n\x0cip_addresses\x18\x04 \x03(\tR\x0bipAddresses\x12\x37\n\tlast_seen\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x08lastSeen\x12\x16\n\x06online\x18\x06 \x01(\x08R\x06onlineB\x07\n\x05_userB\xbe\x01\n\x15\x63om.metalstack.api.v2B\x08VpnProtoP\x01Z5github.com/metal-stack/api/go/metalstack/api/v2;apiv2\xa2\x02\x03MAX\xaa\x02\x11Metalstack.Api.V2\xca\x02\x11Metalstack\\Api\\V2\xe2\x02\x1dMetalstack\\Api\\V2\\GPBMetadata\xea\x02\x13Metalstack::Api::V2b\x06proto3')
+
+_globals = globals()
+_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
+_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'metalstack.api.v2.vpn_pb2', _globals)
+if not _descriptor._USE_C_DESCRIPTORS:
+ _globals['DESCRIPTOR']._loaded_options = None
+ _globals['DESCRIPTOR']._serialized_options = b'\n\025com.metalstack.api.v2B\010VpnProtoP\001Z5github.com/metal-stack/api/go/metalstack/api/v2;apiv2\242\002\003MAX\252\002\021Metalstack.Api.V2\312\002\021Metalstack\\Api\\V2\342\002\035Metalstack\\Api\\V2\\GPBMetadata\352\002\023Metalstack::Api::V2'
+ _globals['_VPNNODE']._serialized_start=84
+ _globals['_VPNNODE']._serialized_end=279
+# @@protoc_insertion_point(module_scope)
diff --git a/python/metalstack/api/v2/vpn_pb2.pyi b/python/metalstack/api/v2/vpn_pb2.pyi
new file mode 100644
index 00000000..af4fee64
--- /dev/null
+++ b/python/metalstack/api/v2/vpn_pb2.pyi
@@ -0,0 +1,26 @@
+import datetime
+
+from google.protobuf import timestamp_pb2 as _timestamp_pb2
+from google.protobuf.internal import containers as _containers
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from collections.abc import Iterable as _Iterable, Mapping as _Mapping
+from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union
+
+DESCRIPTOR: _descriptor.FileDescriptor
+
+class VPNNode(_message.Message):
+ __slots__ = ("id", "name", "user", "ip_addresses", "last_seen", "online")
+ ID_FIELD_NUMBER: _ClassVar[int]
+ NAME_FIELD_NUMBER: _ClassVar[int]
+ USER_FIELD_NUMBER: _ClassVar[int]
+ IP_ADDRESSES_FIELD_NUMBER: _ClassVar[int]
+ LAST_SEEN_FIELD_NUMBER: _ClassVar[int]
+ ONLINE_FIELD_NUMBER: _ClassVar[int]
+ id: int
+ name: str
+ user: str
+ ip_addresses: _containers.RepeatedScalarFieldContainer[str]
+ last_seen: _timestamp_pb2.Timestamp
+ online: bool
+ def __init__(self, id: _Optional[int] = ..., name: _Optional[str] = ..., user: _Optional[str] = ..., ip_addresses: _Optional[_Iterable[str]] = ..., last_seen: _Optional[_Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping]] = ..., online: _Optional[bool] = ...) -> None: ...
diff --git a/python/metalstack/client/client.py b/python/metalstack/client/client.py
index d1e42027..ddd2ff12 100755
--- a/python/metalstack/client/client.py
+++ b/python/metalstack/client/client.py
@@ -13,6 +13,7 @@
import metalstack.admin.v2.switch_connect as admin_switch_connect
import metalstack.admin.v2.tenant_connect as admin_tenant_connect
import metalstack.admin.v2.token_connect as admin_token_connect
+import metalstack.admin.v2.vpn_connect as admin_vpn_connect
import metalstack.api.v2.filesystem_connect as api_filesystem_connect
import metalstack.api.v2.health_connect as api_health_connect
@@ -96,6 +97,9 @@ def tenant(self):
def token(self):
return admin_token_connect.TokenServiceClientSync(address=self._baseurl, session=self._session)
+ def vpn(self):
+ return admin_vpn_connect.VPNServiceClientSync(address=self._baseurl, session=self._session)
+
class _Apiv2:
def __init__(self, baseurl: str, session=None):