Compare commits

..

7 Commits

Author SHA1 Message Date
Jeff McCune
0639562f1c (#175) go mod tidy 2024-05-17 10:09:40 -07:00
Jeff McCune
c1fa9cc531 (#175) Fix lint 2024-05-17 10:08:06 -07:00
Jeff McCune
18653534ad (#175) Add holos push platform form command
This sub-command renders the web app form from CUE code and updates the
form using the `holos.platform.v1alpha1.PlatformService/UpdatePlatform`
rpc method.

Example use case, starting fresh:

```
rm -rf ~/holos
mkdir ~/holos
cd ~/holos
```

Step 1: Login

```sh
holos login
```

```txt
9:53AM INF login.go:40 logged in as jeff@ois.run version=0.79.0 name="Jeff McCune" exp="2024-05-17 21:16:07 -0700 PDT" email=jeff@ois.run
```

Step 2: Register to create server side resources.

```sh
holos register user
```

```
9:52AM INF register.go:68 user version=0.79.0 email=jeff@ois.run user_id=018f826d-85a8-751d-81ee-64d0f2775b3f org_id=018f826d-85a8-751e-98dd-a6cddd9dd8f0
```

Step 3: Generate the bare platform in the local filesystem.

```sh
holos generate platform bare
```

```txt
9:52AM INF generate.go:79 wrote platform.metadata.json version=0.79.0 platform_id=018f826d-85a8-751f-96d0-0d2bf70df909 path=/home/jeff/holos/platform.metadata.json
9:52AM INF generate.go:91 generated platform bare version=0.79.0 platform_id=018f826d-85a8-751f-96d0-0d2bf70df909 path=/home/jeff/holos
```

Step 4: Push the platform form to the `holos server` web app.

```sh
holos push platform form .
```

```txt
9:52AM INF client.go:67 updated platform version=0.79.0 platform_id=018f826d-85a8-751f-96d0-0d2bf70df909 duration=73.62995ms
```

At this point the platform form is published and functions as expected
when visiting the platform web interface.
2024-05-17 09:51:36 -07:00
Jeff McCune
2b89c33067 (#175) Add holos orgid command
Makes it easier to work with grpcurl:

    grpcurl -H "x-oidc-id-token: $(holos token)" -d '{"org_id":"'$(holos orgid)'"}' ${HOLOS_SERVER##*/} holos.platform.v1alpha1.PlatformService.ListPlatforms
2024-05-16 21:11:24 -07:00
Jeff McCune
aee26d9375 (#175) Set header User-Agent: holos/0.70.0 (go1.22.2)
Previously: User-Agent: connect-go/1.16.0 (go1.22.2)
2024-05-16 20:49:06 -07:00
Jeff McCune
7b04d492ab (#175) Set http.Server ReadHeaderTimeout
Upstream connectrpc recommends it.  Refer to
https://connectrpc.com/docs/faq#stream-error
2024-05-16 20:28:31 -07:00
Jeff McCune
8abd03e165 (#175) Log x-request-id and x-b3-trace headers
This patch logs the x-request-id header which makes it straight forward
to correlate the logs with the service mesh logs.

For example, select the request id from the gateway logs by copying the
log from the holos server logs.

```sh
kubectl -n istio-ingress logs -l app=istio-ingressgateway -f \
  | grep --line-buffered '^{' \
  | jq 'select(.request_id=="'d0867115-5795-4096-942e-5ac188cdf618'")'
```

```json
{
  "upstream_local_address": "10.244.1.51:44248",
  "x_forwarded_for": "192.168.2.21",
  "authority": "jeff.app.dev.k2.holos.run:443",
  "upstream_transport_failure_reason": null,
  "connection_termination_details": null,
  "response_code": 200,
  "duration": 6,
  "response_flags": "-",
  "upstream_service_time": "5",
  "upstream_cluster": "outbound|3000||holos.jeff-holos.svc.cluster.local",
  "upstream_host": "10.244.1.249:3000",
  "user_agent": "connect-go/1.16.0 (go1.22.2)",
  "requested_server_name": "jeff.app.dev.k2.holos.run",
  "request_id": "d0867115-5795-4096-942e-5ac188cdf618",
  "start_time": "2024-05-17T03:16:37.900Z",
  "method": "POST",
  "protocol": "HTTP/2",
  "downstream_local_address": "65.102.23.41:443",
  "path": "/holos.user.v1alpha1.UserService/GetUser",
  "bytes_sent": 159,
  "downstream_remote_address": "192.168.2.21:59564",
  "response_code_details": "via_upstream",
  "bytes_received": 0,
  "route_name": "holos-api"
}
```
2024-05-16 20:14:34 -07:00
35 changed files with 1108 additions and 431 deletions

View File

@@ -61,7 +61,7 @@ vet: ## Vet Go code.
.PHONY: gencue
gencue: ## Generate CUE definitions
cd docs/examples && cue get go github.com/holos-run/holos/api/...
cd internal/generate/platforms && cue get go github.com/holos-run/holos/api/v1alpha1/...
.PHONY: rmgen
rmgen: ## Remove generated code
@@ -76,7 +76,7 @@ rmgen: ## Remove generated code
regenerate: generate ## Re-generate code (delete and re-create)
.PHONY: generate
generate: buf ## Generate code.
generate: buf gencue ## Generate code.
go generate ./...
.PHONY: build

13
api/v1alpha1/form.go Normal file
View File

@@ -0,0 +1,13 @@
package v1alpha1
import object "github.com/holos-run/holos/service/gen/holos/object/v1alpha1"
// Form represents a collection of Formly json powered form.
type Form struct {
TypeMeta `json:",inline" yaml:",inline"`
Spec FormSpec `json:"spec" yaml:"spec"`
}
type FormSpec struct {
Form object.Form `json:"form" yaml:"form"`
}

2
go.mod
View File

@@ -16,6 +16,7 @@ require (
github.com/fullstorydev/grpcurl v1.9.1
github.com/go-jose/go-jose/v3 v3.0.3
github.com/gofrs/uuid v4.4.0+incompatible
github.com/gogo/protobuf v1.3.2
github.com/int128/kubelogin v1.28.0
github.com/jackc/pgx/v5 v5.5.5
github.com/lmittmann/tint v1.0.4
@@ -114,7 +115,6 @@ require (
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gofrs/uuid/v5 v5.0.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.4 // indirect

View File

@@ -1,10 +1,10 @@
// Package holos defines types for the rest of the system.
package holos
// A PathCueMod is a string representing the filesystem path of a cue module.
// It is given a unique type so the API is clear.
// A PathCueMod is a string representing the absolute filesystem path of a cue
// module. It is given a unique type so the API is clear.
type PathCueMod string
// A InstancePath is a string representing the filesystem path of a holos instance.
// It is given a unique type so the API is clear.
// A InstancePath is a string representing the absolute filesystem path of a
// holos instance. It is given a unique type so the API is clear.
type InstancePath string

View File

@@ -46,8 +46,20 @@ func NewPlatformForm(cfg *client.Config) *cobra.Command {
if ctx == nil {
return errors.Wrap(errors.New("cannot execute: no context"))
}
rpc := client.New(cfg)
for _, name := range args {
if err := push.PlatformForm(ctx, name); err != nil {
// Get the platform metadata for the platform id.
p, err := push.LoadPlatform(ctx, name)
if err != nil {
return errors.Wrap(err)
}
// Build the form from the cue code.
form, err := push.PlatformForm(ctx, name)
if err != nil {
return errors.Wrap(err)
}
// Make the rpc call to update the platform form.
if err := rpc.UpdateForm(ctx, p.GetId(), form); err != nil {
return errors.Wrap(err)
}
}

View File

@@ -1,6 +1,7 @@
package cli
import (
"fmt"
"log/slog"
"github.com/spf13/cobra"
@@ -12,6 +13,7 @@ import (
"github.com/holos-run/holos/internal/server"
"github.com/holos-run/holos/internal/cli/build"
"github.com/holos-run/holos/internal/cli/command"
"github.com/holos-run/holos/internal/cli/controller"
"github.com/holos-run/holos/internal/cli/create"
"github.com/holos-run/holos/internal/cli/generate"
@@ -72,6 +74,7 @@ func New(cfg *holos.Config) *cobra.Command {
rootCmd.AddCommand(generate.New(cfg))
rootCmd.AddCommand(register.New(cfg))
rootCmd.AddCommand(push.New(cfg))
rootCmd.AddCommand(newOrgCmd())
// Maybe not needed?
rootCmd.AddCommand(txtar.New(cfg))
@@ -87,3 +90,15 @@ func New(cfg *holos.Config) *cobra.Command {
return rootCmd
}
func newOrgCmd() (cmd *cobra.Command) {
cmd = command.New("orgid")
cmd.Short = "print the current context org id."
cmd.RunE = func(cmd *cobra.Command, args []string) error {
ctx := cmd.Root().Context()
cc := holos.NewClientContext(ctx)
_, err := fmt.Fprintln(cmd.OutOrStdout(), cc.OrgID)
return err
}
return cmd
}

View File

@@ -3,10 +3,13 @@ package client
import (
"context"
"errors"
"time"
"connectrpc.com/connect"
"github.com/holos-run/holos/internal/errors"
"github.com/holos-run/holos/internal/server/middleware/logger"
"github.com/holos-run/holos/internal/token"
object "github.com/holos-run/holos/service/gen/holos/object/v1alpha1"
"github.com/holos-run/holos/service/gen/holos/organization/v1alpha1/organizationconnect"
platform "github.com/holos-run/holos/service/gen/holos/platform/v1alpha1"
"github.com/holos-run/holos/service/gen/holos/platform/v1alpha1/platformconnect"
@@ -49,3 +52,18 @@ func (c *Client) Platforms(ctx context.Context, orgID string) ([]*platform.Platf
}
return resp.Msg.GetPlatforms(), nil
}
func (c *Client) UpdateForm(ctx context.Context, platformID string, form *object.Form) error {
start := time.Now()
req := &platform.UpdatePlatformRequest{
Update: &platform.UpdatePlatformOperation{PlatformId: platformID, Form: form},
UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"form"}},
}
_, err := c.pltSvc.UpdatePlatform(ctx, connect.NewRequest(req))
if err != nil {
return errors.Wrap(err)
}
log := logger.FromContext(ctx)
log.InfoContext(ctx, "updated platform", "platform_id", platformID, "duration", time.Since(start))
return nil
}

View File

@@ -2,16 +2,27 @@
package client
import (
"context"
"flag"
"github.com/holos-run/holos/internal/holos"
"github.com/holos-run/holos/internal/token"
)
func NewConfig(cfg *holos.Config) *Config {
return &Config{
holos: cfg,
client: holos.NewClientConfig(),
context: holos.NewClientContext(context.Background()),
token: token.NewConfig(),
}
}
type Config struct {
holos *holos.Config
client *holos.ClientConfig
token *token.Config
holos *holos.Config
client *holos.ClientConfig
context *holos.ClientContext
token *token.Config
}
func (c *Config) ClientFlagSet() *flag.FlagSet {
@@ -42,10 +53,11 @@ func (c *Config) Client() *holos.ClientConfig {
return c.client
}
func NewConfig(cfg *holos.Config) *Config {
return &Config{
holos: cfg,
client: holos.NewClientConfig(),
token: token.NewConfig(),
// Context returns the ClientContext useful to get the OrgID and UserID for rpc
// calls.
func (c *Config) Context() *holos.ClientContext {
if c == nil {
return nil
}
return c.context
}

View File

@@ -4,7 +4,7 @@
// @ts-nocheck
import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
import { Message, proto3, Timestamp } from "@bufbuild/protobuf";
import { Message, proto3, Struct, Timestamp } from "@bufbuild/protobuf";
/**
* @generated from message holos.object.v1alpha1.Detail
@@ -325,3 +325,45 @@ export class ResourceOwner extends Message<ResourceOwner> {
}
}
/**
* Form represents a Formly json powered form.
*
* @generated from message holos.object.v1alpha1.Form
*/
export class Form extends Message<Form> {
/**
* fields represents FormlyFieldConfig[] encoded as an array of JSON objects
* organized by section.
*
* @generated from field: repeated google.protobuf.Struct field_configs = 1;
*/
fieldConfigs: Struct[] = [];
constructor(data?: PartialMessage<Form>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.object.v1alpha1.Form";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "field_configs", kind: "message", T: Struct, repeated: true },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): Form {
return new Form().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): Form {
return new Form().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): Form {
return new Form().fromJsonString(jsonString, options);
}
static equals(a: Form | PlainMessage<Form> | undefined, b: Form | PlainMessage<Form> | undefined): boolean {
return proto3.util.equals(Form, a, b);
}
}

View File

@@ -5,7 +5,7 @@
import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
import { Message, proto3, Struct } from "@bufbuild/protobuf";
import { Detail } from "../../object/v1alpha1/object_pb.js";
import { Detail, Form } from "../../object/v1alpha1/object_pb.js";
/**
* @generated from message holos.platform.v1alpha1.Platform
@@ -147,7 +147,7 @@ export class Spec extends Message<Spec> {
model?: Struct;
/**
* @generated from field: optional holos.platform.v1alpha1.Form form = 2;
* @generated from field: optional holos.object.v1alpha1.Form form = 2;
*/
form?: Form;
@@ -180,45 +180,3 @@ export class Spec extends Message<Spec> {
}
}
/**
* Form represents the Formly input form.
*
* @generated from message holos.platform.v1alpha1.Form
*/
export class Form extends Message<Form> {
/**
* fields represents FormlyFieldConfig[] encoded as an array of JSON objects
* organized by section.
*
* @generated from field: repeated google.protobuf.Struct field_configs = 1;
*/
fieldConfigs: Struct[] = [];
constructor(data?: PartialMessage<Form>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.Form";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "field_configs", kind: "message", T: Struct, repeated: true },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): Form {
return new Form().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): Form {
return new Form().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): Form {
return new Form().fromJsonString(jsonString, options);
}
static equals(a: Form | PlainMessage<Form> | undefined, b: Form | PlainMessage<Form> | undefined): boolean {
return proto3.util.equals(Form, a, b);
}
}

View File

@@ -5,7 +5,8 @@
import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
import { FieldMask, Message, proto3, Struct } from "@bufbuild/protobuf";
import { Form, Platform } from "./platform_pb.js";
import { Platform } from "./platform_pb.js";
import { Form } from "../../object/v1alpha1/object_pb.js";
/**
* @generated from message holos.platform.v1alpha1.CreatePlatformRequest
@@ -367,7 +368,7 @@ export class UpdatePlatformOperation extends Message<UpdatePlatformOperation> {
/**
* Replace the form.
*
* @generated from field: optional holos.platform.v1alpha1.Form form = 5;
* @generated from field: optional holos.object.v1alpha1.Form form = 5;
*/
form?: Form;

View File

@@ -11,6 +11,7 @@ package v1alpha1
// Metadata represents the holos component name
metadata?: #ObjectMeta @go(Metadata)
spec?: #BuildPlanSpec @go(Spec)
platform?: {...} @go(Platform,map[string]any)
}
#BuildPlanSpec: {

View File

@@ -0,0 +1,17 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
import "github.com/holos-run/holos/service/gen/holos/object/v1alpha1:object"
// Form represents a collection of Formly json powered form.
#Form: {
#TypeMeta
spec: #FormSpec @go(Spec)
}
#FormSpec: {
form: object.#Form @go(Form)
}

View File

@@ -1,12 +0,0 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
#KustomizeBuildKind: "KustomizeBuild"
// KustomizeBuild
#KustomizeBuild: {
#HolosComponent
}

View File

@@ -0,0 +1,13 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
// Platform represents a platform to manage. A Platform resource tells holos
// which components to build. The primary use case is to specify the cluster
// names, cluster types, and holos components to build.
#Platform: {
#TypeMeta
metadata?: #ObjectMeta @go(Metadata)
}

View File

@@ -8,3 +8,6 @@ package v1alpha1
kind?: string @go(Kind)
apiVersion?: string @go(APIVersion)
}
// Discriminator is an interface to discriminate the kind api object.
#Discriminator: _

View File

@@ -0,0 +1,116 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/service/gen/holos/object/v1alpha1
package object
import (
"google.golang.org/protobuf/types/known/timestamppb"
"google.golang.org/protobuf/types/known/structpb"
)
#Detail: {
// Created by entity
created_by?: null | #ResourceEditor @go(CreatedBy,*ResourceEditor) @protobuf(1,bytes,opt,json=createdBy,proto3,oneof)
// Created at timestamp
created_at?: null | timestamppb.#Timestamp @go(CreatedAt,*timestamppb.Timestamp) @protobuf(2,bytes,opt,json=createdAt,proto3)
// Updated by entity
updated_by?: null | #ResourceEditor @go(UpdatedBy,*ResourceEditor) @protobuf(3,bytes,opt,json=updatedBy,proto3,oneof)
// Updated at timestamp
updated_at?: null | timestamppb.#Timestamp @go(UpdatedAt,*timestamppb.Timestamp) @protobuf(4,bytes,opt,json=updatedAt,proto3)
}
// Subject represents the oidc iss and sub claims which uniquely identify a subject.
#Subject: {
// iss represents the oidc id token iss claim. Limits defined at
// https://openid.net/specs/openid-authentication-1_1.html#limits
iss?: string @go(Iss) @protobuf(1,bytes,opt,proto3)
// sub represents the oidc id token sub claim.
sub?: string @go(Sub) @protobuf(2,bytes,opt,proto3)
}
// UserRef refers to a User by uuid, email, or by the oidc iss and sub claims.
#UserRef: {
// Types that are assignable to User:
//
// *UserRef_UserId
// *UserRef_Email
// *UserRef_Subject
User: _#isUserRef_User
}
_#isUserRef_User: _
#UserRef_UserId: {
UserId: string @protobuf(1,bytes,opt,name=user_id,json=userId,proto3,oneof)
}
#UserRef_Email: {
Email: string @protobuf(2,bytes,opt,name=email,proto3,oneof)
}
#UserRef_Subject: {
Subject?: null | #Subject @go(,*Subject) @protobuf(3,bytes,opt,name=subject,proto3,oneof)
}
// Organization represents the ways in which a organization may be uniquely identified in the system.
#OrganizationRef: {
// Types that are assignable to Org:
//
// *OrganizationRef_OrgId
// *OrganizationRef_OrgName
Org: _#isOrganizationRef_Org
}
_#isOrganizationRef_Org: _
#OrganizationRef_OrgId: {
OrgId: string @protobuf(1,bytes,opt,name=org_id,json=orgId,proto3,oneof)
}
#OrganizationRef_OrgName: {
OrgName: string @protobuf(2,bytes,opt,name=org_name,json=orgName,proto3,oneof)
}
// ResourceEditor represents the entity that most recently created or edited a resource.
#ResourceEditor: {
// Types that are assignable to Editor:
//
// *ResourceEditor_UserId
Editor: _#isResourceEditor_Editor
}
_#isResourceEditor_Editor: _
#ResourceEditor_UserId: {
UserId: string @protobuf(1,bytes,opt,name=user_id,json=userId,proto3,oneof)
}
#ResourceOwner: {
// Types that are assignable to ResourceOwner:
//
// *ResourceOwner_OrgId
// *ResourceOwner_UserId
ResourceOwner: _#isResourceOwner_ResourceOwner
}
_#isResourceOwner_ResourceOwner: _
#ResourceOwner_OrgId: {
OrgId: string @protobuf(1,bytes,opt,name=org_id,json=orgId,proto3,oneof)
}
#ResourceOwner_UserId: {
UserId: string @protobuf(2,bytes,opt,name=user_id,json=userId,proto3,oneof)
}
// Form represents a Formly json powered form.
#Form: {
// fields represents FormlyFieldConfig[] encoded as an array of JSON objects
// organized by section.
field_configs?: [...null | structpb.#Struct] @go(FieldConfigs,[]*structpb.Struct) @protobuf(1,bytes,rep,json=fieldConfigs,proto3)
}

