mirror of
https://github.com/holos-run/holos.git
synced 2026-03-19 16:54:58 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d3888a884f | ||
|
|
3845871368 | ||
|
|
a3b2d19adb | ||
|
|
e4e7cd8c47 | ||
|
|
fb22e5521b | ||
|
|
d2ae766ae3 | ||
|
|
c0db949729 | ||
|
|
d2d4337ffd | ||
|
|
b0ca04635e | ||
|
|
198c66e6cd | ||
|
|
24346b9a38 |
@@ -9,9 +9,8 @@ import (
|
||||
type BuildPlan struct {
|
||||
TypeMeta `json:",inline" yaml:",inline"`
|
||||
// Metadata represents the holos component name
|
||||
Metadata ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
|
||||
Spec BuildPlanSpec `json:"spec,omitempty" yaml:"spec,omitempty"`
|
||||
Platform map[string]any `json:"platform,omitempty" yaml:"platform,omitempty"`
|
||||
Metadata ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
|
||||
Spec BuildPlanSpec `json:"spec,omitempty" yaml:"spec,omitempty"`
|
||||
}
|
||||
|
||||
type BuildPlanSpec struct {
|
||||
|
||||
@@ -1,9 +1,22 @@
|
||||
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.
|
||||
import "google.golang.org/protobuf/types/known/structpb"
|
||||
|
||||
// Platform represents a platform to manage. A Platform resource informs holos
|
||||
// which components to build. The platform resource also acts as a container
|
||||
// for the platform model form values provided by the PlatformService. The
|
||||
// primary use case is to collect the cluster names, cluster types, platform
|
||||
// model, and holos components to build into one resource.
|
||||
type Platform struct {
|
||||
TypeMeta `json:",inline" yaml:",inline"`
|
||||
Metadata ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
|
||||
Metadata ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
|
||||
Spec PlatformSpec `json:"spec,omitempty" yaml:"spec,omitempty"`
|
||||
}
|
||||
|
||||
// PlatformSpec represents the platform build plan specification.
|
||||
type PlatformSpec struct {
|
||||
// Model represents the platform model holos gets from from the
|
||||
// holos.platform.v1alpha1.PlatformService.GetPlatform method and provides to
|
||||
// CUE using a tag.
|
||||
Model structpb.Struct `json:"model,omitempty" yaml:"model,omitempty"`
|
||||
}
|
||||
|
||||
2
cmd/holos/testdata/version.txt
vendored
2
cmd/holos/testdata/version.txt
vendored
@@ -1,5 +1,3 @@
|
||||
exec holos --version
|
||||
# want version with no v on stdout
|
||||
stdout -count=1 '^\d+\.\d+\.\d+$'
|
||||
# want nothing on stderr
|
||||
! stderr .
|
||||
|
||||
@@ -34,7 +34,7 @@ let OBJECTS = #APIObjects & {
|
||||
containers: [
|
||||
{
|
||||
name: Holos
|
||||
image: "271053619184.dkr.ecr.us-east-2.amazonaws.com/holos-run/holos-server/holos:v0.76.0"
|
||||
image: "271053619184.dkr.ecr.us-east-2.amazonaws.com/holos-run/holos-server/holos:v0.79.0"
|
||||
imagePullPolicy: "Always"
|
||||
env: [
|
||||
{
|
||||
|
||||
4
go.mod
4
go.mod
@@ -16,7 +16,6 @@ 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
|
||||
@@ -87,7 +86,7 @@ require (
|
||||
github.com/distribution/reference v0.6.0 // indirect
|
||||
github.com/docker/cli v26.0.0+incompatible // indirect
|
||||
github.com/docker/distribution v2.8.3+incompatible // indirect
|
||||
github.com/docker/docker v26.0.0+incompatible // indirect
|
||||
github.com/docker/docker v26.0.2+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.8.1 // indirect
|
||||
github.com/docker/go-connections v0.5.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
@@ -115,6 +114,7 @@ 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
|
||||
|
||||
4
go.sum
4
go.sum
@@ -187,8 +187,8 @@ github.com/docker/cli v26.0.0+incompatible h1:90BKrx1a1HKYpSnnBFR6AgDq/FqkHxwlUy
|
||||
github.com/docker/cli v26.0.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
||||
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v26.0.0+incompatible h1:Ng2qi+gdKADUa/VM+6b6YaY2nlZhk/lVJiKR/2bMudU=
|
||||
github.com/docker/docker v26.0.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v26.0.2+incompatible h1:yGVmKUFGgcxA6PXWAokO0sQL22BrQ67cgVjko8tGdXE=
|
||||
github.com/docker/docker v26.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.8.1 h1:j/eKUktUltBtMzKqmfLB0PAgqYyMHOp5vfsD1807oKo=
|
||||
github.com/docker/docker-credential-helpers v0.8.1/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
|
||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
"github.com/holos-run/holos/api/v1alpha1"
|
||||
|
||||
"github.com/holos-run/holos"
|
||||
"github.com/holos-run/holos/internal/client"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/logger"
|
||||
)
|
||||
@@ -70,7 +71,7 @@ func (b *Builder) Cluster() string {
|
||||
}
|
||||
|
||||
// Instances returns the cue build instances being built.
|
||||
func (b *Builder) Instances(ctx context.Context) ([]*build.Instance, error) {
|
||||
func (b *Builder) Instances(ctx context.Context, cfg *client.Config) ([]*build.Instance, error) {
|
||||
log := logger.FromContext(ctx)
|
||||
|
||||
mod, err := b.findCueMod()
|
||||
@@ -79,7 +80,18 @@ func (b *Builder) Instances(ctx context.Context) ([]*build.Instance, error) {
|
||||
}
|
||||
dir := string(mod)
|
||||
|
||||
cfg := load.Config{Dir: dir}
|
||||
cueConfig := load.Config{Dir: dir}
|
||||
|
||||
// Get the platform model from the PlatformConfig
|
||||
pc, err := client.LoadPlatformConfig(ctx, dir)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
data, err := json.Marshal(pc)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
cueConfig.Tags = append(cueConfig.Tags, "platform_config="+string(data))
|
||||
|
||||
// Make args relative to the module directory
|
||||
args := make([]string, len(b.cfg.args))
|
||||
@@ -99,16 +111,18 @@ func (b *Builder) Instances(ctx context.Context) ([]*build.Instance, error) {
|
||||
}
|
||||
|
||||
// Refer to https://github.com/cue-lang/cue/blob/v0.7.0/cmd/cue/cmd/common.go#L429
|
||||
cfg.Tags = append(cfg.Tags, "cluster="+b.Cluster())
|
||||
log.DebugContext(ctx, fmt.Sprintf("cue: tags %v", cfg.Tags))
|
||||
if b.Cluster() != "" {
|
||||
cueConfig.Tags = append(cueConfig.Tags, "cluster="+b.Cluster())
|
||||
}
|
||||
log.DebugContext(ctx, fmt.Sprintf("cue: tags %v", cueConfig.Tags))
|
||||
|
||||
return load.Instances(args, &cfg), nil
|
||||
return load.Instances(args, &cueConfig), nil
|
||||
}
|
||||
|
||||
func (b *Builder) Run(ctx context.Context) (results []*v1alpha1.Result, err error) {
|
||||
func (b *Builder) Run(ctx context.Context, cfg *client.Config) (results []*v1alpha1.Result, err error) {
|
||||
log := logger.FromContext(ctx)
|
||||
log.DebugContext(ctx, "cue: building instances")
|
||||
instances, err := b.Instances(ctx)
|
||||
instances, err := b.Instances(ctx, cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -164,6 +178,7 @@ func (b Builder) runInstance(ctx context.Context, instance *build.Instance) (res
|
||||
decoder.DisallowUnknownFields()
|
||||
|
||||
switch tm.Kind {
|
||||
// TODO(jeff) Process a v1alpha1.Result here, the result is tightly coupled to a BuildPlan.
|
||||
case "BuildPlan":
|
||||
var bp v1alpha1.BuildPlan
|
||||
if err = decoder.Decode(&bp); err != nil {
|
||||
@@ -171,6 +186,7 @@ func (b Builder) runInstance(ctx context.Context, instance *build.Instance) (res
|
||||
return
|
||||
}
|
||||
results, err = b.buildPlan(ctx, &bp, path)
|
||||
// TODO(jeff) Platform should not return a Result like an individual holos component does.
|
||||
case "Platform":
|
||||
var pf v1alpha1.Platform
|
||||
if err = decoder.Decode(&pf); err != nil {
|
||||
@@ -185,9 +201,30 @@ func (b Builder) runInstance(ctx context.Context, instance *build.Instance) (res
|
||||
return
|
||||
}
|
||||
|
||||
// buildPlatform builds all of the holos components specified in a Platform resource returned from CUE.
|
||||
//
|
||||
// TODO(jeff): There is technical debt here in the way results are handled.
|
||||
// Results were intended as a way to define how holos should build various kinds
|
||||
// of individual components, not a whole platform though. After launch,
|
||||
// refactor the platform building to return something else. The result itself
|
||||
// also needs to be refactored to an interface instead of a struct. Each kind
|
||||
// of component should implement the interface.
|
||||
func (b *Builder) buildPlatform(ctx context.Context, pf *v1alpha1.Platform) (results []*v1alpha1.Result, err error) {
|
||||
log := logger.FromContext(ctx)
|
||||
log.ErrorContext(ctx, "not implemented", "platform", pf)
|
||||
// TODO: Iterate over each platform component in Platform.spec.components.
|
||||
// each component should note the cluster name and path to the holos
|
||||
// component.
|
||||
data, err := pf.Spec.Model.MarshalJSON()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
if len(data) > 0 {
|
||||
data = append(data, '\n')
|
||||
}
|
||||
buf := bytes.NewBuffer(data)
|
||||
if _, err := buf.WriteTo(os.Stdout); err != nil {
|
||||
log.ErrorContext(ctx, "could not write", "err", err)
|
||||
}
|
||||
return nil, errors.Wrap(fmt.Errorf("not implemeneted"))
|
||||
}
|
||||
|
||||
|
||||
@@ -7,16 +7,18 @@ import (
|
||||
|
||||
"github.com/holos-run/holos/internal/builder"
|
||||
"github.com/holos-run/holos/internal/cli/command"
|
||||
"github.com/holos-run/holos/internal/client"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// makeBuildRunFunc returns the internal implementation of the build cli command
|
||||
func makeBuildRunFunc(cfg *holos.Config) command.RunFunc {
|
||||
func makeBuildRunFunc(cfg *client.Config) command.RunFunc {
|
||||
return func(cmd *cobra.Command, args []string) error {
|
||||
build := builder.New(builder.Entrypoints(args), builder.Cluster(cfg.ClusterName()))
|
||||
results, err := build.Run(cmd.Context())
|
||||
ctx := cmd.Root().Context()
|
||||
build := builder.New(builder.Entrypoints(args), builder.Cluster(cfg.Holos().ClusterName()))
|
||||
results, err := build.Run(ctx, cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -42,7 +44,12 @@ func New(cfg *holos.Config) *cobra.Command {
|
||||
cmd := command.New("build [directory...]")
|
||||
cmd.Args = cobra.MinimumNArgs(1)
|
||||
cmd.Short = "build kubernetes api objects from a directory"
|
||||
cmd.RunE = makeBuildRunFunc(cfg)
|
||||
|
||||
cmd.Flags().AddGoFlagSet(cfg.ClusterFlagSet())
|
||||
config := client.NewConfig(cfg)
|
||||
cmd.PersistentFlags().AddGoFlagSet(config.ClientFlagSet())
|
||||
cmd.PersistentFlags().AddGoFlagSet(config.TokenFlagSet())
|
||||
|
||||
cmd.RunE = makeBuildRunFunc(config)
|
||||
return cmd
|
||||
}
|
||||
|
||||
81
internal/cli/pull/pull.go
Normal file
81
internal/cli/pull/pull.go
Normal file
@@ -0,0 +1,81 @@
|
||||
// Package pull pulls resources from the PlatformService and caches them in the
|
||||
// local filesystem.
|
||||
package pull
|
||||
|
||||
import (
|
||||
"github.com/holos-run/holos/internal/cli/command"
|
||||
"github.com/holos-run/holos/internal/client"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"github.com/holos-run/holos/internal/server/middleware/logger"
|
||||
object "github.com/holos-run/holos/service/gen/holos/object/v1alpha1"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func New(cfg *holos.Config) *cobra.Command {
|
||||
cmd := command.New("pull")
|
||||
cmd.Short = "pull resources from holos server"
|
||||
cmd.Args = cobra.NoArgs
|
||||
|
||||
config := client.NewConfig(cfg)
|
||||
cmd.PersistentFlags().AddGoFlagSet(config.ClientFlagSet())
|
||||
cmd.PersistentFlags().AddGoFlagSet(config.TokenFlagSet())
|
||||
|
||||
cmd.AddCommand(NewPlatform(config))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewPlatform(cfg *client.Config) *cobra.Command {
|
||||
cmd := command.New("platform")
|
||||
|
||||
cmd.Short = "pull platform resources"
|
||||
cmd.Args = cobra.NoArgs
|
||||
|
||||
cmd.AddCommand(NewPlatformConfig(cfg))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewPlatformConfig(cfg *client.Config) *cobra.Command {
|
||||
cmd := command.New("config")
|
||||
cmd.Short = "pull platform config"
|
||||
cmd.Args = cobra.MinimumNArgs(1)
|
||||
|
||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Root().Context()
|
||||
if ctx == nil {
|
||||
return errors.Wrap(errors.New("cannot execute: no context"))
|
||||
}
|
||||
ctx = logger.NewContext(ctx, logger.FromContext(ctx).With("server", cfg.Client().Server()))
|
||||
rpc := client.New(cfg)
|
||||
for _, name := range args {
|
||||
// Get the platform metadata for the platform id.
|
||||
pmd, err := client.LoadPlatform(ctx, name)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
log := logger.FromContext(ctx).With("platform_id", pmd.GetId())
|
||||
// Get the platform model
|
||||
model, err := rpc.PlatformModel(ctx, pmd.GetId())
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
log.Info("pulled platform model")
|
||||
// Build the PlatformConfig
|
||||
pc := &object.PlatformConfig{
|
||||
PlatformId: pmd.GetId(),
|
||||
PlatformModel: model,
|
||||
}
|
||||
// Save the PlatformConfig
|
||||
path, err := client.SavePlatformConfig(ctx, name, pc)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
log.Info("saved platform config", "path", path)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
@@ -2,11 +2,15 @@
|
||||
package push
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/holos-run/holos/internal/cli/command"
|
||||
"github.com/holos-run/holos/internal/client"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"github.com/holos-run/holos/internal/push"
|
||||
"github.com/holos-run/holos/internal/server/middleware/logger"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -46,10 +50,11 @@ func NewPlatformForm(cfg *client.Config) *cobra.Command {
|
||||
if ctx == nil {
|
||||
return errors.Wrap(errors.New("cannot execute: no context"))
|
||||
}
|
||||
ctx = logger.NewContext(ctx, logger.FromContext(ctx).With("server", cfg.Client().Server()))
|
||||
rpc := client.New(cfg)
|
||||
for _, name := range args {
|
||||
// Get the platform metadata for the platform id.
|
||||
p, err := push.LoadPlatform(ctx, name)
|
||||
p, err := client.LoadPlatform(ctx, name)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
@@ -62,6 +67,7 @@ func NewPlatformForm(cfg *client.Config) *cobra.Command {
|
||||
if err := rpc.UpdateForm(ctx, p.GetId(), form); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
slog.Default().InfoContext(ctx, fmt.Sprintf("pushed: %s/ui/platform/%s", cfg.Client().Server(), p.GetId()))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/holos-run/holos/internal/builder"
|
||||
"github.com/holos-run/holos/internal/cli/command"
|
||||
"github.com/holos-run/holos/internal/client"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"github.com/holos-run/holos/internal/logger"
|
||||
@@ -22,22 +23,22 @@ func New(cfg *holos.Config) *cobra.Command {
|
||||
cmd.Flags().AddGoFlagSet(cfg.WriteFlagSet())
|
||||
cmd.Flags().AddGoFlagSet(cfg.ClusterFlagSet())
|
||||
|
||||
config := client.NewConfig(cfg)
|
||||
cmd.PersistentFlags().AddGoFlagSet(config.ClientFlagSet())
|
||||
cmd.PersistentFlags().AddGoFlagSet(config.TokenFlagSet())
|
||||
|
||||
var printInstances bool
|
||||
flagSet := flag.NewFlagSet("", flag.ContinueOnError)
|
||||
flagSet.BoolVar(&printInstances, "print-instances", false, "expand /... paths for xargs")
|
||||
cmd.Flags().AddGoFlagSet(flagSet)
|
||||
|
||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
if cfg.ClusterName() == "" {
|
||||
return errors.Wrap(fmt.Errorf("missing cluster name"))
|
||||
}
|
||||
|
||||
ctx := cmd.Context()
|
||||
ctx := cmd.Root().Context()
|
||||
log := logger.FromContext(ctx).With("cluster", cfg.ClusterName())
|
||||
build := builder.New(builder.Entrypoints(args), builder.Cluster(cfg.ClusterName()))
|
||||
|
||||
if printInstances {
|
||||
instances, err := build.Instances(ctx)
|
||||
instances, err := build.Instances(ctx, config)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
@@ -47,13 +48,14 @@ func New(cfg *holos.Config) *cobra.Command {
|
||||
return nil
|
||||
}
|
||||
|
||||
results, err := build.Run(cmd.Context())
|
||||
results, err := build.Run(ctx, config)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
// TODO: Avoid accidental over-writes if to holos component instances result in
|
||||
// the same file path. Write files into a blank temporary directory, error if a
|
||||
// file exists, then move the directory into place.
|
||||
// TODO: Avoid accidental over-writes if two or more holos component
|
||||
// instances result in the same file path. Write files into a blank
|
||||
// temporary directory, error if a file exists, then move the directory into
|
||||
// place.
|
||||
var result Result
|
||||
for _, result = range results {
|
||||
if result.Continue() {
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"github.com/holos-run/holos/internal/cli/login"
|
||||
"github.com/holos-run/holos/internal/cli/logout"
|
||||
"github.com/holos-run/holos/internal/cli/preflight"
|
||||
"github.com/holos-run/holos/internal/cli/pull"
|
||||
"github.com/holos-run/holos/internal/cli/push"
|
||||
"github.com/holos-run/holos/internal/cli/register"
|
||||
"github.com/holos-run/holos/internal/cli/render"
|
||||
@@ -73,6 +74,7 @@ func New(cfg *holos.Config) *cobra.Command {
|
||||
rootCmd.AddCommand(rpc.New(cfg))
|
||||
rootCmd.AddCommand(generate.New(cfg))
|
||||
rootCmd.AddCommand(register.New(cfg))
|
||||
rootCmd.AddCommand(pull.New(cfg))
|
||||
rootCmd.AddCommand(push.New(cfg))
|
||||
rootCmd.AddCommand(newOrgCmd())
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/holos-run/holos/service/gen/holos/platform/v1alpha1/platformconnect"
|
||||
"github.com/holos-run/holos/service/gen/holos/user/v1alpha1/userconnect"
|
||||
"google.golang.org/protobuf/types/known/fieldmaskpb"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
)
|
||||
|
||||
func New(cfg *Config) *Client {
|
||||
@@ -64,6 +65,22 @@ func (c *Client) UpdateForm(ctx context.Context, platformID string, form *object
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
log := logger.FromContext(ctx)
|
||||
log.InfoContext(ctx, "updated platform", "platform_id", platformID, "duration", time.Since(start))
|
||||
log.DebugContext(ctx, "updated platform", "platform_id", platformID, "duration", time.Since(start))
|
||||
return nil
|
||||
}
|
||||
|
||||
// PlatformModel gets the platform model from the PlatformService.
|
||||
func (c *Client) PlatformModel(ctx context.Context, platformID string) (*structpb.Struct, error) {
|
||||
start := time.Now()
|
||||
req := &platform.GetPlatformRequest{
|
||||
PlatformId: platformID,
|
||||
FieldMask: &fieldmaskpb.FieldMask{Paths: []string{"spec.model"}},
|
||||
}
|
||||
pf, err := c.pltSvc.GetPlatform(ctx, connect.NewRequest(req))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
log := logger.FromContext(ctx)
|
||||
log.DebugContext(ctx, "get platform", "platform_id", platformID, "duration", time.Since(start))
|
||||
return pf.Msg.GetPlatform().GetSpec().GetModel(), nil
|
||||
}
|
||||
|
||||
@@ -61,3 +61,11 @@ func (c *Config) Context() *holos.ClientContext {
|
||||
}
|
||||
return c.context
|
||||
}
|
||||
|
||||
// Holos returns the *holos.Config
|
||||
func (c *Config) Holos() *holos.Config {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.holos
|
||||
}
|
||||
|
||||
68
internal/client/platform.go
Normal file
68
internal/client/platform.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/holos-run/holos/internal/server/middleware/logger"
|
||||
object "github.com/holos-run/holos/service/gen/holos/object/v1alpha1"
|
||||
platform "github.com/holos-run/holos/service/gen/holos/platform/v1alpha1"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
)
|
||||
|
||||
// PlatformMetadataFile is the platform metadata json file name located in the root
|
||||
// of a platform directory.
|
||||
const PlatformMetadataFile = "platform.metadata.json"
|
||||
|
||||
// PlatformConfigFile is the marshaled json representation of the PlatformConfig
|
||||
// DTO used to cache the data holos passes from the PlatformService to CUE when
|
||||
// rendering platform components.
|
||||
const PlatformConfigFile = "platform.config.json"
|
||||
|
||||
// LoadPlatform loads the platform.metadata.json file from a named path. Useful
|
||||
// to obtain a platform id for PlatformService rpc methods.
|
||||
func LoadPlatform(ctx context.Context, name string) (*platform.Platform, error) {
|
||||
data, err := os.ReadFile(filepath.Join(name, PlatformMetadataFile))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not load platform metadata: %w", err)
|
||||
}
|
||||
p := &platform.Platform{}
|
||||
if err := protojson.Unmarshal(data, p); err != nil {
|
||||
return nil, fmt.Errorf("could not load platform metadata: %w", err)
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// LoadPlatformConfig loads the PlatformConfig DTO from the platform.config.json
|
||||
// file. Useful to provide all values necessary to render cue config without an
|
||||
// rpc to the HolosService.
|
||||
func LoadPlatformConfig(ctx context.Context, name string) (*object.PlatformConfig, error) {
|
||||
data, err := os.ReadFile(filepath.Join(name, PlatformConfigFile))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not load platform config: %w", err)
|
||||
}
|
||||
pc := &object.PlatformConfig{}
|
||||
if err := protojson.Unmarshal(data, pc); err != nil {
|
||||
return nil, fmt.Errorf("could not load platform config: %w", err)
|
||||
}
|
||||
return pc, nil
|
||||
}
|
||||
|
||||
// SavePlatformConfig writes pc to the platform root directory path identified by name.
|
||||
func SavePlatformConfig(ctx context.Context, name string, pc *object.PlatformConfig) (string, error) {
|
||||
data, err := protojson.Marshal(pc)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(data) > 0 {
|
||||
data = append(data, '\n')
|
||||
}
|
||||
path := filepath.Join(name, PlatformConfigFile)
|
||||
if err := os.WriteFile(path, data, 0644); err != nil {
|
||||
return "", fmt.Errorf("could not write platform config: %w", err)
|
||||
}
|
||||
logger.FromContext(ctx).DebugContext(ctx, "wrote", "path", path)
|
||||
return path, nil
|
||||
}
|
||||
@@ -367,3 +367,53 @@ export class Form extends Message<Form> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PlatformConfig represents the data passed from the holos cli to CUE when
|
||||
* rendering configuration.
|
||||
*
|
||||
* @generated from message holos.object.v1alpha1.PlatformConfig
|
||||
*/
|
||||
export class PlatformConfig extends Message<PlatformConfig> {
|
||||
/**
|
||||
* Platform UUID.
|
||||
*
|
||||
* @generated from field: string platform_id = 1;
|
||||
*/
|
||||
platformId = "";
|
||||
|
||||
/**
|
||||
* Platform Model.
|
||||
*
|
||||
* @generated from field: optional google.protobuf.Struct platform_model = 2;
|
||||
*/
|
||||
platformModel?: Struct;
|
||||
|
||||
constructor(data?: PartialMessage<PlatformConfig>) {
|
||||
super();
|
||||
proto3.util.initPartial(data, this);
|
||||
}
|
||||
|
||||
static readonly runtime: typeof proto3 = proto3;
|
||||
static readonly typeName = "holos.object.v1alpha1.PlatformConfig";
|
||||
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
||||
{ no: 1, name: "platform_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 2, name: "platform_model", kind: "message", T: Struct, opt: true },
|
||||
]);
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): PlatformConfig {
|
||||
return new PlatformConfig().fromBinary(bytes, options);
|
||||
}
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): PlatformConfig {
|
||||
return new PlatformConfig().fromJson(jsonValue, options);
|
||||
}
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): PlatformConfig {
|
||||
return new PlatformConfig().fromJsonString(jsonString, options);
|
||||
}
|
||||
|
||||
static equals(a: PlatformConfig | PlainMessage<PlatformConfig> | undefined, b: PlatformConfig | PlainMessage<PlatformConfig> | undefined): boolean {
|
||||
return proto3.util.equals(PlatformConfig, a, b);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,11 +72,10 @@ func GeneratePlatform(ctx context.Context, rpc *client.Client, orgID string, nam
|
||||
data = append(data, '\n')
|
||||
}
|
||||
log = log.With("platform_id", rpcPlatform.GetId())
|
||||
path := "platform.metadata.json"
|
||||
if err := os.WriteFile(path, data, 0644); err != nil {
|
||||
if err := os.WriteFile(client.PlatformMetadataFile, data, 0644); err != nil {
|
||||
return errors.Wrap(fmt.Errorf("could not write platform metadata: %w", err))
|
||||
}
|
||||
log.InfoContext(ctx, "wrote "+path, "path", filepath.Join(getCwd(ctx), path))
|
||||
log.InfoContext(ctx, "wrote "+client.PlatformMetadataFile, "path", filepath.Join(getCwd(ctx), client.PlatformMetadataFile))
|
||||
|
||||
// Copy the cue.mod directory
|
||||
if err := copyEmbedFS(ctx, platforms, filepath.Join(root, "cue.mod"), "cue.mod"); err != nil {
|
||||
|
||||
26
internal/generate/platforms/bare/platform.cue
Normal file
26
internal/generate/platforms/bare/platform.cue
Normal file
@@ -0,0 +1,26 @@
|
||||
package holos
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
import v1 "github.com/holos-run/holos/api/v1alpha1"
|
||||
import dto "github.com/holos-run/holos/service/gen/holos/object/v1alpha1:object"
|
||||
|
||||
// _PlatformConfig represents all of the data passed from holos to cue.
|
||||
// Intended to carry the platform model and project models.
|
||||
_PlatformConfig: dto.#PlatformConfig & json.Unmarshal(_PlatformConfigJSON)
|
||||
_PlatformConfigJSON: string | *"{}" @tag(platform_config, type=string)
|
||||
|
||||
// _Platform provides a platform resource to the holos cli for rendering. The
|
||||
// field is hidden because most components need to refer to platform data,
|
||||
// specifically the platform model and the project models. The platform
|
||||
// resource itself is output once when rendering the entire platform, see the
|
||||
// platform/ subdirectory.
|
||||
_Platform: v1.#Platform & {
|
||||
metadata: name: string | *"bare" @tag(platform_name, type=string)
|
||||
|
||||
// spec is the platform specification
|
||||
spec: {
|
||||
// model represents the web form values provided by the user.
|
||||
model: _PlatformConfig.platform_model
|
||||
}
|
||||
}
|
||||
4
internal/generate/platforms/bare/platform/platform.cue
Normal file
4
internal/generate/platforms/bare/platform/platform.cue
Normal file
@@ -0,0 +1,4 @@
|
||||
package holos
|
||||
|
||||
// Output the Platform resource for holos to render the entire platform.
|
||||
{} & _Platform
|
||||
@@ -11,7 +11,6 @@ package v1alpha1
|
||||
// Metadata represents the holos component name
|
||||
metadata?: #ObjectMeta @go(Metadata)
|
||||
spec?: #BuildPlanSpec @go(Spec)
|
||||
platform?: {...} @go(Platform,map[string]any)
|
||||
}
|
||||
|
||||
#BuildPlanSpec: {
|
||||
|
||||
@@ -4,10 +4,23 @@
|
||||
|
||||
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.
|
||||
import "google.golang.org/protobuf/types/known/structpb"
|
||||
|
||||
// Platform represents a platform to manage. A Platform resource informs holos
|
||||
// which components to build. The platform resource also acts as a container
|
||||
// for the platform model form values provided by the PlatformService. The
|
||||
// primary use case is to collect the cluster names, cluster types, platform
|
||||
// model, and holos components to build into one resource.
|
||||
#Platform: {
|
||||
#TypeMeta
|
||||
metadata?: #ObjectMeta @go(Metadata)
|
||||
metadata?: #ObjectMeta @go(Metadata)
|
||||
spec?: #PlatformSpec @go(Spec)
|
||||
}
|
||||
|
||||
// PlatformSpec represents the platform build plan specification.
|
||||
#PlatformSpec: {
|
||||
// Model represents the platform model holos gets from from the
|
||||
// holos.platform.v1alpha1.PlatformService.GetPlatform method and provides to
|
||||
// CUE using a tag.
|
||||
model?: structpb.#Struct @go(Model)
|
||||
}
|
||||
|
||||
@@ -114,3 +114,13 @@ _#isResourceOwner_ResourceOwner: _
|
||||
// organized by section.
|
||||
field_configs?: [...null | structpb.#Struct] @go(FieldConfigs,[]*structpb.Struct) @protobuf(1,bytes,rep,json=fieldConfigs,proto3)
|
||||
}
|
||||
|
||||
// PlatformConfig represents the data passed from the holos cli to CUE when
|
||||
// rendering configuration.
|
||||
#PlatformConfig: {
|
||||
// Platform UUID.
|
||||
platform_id?: string @go(PlatformId) @protobuf(1,bytes,opt,json=platformId,proto3)
|
||||
|
||||
// Platform Model.
|
||||
platform_model?: null | structpb.#Struct @go(PlatformModel,*structpb.Struct) @protobuf(2,bytes,opt,json=platformModel,proto3,oneof)
|
||||
}
|
||||
|
||||
@@ -12,9 +12,5 @@ package v1alpha1
|
||||
// model represents the user defined platform model, which is produced and
|
||||
// defined by the user supplied form.
|
||||
model: {...}
|
||||
|
||||
// components represents components to manage in the platform, organized by
|
||||
// the kind of cluster the rendered configuration applies to.
|
||||
components: {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,9 @@ func (cc *ClientContext) Save(ctx context.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(data) > 0 {
|
||||
data = append(data, '\n')
|
||||
}
|
||||
if err := os.WriteFile(config, data, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -170,15 +170,25 @@ func (c *Config) Finalize() error {
|
||||
|
||||
// Vet validates the config.
|
||||
func (c *Config) Vet() error {
|
||||
if c == nil || c.logConfig == nil {
|
||||
return fmt.Errorf("cannot vet: not configured")
|
||||
}
|
||||
return c.logConfig.Vet()
|
||||
}
|
||||
|
||||
// Logger returns a *slog.Logger configured by the user.
|
||||
// Logger returns a *slog.Logger configured by the user or the default logger if
|
||||
// no logger has been configured by the user.
|
||||
func (c *Config) Logger() *slog.Logger {
|
||||
if c == nil {
|
||||
return slog.Default()
|
||||
}
|
||||
if c.logger != nil {
|
||||
return c.logger
|
||||
}
|
||||
return c.logConfig.NewLogger(c.options.stderr)
|
||||
if c.logConfig == nil {
|
||||
return slog.Default()
|
||||
}
|
||||
return c.logConfig.NewLogger(c.Stderr())
|
||||
}
|
||||
|
||||
// NewTopLevelLogger returns a *slog.Logger with a handler that filters source
|
||||
@@ -189,21 +199,33 @@ func (c *Config) NewTopLevelLogger() *slog.Logger {
|
||||
|
||||
// Stdin should be used instead of os.Stdin to capture input from tests.
|
||||
func (c *Config) Stdin() io.Reader {
|
||||
if c == nil || c.options == nil {
|
||||
return os.Stdin
|
||||
}
|
||||
return c.options.stdin
|
||||
}
|
||||
|
||||
// Stdout should be used instead of os.Stdout to capture output for tests.
|
||||
func (c *Config) Stdout() io.Writer {
|
||||
if c == nil || c.options == nil {
|
||||
return os.Stdout
|
||||
}
|
||||
return c.options.stdout
|
||||
}
|
||||
|
||||
// Stderr should be used instead of os.Stderr to capture output for tests.
|
||||
func (c *Config) Stderr() io.Writer {
|
||||
if c == nil || c.options == nil {
|
||||
return os.Stderr
|
||||
}
|
||||
return c.options.stderr
|
||||
}
|
||||
|
||||
// WriteTo returns the write to path configured by flags.
|
||||
func (c *Config) WriteTo() string {
|
||||
if c == nil {
|
||||
return ""
|
||||
}
|
||||
return c.writeTo
|
||||
}
|
||||
|
||||
@@ -230,6 +252,9 @@ func (c *Config) Write(p []byte) {
|
||||
|
||||
// ClusterName returns the cluster name configured by flags.
|
||||
func (c *Config) ClusterName() string {
|
||||
if c == nil {
|
||||
return ""
|
||||
}
|
||||
return c.clusterName
|
||||
}
|
||||
|
||||
@@ -243,7 +268,7 @@ func (c *Config) KVKubeconfig() string {
|
||||
|
||||
// KVNamespace returns the configured namespace to operate against in the provisioner cluster.
|
||||
func (c *Config) KVNamespace() string {
|
||||
if c.kvNamespace == nil {
|
||||
if c == nil || c.kvNamespace == nil {
|
||||
return DefaultProvisionerNamespace
|
||||
}
|
||||
return *c.kvNamespace
|
||||
@@ -251,7 +276,7 @@ func (c *Config) KVNamespace() string {
|
||||
|
||||
// TxtarIndex returns the
|
||||
func (c *Config) TxtarIndex() int {
|
||||
if c.txtarIndex == nil {
|
||||
if c == nil || c.txtarIndex == nil {
|
||||
return 0
|
||||
}
|
||||
return *c.txtarIndex
|
||||
@@ -259,7 +284,7 @@ func (c *Config) TxtarIndex() int {
|
||||
|
||||
// ProvisionerClientset returns a kubernetes client set for the provisioner cluster.
|
||||
func (c *Config) ProvisionerClientset() (kubernetes.Interface, error) {
|
||||
if c.provisionerClientset == nil {
|
||||
if c == nil || c.provisionerClientset == nil {
|
||||
kcfg, err := clientcmd.BuildConfigFromFlags("", c.KVKubeconfig())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
|
||||
@@ -5,29 +5,13 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"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.
|
||||
|
||||
@@ -48,8 +48,17 @@ func User(ctx context.Context, cfg *client.Config) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the current user id gets saved.
|
||||
cc.UserID = u.GetId()
|
||||
server := cfg.Client().Server()
|
||||
|
||||
// If the user switched servers, they've switched contexts and we need to
|
||||
// replace the current context. Consider indexing the client context on the
|
||||
// server hostname instead of replacing it. For now, it's easy enough to
|
||||
// re-run the registration command to get the current context.
|
||||
if cc.UserID != u.GetId() {
|
||||
log.WarnContext(ctx, "context changed", "server", server, "prevUserID", cc.UserID, "currentUserID", u.GetId())
|
||||
cc.UserID = u.GetId()
|
||||
cc.OrgID = ""
|
||||
}
|
||||
|
||||
// Ensure an org ID gets saved.
|
||||
if cc.OrgID == "" {
|
||||
@@ -65,7 +74,7 @@ func User(ctx context.Context, cfg *client.Config) error {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
log.InfoContext(ctx, "user", "email", u.GetEmail(), "user_id", cc.UserID, "org_id", cc.OrgID)
|
||||
log.InfoContext(ctx, "user", "email", u.GetEmail(), "server", server, "user_id", cc.UserID, "org_id", cc.OrgID)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -534,6 +534,65 @@ func (x *Form) GetFieldConfigs() []*structpb.Struct {
|
||||
return nil
|
||||
}
|
||||
|
||||
// PlatformConfig represents the data passed from the holos cli to CUE when
|
||||
// rendering configuration.
|
||||
type PlatformConfig struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// Platform UUID.
|
||||
PlatformId string `protobuf:"bytes,1,opt,name=platform_id,json=platformId,proto3" json:"platform_id,omitempty"`
|
||||
// Platform Model.
|
||||
PlatformModel *structpb.Struct `protobuf:"bytes,2,opt,name=platform_model,json=platformModel,proto3,oneof" json:"platform_model,omitempty"`
|
||||
}
|
||||
|
||||
func (x *PlatformConfig) Reset() {
|
||||
*x = PlatformConfig{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_holos_object_v1alpha1_object_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *PlatformConfig) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PlatformConfig) ProtoMessage() {}
|
||||
|
||||
func (x *PlatformConfig) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_holos_object_v1alpha1_object_proto_msgTypes[7]
|
||||
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 PlatformConfig.ProtoReflect.Descriptor instead.
|
||||
func (*PlatformConfig) Descriptor() ([]byte, []int) {
|
||||
return file_holos_object_v1alpha1_object_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
func (x *PlatformConfig) GetPlatformId() string {
|
||||
if x != nil {
|
||||
return x.PlatformId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PlatformConfig) GetPlatformModel() *structpb.Struct {
|
||||
if x != nil {
|
||||
return x.PlatformModel
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_holos_object_v1alpha1_object_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_holos_object_v1alpha1_object_proto_rawDesc = []byte{
|
||||
@@ -619,12 +678,21 @@ var file_holos_object_v1alpha1_object_proto_rawDesc = []byte{
|
||||
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,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x73, 0x22, 0x93, 0x01, 0x0a, 0x0e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f,
|
||||
0x72, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 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, 0x43, 0x0a, 0x0e, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f,
|
||||
0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x02, 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, 0x00, 0x52, 0x0d, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d,
|
||||
0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x88, 0x01, 0x01, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x70, 0x6c, 0x61,
|
||||
0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 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 (
|
||||
@@ -639,7 +707,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, 7)
|
||||
var file_holos_object_v1alpha1_object_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
|
||||
var file_holos_object_v1alpha1_object_proto_goTypes = []interface{}{
|
||||
(*Detail)(nil), // 0: holos.object.v1alpha1.Detail
|
||||
(*Subject)(nil), // 1: holos.object.v1alpha1.Subject
|
||||
@@ -648,21 +716,23 @@ var file_holos_object_v1alpha1_object_proto_goTypes = []interface{}{
|
||||
(*ResourceEditor)(nil), // 4: holos.object.v1alpha1.ResourceEditor
|
||||
(*ResourceOwner)(nil), // 5: holos.object.v1alpha1.ResourceOwner
|
||||
(*Form)(nil), // 6: holos.object.v1alpha1.Form
|
||||
(*timestamppb.Timestamp)(nil), // 7: google.protobuf.Timestamp
|
||||
(*structpb.Struct)(nil), // 8: google.protobuf.Struct
|
||||
(*PlatformConfig)(nil), // 7: holos.object.v1alpha1.PlatformConfig
|
||||
(*timestamppb.Timestamp)(nil), // 8: google.protobuf.Timestamp
|
||||
(*structpb.Struct)(nil), // 9: 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
|
||||
7, // 1: holos.object.v1alpha1.Detail.created_at:type_name -> google.protobuf.Timestamp
|
||||
8, // 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
|
||||
7, // 3: holos.object.v1alpha1.Detail.updated_at:type_name -> google.protobuf.Timestamp
|
||||
8, // 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
|
||||
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
|
||||
9, // 5: holos.object.v1alpha1.Form.field_configs:type_name -> google.protobuf.Struct
|
||||
9, // 6: holos.object.v1alpha1.PlatformConfig.platform_model:type_name -> google.protobuf.Struct
|
||||
7, // [7:7] is the sub-list for method output_type
|
||||
7, // [7:7] is the sub-list for method input_type
|
||||
7, // [7:7] is the sub-list for extension type_name
|
||||
7, // [7:7] is the sub-list for extension extendee
|
||||
0, // [0:7] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_holos_object_v1alpha1_object_proto_init() }
|
||||
@@ -755,6 +825,18 @@ func file_holos_object_v1alpha1_object_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_holos_object_v1alpha1_object_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*PlatformConfig); 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{}{
|
||||
@@ -773,13 +855,14 @@ func file_holos_object_v1alpha1_object_proto_init() {
|
||||
(*ResourceOwner_OrgId)(nil),
|
||||
(*ResourceOwner_UserId)(nil),
|
||||
}
|
||||
file_holos_object_v1alpha1_object_proto_msgTypes[7].OneofWrappers = []interface{}{}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_holos_object_v1alpha1_object_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 7,
|
||||
NumMessages: 8,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
||||
@@ -87,3 +87,12 @@ message Form {
|
||||
// organized by section.
|
||||
repeated google.protobuf.Struct field_configs = 1;
|
||||
}
|
||||
|
||||
// PlatformConfig represents the data passed from the holos cli to CUE when
|
||||
// rendering configuration.
|
||||
message PlatformConfig {
|
||||
// Platform UUID.
|
||||
string platform_id = 1 [(buf.validate.field).string.uuid = true];
|
||||
// Platform Model.
|
||||
optional google.protobuf.Struct platform_model = 2;
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
79
|
||||
80
|
||||
|
||||
@@ -1 +1 @@
|
||||
0
|
||||
1
|
||||
|
||||
Reference in New Issue
Block a user