View File

@@ -0,0 +1,159 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go google.golang.org/protobuf/types/known/structpb
// Package structpb contains generated types for google/protobuf/struct.proto.
//
// The messages (i.e., Value, Struct, and ListValue) defined in struct.proto are
// used to represent arbitrary JSON. The Value message represents a JSON value,
// the Struct message represents a JSON object, and the ListValue message
// represents a JSON array. See https://json.org for more information.
//
// The Value, Struct, and ListValue types have generated MarshalJSON and
// UnmarshalJSON methods such that they serialize JSON equivalent to what the
// messages themselves represent. Use of these types with the
// "google.golang.org/protobuf/encoding/protojson" package
// ensures that they will be serialized as their JSON equivalent.
//
// # Conversion to and from a Go interface
//
// The standard Go "encoding/json" package has functionality to serialize
// arbitrary types to a large degree. The Value.AsInterface, Struct.AsMap, and
// ListValue.AsSlice methods can convert the protobuf message representation into
// a form represented by interface{}, map[string]interface{}, and []interface{}.
// This form can be used with other packages that operate on such data structures
// and also directly with the standard json package.
//
// In order to convert the interface{}, map[string]interface{}, and []interface{}
// forms back as Value, Struct, and ListValue messages, use the NewStruct,
// NewList, and NewValue constructor functions.
//
// # Example usage
//
// Consider the following example JSON object:
//
// {
// "firstName": "John",
// "lastName": "Smith",
// "isAlive": true,
// "age": 27,
// "address": {
// "streetAddress": "21 2nd Street",
// "city": "New York",
// "state": "NY",
// "postalCode": "10021-3100"
// },
// "phoneNumbers": [
// {
// "type": "home",
// "number": "212 555-1234"
// },
// {
// "type": "office",
// "number": "646 555-4567"
// }
// ],
// "children": [],
// "spouse": null
// }
//
// To construct a Value message representing the above JSON object:
//
// m, err := structpb.NewValue(map[string]interface{}{
// "firstName": "John",
// "lastName": "Smith",
// "isAlive": true,
// "age": 27,
// "address": map[string]interface{}{
// "streetAddress": "21 2nd Street",
// "city": "New York",
// "state": "NY",
// "postalCode": "10021-3100",
// },
// "phoneNumbers": []interface{}{
// map[string]interface{}{
// "type": "home",
// "number": "212 555-1234",
// },
// map[string]interface{}{
// "type": "office",
// "number": "646 555-4567",
// },
// },
// "children": []interface{}{},
// "spouse": nil,
// })
// if err != nil {
// ... // handle error
// }
// ... // make use of m as a *structpb.Value
package structpb
// `NullValue` is a singleton enumeration to represent the null value for the
// `Value` type union.
//
// The JSON representation for `NullValue` is JSON `null`.
#NullValue: int32 // #enumNullValue
#enumNullValue:
#NullValue_NULL_VALUE
#values_NullValue: NullValue_NULL_VALUE: #NullValue_NULL_VALUE
// Null value.
#NullValue_NULL_VALUE: #NullValue & 0
// `Struct` represents a structured data value, consisting of fields
// which map to dynamically typed values. In some languages, `Struct`
// might be supported by a native representation. For example, in
// scripting languages like JS a struct is represented as an
// object. The details of that representation are described together
// with the proto support for the language.
//
// The JSON representation for `Struct` is JSON object.
#Struct: _
// `Value` represents a dynamically typed value which can be either
// null, a number, a string, a boolean, a recursive struct value, or a
// list of values. A producer of value is expected to set one of these
// variants. Absence of any variant indicates an error.
//
// The JSON representation for `Value` is JSON value.
#Value: _
_#isValue_Kind: _
#Value_NullValue: {
// Represents a null value.
NullValue: #NullValue @protobuf(1,varint,opt,name=null_value,json=nullValue,proto3,enum=google.protobuf.NullValue,oneof)
}
#Value_NumberValue: {
// Represents a double value.
NumberValue: float64 @protobuf(2,fixed64,opt,name=number_value,json=numberValue,proto3,oneof)
}
#Value_StringValue: {
// Represents a string value.
StringValue: string @protobuf(3,bytes,opt,name=string_value,json=stringValue,proto3,oneof)
}
#Value_BoolValue: {
// Represents a boolean value.
BoolValue: bool @protobuf(4,varint,opt,name=bool_value,json=boolValue,proto3,oneof)
}
#Value_StructValue: {
// Represents a structured value.
StructValue?: null | #Struct @go(,*Struct) @protobuf(5,bytes,opt,name=struct_value,json=structValue,proto3,oneof)
}
#Value_ListValue: {
// Represents a repeated `Value`.
ListValue?: null | #ListValue @go(,*ListValue) @protobuf(6,bytes,opt,name=list_value,json=listValue,proto3,oneof)
}
// `ListValue` is a wrapper around a repeated field of values.
//
// The JSON representation for `ListValue` is JSON array.
#ListValue: _

View File

@@ -0,0 +1,150 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go google.golang.org/protobuf/types/known/timestamppb
// Package timestamppb contains generated types for google/protobuf/timestamp.proto.
//
// The Timestamp message represents a timestamp,
// an instant in time since the Unix epoch (January 1st, 1970).
//
// # Conversion to a Go Time
//
// The AsTime method can be used to convert a Timestamp message to a
// standard Go time.Time value in UTC:
//
// t := ts.AsTime()
// ... // make use of t as a time.Time
//
// Converting to a time.Time is a common operation so that the extensive
// set of time-based operations provided by the time package can be leveraged.
// See https://golang.org/pkg/time for more information.
//
// The AsTime method performs the conversion on a best-effort basis. Timestamps
// with denormal values (e.g., nanoseconds beyond 0 and 99999999, inclusive)
// are normalized during the conversion to a time.Time. To manually check for
// invalid Timestamps per the documented limitations in timestamp.proto,
// additionally call the CheckValid method:
//
// if err := ts.CheckValid(); err != nil {
// ... // handle error
// }
//
// # Conversion from a Go Time
//
// The timestamppb.New function can be used to construct a Timestamp message
// from a standard Go time.Time value:
//
// ts := timestamppb.New(t)
// ... // make use of ts as a *timestamppb.Timestamp
//
// In order to construct a Timestamp representing the current time, use Now:
//
// ts := timestamppb.Now()
// ... // make use of ts as a *timestamppb.Timestamp
package timestamppb
// A Timestamp represents a point in time independent of any time zone or local
// calendar, encoded as a count of seconds and fractions of seconds at
// nanosecond resolution. The count is relative to an epoch at UTC midnight on
// January 1, 1970, in the proleptic Gregorian calendar which extends the
// Gregorian calendar backwards to year one.
//
// All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap
// second table is needed for interpretation, using a [24-hour linear
// smear](https://developers.google.com/time/smear).
//
// The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By
// restricting to that range, we ensure that we can convert to and from [RFC
// 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings.
//
// # Examples
//
// Example 1: Compute Timestamp from POSIX `time()`.
//
// Timestamp timestamp;
// timestamp.set_seconds(time(NULL));
// timestamp.set_nanos(0);
//
// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
//
// struct timeval tv;
// gettimeofday(&tv, NULL);
//
// Timestamp timestamp;
// timestamp.set_seconds(tv.tv_sec);
// timestamp.set_nanos(tv.tv_usec * 1000);
//
// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
//
// FILETIME ft;
// GetSystemTimeAsFileTime(&ft);
// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
//
// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
// Timestamp timestamp;
// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
//
// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
//
// long millis = System.currentTimeMillis();
//
// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
// .setNanos((int) ((millis % 1000) * 1000000)).build();
//
// Example 5: Compute Timestamp from Java `Instant.now()`.
//
// Instant now = Instant.now();
//
// Timestamp timestamp =
// Timestamp.newBuilder().setSeconds(now.getEpochSecond())
// .setNanos(now.getNano()).build();
//
// Example 6: Compute Timestamp from current time in Python.
//
// timestamp = Timestamp()
// timestamp.GetCurrentTime()
//
// # JSON Mapping
//
// In JSON format, the Timestamp type is encoded as a string in the
// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the
// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z"
// where {year} is always expressed using four digits while {month}, {day},
// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional
// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),
// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone
// is required. A proto3 JSON serializer should always use UTC (as indicated by
// "Z") when printing the Timestamp type and a proto3 JSON parser should be
// able to accept both UTC and other timezones (as indicated by an offset).
//
// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
// 01:30 UTC on January 15, 2017.
//
// In JavaScript, one can convert a Date object to this format using the
// standard
// [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)
// method. In Python, a standard `datetime.datetime` object can be converted
// to this format using
// [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with
// the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use
// the Joda Time's [`ISODateTimeFormat.dateTime()`](
// http://joda-time.sourceforge.net/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime()
// ) to obtain a formatter capable of generating timestamps in this format.
#Timestamp: {
// Represents seconds of UTC time since Unix epoch
// 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
// 9999-12-31T23:59:59Z inclusive.
seconds?: int64 @go(Seconds) @protobuf(1,varint,opt,proto3)
// Non-negative fractions of a second at nanosecond resolution. Negative
// second values with fractions must still have non-negative nanos values
// that count forward in time. Must be from 0 to 999,999,999
// inclusive.
nanos?: int32 @go(Nanos) @protobuf(2,varint,opt,proto3)
}
_#invalidNil: 1
_#invalidUnderflow: 2
_#invalidOverflow: 3
_#invalidNanos: 4

View File

@@ -1,14 +1,9 @@
package v1alpha1
// #Form represents a web app form to provide to the Holos API for display in
// the web app. A form is implemented as an Formly FieldConfig array using
// Angular Material form field components.
// Form represents a collection of Formly json powered form.
#Form: {
#TypeMeta
apiVersion: #APIVersion
kind: "Form"
spec: fields: [...#FieldConfig]
}
// #FormBuilder provides a concrete #Form via the Output field.
@@ -17,7 +12,7 @@ package v1alpha1
Sections: {[NAME=string]: #FormSection & {name: NAME}}
Output: #Form & {
spec: fields: [for s in Sections {s.wrapper}]
spec: form: field_configs: [for s in Sections {s.wrapper}]
}
}

View File

@@ -11,6 +11,8 @@ import (
"k8s.io/client-go/util/homedir"
)
// NewClientContext loads a ClientContext from the file system if it exists,
// otherwise returns a ClientContext with default values.
func NewClientContext(ctx context.Context) *ClientContext {
cc := &ClientContext{}
if cc.Exists() {

91
internal/push/instance.go Normal file
View File

@@ -0,0 +1,91 @@
package push
import (
"context"
"fmt"
"os"
"path/filepath"
"cuelang.org/go/cue/cuecontext"
"cuelang.org/go/cue/load"
"github.com/holos-run/holos"
"github.com/holos-run/holos/internal/errors"
)
func NewInstance(name string) (*Instance, error) {
absPath, err := filepath.Abs(name)
if err != nil {
return nil, err
}
path := holos.InstancePath(absPath)
mod, err := FindCueMod(path)
if err != nil {
return nil, err
}
return &Instance{path: path, mod: mod}, nil
}
// Instance represents a CUE instance.
type Instance struct {
path holos.InstancePath
mod holos.PathCueMod
}
// Export builds the cue instance into a JSON byte slice. Equivalent of cue
// export.
func (i *Instance) Export(ctx context.Context) ([]byte, error) {
// CUE Loader
cfg := load.Config{Dir: string(i.mod)}
// Make target relative to the module directory
relPath, err := filepath.Rel(string(i.mod), string(i.path))
if err != nil {
return nil, err
}
relPath = "./" + relPath
instances := load.Instances([]string{relPath}, &cfg)
if len(instances) != 1 {
return nil, errors.Wrap(errors.New("exactly one instance is required"))
}
instance := instances[0]
if err := instance.Err; err != nil {
return nil, errors.Wrap(fmt.Errorf("could not load: %w", err))
}
cueCtx := cuecontext.New()
value := cueCtx.BuildInstance(instance)
if err := value.Err(); err != nil {
return nil, errors.Wrap(fmt.Errorf("could not build %s: %w", instance.Dir, err))
}
if err := value.Validate(); err != nil {
return nil, errors.Wrap(fmt.Errorf("could not validate: %w", err))
}
b, err := value.MarshalJSON()
if err != nil {
return nil, errors.Wrap(fmt.Errorf("could not marshal cue instance %s: %w", instance.Dir, err))
}
return b, nil
}
func FindCueMod(name holos.InstancePath) (dir holos.PathCueMod, err error) {
path := holos.PathCueMod(name)
for {
if _, err := os.Stat(filepath.Join(string(path), "cue.mod")); err == nil {
dir = path
break
} else if !os.IsNotExist(err) {
return "", err
}
parentPath := holos.PathCueMod(filepath.Dir(string(path)))
if parentPath == path {
return "", fmt.Errorf("no cue.mod from root to leaf: %v", name)
}
path = parentPath
}
return dir, nil
}

View File

@@ -1,8 +1,55 @@
// Package push pushes resources to the holos api server.
package push
import "context"
import (
"bytes"
"context"
"encoding/json"
"os"
"path/filepath"
func PlatformForm(ctx context.Context, path string) error {
return nil
"github.com/gogo/protobuf/jsonpb"
"github.com/holos-run/holos/api/v1alpha1"
"github.com/holos-run/holos/internal/errors"
object "github.com/holos-run/holos/service/gen/holos/object/v1alpha1"
platform "github.com/holos-run/holos/service/gen/holos/platform/v1alpha1"
)
// LoadPlatform loads the platform.metadata.json file from a named path.
func LoadPlatform(ctx context.Context, name string) (*platform.Platform, error) {
data, err := os.ReadFile(filepath.Join(name, "platform.metadata.json"))
if err != nil {
return nil, err
}
p := &platform.Platform{}
if err := jsonpb.Unmarshal(bytes.NewReader(data), p); err != nil {
return nil, err
}
return p, nil
}
// PlatformForm builds a json powered web form from CUE code. The CUE code is
// expected to be derived from the code generated by the `holos generate
// platform` command.
func PlatformForm(ctx context.Context, name string) (*object.Form, error) {
// build the form which always lives at ./forms/platform relative to the
// platform root where platform.metadata.json is.
instance, err := NewInstance(filepath.Join(name, "forms", "platform"))
if err != nil {
return nil, errors.Wrap(err)
}
formData, err := instance.Export(ctx)
if err != nil {
return nil, errors.Wrap(err)
}
form := &v1alpha1.Form{}
decoder := json.NewDecoder(bytes.NewReader(formData))
decoder.DisallowUnknownFields()
if err := decoder.Decode(form); err != nil {
return nil, errors.Wrap(err)
}
return &form.Spec.Form, nil
}

View File

@@ -258,7 +258,7 @@ func PlatformToRPC(entity *ent.Platform) *platform.Platform {
DisplayName: &entity.DisplayName,
Spec: &platform.Spec{
Model: entity.Model.GetModel(),
Form: &platform.Form{
Form: &object.Form{
FieldConfigs: entity.Form.GetFieldConfigs(),
},
},

View File

@@ -12,7 +12,15 @@ func NewLogger() connect.UnaryInterceptorFunc {
interceptor := func(next connect.UnaryFunc) connect.UnaryFunc {
return connect.UnaryFunc(func(ctx context.Context, req connect.AnyRequest) (connect.AnyResponse, error) {
start := time.Now()
rpcLogger := logger.FromContext(ctx).With("procedure", req.Spec().Procedure)
rpcLogger := logger.FromContext(ctx).With(
"procedure", req.Spec().Procedure,
"request_id", req.Header().Get("x-request-id"),
"traceid", req.Header().Get("x-b3-traceid"),
"spanid", req.Header().Get("x-b3-spanid"),
"parentspanid", req.Header().Get("x-b3-parentspanid"),
"sampled", req.Header().Get("x-b3-sampled"),
"host", req.Header().Get("host"),
)
ctx = logger.NewContext(ctx, rpcLogger)
resp, err := next(ctx, req)
go emitLog(ctx, start, err)

View File

@@ -6,6 +6,7 @@ import (
_ "net/http/pprof"
"os"
"sync/atomic"
"time"
"connectrpc.com/connect"
"connectrpc.com/grpcreflect"
@@ -177,6 +178,9 @@ func (s *Server) startServer() *http.Server {
// WriteTimeout: s.cfg.ServerConfig.HttpServerTimeout,
// ReadTimeout: s.cfg.ServerConfig.HttpServerTimeout,
// IdleTimeout: 2 * s.cfg.ServerConfig.HttpServerTimeout,
// "we encourage you to set ReadHeaderTimeout in particular."
// Refer to: https://connectrpc.com/docs/faq#stream-error
ReadHeaderTimeout: 10 * time.Second,
}
httpLog := s.cfg.Logger().With("addr", srv.Addr, "server", "http")

View File

@@ -15,6 +15,7 @@ import (
"github.com/holos-run/holos/internal/errors"
hlogger "github.com/holos-run/holos/internal/logger"
"github.com/holos-run/holos/internal/server/middleware/authn"
"github.com/holos-run/holos/version"
"github.com/int128/kubelogin/pkg/infrastructure/browser"
"github.com/int128/kubelogin/pkg/infrastructure/clock"
"github.com/int128/kubelogin/pkg/infrastructure/logger"
@@ -119,6 +120,8 @@ func (t *customTransport) RoundTrip(req *http.Request) (*http.Response, error) {
return nil, errors.Wrap(fmt.Errorf("could not get token: %w", err))
}
req.Header.Set(authn.Header, token.Bearer)
ua := fmt.Sprintf("holos/%s (%s)", version.Version, version.GoVersion)
req.Header.Set("User-Agent", ua)
return t.Transport.RoundTrip(req)
}

View File

@@ -10,6 +10,7 @@ import (
_ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
structpb "google.golang.org/protobuf/types/known/structpb"
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
reflect "reflect"
sync "sync"
@@ -483,6 +484,56 @@ func (*ResourceOwner_OrgId) isResourceOwner_ResourceOwner() {}
func (*ResourceOwner_UserId) isResourceOwner_ResourceOwner() {}
// Form represents a Formly json powered form.
type Form struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// fields represents FormlyFieldConfig[] encoded as an array of JSON objects
// organized by section.
FieldConfigs []*structpb.Struct `protobuf:"bytes,1,rep,name=field_configs,json=fieldConfigs,proto3" json:"field_configs,omitempty"`
}
func (x *Form) Reset() {
*x = Form{}
if protoimpl.UnsafeEnabled {
mi := &file_holos_object_v1alpha1_object_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Form) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Form) ProtoMessage() {}
func (x *Form) ProtoReflect() protoreflect.Message {
mi := &file_holos_object_v1alpha1_object_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Form.ProtoReflect.Descriptor instead.
func (*Form) Descriptor() ([]byte, []int) {
return file_holos_object_v1alpha1_object_proto_rawDescGZIP(), []int{6}
}
func (x *Form) GetFieldConfigs() []*structpb.Struct {
if x != nil {
return x.FieldConfigs
}
return nil
}
var File_holos_object_v1alpha1_object_proto protoreflect.FileDescriptor
var file_holos_object_v1alpha1_object_proto_rawDesc = []byte{
@@ -491,82 +542,89 @@ var file_holos_object_v1alpha1_object_proto_rawDesc = []byte{
0x72, 0x6f, 0x74, 0x6f, 0x12, 0x15, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x6f, 0x62, 0x6a, 0x65,
0x63, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d,
0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x62, 0x75,
0x66, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64,
0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc6, 0x02, 0x0a, 0x06, 0x44, 0x65,
0x74, 0x61, 0x69, 0x6c, 0x12, 0x49, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f,
0x62, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73,
0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x45, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x48,
0x00, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x88, 0x01, 0x01, 0x12,
0x43, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42,
0x08, 0xba, 0x48, 0x05, 0xb2, 0x01, 0x02, 0x38, 0x01, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74,
0x65, 0x64, 0x41, 0x74, 0x12, 0x49, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f,
0x62, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73,
0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x45, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x48,
0x01, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x88, 0x01, 0x01, 0x12,
0x43, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42,
0x08, 0xba, 0x48, 0x05, 0xb2, 0x01, 0x02, 0x38, 0x01, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74,
0x65, 0x64, 0x41, 0x74, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64,
0x5f, 0x62, 0x79, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f,
0x62, 0x79, 0x22, 0x52, 0x0a, 0x07, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x29, 0x0a,
0x03, 0x69, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x17, 0xba, 0x48, 0x14, 0x72,
0x12, 0x10, 0x01, 0x18, 0xff, 0x01, 0x3a, 0x08, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
0x88, 0x01, 0x01, 0x52, 0x03, 0x69, 0x73, 0x73, 0x12, 0x1c, 0x0a, 0x03, 0x73, 0x75, 0x62, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x18, 0xff,
0x01, 0x52, 0x03, 0x73, 0x75, 0x62, 0x22, 0x9a, 0x01, 0x0a, 0x07, 0x55, 0x73, 0x65, 0x72, 0x52,
0x65, 0x66, 0x12, 0x23, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52,
0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x60, 0x01, 0x48,
0x00, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x3a, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a,
0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x6f, 0x6c, 0x6f,
0x73, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
0x31, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x48, 0x00, 0x52, 0x07, 0x73, 0x75, 0x62,
0x6a, 0x65, 0x63, 0x74, 0x42, 0x0d, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x05, 0xba, 0x48,
0x02, 0x08, 0x01, 0x22, 0xd1, 0x02, 0x0a, 0x0f, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x66, 0x12, 0x21, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69,
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01,
0x01, 0x48, 0x00, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x12, 0x8c, 0x02, 0x0a, 0x08, 0x6f,
0x72, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0xee, 0x01,
0xba, 0x48, 0xea, 0x01, 0xba, 0x01, 0xe6, 0x01, 0x0a, 0x08, 0x6f, 0x72, 0x67, 0x2e, 0x6e, 0x61,
0x6d, 0x65, 0x12, 0xa4, 0x01, 0x41, 0x6c, 0x6c, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74,
0x65, 0x72, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x65, 0x69, 0x74, 0x68,
0x65, 0x72, 0x20, 0x61, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x61,
0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x2e, 0x20, 0x20, 0x43, 0x61,
0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20,
0x61, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x2e, 0x20, 0x20, 0x43, 0x61, 0x6e, 0x6e, 0x6f,
0x74, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63,
0x75, 0x74, 0x69, 0x76, 0x65, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x2e, 0x20, 0x20,
0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61,
0x74, 0x20, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x20, 0x33, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x74,
0x20, 0x6d, 0x6f, 0x73, 0x74, 0x20, 0x33, 0x39, 0x2e, 0x1a, 0x33, 0x74, 0x68, 0x69, 0x73, 0x2e,
0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x28, 0x3f, 0x21, 0x2d, 0x29, 0x28,
0x3f, 0x21, 0x2e, 0x2a, 0x2d, 0x2d, 0x29, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30,
0x2d, 0x39, 0x2d, 0x5d, 0x29, 0x7b, 0x33, 0x2c, 0x33, 0x39, 0x7d, 0x24, 0x27, 0x29, 0x48, 0x00,
0x52, 0x07, 0x6f, 0x72, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x42, 0x0c, 0x0a, 0x03, 0x6f, 0x72, 0x67,
0x12, 0x05, 0xba, 0x48, 0x02, 0x08, 0x01, 0x22, 0x46, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x45, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x12, 0x23, 0x0a, 0x07, 0x75, 0x73, 0x65,
0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72,
0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x42, 0x0f,
0x0a, 0x06, 0x65, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x12, 0x05, 0xba, 0x48, 0x02, 0x08, 0x01, 0x22,
0x70, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72,
0x12, 0x21, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, 0x05, 0x6f, 0x72,
0x67, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00,
0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x42, 0x17, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x05, 0xba, 0x48, 0x02, 0x08,
0x01, 0x42, 0x45, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2d, 0x72, 0x75, 0x6e, 0x2f, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2f,
0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x68, 0x6f, 0x6c, 0x6f,
0x73, 0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
0x31, 0x3b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74,
0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x62, 0x75, 0x66, 0x2f,
0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74,
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc6, 0x02, 0x0a, 0x06, 0x44, 0x65, 0x74, 0x61,
0x69, 0x6c, 0x12, 0x49, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x6f,
0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52,
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x45, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x48, 0x00, 0x52,
0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x88, 0x01, 0x01, 0x12, 0x43, 0x0a,
0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x08, 0xba,
0x48, 0x05, 0xb2, 0x01, 0x02, 0x38, 0x01, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64,
0x41, 0x74, 0x12, 0x49, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79,
0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x6f,
0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52,
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x45, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x48, 0x01, 0x52,
0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x88, 0x01, 0x01, 0x12, 0x43, 0x0a,
0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x08, 0xba,
0x48, 0x05, 0xb2, 0x01, 0x02, 0x38, 0x01, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64,
0x41, 0x74, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62,
0x79, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79,
0x22, 0x52, 0x0a, 0x07, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x29, 0x0a, 0x03, 0x69,
0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x17, 0xba, 0x48, 0x14, 0x72, 0x12, 0x10,
0x01, 0x18, 0xff, 0x01, 0x3a, 0x08, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x88, 0x01,
0x01, 0x52, 0x03, 0x69, 0x73, 0x73, 0x12, 0x1c, 0x0a, 0x03, 0x73, 0x75, 0x62, 0x18, 0x02, 0x20,
0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x18, 0xff, 0x01, 0x52,
0x03, 0x73, 0x75, 0x62, 0x22, 0x9a, 0x01, 0x0a, 0x07, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x66,
0x12, 0x23, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, 0x06, 0x75,
0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x60, 0x01, 0x48, 0x00, 0x52,
0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x3a, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63,
0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e,
0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x48, 0x00, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65,
0x63, 0x74, 0x42, 0x0d, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x05, 0xba, 0x48, 0x02, 0x08,
0x01, 0x22, 0xd1, 0x02, 0x0a, 0x0f, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x52, 0x65, 0x66, 0x12, 0x21, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48,
0x00, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x12, 0x8c, 0x02, 0x0a, 0x08, 0x6f, 0x72, 0x67,
0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0xee, 0x01, 0xba, 0x48,
0xea, 0x01, 0xba, 0x01, 0xe6, 0x01, 0x0a, 0x08, 0x6f, 0x72, 0x67, 0x2e, 0x6e, 0x61, 0x6d, 0x65,
0x12, 0xa4, 0x01, 0x41, 0x6c, 0x6c, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72,
0x73, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72,
0x20, 0x61, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x70,
0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x2e, 0x20, 0x20, 0x43, 0x61, 0x6e, 0x6e,
0x6f, 0x74, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20,
0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x2e, 0x20, 0x20, 0x43, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20,
0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x74,
0x69, 0x76, 0x65, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x2e, 0x20, 0x20, 0x4c, 0x65,
0x6e, 0x67, 0x74, 0x68, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x74, 0x20,
0x6c, 0x65, 0x61, 0x73, 0x74, 0x20, 0x33, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x74, 0x20, 0x6d,
0x6f, 0x73, 0x74, 0x20, 0x33, 0x39, 0x2e, 0x1a, 0x33, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61,
0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x28, 0x3f, 0x21, 0x2d, 0x29, 0x28, 0x3f, 0x21,
0x2e, 0x2a, 0x2d, 0x2d, 0x29, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39,
0x2d, 0x5d, 0x29, 0x7b, 0x33, 0x2c, 0x33, 0x39, 0x7d, 0x24, 0x27, 0x29, 0x48, 0x00, 0x52, 0x07,
0x6f, 0x72, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x42, 0x0c, 0x0a, 0x03, 0x6f, 0x72, 0x67, 0x12, 0x05,
0xba, 0x48, 0x02, 0x08, 0x01, 0x22, 0x46, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x45, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x12, 0x23, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f,
0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0,
0x01, 0x01, 0x48, 0x00, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x42, 0x0f, 0x0a, 0x06,
0x65, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x12, 0x05, 0xba, 0x48, 0x02, 0x08, 0x01, 0x22, 0x70, 0x0a,
0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x21,
0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08,
0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49,
0x64, 0x12, 0x23, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, 0x06,
0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x42, 0x17, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x05, 0xba, 0x48, 0x02, 0x08, 0x01, 0x22,
0x44, 0x0a, 0x04, 0x46, 0x6f, 0x72, 0x6d, 0x12, 0x3c, 0x0a, 0x0d, 0x66, 0x69, 0x65, 0x6c, 0x64,
0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x43, 0x6f,
0x6e, 0x66, 0x69, 0x67, 0x73, 0x42, 0x45, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2d, 0x72, 0x75, 0x6e, 0x2f, 0x68, 0x6f,
0x6c, 0x6f, 0x73, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x67, 0x65, 0x6e, 0x2f,
0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2f, 0x76, 0x31, 0x61,
0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -581,7 +639,7 @@ func file_holos_object_v1alpha1_object_proto_rawDescGZIP() []byte {
return file_holos_object_v1alpha1_object_proto_rawDescData
}
var file_holos_object_v1alpha1_object_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_holos_object_v1alpha1_object_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
var file_holos_object_v1alpha1_object_proto_goTypes = []interface{}{
(*Detail)(nil), // 0: holos.object.v1alpha1.Detail
(*Subject)(nil), // 1: holos.object.v1alpha1.Subject
@@ -589,19 +647,22 @@ var file_holos_object_v1alpha1_object_proto_goTypes = []interface{}{
(*OrganizationRef)(nil), // 3: holos.object.v1alpha1.OrganizationRef
(*ResourceEditor)(nil), // 4: holos.object.v1alpha1.ResourceEditor
(*ResourceOwner)(nil), // 5: holos.object.v1alpha1.ResourceOwner
(*timestamppb.Timestamp)(nil), // 6: google.protobuf.Timestamp
(*Form)(nil), // 6: holos.object.v1alpha1.Form
(*timestamppb.Timestamp)(nil), // 7: google.protobuf.Timestamp
(*structpb.Struct)(nil), // 8: google.protobuf.Struct
}
var file_holos_object_v1alpha1_object_proto_depIdxs = []int32{
4, // 0: holos.object.v1alpha1.Detail.created_by:type_name -> holos.object.v1alpha1.ResourceEditor
6, // 1: holos.object.v1alpha1.Detail.created_at:type_name -> google.protobuf.Timestamp
7, // 1: holos.object.v1alpha1.Detail.created_at:type_name -> google.protobuf.Timestamp
4, // 2: holos.object.v1alpha1.Detail.updated_by:type_name -> holos.object.v1alpha1.ResourceEditor
6, // 3: holos.object.v1alpha1.Detail.updated_at:type_name -> google.protobuf.Timestamp
7, // 3: holos.object.v1alpha1.Detail.updated_at:type_name -> google.protobuf.Timestamp
1, // 4: holos.object.v1alpha1.UserRef.subject:type_name -> holos.object.v1alpha1.Subject
5, // [5:5] is the sub-list for method output_type
5, // [5:5] is the sub-list for method input_type
5, // [5:5] is the sub-list for extension type_name
5, // [5:5] is the sub-list for extension extendee
0, // [0:5] is the sub-list for field type_name
8, // 5: holos.object.v1alpha1.Form.field_configs:type_name -> google.protobuf.Struct
6, // [6:6] is the sub-list for method output_type
6, // [6:6] is the sub-list for method input_type
6, // [6:6] is the sub-list for extension type_name
6, // [6:6] is the sub-list for extension extendee
0, // [0:6] is the sub-list for field type_name
}
func init() { file_holos_object_v1alpha1_object_proto_init() }
@@ -682,6 +743,18 @@ func file_holos_object_v1alpha1_object_proto_init() {
return nil
}
}
file_holos_object_v1alpha1_object_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Form); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
file_holos_object_v1alpha1_object_proto_msgTypes[0].OneofWrappers = []interface{}{}
file_holos_object_v1alpha1_object_proto_msgTypes[2].OneofWrappers = []interface{}{
@@ -706,7 +779,7 @@ func file_holos_object_v1alpha1_object_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_holos_object_v1alpha1_object_proto_rawDesc,
NumEnums: 0,
NumMessages: 6,
NumMessages: 7,
NumExtensions: 0,
NumServices: 0,
},

View File

@@ -199,7 +199,7 @@ type Spec struct {
// The model is a Struct to ensure any valid JSON object defined by the user
// via the form can be represented and stored.
Model *structpb.Struct `protobuf:"bytes,1,opt,name=model,proto3" json:"model,omitempty"`
Form *Form `protobuf:"bytes,2,opt,name=form,proto3,oneof" json:"form,omitempty"`
Form *v1alpha1.Form `protobuf:"bytes,2,opt,name=form,proto3,oneof" json:"form,omitempty"`
}
func (x *Spec) Reset() {
@@ -241,63 +241,13 @@ func (x *Spec) GetModel() *structpb.Struct {
return nil
}
func (x *Spec) GetForm() *Form {
func (x *Spec) GetForm() *v1alpha1.Form {
if x != nil {
return x.Form
}
return nil
}
// Form represents the Formly input form.
type Form struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// fields represents FormlyFieldConfig[] encoded as an array of JSON objects
// organized by section.
FieldConfigs []*structpb.Struct `protobuf:"bytes,1,rep,name=field_configs,json=fieldConfigs,proto3" json:"field_configs,omitempty"`
}
func (x *Form) Reset() {
*x = Form{}
if protoimpl.UnsafeEnabled {
mi := &file_holos_platform_v1alpha1_platform_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Form) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Form) ProtoMessage() {}
func (x *Form) ProtoReflect() protoreflect.Message {
mi := &file_holos_platform_v1alpha1_platform_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Form.ProtoReflect.Descriptor instead.
func (*Form) Descriptor() ([]byte, []int) {
return file_holos_platform_v1alpha1_platform_proto_rawDescGZIP(), []int{3}
}
func (x *Form) GetFieldConfigs() []*structpb.Struct {
if x != nil {
return x.FieldConfigs
}
return nil
}
var File_holos_platform_v1alpha1_platform_proto protoreflect.FileDescriptor
var file_holos_platform_v1alpha1_platform_proto_rawDesc = []byte{
@@ -377,24 +327,19 @@ var file_holos_platform_v1alpha1_platform_proto_rawDesc = []byte{
0x6e, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52,
0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x42, 0x0e, 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x12,
0x05, 0xba, 0x48, 0x02, 0x08, 0x01, 0x22, 0x76, 0x0a, 0x04, 0x53, 0x70, 0x65, 0x63, 0x12, 0x2d,
0x05, 0xba, 0x48, 0x02, 0x08, 0x01, 0x22, 0x74, 0x0a, 0x04, 0x53, 0x70, 0x65, 0x63, 0x12, 0x2d,
0x0a, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x36, 0x0a,
0x04, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x68, 0x6f,
0x6c, 0x6f, 0x73, 0x2e, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x61,
0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x46, 0x6f, 0x72, 0x6d, 0x48, 0x00, 0x52, 0x04, 0x66, 0x6f,
0x72, 0x6d, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x22, 0x44,
0x0a, 0x04, 0x46, 0x6f, 0x72, 0x6d, 0x12, 0x3c, 0x0a, 0x0d, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f,
0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x43, 0x6f, 0x6e,
0x66, 0x69, 0x67, 0x73, 0x42, 0x49, 0x5a, 0x47, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
0x6f, 0x6d, 0x2f, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2d, 0x72, 0x75, 0x6e, 0x2f, 0x68, 0x6f, 0x6c,
0x6f, 0x73, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x68,
0x6f, 0x6c, 0x6f, 0x73, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x76, 0x31,
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x34, 0x0a,
0x04, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x68, 0x6f,
0x6c, 0x6f, 0x73, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
0x68, 0x61, 0x31, 0x2e, 0x46, 0x6f, 0x72, 0x6d, 0x48, 0x00, 0x52, 0x04, 0x66, 0x6f, 0x72, 0x6d,
0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x42, 0x49, 0x5a, 0x47,
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x6f, 0x6c, 0x6f, 0x73,
0x2d, 0x72, 0x75, 0x6e, 0x2f, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2f, 0x70, 0x6c, 0x61,
0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x70,
0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -409,27 +354,26 @@ func file_holos_platform_v1alpha1_platform_proto_rawDescGZIP() []byte {
return file_holos_platform_v1alpha1_platform_proto_rawDescData
}
var file_holos_platform_v1alpha1_platform_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_holos_platform_v1alpha1_platform_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_holos_platform_v1alpha1_platform_proto_goTypes = []interface{}{
(*Platform)(nil), // 0: holos.platform.v1alpha1.Platform
(*Owner)(nil), // 1: holos.platform.v1alpha1.Owner
(*Spec)(nil), // 2: holos.platform.v1alpha1.Spec
(*Form)(nil), // 3: holos.platform.v1alpha1.Form
(*v1alpha1.Detail)(nil), // 4: holos.object.v1alpha1.Detail
(*structpb.Struct)(nil), // 5: google.protobuf.Struct
(*v1alpha1.Detail)(nil), // 3: holos.object.v1alpha1.Detail
(*structpb.Struct)(nil), // 4: google.protobuf.Struct
(*v1alpha1.Form)(nil), // 5: holos.object.v1alpha1.Form
}
var file_holos_platform_v1alpha1_platform_proto_depIdxs = []int32{
1, // 0: holos.platform.v1alpha1.Platform.owner:type_name -> holos.platform.v1alpha1.Owner
2, // 1: holos.platform.v1alpha1.Platform.spec:type_name -> holos.platform.v1alpha1.Spec
4, // 2: holos.platform.v1alpha1.Platform.detail:type_name -> holos.object.v1alpha1.Detail
5, // 3: holos.platform.v1alpha1.Spec.model:type_name -> google.protobuf.Struct
3, // 4: holos.platform.v1alpha1.Spec.form:type_name -> holos.platform.v1alpha1.Form
5, // 5: holos.platform.v1alpha1.Form.field_configs:type_name -> google.protobuf.Struct
6, // [6:6] is the sub-list for method output_type
6, // [6:6] is the sub-list for method input_type
6, // [6:6] is the sub-list for extension type_name
6, // [6:6] is the sub-list for extension extendee
0, // [0:6] is the sub-list for field type_name
3, // 2: holos.platform.v1alpha1.Platform.detail:type_name -> holos.object.v1alpha1.Detail
4, // 3: holos.platform.v1alpha1.Spec.model:type_name -> google.protobuf.Struct
5, // 4: holos.platform.v1alpha1.Spec.form:type_name -> holos.object.v1alpha1.Form
5, // [5:5] is the sub-list for method output_type
5, // [5:5] is the sub-list for method input_type
5, // [5:5] is the sub-list for extension type_name
5, // [5:5] is the sub-list for extension extendee
0, // [0:5] is the sub-list for field type_name
}
func init() { file_holos_platform_v1alpha1_platform_proto_init() }
@@ -474,18 +418,6 @@ func file_holos_platform_v1alpha1_platform_proto_init() {
return nil
}
}
file_holos_platform_v1alpha1_platform_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Form); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
file_holos_platform_v1alpha1_platform_proto_msgTypes[0].OneofWrappers = []interface{}{}
file_holos_platform_v1alpha1_platform_proto_msgTypes[1].OneofWrappers = []interface{}{
@@ -498,7 +430,7 @@ func file_holos_platform_v1alpha1_platform_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_holos_platform_v1alpha1_platform_proto_rawDesc,
NumEnums: 0,
NumMessages: 4,
NumMessages: 3,
NumExtensions: 0,
NumServices: 0,
},

View File

@@ -8,6 +8,7 @@ package platform
import (
_ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate"
v1alpha1 "github.com/holos-run/holos/service/gen/holos/object/v1alpha1"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb"
@@ -444,7 +445,7 @@ type UpdatePlatformOperation struct {
// Replace the form model.
Model *structpb.Struct `protobuf:"bytes,4,opt,name=model,proto3,oneof" json:"model,omitempty"`
// Replace the form.
Form *Form `protobuf:"bytes,5,opt,name=form,proto3,oneof" json:"form,omitempty"`
Form *v1alpha1.Form `protobuf:"bytes,5,opt,name=form,proto3,oneof" json:"form,omitempty"`
}
func (x *UpdatePlatformOperation) Reset() {
@@ -507,7 +508,7 @@ func (x *UpdatePlatformOperation) GetModel() *structpb.Struct {
return nil
}
func (x *UpdatePlatformOperation) GetForm() *Form {
func (x *UpdatePlatformOperation) GetForm() *v1alpha1.Form {
if x != nil {
return x.Form
}
@@ -527,156 +528,158 @@ var file_holos_platform_v1alpha1_platform_service_proto_rawDesc = []byte{
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61,
0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x26, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2f, 0x70, 0x6c,
0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f,
0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x56,
0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3d, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66,
0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x68, 0x6f, 0x6c, 0x6f,
0x73, 0x2e, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
0x68, 0x61, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c,
0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x22, 0x57, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x3d, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x21, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x70, 0x6c, 0x61, 0x74, 0x66,
0x6f, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x6c, 0x61,
0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x22,
0x7a, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x0b, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72,
0x6d, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72,
0x03, 0xb0, 0x01, 0x01, 0x52, 0x0a, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x49, 0x64,
0x12, 0x39, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b,
0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x54, 0x0a, 0x13, 0x47,
0x65, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x12, 0x3d, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x70, 0x6c, 0x61,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x22, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2f, 0x6f, 0x62,
0x6a, 0x65, 0x63, 0x74, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x6f, 0x62,
0x6a, 0x65, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x26, 0x68, 0x6f, 0x6c, 0x6f,
0x73, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70,
0x68, 0x61, 0x31, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x22, 0x56, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61, 0x74,
0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3d, 0x0a, 0x08, 0x70,
0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e,
0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x76,
0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d,
0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x22, 0x57, 0x0a, 0x16, 0x43, 0x72,
0x65, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x70,
0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66,
0x6f, 0x72, 0x6d, 0x22, 0x7a, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f,
0x72, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x0b, 0x70, 0x6c, 0x61,
0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08,
0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x0a, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f,
0x72, 0x6d, 0x49, 0x64, 0x12, 0x39, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61,
0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64,
0x4d, 0x61, 0x73, 0x6b, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x22,
0x54, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f,
0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73,
0x2e, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
0x61, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61,
0x74, 0x66, 0x6f, 0x72, 0x6d, 0x22, 0xb3, 0x01, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x48, 0x0a, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x30, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d,
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x52, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x40, 0x0a, 0x0b, 0x75, 0x70, 0x64,
0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x48, 0x00, 0x52, 0x0a, 0x75, 0x70,
0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f,
0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x22, 0x57, 0x0a, 0x16, 0x55,
0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72,
0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e,
0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
0x31, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74,
0x66, 0x6f, 0x72, 0x6d, 0x22, 0x72, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6c, 0x61, 0x74,
0x66, 0x6f, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x06,
0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48,
0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x12, 0x39, 0x0a,
0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x09, 0x66,
0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x58, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74,
0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x3f, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x18, 0x01,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x70, 0x6c, 0x61,
0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50,
0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72,
0x6d, 0x22, 0xb3, 0x01, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61, 0x74,
0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x48, 0x0a, 0x06, 0x75,
0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x6f,
0x6c, 0x6f, 0x73, 0x2e, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x61,
0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61, 0x74,
0x66, 0x6f, 0x72, 0x6d, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x75,
0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x40, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f,
0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65,
0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x48, 0x00, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65,
0x4d, 0x61, 0x73, 0x6b, 0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x75, 0x70, 0x64, 0x61,
0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x22, 0x57, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74,
0x65, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x3d, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x70, 0x6c, 0x61, 0x74,
0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x6c,
0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d,
0x22, 0x72, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d,
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f,
0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0,
0x01, 0x01, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x12, 0x39, 0x0a, 0x0a, 0x66, 0x69, 0x65,
0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64,
0x4d, 0x61, 0x73, 0x6b, 0x22, 0x58, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6c, 0x61, 0x74,
0x66, 0x6f, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a,
0x09, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x21, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72,
0x6d, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66,
0x6f, 0x72, 0x6d, 0x52, 0x09, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x22, 0x95,
0x07, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72,
0x6d, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x0b, 0x70, 0x6c,
0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42,
0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x0a, 0x70, 0x6c, 0x61, 0x74, 0x66,
0x6f, 0x72, 0x6d, 0x49, 0x64, 0x12, 0xfe, 0x02, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x42, 0xe4, 0x02, 0xba, 0x48, 0xe0, 0x02, 0xba, 0x01, 0x4a, 0x0a, 0x14,
0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x6e, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x68, 0x79,
0x70, 0x68, 0x65, 0x6e, 0x12, 0x1b, 0x43, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, 0x61,
0x72, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e,
0x2e, 0x1a, 0x15, 0x21, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x57,
0x69, 0x74, 0x68, 0x28, 0x27, 0x2d, 0x27, 0x29, 0xba, 0x01, 0x44, 0x0a, 0x12, 0x6e, 0x61, 0x6d,
0x65, 0x2e, 0x6e, 0x6f, 0x5f, 0x65, 0x6e, 0x64, 0x5f, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x12,
0x19, 0x43, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68,
0x20, 0x61, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x2e, 0x1a, 0x13, 0x21, 0x74, 0x68, 0x69,
0x73, 0x2e, 0x65, 0x6e, 0x64, 0x73, 0x57, 0x69, 0x74, 0x68, 0x28, 0x27, 0x2d, 0x27, 0x29, 0xba,
0x01, 0x58, 0x0a, 0x1b, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x6e, 0x6f, 0x5f, 0x63, 0x6f, 0x6e, 0x73,
0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x12,
0x23, 0x43, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20,
0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, 0x20, 0x68, 0x79, 0x70, 0x68,
0x65, 0x6e, 0x73, 0x2e, 0x1a, 0x14, 0x21, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
0x61, 0x69, 0x6e, 0x73, 0x28, 0x27, 0x2d, 0x2d, 0x27, 0x29, 0xba, 0x01, 0x68, 0x0a, 0x0c, 0x6e,
0x61, 0x6d, 0x65, 0x2e, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x12, 0x37, 0x41, 0x6c, 0x6c,
0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x74,
0x20, 0x62, 0x65, 0x20, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x61, 0x20, 0x68, 0x79, 0x70,
0x68, 0x65, 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65,
0x72, 0x69, 0x63, 0x2e, 0x1a, 0x1f, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68,
0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x41, 0x2d, 0x5a, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x2d,
0x5d, 0x2b, 0x24, 0x27, 0x29, 0x72, 0x04, 0x10, 0x01, 0x18, 0x27, 0x48, 0x00, 0x52, 0x04, 0x6e,
0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0xb4, 0x02, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c,
0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8b, 0x02,
0xba, 0x48, 0x87, 0x02, 0xba, 0x01, 0x50, 0x0a, 0x1b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79,
0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x6e, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x73,
0x70, 0x61, 0x63, 0x65, 0x12, 0x1a, 0x43, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, 0x61,
0x72, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e,
0x1a, 0x15, 0x21, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x57, 0x69,
0x74, 0x68, 0x28, 0x27, 0x20, 0x27, 0x29, 0xba, 0x01, 0x4a, 0x0a, 0x19, 0x64, 0x69, 0x73, 0x70,
0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x6e, 0x6f, 0x5f, 0x65, 0x6e, 0x64, 0x5f,
0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x18, 0x43, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x65, 0x6e,
0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x1a,
0x13, 0x21, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, 0x6e, 0x64, 0x73, 0x57, 0x69, 0x74, 0x68, 0x28,
0x27, 0x20, 0x27, 0x29, 0xba, 0x01, 0x5e, 0x0a, 0x22, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79,
0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x6e, 0x6f, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75,
0x74, 0x69, 0x76, 0x65, 0x5f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x22, 0x43, 0x61, 0x6e,
0x6e, 0x6f, 0x74, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x73,
0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x1a,
0x14, 0x21, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x28,
0x27, 0x20, 0x20, 0x27, 0x29, 0x72, 0x04, 0x10, 0x01, 0x18, 0x64, 0x48, 0x01, 0x52, 0x0b, 0x64,
0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x32, 0x0a,
0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53,
0x74, 0x72, 0x75, 0x63, 0x74, 0x48, 0x02, 0x52, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x88, 0x01,
0x01, 0x12, 0x36, 0x0a, 0x04, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x1d, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d,
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x46, 0x6f, 0x72, 0x6d, 0x48, 0x03,
0x52, 0x04, 0x66, 0x6f, 0x72, 0x6d, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61,
0x6d, 0x65, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e,
0x61, 0x6d, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x42, 0x07, 0x0a,
0x05, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x32, 0xd9, 0x03, 0x0a, 0x0f, 0x50, 0x6c, 0x61, 0x74, 0x66,
0x6f, 0x72, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x73, 0x0a, 0x0e, 0x43, 0x72,
0x65, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x2e, 0x2e, 0x68,
0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x76, 0x31,
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61,
0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x68,
0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x76, 0x31,
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61,
0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
0x6a, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x2b,
0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x09, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72,
0x6d, 0x73, 0x22, 0x93, 0x07, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61,
0x74, 0x66, 0x6f, 0x72, 0x6d, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29,
0x0a, 0x0b, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x0a, 0x70,
0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x49, 0x64, 0x12, 0xfe, 0x02, 0x0a, 0x04, 0x6e, 0x61,
0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0xe4, 0x02, 0xba, 0x48, 0xe0, 0x02, 0xba,
0x01, 0x4a, 0x0a, 0x14, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x6e, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72,
0x74, 0x5f, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x12, 0x1b, 0x43, 0x61, 0x6e, 0x6e, 0x6f, 0x74,
0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, 0x68, 0x79,
0x70, 0x68, 0x65, 0x6e, 0x2e, 0x1a, 0x15, 0x21, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x74, 0x61,
0x72, 0x74, 0x73, 0x57, 0x69, 0x74, 0x68, 0x28, 0x27, 0x2d, 0x27, 0x29, 0xba, 0x01, 0x44, 0x0a,
0x12, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x6e, 0x6f, 0x5f, 0x65, 0x6e, 0x64, 0x5f, 0x68, 0x79, 0x70,
0x68, 0x65, 0x6e, 0x12, 0x19, 0x43, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x65, 0x6e, 0x64, 0x20,
0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x2e, 0x1a, 0x13,
0x21, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, 0x6e, 0x64, 0x73, 0x57, 0x69, 0x74, 0x68, 0x28, 0x27,
0x2d, 0x27, 0x29, 0xba, 0x01, 0x58, 0x0a, 0x1b, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x6e, 0x6f, 0x5f,
0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x68, 0x79, 0x70, 0x68,
0x65, 0x6e, 0x73, 0x12, 0x23, 0x43, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x69, 0x6e, 0x63, 0x6c,
0x75, 0x64, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, 0x20,
0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x2e, 0x1a, 0x14, 0x21, 0x74, 0x68, 0x69, 0x73, 0x2e,
0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x28, 0x27, 0x2d, 0x2d, 0x27, 0x29, 0xba, 0x01,
0x68, 0x0a, 0x0c, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x12,
0x37, 0x41, 0x6c, 0x6c, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x20,
0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x61,
0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61,
0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x2e, 0x1a, 0x1f, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d,
0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x41, 0x2d, 0x5a, 0x61, 0x2d, 0x7a,
0x30, 0x2d, 0x39, 0x2d, 0x5d, 0x2b, 0x24, 0x27, 0x29, 0x72, 0x04, 0x10, 0x01, 0x18, 0x27, 0x48,
0x00, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0xb4, 0x02, 0x0a, 0x0c, 0x64,
0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
0x09, 0x42, 0x8b, 0x02, 0xba, 0x48, 0x87, 0x02, 0xba, 0x01, 0x50, 0x0a, 0x1b, 0x64, 0x69, 0x73,
0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x6e, 0x6f, 0x5f, 0x73, 0x74, 0x61,
0x72, 0x74, 0x5f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1a, 0x43, 0x61, 0x6e, 0x6e, 0x6f, 0x74,
0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, 0x73, 0x70,
0x61, 0x63, 0x65, 0x2e, 0x1a, 0x15, 0x21, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x72,
0x74, 0x73, 0x57, 0x69, 0x74, 0x68, 0x28, 0x27, 0x20, 0x27, 0x29, 0xba, 0x01, 0x4a, 0x0a, 0x19,
0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x6e, 0x6f, 0x5f,
0x65, 0x6e, 0x64, 0x5f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x18, 0x43, 0x61, 0x6e, 0x6e, 0x6f,
0x74, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, 0x73, 0x70, 0x61,
0x63, 0x65, 0x2e, 0x1a, 0x13, 0x21, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, 0x6e, 0x64, 0x73, 0x57,
0x69, 0x74, 0x68, 0x28, 0x27, 0x20, 0x27, 0x29, 0xba, 0x01, 0x5e, 0x0a, 0x22, 0x64, 0x69, 0x73,
0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x6e, 0x6f, 0x5f, 0x63, 0x6f, 0x6e,
0x73, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12,
0x22, 0x43, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20,
0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, 0x20, 0x73, 0x70, 0x61, 0x63,
0x65, 0x73, 0x2e, 0x1a, 0x14, 0x21, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61,
0x69, 0x6e, 0x73, 0x28, 0x27, 0x20, 0x20, 0x27, 0x29, 0x72, 0x04, 0x10, 0x01, 0x18, 0x64, 0x48,
0x01, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01,
0x01, 0x12, 0x32, 0x0a, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x48, 0x02, 0x52, 0x05, 0x6d, 0x6f, 0x64,
0x65, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x34, 0x0a, 0x04, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x05, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x6f, 0x62, 0x6a, 0x65,
0x63, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x46, 0x6f, 0x72, 0x6d,
0x48, 0x03, 0x52, 0x04, 0x66, 0x6f, 0x72, 0x6d, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f,
0x6e, 0x61, 0x6d, 0x65, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79,
0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x42,
0x07, 0x0a, 0x05, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x32, 0xd9, 0x03, 0x0a, 0x0f, 0x50, 0x6c, 0x61,
0x74, 0x66, 0x6f, 0x72, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x73, 0x0a, 0x0e,
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x2e,
0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e,
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x74,
0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x68, 0x6f,
0x6c, 0x6f, 0x73, 0x2e, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x61,
0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72,
0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x73, 0x0a, 0x0e, 0x55,
0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x2e, 0x2e,
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50,
0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f,
0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e,
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50,
0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x00, 0x12, 0x6a, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d,
0x12, 0x2b, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72,
0x6d, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6c,
0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e,
0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x76,
0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6c,
0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e,
0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x76,
0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6c,
0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
0x12, 0x70, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d,
0x73, 0x12, 0x2d, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f,
0x72, 0x6d, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74,
0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x2e, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72,
0x6d, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50,
0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x42, 0x49, 0x5a, 0x47, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
0x2f, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2d, 0x72, 0x75, 0x6e, 0x2f, 0x68, 0x6f, 0x6c, 0x6f, 0x73,
0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x68, 0x6f, 0x6c,
0x6f, 0x73, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c,
0x70, 0x68, 0x61, 0x31, 0x3b, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66,
0x6f, 0x72, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x73, 0x0a,
0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12,
0x2e, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d,
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x2f, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d,
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x12, 0x70, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f,
0x72, 0x6d, 0x73, 0x12, 0x2d, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x70, 0x6c, 0x61, 0x74,
0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69,
0x73, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2e, 0x70, 0x6c, 0x61, 0x74, 0x66,
0x6f, 0x72, 0x6d, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73,
0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x00, 0x42, 0x49, 0x5a, 0x47, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
0x6f, 0x6d, 0x2f, 0x68, 0x6f, 0x6c, 0x6f, 0x73, 0x2d, 0x72, 0x75, 0x6e, 0x2f, 0x68, 0x6f, 0x6c,
0x6f, 0x73, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x68,
0x6f, 0x6c, 0x6f, 0x73, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x76, 0x31,
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -705,7 +708,7 @@ var file_holos_platform_v1alpha1_platform_service_proto_goTypes = []interface{}{
(*Platform)(nil), // 9: holos.platform.v1alpha1.Platform
(*fieldmaskpb.FieldMask)(nil), // 10: google.protobuf.FieldMask
(*structpb.Struct)(nil), // 11: google.protobuf.Struct
(*Form)(nil), // 12: holos.platform.v1alpha1.Form
(*v1alpha1.Form)(nil), // 12: holos.object.v1alpha1.Form
}
var file_holos_platform_v1alpha1_platform_service_proto_depIdxs = []int32{
9, // 0: holos.platform.v1alpha1.CreatePlatformRequest.platform:type_name -> holos.platform.v1alpha1.Platform
@@ -718,7 +721,7 @@ var file_holos_platform_v1alpha1_platform_service_proto_depIdxs = []int32{
10, // 7: holos.platform.v1alpha1.ListPlatformsRequest.field_mask:type_name -> google.protobuf.FieldMask
9, // 8: holos.platform.v1alpha1.ListPlatformsResponse.platforms:type_name -> holos.platform.v1alpha1.Platform
11, // 9: holos.platform.v1alpha1.UpdatePlatformOperation.model:type_name -> google.protobuf.Struct
12, // 10: holos.platform.v1alpha1.UpdatePlatformOperation.form:type_name -> holos.platform.v1alpha1.Form
12, // 10: holos.platform.v1alpha1.UpdatePlatformOperation.form:type_name -> holos.object.v1alpha1.Form
0, // 11: holos.platform.v1alpha1.PlatformService.CreatePlatform:input_type -> holos.platform.v1alpha1.CreatePlatformRequest
2, // 12: holos.platform.v1alpha1.PlatformService.GetPlatform:input_type -> holos.platform.v1alpha1.GetPlatformRequest
4, // 13: holos.platform.v1alpha1.PlatformService.UpdatePlatform:input_type -> holos.platform.v1alpha1.UpdatePlatformRequest

View File

@@ -5,7 +5,7 @@ package holos.object.v1alpha1;
option go_package = "github.com/holos-run/holos/service/gen/holos/object/v1alpha1;object";
import "google/protobuf/timestamp.proto";
// git clone https://github.com/bufbuild/protovalidate then add <parent>/protovalidate/proto/protovalidate to your editor proto search path
import "google/protobuf/struct.proto";
import "buf/validate/validate.proto";
// For validation, see the [Standard constraints](https://github.com/bufbuild/protovalidate/blob/main/docs/standard-constraints.md)
@@ -80,3 +80,10 @@ message ResourceOwner {
string user_id = 2 [(buf.validate.field).string.uuid = true];
}
}
// Form represents a Formly json powered form.
message Form {
// fields represents FormlyFieldConfig[] encoded as an array of JSON objects
// organized by section.
repeated google.protobuf.Struct field_configs = 1;
}

View File

@@ -82,12 +82,5 @@ message Spec {
// The model is a Struct to ensure any valid JSON object defined by the user
// via the form can be represented and stored.
google.protobuf.Struct model = 1;
optional Form form = 2;
}
// Form represents the Formly input form.
message Form {
// fields represents FormlyFieldConfig[] encoded as an array of JSON objects
// organized by section.
repeated google.protobuf.Struct field_configs = 1;
optional holos.object.v1alpha1.Form form = 2;
}

View File

@@ -6,6 +6,7 @@ option go_package = "github.com/holos-run/holos/service/gen/holos/platform/v1alp
import "buf/validate/validate.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/struct.proto";
import "holos/object/v1alpha1/object.proto";
import "holos/platform/v1alpha1/platform.proto";
message CreatePlatformRequest {
@@ -104,7 +105,7 @@ message UpdatePlatformOperation {
// Replace the form model.
optional google.protobuf.Struct model = 4;
// Replace the form.
optional Form form = 5;
optional holos.object.v1alpha1.Form form = 5;
}
service PlatformService {

View File

@@ -1 +1 @@
78
79

View File

@@ -16,7 +16,7 @@ var Minor string
//go:embed embedded/patch
var Patch string
// Version of this module
// Version of this module for example "0.70.0"
var Version = strings.ReplaceAll(Major+"."+Minor+"."+Patch, "\n", "")
// GitCommit defined dynamically by the Makefile