diff --git a/api/config.yaml b/api/config.yaml index 1d81688d86..5a49d28a30 100644 --- a/api/config.yaml +++ b/api/config.yaml @@ -164,3 +164,12 @@ components: $ref: "#/components/schemas/DemoOpenTelemetryStore" required: - enabled + DemoList: + type: object + properties: + count: + type: integer + items: + type: array + items: + $ref: "./config.yaml#/components/schemas/Demo" diff --git a/api/environments.yaml b/api/environments.yaml index dfad862f53..6b9a8df72f 100644 --- a/api/environments.yaml +++ b/api/environments.yaml @@ -2,6 +2,16 @@ openapi: 3.0.0 components: schemas: + EnvironmentResourceList: + type: object + properties: + count: + type: integer + items: + type: array + items: + $ref: "./environments.yaml#/components/schemas/EnvironmentResource" + EnvironmentResource: type: object description: "Represents an environment structured into the Resources format." diff --git a/api/openapi.yaml b/api/openapi.yaml index f52a86844b..a849b38e1d 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -882,14 +882,7 @@ paths: content: application/json: schema: - type: object - properties: - count: - type: integer - items: - type: array - items: - $ref: "./config.yaml#/components/schemas/Demo" + $ref: "./config.yaml#/components/schemas/DemoList" text/yaml: schema: type: object @@ -1075,14 +1068,7 @@ paths: content: application/json: schema: - type: object - properties: - count: - type: integer - items: - type: array - items: - $ref: "./environments.yaml#/components/schemas/EnvironmentResource" + $ref: "./environments.yaml#/components/schemas/EnvironmentResourceList" text/yaml: schema: type: object diff --git a/cli/actions/config.go b/cli/actions/config.go index c859be19d3..0b80d384c4 100644 --- a/cli/actions/config.go +++ b/cli/actions/config.go @@ -2,8 +2,10 @@ package actions import ( "context" + "fmt" "github.com/kubeshop/tracetest/cli/file" + "github.com/kubeshop/tracetest/cli/openapi" "github.com/kubeshop/tracetest/cli/utils" "github.com/kubeshop/tracetest/server/model/yaml" ) @@ -31,8 +33,18 @@ func (configActions) Name() string { return "config" } -func (config configActions) Apply(ctx context.Context, fileContent file.File) (*file.File, error) { - return config.resourceClient.Update(ctx, fileContent, currentConfigID) +func (config configActions) GetID(file *file.File) (string, error) { + resource, err := config.formatter.ToStruct(file) + if err != nil { + return "", err + } + + return *resource.(openapi.ConfigurationResource).Spec.Id, nil +} + +func (config configActions) Apply(ctx context.Context, fileContent file.File) (result *file.File, err error) { + result, err = config.resourceClient.Update(ctx, fileContent, currentConfigID) + return result, err } func (config configActions) Get(ctx context.Context, ID string) (*file.File, error) { @@ -40,9 +52,9 @@ func (config configActions) Get(ctx context.Context, ID string) (*file.File, err } func (config configActions) List(ctx context.Context, listArgs utils.ListArgs) (*file.File, error) { - return nil, ErrNotSupportedResourceAction + return nil, fmt.Errorf("Config does not support listing. Try `tracetest get config` instead") } -func (config configActions) Delete(ctx context.Context, ID string) error { - return ErrNotSupportedResourceAction +func (config configActions) Delete(ctx context.Context, ID string) (string, error) { + return "Config successfully reset to default", ErrNotSupportedResourceAction } diff --git a/cli/actions/datastore.go b/cli/actions/datastore.go index 5af6921772..3ed759c206 100644 --- a/cli/actions/datastore.go +++ b/cli/actions/datastore.go @@ -2,6 +2,7 @@ package actions import ( "context" + "fmt" "github.com/kubeshop/tracetest/cli/file" "github.com/kubeshop/tracetest/cli/openapi" @@ -32,21 +33,32 @@ func (d *dataStoreActions) Name() string { return "datastore" } -func (d *dataStoreActions) Apply(ctx context.Context, fileContent file.File) (*file.File, error) { +func (d dataStoreActions) GetID(file *file.File) (string, error) { + resource, err := d.formatter.ToStruct(file) + if err != nil { + return "", err + } + + return *resource.(openapi.DataStoreResource).Spec.Id, nil +} + +func (d *dataStoreActions) Apply(ctx context.Context, fileContent file.File) (result *file.File, err error) { var dataStore openapi.DataStore mapstructure.Decode(fileContent.Definition().Spec, &dataStore) - return d.resourceClient.Update(ctx, fileContent, currentConfigID) + result, err = d.resourceClient.Update(ctx, fileContent, currentConfigID) + return result, err } func (d *dataStoreActions) List(ctx context.Context, args utils.ListArgs) (*file.File, error) { - return nil, ErrNotSupportedResourceAction + return nil, fmt.Errorf("DataStore does not support listing. Try `tracetest get datastore`") } func (d *dataStoreActions) Get(ctx context.Context, id string) (*file.File, error) { return d.resourceClient.Get(ctx, currentConfigID) } -func (d *dataStoreActions) Delete(ctx context.Context, id string) error { - return d.resourceClient.Delete(ctx, currentConfigID) +func (d *dataStoreActions) Delete(ctx context.Context, id string) (string, error) { + err := d.resourceClient.Delete(ctx, currentConfigID) + return "DataStore removed. Defaulting back to no-tracing mode", err } diff --git a/cli/actions/demo.go b/cli/actions/demo.go index 172dfdbc86..3ba31cff58 100644 --- a/cli/actions/demo.go +++ b/cli/actions/demo.go @@ -32,23 +32,35 @@ func (demoActions) Name() string { return "demo" } -func (demo demoActions) Apply(ctx context.Context, fileContent file.File) (*file.File, error) { +func (demo demoActions) GetID(file *file.File) (string, error) { + resource, err := demo.formatter.ToStruct(file) + if err != nil { + return "", err + } + + return *resource.(openapi.Demo).Spec.Id, nil +} + +func (demo demoActions) Apply(ctx context.Context, fileContent file.File) (result *file.File, err error) { var demoResource openapi.Demo mapstructure.Decode(fileContent.Definition().Spec, &demoResource.Spec) if demoResource.Spec.Id == nil || *demoResource.Spec.Id == "" { - return demo.resourceClient.Create(ctx, fileContent) + result, err = demo.resourceClient.Create(ctx, fileContent) + return result, err } - return demo.resourceClient.Update(ctx, fileContent, *demoResource.Spec.Id) + result, err = demo.resourceClient.Update(ctx, fileContent, *demoResource.Spec.Id) + return result, err } func (demo demoActions) List(ctx context.Context, listArgs utils.ListArgs) (*file.File, error) { return demo.resourceClient.List(ctx, listArgs) } -func (demo demoActions) Delete(ctx context.Context, ID string) error { - return demo.resourceClient.Delete(ctx, ID) +func (demo demoActions) Delete(ctx context.Context, ID string) (string, error) { + err := demo.resourceClient.Delete(ctx, ID) + return "Demo successfully deleted", err } func (demo demoActions) Get(ctx context.Context, ID string) (*file.File, error) { diff --git a/cli/actions/environments.go b/cli/actions/environments.go index 48568c6e94..4588f9df40 100644 --- a/cli/actions/environments.go +++ b/cli/actions/environments.go @@ -34,7 +34,16 @@ func (environmentsActions) Name() string { return "environment" } -func (environment environmentsActions) Apply(ctx context.Context, fileContent file.File) (*file.File, error) { +func (environment environmentsActions) GetID(file *file.File) (string, error) { + resource, err := environment.formatter.ToStruct(file) + if err != nil { + return "", err + } + + return *resource.(openapi.EnvironmentResource).Spec.Id, nil +} + +func (environment environmentsActions) Apply(ctx context.Context, fileContent file.File) (result *file.File, err error) { envResource := openapi.EnvironmentResource{ Spec: &openapi.Environment{}, } @@ -42,18 +51,20 @@ func (environment environmentsActions) Apply(ctx context.Context, fileContent fi mapstructure.Decode(fileContent.Definition().Spec, &envResource.Spec) if envResource.Spec.Id == nil || *envResource.Spec.Id == "" { - return environment.resourceClient.Create(ctx, fileContent) + result, err := environment.resourceClient.Create(ctx, fileContent) + return result, err } - return environment.resourceClient.Update(ctx, fileContent, *envResource.Spec.Id) + result, err = environment.resourceClient.Update(ctx, fileContent, *envResource.Spec.Id) + return result, err } func (environment environmentsActions) List(ctx context.Context, listArgs utils.ListArgs) (*file.File, error) { return environment.resourceClient.List(ctx, listArgs) } -func (environment environmentsActions) Delete(ctx context.Context, ID string) error { - return environment.resourceClient.Delete(ctx, ID) +func (environment environmentsActions) Delete(ctx context.Context, ID string) (string, error) { + return "Environment successfully deleted", environment.resourceClient.Delete(ctx, ID) } func (environment environmentsActions) Get(ctx context.Context, ID string) (*file.File, error) { diff --git a/cli/actions/polling.go b/cli/actions/polling.go index de30f242e6..cddb304a8b 100644 --- a/cli/actions/polling.go +++ b/cli/actions/polling.go @@ -32,19 +32,29 @@ func (pollingActions) Name() string { return "pollingprofile" } -func (polling pollingActions) Apply(ctx context.Context, fileContent file.File) (*file.File, error) { +func (polling pollingActions) GetID(file *file.File) (string, error) { + resource, err := polling.formatter.ToStruct(file) + if err != nil { + return "", err + } + + return resource.(openapi.PollingProfile).Spec.Id, nil +} + +func (polling pollingActions) Apply(ctx context.Context, fileContent file.File) (result *file.File, err error) { var pollingProfile openapi.PollingProfile mapstructure.Decode(fileContent.Definition().Spec, &pollingProfile.Spec) - return polling.resourceClient.Update(ctx, fileContent, currentConfigID) + result, err = polling.resourceClient.Update(ctx, fileContent, currentConfigID) + return result, err } func (polling pollingActions) List(ctx context.Context, listArgs utils.ListArgs) (*file.File, error) { return nil, ErrNotSupportedResourceAction } -func (polling pollingActions) Delete(ctx context.Context, ID string) error { - return ErrNotSupportedResourceAction +func (polling pollingActions) Delete(ctx context.Context, ID string) (string, error) { + return "PollingProfile successfully reset to default", ErrNotSupportedResourceAction } func (polling pollingActions) Get(ctx context.Context, ID string) (*file.File, error) { diff --git a/cli/actions/resource.go b/cli/actions/resource.go index 6ce53bace4..ae44a12dba 100644 --- a/cli/actions/resource.go +++ b/cli/actions/resource.go @@ -4,6 +4,7 @@ import ( "errors" "github.com/kubeshop/tracetest/cli/config" + "github.com/kubeshop/tracetest/cli/formatters" "github.com/kubeshop/tracetest/cli/utils" "go.uber.org/zap" ) @@ -16,12 +17,17 @@ type resourceArgs struct { logger *zap.Logger resourceClient utils.ResourceClient config config.Config + formatter formatters.ResourceFormatter } func (r resourceArgs) Logger() *zap.Logger { return r.logger } +func (r resourceArgs) Formatter() formatters.ResourceFormatter { + return r.formatter +} + type ResourceArgsOption = func(args *resourceArgs) type ResourceRegistry map[string]resourceActions @@ -66,6 +72,12 @@ func WithConfig(config config.Config) ResourceArgsOption { } } +func WithFormatter(formatter formatters.ResourceFormatter) ResourceArgsOption { + return func(args *resourceArgs) { + args.formatter = formatter + } +} + func NewResourceArgs(options ...ResourceArgsOption) resourceArgs { args := resourceArgs{} diff --git a/cli/actions/resource_actions.go b/cli/actions/resource_actions.go index 8b7e6be631..0d867ad169 100644 --- a/cli/actions/resource_actions.go +++ b/cli/actions/resource_actions.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/kubeshop/tracetest/cli/file" + "github.com/kubeshop/tracetest/cli/formatters" "github.com/kubeshop/tracetest/cli/utils" "github.com/kubeshop/tracetest/server/model/yaml" "go.uber.org/zap" @@ -12,12 +13,14 @@ import ( type ResourceActions interface { Logger() *zap.Logger + Formatter() formatters.ResourceFormatter FileType() yaml.FileType Name() string + GetID(*file.File) (string, error) Apply(context.Context, file.File) (*file.File, error) List(context.Context, utils.ListArgs) (*file.File, error) Get(context.Context, string) (*file.File, error) - Delete(context.Context, string) error + Delete(context.Context, string) (string, error) } type resourceActions struct { @@ -34,9 +37,9 @@ func (r *resourceActions) Name() string { return r.actions.Name() } -func (r *resourceActions) Apply(ctx context.Context, args ApplyArgs) error { +func (r *resourceActions) Apply(ctx context.Context, args ApplyArgs) (*file.File, string, error) { if args.File == "" { - return fmt.Errorf("you must specify a file to be applied") + return nil, "", fmt.Errorf("you must specify a file to be applied") } r.actions.Logger().Debug( @@ -46,40 +49,47 @@ func (r *resourceActions) Apply(ctx context.Context, args ApplyArgs) error { fileContent, err := file.ReadRaw(args.File) if err != nil { - return fmt.Errorf("could not read file: %w", err) + return nil, "", fmt.Errorf("could not read file: %w", err) } if fileContent.Definition().Type != r.actions.FileType() { - return fmt.Errorf(fmt.Sprintf(`file must be of type "%s"`, r.actions.FileType())) + return nil, "", fmt.Errorf(fmt.Sprintf(`file must be of type "%s"`, r.actions.FileType())) } - file, err := r.actions.Apply(ctx, fileContent) + f, err := r.actions.Apply(ctx, fileContent) if err != nil { - return err + return nil, "", err } - _, err = file.WriteRaw() - return err + Id, err := r.actions.GetID(f) + if err != nil { + return nil, "", err + } + + result, err := f.WriteRaw() + if err != nil { + return nil, "", err + } + + return &result, fmt.Sprintf("%s applied successfully (id: %s)", utils.Capitalize(r.actions.Name()), Id), nil } -func (r *resourceActions) List(ctx context.Context, args utils.ListArgs) error { - resources, err := r.actions.List(ctx, args) +func (r *resourceActions) List(ctx context.Context, args utils.ListArgs) (*file.File, error) { + resource, err := r.actions.List(ctx, args) if err != nil { - return err + return nil, err } - fmt.Println(resources.Contents()) - return nil + return resource, nil } -func (r *resourceActions) Get(ctx context.Context, id string) error { +func (r *resourceActions) Get(ctx context.Context, id string) (*file.File, error) { resource, err := r.actions.Get(ctx, id) if err != nil { - return err + return nil, err } - fmt.Println(resource.Contents()) - return nil + return resource, err } func (r *resourceActions) Export(ctx context.Context, id string, filePath string) error { @@ -92,6 +102,10 @@ func (r *resourceActions) Export(ctx context.Context, id string, filePath string return err } -func (r *resourceActions) Delete(ctx context.Context, id string) error { +func (r *resourceActions) Delete(ctx context.Context, id string) (string, error) { return r.actions.Delete(ctx, id) } + +func (r *resourceActions) Formatter() formatters.ResourceFormatter { + return r.actions.Formatter() +} diff --git a/cli/cmd/apply_cmd.go b/cli/cmd/apply_cmd.go index 0280bc0c75..ad8c6ebee1 100644 --- a/cli/cmd/apply_cmd.go +++ b/cli/cmd/apply_cmd.go @@ -7,7 +7,7 @@ import ( "github.com/kubeshop/tracetest/cli/actions" "github.com/kubeshop/tracetest/cli/analytics" - "github.com/pterm/pterm" + "github.com/kubeshop/tracetest/cli/formatters" "github.com/spf13/cobra" "go.uber.org/zap" ) @@ -47,15 +47,24 @@ var applyCmd = &cobra.Command{ File: definitionFile, } - err = resourceActions.Apply(ctx, applyArgs) - + resource, _, err := resourceActions.Apply(ctx, applyArgs) if err != nil { cliLogger.Error(fmt.Sprintf("failed to apply definition for type: %s", resourceType), zap.Error(err)) os.Exit(1) return } - cmd.Println(pterm.FgGreen.Sprintf(fmt.Sprintf("✔ Definition applied successfully for resource type: %s", resourceType))) + resourceFormatter := resourceActions.Formatter() + formatter := formatters.BuildFormatter(output, formatters.YAML, resourceFormatter) + + result, err := formatter.Format(resource) + if err != nil { + cliLogger.Error("failed to format resource", zap.Error(err)) + os.Exit(1) + return + } + + fmt.Println(result) }, PostRun: teardownCommand, } diff --git a/cli/cmd/config.go b/cli/cmd/config.go index 0acdfe66c0..691128473b 100644 --- a/cli/cmd/config.go +++ b/cli/cmd/config.go @@ -46,23 +46,43 @@ func setupCommand(options ...setupOption) func(cmd *cobra.Command, args []string baseOptions := []actions.ResourceArgsOption{actions.WithLogger(cliLogger), actions.WithConfig(cliConfig)} - configOptions := append(baseOptions, actions.WithClient(utils.GetResourceAPIClient("configs", cliConfig))) + configOptions := append( + baseOptions, + actions.WithClient(utils.GetResourceAPIClient("configs", cliConfig)), + actions.WithFormatter(formatters.NewConfigFormatter()), + ) configActions := actions.NewConfigActions(configOptions...) resourceRegistry.Register(configActions) - pollingOptions := append(baseOptions, actions.WithClient(utils.GetResourceAPIClient("pollingprofiles", cliConfig))) + pollingOptions := append( + baseOptions, + actions.WithClient(utils.GetResourceAPIClient("pollingprofiles", cliConfig)), + actions.WithFormatter(formatters.NewPollingFormatter()), + ) pollingActions := actions.NewPollingActions(pollingOptions...) resourceRegistry.Register(pollingActions) - demoOptions := append(baseOptions, actions.WithClient(utils.GetResourceAPIClient("demos", cliConfig))) + demoOptions := append( + baseOptions, + actions.WithClient(utils.GetResourceAPIClient("demos", cliConfig)), + actions.WithFormatter(formatters.NewDemoFormatter()), + ) demoActions := actions.NewDemoActions(demoOptions...) resourceRegistry.Register(demoActions) - dataStoreOptions := append(baseOptions, actions.WithClient(utils.GetResourceAPIClient("datastores", cliConfig))) + dataStoreOptions := append( + baseOptions, + actions.WithClient(utils.GetResourceAPIClient("datastores", cliConfig)), + actions.WithFormatter(formatters.NewDatastoreFormatter()), + ) dataStoreActions := actions.NewDataStoreActions(dataStoreOptions...) resourceRegistry.Register(dataStoreActions) - environmentOptions := append(baseOptions, actions.WithClient(utils.GetResourceAPIClient("environments", cliConfig))) + environmentOptions := append( + baseOptions, + actions.WithClient(utils.GetResourceAPIClient("environments", cliConfig)), + actions.WithFormatter(formatters.NewEnvironmentsFormatter()), + ) environmentActions := actions.NewEnvironmentsActions(environmentOptions...) resourceRegistry.Register(environmentActions) diff --git a/cli/cmd/delete_cmd.go b/cli/cmd/delete_cmd.go index fa5a150f78..5afc8980f7 100644 --- a/cli/cmd/delete_cmd.go +++ b/cli/cmd/delete_cmd.go @@ -6,7 +6,6 @@ import ( "os" "github.com/kubeshop/tracetest/cli/analytics" - "github.com/pterm/pterm" "github.com/spf13/cobra" "go.uber.org/zap" ) @@ -35,22 +34,20 @@ var deleteCmd = &cobra.Command{ }) resourceActions, err := resourceRegistry.Get(resourceType) - if err != nil { cliLogger.Error(fmt.Sprintf("failed to get resource instance for type: %s", resourceType), zap.Error(err)) os.Exit(1) return } - err = resourceActions.Delete(ctx, deletedResourceID) - + message, err := resourceActions.Delete(ctx, deletedResourceID) if err != nil { cliLogger.Error(fmt.Sprintf("failed to apply definition for type: %s", resourceType), zap.Error(err)) os.Exit(1) return } - cmd.Println(pterm.FgGreen.Sprintf(fmt.Sprintf("✔ Resource deleted successfully for resource type: %s", resourceType))) + cmd.Println(fmt.Sprintf("✔ %s", message)) }, PostRun: teardownCommand, } diff --git a/cli/cmd/export_cmd.go b/cli/cmd/export_cmd.go index b48f1333f3..d4b4987687 100644 --- a/cli/cmd/export_cmd.go +++ b/cli/cmd/export_cmd.go @@ -6,7 +6,6 @@ import ( "os" "github.com/kubeshop/tracetest/cli/analytics" - "github.com/pterm/pterm" "github.com/spf13/cobra" "go.uber.org/zap" ) @@ -45,7 +44,7 @@ var exportCmd = &cobra.Command{ return } - cmd.Println(pterm.FgGreen.Sprintf(fmt.Sprintf("✔ Definition exported successfully for resource type: %s", resourceType))) + cmd.Println(fmt.Sprintf("✔ Definition exported successfully for resource type: %s", resourceType)) }, PostRun: teardownCommand, } diff --git a/cli/cmd/get_cmd.go b/cli/cmd/get_cmd.go index 4b1fb0e382..8bc5427397 100644 --- a/cli/cmd/get_cmd.go +++ b/cli/cmd/get_cmd.go @@ -6,6 +6,7 @@ import ( "os" "github.com/kubeshop/tracetest/cli/analytics" + "github.com/kubeshop/tracetest/cli/formatters" "github.com/spf13/cobra" "go.uber.org/zap" ) @@ -41,13 +42,24 @@ var getCmd = &cobra.Command{ return } - err = resourceActions.Get(ctx, resourceID) - + resource, err := resourceActions.Get(ctx, resourceID) if err != nil { cliLogger.Error(fmt.Sprintf("failed to get resource for type: %s", resourceType), zap.Error(err)) os.Exit(1) return } + + resourceFormatter := resourceActions.Formatter() + formatter := formatters.BuildFormatter(output, formatters.YAML, resourceFormatter) + + result, err := formatter.Format(resource) + if err != nil { + cliLogger.Error("failed to format resource", zap.Error(err)) + os.Exit(1) + return + } + + fmt.Println(result) }, PostRun: teardownCommand, } diff --git a/cli/cmd/list_cmd.go b/cli/cmd/list_cmd.go index 2f3a0a3489..3c594feeba 100644 --- a/cli/cmd/list_cmd.go +++ b/cli/cmd/list_cmd.go @@ -6,6 +6,7 @@ import ( "os" "github.com/kubeshop/tracetest/cli/analytics" + "github.com/kubeshop/tracetest/cli/formatters" "github.com/kubeshop/tracetest/cli/utils" "github.com/spf13/cobra" "go.uber.org/zap" @@ -48,13 +49,24 @@ var listCmd = &cobra.Command{ SortBy: listSortBy, } - err = resourceActions.List(ctx, listArgs) - + resource, err := resourceActions.List(ctx, listArgs) if err != nil { cliLogger.Error(fmt.Sprintf("failed to list for type: %s", resourceType), zap.Error(err)) os.Exit(1) return } + + resourceFormatter := resourceActions.Formatter() + formatter := formatters.BuildFormatter(output, formatters.Pretty, resourceFormatter) + + result, err := formatter.FormatList(resource) + if err != nil { + cliLogger.Error("failed to format resource", zap.Error(err)) + os.Exit(1) + return + } + + fmt.Println(result) }, PostRun: teardownCommand, } @@ -64,5 +76,6 @@ func init() { listCmd.Flags().Int32Var(&listSkip, "skip", 0, "Skip number") listCmd.Flags().StringVar(&listSortBy, "sortBy", "", "Sort by") listCmd.Flags().StringVar(&listSortDirection, "sortDirection", "desc", "Sort direction") + rootCmd.AddCommand(listCmd) } diff --git a/cli/cmd/root.go b/cli/cmd/root.go index 0af8a9f620..ff3cf385e4 100644 --- a/cli/cmd/root.go +++ b/cli/cmd/root.go @@ -59,7 +59,7 @@ var ( ) func init() { - rootCmd.PersistentFlags().StringVarP(&output, "output", "o", string(formatters.DefaultOutput), fmt.Sprintf("output format [%s]", outputFormatsString)) + rootCmd.PersistentFlags().StringVarP(&output, "output", "o", "", fmt.Sprintf("output format [%s]", outputFormatsString)) rootCmd.PersistentFlags().StringVarP(&configFile, "config", "c", "config.yml", "config file will be used by the CLI") rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "display debug information") diff --git a/cli/file/definition.go b/cli/file/definition.go index 66f7570124..e7e7e69b56 100644 --- a/cli/file/definition.go +++ b/cli/file/definition.go @@ -13,6 +13,10 @@ import ( "gopkg.in/yaml.v3" ) +type SpecWithID struct { + ID string `yaml:"id"` +} + type File struct { path string contents []byte diff --git a/cli/formatters/config.go b/cli/formatters/config.go new file mode 100644 index 0000000000..6b4b8327ad --- /dev/null +++ b/cli/formatters/config.go @@ -0,0 +1,74 @@ +package formatters + +import ( + "fmt" + + "github.com/alexeyco/simpletable" + "github.com/kubeshop/tracetest/cli/file" + "github.com/kubeshop/tracetest/cli/openapi" + + "gopkg.in/yaml.v2" +) + +type ConfigFormatter struct{} + +var _ ResourceFormatter = ConfigFormatter{} + +func NewConfigFormatter() ConfigFormatter { + return ConfigFormatter{} +} + +func (f ConfigFormatter) ToTable(file *file.File) (*simpletable.Header, *simpletable.Body, error) { + rawConfig, err := f.ToStruct(file) + if err != nil { + return nil, nil, err + } + + ConfigResource := rawConfig.(openapi.ConfigurationResource) + row, err := f.getTableRow(ConfigResource) + if err != nil { + return nil, nil, err + } + + body := simpletable.Body{} + body.Cells = [][]*simpletable.Cell{row} + + return f.getTableHeader(), &body, nil +} + +func (f ConfigFormatter) ToListTable(file *file.File) (*simpletable.Header, *simpletable.Body, error) { + return nil, nil, nil +} + +func (f ConfigFormatter) ToStruct(file *file.File) (interface{}, error) { + var ConfigResource openapi.ConfigurationResource + + err := yaml.Unmarshal([]byte(file.Contents()), &ConfigResource) + if err != nil { + return nil, err + } + + return ConfigResource, nil +} + +func (f ConfigFormatter) ToListStruct(file *file.File) ([]interface{}, error) { + return nil, nil +} + +func (f ConfigFormatter) getTableHeader() *simpletable.Header { + return &simpletable.Header{ + Cells: []*simpletable.Cell{ + {Text: "ID"}, + {Text: "NAME"}, + {Text: "ANALYTICS ENABLED"}, + }, + } +} + +func (f ConfigFormatter) getTableRow(t openapi.ConfigurationResource) ([]*simpletable.Cell, error) { + return []*simpletable.Cell{ + {Text: *t.Spec.Id}, + {Text: *t.Spec.Name}, + {Text: fmt.Sprintf("%t", t.Spec.AnalyticsEnabled)}, + }, nil +} diff --git a/cli/formatters/datastore.go b/cli/formatters/datastore.go new file mode 100644 index 0000000000..fdbb5d863d --- /dev/null +++ b/cli/formatters/datastore.go @@ -0,0 +1,80 @@ +package formatters + +import ( + "github.com/alexeyco/simpletable" + "github.com/kubeshop/tracetest/cli/file" + "github.com/kubeshop/tracetest/cli/openapi" + + "gopkg.in/yaml.v2" +) + +type DatastoreFormatter struct{} + +var _ ResourceFormatter = DatastoreFormatter{} + +func NewDatastoreFormatter() DatastoreFormatter { + return DatastoreFormatter{} +} + +func (f DatastoreFormatter) ToTable(file *file.File) (*simpletable.Header, *simpletable.Body, error) { + rawDatastore, err := f.ToStruct(file) + if err != nil { + return nil, nil, err + } + + datastoreResource := rawDatastore.(openapi.DataStoreResource) + row, err := f.getTableRow(datastoreResource) + if err != nil { + return nil, nil, err + } + + body := simpletable.Body{} + body.Cells = [][]*simpletable.Cell{row} + + return f.getTableHeader(), &body, nil +} + +func (f DatastoreFormatter) ToListTable(file *file.File) (*simpletable.Header, *simpletable.Body, error) { + return nil, nil, nil +} + +func (f DatastoreFormatter) ToStruct(file *file.File) (interface{}, error) { + var datastoreResource openapi.DataStoreResource + + err := yaml.Unmarshal([]byte(file.Contents()), &datastoreResource) + if err != nil { + return nil, err + } + + return datastoreResource, nil +} + +func (f DatastoreFormatter) ToListStruct(file *file.File) ([]interface{}, error) { + return nil, nil +} + +func (f DatastoreFormatter) getTableHeader() *simpletable.Header { + return &simpletable.Header{ + Cells: []*simpletable.Cell{ + {Text: "ID"}, + {Text: "NAME"}, + {Text: "DEFAULT"}, + }, + } +} + +func (f DatastoreFormatter) getTableRow(t openapi.DataStoreResource) ([]*simpletable.Cell, error) { + return []*simpletable.Cell{ + {Text: *t.Spec.Id}, + {Text: t.Spec.Name}, + {Text: f.getDefaultMark(*t.Spec)}, + }, nil +} + +func (f DatastoreFormatter) getDefaultMark(dataStore openapi.DataStore) string { + if dataStore.Default != nil && *dataStore.Default { + return "*" + } + + return "" +} diff --git a/cli/formatters/datastore_list.go b/cli/formatters/datastore_list.go deleted file mode 100644 index 238320d025..0000000000 --- a/cli/formatters/datastore_list.go +++ /dev/null @@ -1,76 +0,0 @@ -package formatters - -import ( - "encoding/json" - "fmt" - - "github.com/alexeyco/simpletable" - "github.com/kubeshop/tracetest/cli/config" - "github.com/kubeshop/tracetest/cli/openapi" -) - -type dataStoreList struct { - config config.Config -} - -func DataStoreList(config config.Config) dataStoreList { - return dataStoreList{ - config: config, - } -} - -func (f dataStoreList) Format(dataStores []openapi.DataStore) string { - switch CurrentOutput { - case Pretty: - return f.pretty(dataStores) - case JSON: - return f.json(dataStores) - } - - return "" -} - -func (f dataStoreList) json(dataStores []openapi.DataStore) string { - bytes, err := json.Marshal(dataStores) - if err != nil { - panic(fmt.Errorf("could not marshal output json: %w", err)) - } - - return string(bytes) -} - -func (f dataStoreList) pretty(dataStores []openapi.DataStore) string { - if len(dataStores) == 0 { - return "No tests" - } - - table := simpletable.New() - - table.Header = &simpletable.Header{ - Cells: []*simpletable.Cell{ - {Text: "ID"}, - {Text: "NAME"}, - {Text: "DEFAULT"}, - }, - } - - for _, t := range dataStores { - table.Body.Cells = append(table.Body.Cells, []*simpletable.Cell{ - {Text: *t.Id}, - {Text: t.Name}, - {Text: f.getDefaultMark(t)}, - }) - } - - table.SetStyle(simpletable.StyleCompactLite) - - return table.String() -} - -func (f dataStoreList) getDefaultMark(dataStore openapi.DataStore) string { - if dataStore.Default != nil && *dataStore.Default { - return "*" - } - - return "" -} diff --git a/cli/formatters/demo.go b/cli/formatters/demo.go new file mode 100644 index 0000000000..a1ded24667 --- /dev/null +++ b/cli/formatters/demo.go @@ -0,0 +1,103 @@ +package formatters + +import ( + "fmt" + + "github.com/alexeyco/simpletable" + "github.com/kubeshop/tracetest/cli/file" + "github.com/kubeshop/tracetest/cli/openapi" + + "gopkg.in/yaml.v2" +) + +type DemoFormatter struct{} + +var _ ResourceFormatter = DemoFormatter{} + +func NewDemoFormatter() DemoFormatter { + return DemoFormatter{} +} + +func (f DemoFormatter) ToTable(file *file.File) (*simpletable.Header, *simpletable.Body, error) { + rawDemo, err := f.ToStruct(file) + if err != nil { + return nil, nil, err + } + + DemoResource := rawDemo.(openapi.Demo) + row, err := f.getTableRow(DemoResource) + if err != nil { + return nil, nil, err + } + + body := simpletable.Body{} + body.Cells = [][]*simpletable.Cell{row} + + return f.getTableHeader(), &body, nil +} + +func (f DemoFormatter) ToListTable(file *file.File) (*simpletable.Header, *simpletable.Body, error) { + rawDemoList, err := f.ToListStruct(file) + if err != nil { + return nil, nil, err + } + + body := simpletable.Body{} + for _, rawDemo := range rawDemoList { + demo := rawDemo.(openapi.Demo) + row, err := f.getTableRow(demo) + if err != nil { + return nil, nil, err + } + + body.Cells = append(body.Cells, row) + } + + return f.getTableHeader(), &body, nil +} + +func (f DemoFormatter) ToStruct(file *file.File) (interface{}, error) { + var demoResource openapi.Demo + err := yaml.Unmarshal([]byte(file.Contents()), &demoResource) + if err != nil { + return nil, err + } + + return demoResource, nil +} + +func (f DemoFormatter) ToListStruct(file *file.File) ([]interface{}, error) { + var demoList openapi.DemoList + + err := yaml.Unmarshal([]byte(file.Contents()), &demoList) + if err != nil { + return nil, err + } + + items := make([]interface{}, len(demoList.Items)) + for i, item := range demoList.Items { + items[i] = item + } + + return items, nil +} + +func (f DemoFormatter) getTableHeader() *simpletable.Header { + return &simpletable.Header{ + Cells: []*simpletable.Cell{ + {Text: "ID"}, + {Text: "NAME"}, + {Text: "TYPE"}, + {Text: "ENABLED"}, + }, + } +} + +func (f DemoFormatter) getTableRow(t openapi.Demo) ([]*simpletable.Cell, error) { + return []*simpletable.Cell{ + {Text: *t.Spec.Id}, + {Text: *t.Spec.Name}, + {Text: *t.Spec.Type}, + {Text: fmt.Sprintf("%t", t.Spec.Enabled)}, + }, nil +} diff --git a/cli/formatters/environment.go b/cli/formatters/environment.go new file mode 100644 index 0000000000..8473bb2796 --- /dev/null +++ b/cli/formatters/environment.go @@ -0,0 +1,102 @@ +package formatters + +import ( + "github.com/alexeyco/simpletable" + "github.com/kubeshop/tracetest/cli/file" + "github.com/kubeshop/tracetest/cli/openapi" + + "gopkg.in/yaml.v2" +) + +type EnvironmentsFormatter struct{} + +var _ ResourceFormatter = EnvironmentsFormatter{} + +func NewEnvironmentsFormatter() EnvironmentsFormatter { + return EnvironmentsFormatter{} +} + +func (f EnvironmentsFormatter) ToTable(file *file.File) (*simpletable.Header, *simpletable.Body, error) { + rawEnvironment, err := f.ToStruct(file) + if err != nil { + return nil, nil, err + } + + environmentResource := rawEnvironment.(openapi.EnvironmentResource) + row, err := f.getTableRow(environmentResource) + if err != nil { + return nil, nil, err + } + + body := simpletable.Body{} + body.Cells = [][]*simpletable.Cell{row} + + return f.getTableHeader(), &body, nil +} + +func (f EnvironmentsFormatter) ToListTable(file *file.File) (*simpletable.Header, *simpletable.Body, error) { + rawEnvironmentList, err := f.ToListStruct(file) + if err != nil { + return nil, nil, err + } + + // environmentResourceList := rawEnvironmentList.(openapi.EnvironmentResourceList) + + body := simpletable.Body{} + for _, rawDemo := range rawEnvironmentList { + environmentResource := rawDemo.(openapi.EnvironmentResource) + row, err := f.getTableRow(environmentResource) + if err != nil { + return nil, nil, err + } + + body.Cells = append(body.Cells, row) + } + + return f.getTableHeader(), &body, nil +} + +func (f EnvironmentsFormatter) ToStruct(file *file.File) (interface{}, error) { + var environmentResource openapi.EnvironmentResource + + err := yaml.Unmarshal([]byte(file.Contents()), &environmentResource) + if err != nil { + return nil, err + } + + return environmentResource, nil +} + +func (f EnvironmentsFormatter) ToListStruct(file *file.File) ([]interface{}, error) { + var environmentResourceList openapi.EnvironmentResourceList + + err := yaml.Unmarshal([]byte(file.Contents()), &environmentResourceList) + if err != nil { + return nil, err + } + + items := make([]interface{}, len(environmentResourceList.Items)) + for i, item := range environmentResourceList.Items { + items[i] = item + } + + return items, nil +} + +func (f EnvironmentsFormatter) getTableHeader() *simpletable.Header { + return &simpletable.Header{ + Cells: []*simpletable.Cell{ + {Text: "ID"}, + {Text: "NAME"}, + {Text: "DESCRIPTION"}, + }, + } +} + +func (f EnvironmentsFormatter) getTableRow(t openapi.EnvironmentResource) ([]*simpletable.Cell, error) { + return []*simpletable.Cell{ + {Text: *t.Spec.Id}, + {Text: *t.Spec.Name}, + {Text: *t.Spec.Description}, + }, nil +} diff --git a/cli/formatters/formatter.go b/cli/formatters/formatter.go new file mode 100644 index 0000000000..79006188e0 --- /dev/null +++ b/cli/formatters/formatter.go @@ -0,0 +1,76 @@ +package formatters + +import ( + "fmt" + + "github.com/alexeyco/simpletable" + "github.com/kubeshop/tracetest/cli/file" +) + +type ToStruct func(*file.File) (interface{}, error) +type ToListStruct func(*file.File) ([]interface{}, error) + +type ToTable func(*file.File) (*simpletable.Header, *simpletable.Body, error) +type ToListTable ToTable + +type ResourceFormatter interface { + ToTable(*file.File) (*simpletable.Header, *simpletable.Body, error) + ToListTable(*file.File) (*simpletable.Header, *simpletable.Body, error) + ToStruct(*file.File) (interface{}, error) + ToListStruct(*file.File) ([]interface{}, error) +} + +type FormatterInterface interface { + Format(*file.File) (string, error) + FormatList(*file.File) (string, error) + Type() string +} + +type Formatter struct { + formatType string + registry map[string]FormatterInterface +} + +func NewFormatter(formatType string, formatters ...FormatterInterface) Formatter { + registry := make(map[string]FormatterInterface, len(formatters)) + + for _, option := range formatters { + registry[option.Type()] = option + } + + return Formatter{formatType, registry} +} + +func (f Formatter) Format(file *file.File) (string, error) { + formatter, ok := f.registry[f.formatType] + if !ok { + return "", fmt.Errorf("formatter %s not found", f.formatType) + } + + return formatter.Format(file) +} + +func (f Formatter) FormatList(file *file.File) (string, error) { + formatter, ok := f.registry[f.formatType] + if !ok { + return "", fmt.Errorf("formatter %s not found", f.formatType) + } + + return formatter.FormatList(file) +} + +func BuildFormatter(formatType string, defaultType Output, resourceFormatter ResourceFormatter) Formatter { + jsonFormatter := NewJson(resourceFormatter) + yamlFormatter := NewYaml(resourceFormatter) + tableFormatter := NewTable(resourceFormatter) + + if defaultType == "" { + defaultType = YAML + } + + if formatType == "" { + formatType = string(defaultType) + } + + return NewFormatter(formatType, jsonFormatter, yamlFormatter, tableFormatter) +} diff --git a/cli/formatters/json.go b/cli/formatters/json.go new file mode 100644 index 0000000000..f04debb8fa --- /dev/null +++ b/cli/formatters/json.go @@ -0,0 +1,54 @@ +package formatters + +import ( + "encoding/json" + "fmt" + + "github.com/kubeshop/tracetest/cli/file" +) + +type Json struct { + toStructFn ToStruct + toListStructFn ToListStruct +} + +var _ FormatterInterface = Json{} + +func NewJson(resourceFormatter ResourceFormatter) Json { + return Json{ + toStructFn: resourceFormatter.ToStruct, + toListStructFn: resourceFormatter.ToListStruct, + } +} + +func (j Json) Type() string { + return "json" +} + +func (j Json) Format(file *file.File) (string, error) { + data, err := j.toStructFn(file) + if err != nil { + return "", fmt.Errorf("could not convert file to struct: %w", err) + } + + bytes, err := json.MarshalIndent(data, "", " ") + if err != nil { + return "", fmt.Errorf("could not marshal output json: %w", err) + } + + return string(bytes), nil +} + +func (j Json) FormatList(file *file.File) (string, error) { + data, err := j.toListStructFn(file) + if err != nil { + return "", fmt.Errorf("could not convert file to struct: %w", err) + } + + bytes, err := json.MarshalIndent(data, "", " ") + if err != nil { + return "", fmt.Errorf("could not marshal output json: %w", err) + } + + return string(bytes), nil +} diff --git a/cli/formatters/outputs.go b/cli/formatters/outputs.go index 46428ee246..a98c29deca 100644 --- a/cli/formatters/outputs.go +++ b/cli/formatters/outputs.go @@ -10,12 +10,16 @@ var ( Outputs = []Output{ Pretty, JSON, + YAML, + Empty, } DefaultOutput = Pretty + Empty Output = "" Pretty Output = "pretty" JSON Output = "json" + YAML Output = "yaml" ) func SetOutput(o Output) { diff --git a/cli/formatters/polling.go b/cli/formatters/polling.go new file mode 100644 index 0000000000..37f1abf8ba --- /dev/null +++ b/cli/formatters/polling.go @@ -0,0 +1,72 @@ +package formatters + +import ( + "github.com/alexeyco/simpletable" + "github.com/kubeshop/tracetest/cli/file" + "github.com/kubeshop/tracetest/cli/openapi" + + "gopkg.in/yaml.v2" +) + +type PollingFormatter struct{} + +var _ ResourceFormatter = PollingFormatter{} + +func NewPollingFormatter() PollingFormatter { + return PollingFormatter{} +} + +func (f PollingFormatter) ToTable(file *file.File) (*simpletable.Header, *simpletable.Body, error) { + rawPolling, err := f.ToStruct(file) + if err != nil { + return nil, nil, err + } + + PollingResource := rawPolling.(openapi.PollingProfile) + row, err := f.getTableRow(PollingResource) + if err != nil { + return nil, nil, err + } + + body := simpletable.Body{} + body.Cells = [][]*simpletable.Cell{row} + + return f.getTableHeader(), &body, nil +} + +func (f PollingFormatter) ToListTable(file *file.File) (*simpletable.Header, *simpletable.Body, error) { + return nil, nil, nil +} + +func (f PollingFormatter) ToStruct(file *file.File) (interface{}, error) { + var pollingResource openapi.PollingProfile + + err := yaml.Unmarshal([]byte(file.Contents()), &pollingResource) + if err != nil { + return nil, err + } + + return pollingResource, nil +} + +func (f PollingFormatter) ToListStruct(file *file.File) ([]interface{}, error) { + return nil, nil +} + +func (f PollingFormatter) getTableHeader() *simpletable.Header { + return &simpletable.Header{ + Cells: []*simpletable.Cell{ + {Text: "ID"}, + {Text: "NAME"}, + {Text: "STRAGETY"}, + }, + } +} + +func (f PollingFormatter) getTableRow(t openapi.PollingProfile) ([]*simpletable.Cell, error) { + return []*simpletable.Cell{ + {Text: t.Spec.Id}, + {Text: t.Spec.Name}, + {Text: t.Spec.Strategy}, + }, nil +} diff --git a/cli/formatters/table.go b/cli/formatters/table.go new file mode 100644 index 0000000000..896341d70d --- /dev/null +++ b/cli/formatters/table.go @@ -0,0 +1,54 @@ +package formatters + +import ( + "github.com/alexeyco/simpletable" + "github.com/kubeshop/tracetest/cli/file" +) + +type Table struct { + toTableFn ToTable + toListTableFn ToListTable +} + +var _ FormatterInterface = Table{} + +func NewTable(resourceFormatter ResourceFormatter) Table { + return Table{ + toTableFn: resourceFormatter.ToTable, + toListTableFn: resourceFormatter.ToListTable, + } +} + +func (t Table) Type() string { + return "pretty" +} + +func (t Table) Format(file *file.File) (string, error) { + table := simpletable.New() + + header, body, err := t.toTableFn(file) + if err != nil { + return "", err + } + + table.Header = header + table.Body = body + + table.SetStyle(simpletable.StyleCompactLite) + return table.String(), nil +} + +func (t Table) FormatList(file *file.File) (string, error) { + table := simpletable.New() + + header, body, err := t.toListTableFn(file) + if err != nil { + return "", err + } + + table.Header = header + table.Body = body + + table.SetStyle(simpletable.StyleCompactLite) + return table.String(), nil +} diff --git a/cli/formatters/yaml.go b/cli/formatters/yaml.go new file mode 100644 index 0000000000..b8a5352f2a --- /dev/null +++ b/cli/formatters/yaml.go @@ -0,0 +1,60 @@ +package formatters + +import ( + "fmt" + + "gopkg.in/yaml.v2" + + "github.com/kubeshop/tracetest/cli/file" +) + +type Yaml struct { + toStructFn ToStruct + toListStructFn ToListStruct +} + +var _ FormatterInterface = Yaml{} + +func NewYaml(resourceFormatter ResourceFormatter) Yaml { + return Yaml{ + toStructFn: resourceFormatter.ToStruct, + toListStructFn: resourceFormatter.ToListStruct, + } +} + +func (Yaml) Type() string { + return "yaml" +} + +func (y Yaml) FormatList(file *file.File) (string, error) { + data, err := y.toListStructFn(file) + if err != nil { + return "", fmt.Errorf("could not convert file to struct: %w", err) + } + + result := "" + for _, value := range data { + bytes, err := yaml.Marshal(value) + if err != nil { + return "", fmt.Errorf("could not marshal output json: %w", err) + } + + result += "---\n" + string(bytes) + "\n" + } + + return result, nil +} + +func (y Yaml) Format(file *file.File) (string, error) { + data, err := y.toStructFn(file) + if err != nil { + return "", fmt.Errorf("could not convert file to struct: %w", err) + } + + bytes, err := yaml.Marshal(data) + if err != nil { + return "", fmt.Errorf("could not marshal output json: %w", err) + } + + return "---\n" + string(bytes), nil +} diff --git a/cli/openapi/api_resource_api.go b/cli/openapi/api_resource_api.go index 3b8010fa5a..1ede1273db 100644 --- a/cli/openapi/api_resource_api.go +++ b/cli/openapi/api_resource_api.go @@ -1067,7 +1067,7 @@ func (r ApiListDemosRequest) SortDirection(sortDirection string) ApiListDemosReq return r } -func (r ApiListDemosRequest) Execute() (*ListDemos200Response, *http.Response, error) { +func (r ApiListDemosRequest) Execute() (*DemoList, *http.Response, error) { return r.ApiService.ListDemosExecute(r) } @@ -1088,13 +1088,13 @@ func (a *ResourceApiApiService) ListDemos(ctx context.Context) ApiListDemosReque // Execute executes the request // -// @return ListDemos200Response -func (a *ResourceApiApiService) ListDemosExecute(r ApiListDemosRequest) (*ListDemos200Response, *http.Response, error) { +// @return DemoList +func (a *ResourceApiApiService) ListDemosExecute(r ApiListDemosRequest) (*DemoList, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} formFiles []formFile - localVarReturnValue *ListDemos200Response + localVarReturnValue *DemoList ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ResourceApiApiService.ListDemos") @@ -1207,7 +1207,7 @@ func (r ApiListEnvironmentsRequest) SortDirection(sortDirection string) ApiListE return r } -func (r ApiListEnvironmentsRequest) Execute() (*ListEnvironments200Response, *http.Response, error) { +func (r ApiListEnvironmentsRequest) Execute() (*EnvironmentResourceList, *http.Response, error) { return r.ApiService.ListEnvironmentsExecute(r) } @@ -1228,13 +1228,13 @@ func (a *ResourceApiApiService) ListEnvironments(ctx context.Context) ApiListEnv // Execute executes the request // -// @return ListEnvironments200Response -func (a *ResourceApiApiService) ListEnvironmentsExecute(r ApiListEnvironmentsRequest) (*ListEnvironments200Response, *http.Response, error) { +// @return EnvironmentResourceList +func (a *ResourceApiApiService) ListEnvironmentsExecute(r ApiListEnvironmentsRequest) (*EnvironmentResourceList, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} formFiles []formFile - localVarReturnValue *ListEnvironments200Response + localVarReturnValue *EnvironmentResourceList ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ResourceApiApiService.ListEnvironments") diff --git a/cli/openapi/model_demo_list.go b/cli/openapi/model_demo_list.go new file mode 100644 index 0000000000..8599c14b60 --- /dev/null +++ b/cli/openapi/model_demo_list.go @@ -0,0 +1,160 @@ +/* +TraceTest + +OpenAPI definition for TraceTest endpoint and resources + +API version: 0.2.1 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the DemoList type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &DemoList{} + +// DemoList struct for DemoList +type DemoList struct { + Count *int32 `json:"count,omitempty"` + Items []Demo `json:"items,omitempty"` +} + +// NewDemoList instantiates a new DemoList object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewDemoList() *DemoList { + this := DemoList{} + return &this +} + +// NewDemoListWithDefaults instantiates a new DemoList object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewDemoListWithDefaults() *DemoList { + this := DemoList{} + return &this +} + +// GetCount returns the Count field value if set, zero value otherwise. +func (o *DemoList) GetCount() int32 { + if o == nil || isNil(o.Count) { + var ret int32 + return ret + } + return *o.Count +} + +// GetCountOk returns a tuple with the Count field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DemoList) GetCountOk() (*int32, bool) { + if o == nil || isNil(o.Count) { + return nil, false + } + return o.Count, true +} + +// HasCount returns a boolean if a field has been set. +func (o *DemoList) HasCount() bool { + if o != nil && !isNil(o.Count) { + return true + } + + return false +} + +// SetCount gets a reference to the given int32 and assigns it to the Count field. +func (o *DemoList) SetCount(v int32) { + o.Count = &v +} + +// GetItems returns the Items field value if set, zero value otherwise. +func (o *DemoList) GetItems() []Demo { + if o == nil || isNil(o.Items) { + var ret []Demo + return ret + } + return o.Items +} + +// GetItemsOk returns a tuple with the Items field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DemoList) GetItemsOk() ([]Demo, bool) { + if o == nil || isNil(o.Items) { + return nil, false + } + return o.Items, true +} + +// HasItems returns a boolean if a field has been set. +func (o *DemoList) HasItems() bool { + if o != nil && !isNil(o.Items) { + return true + } + + return false +} + +// SetItems gets a reference to the given []Demo and assigns it to the Items field. +func (o *DemoList) SetItems(v []Demo) { + o.Items = v +} + +func (o DemoList) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o DemoList) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !isNil(o.Count) { + toSerialize["count"] = o.Count + } + if !isNil(o.Items) { + toSerialize["items"] = o.Items + } + return toSerialize, nil +} + +type NullableDemoList struct { + value *DemoList + isSet bool +} + +func (v NullableDemoList) Get() *DemoList { + return v.value +} + +func (v *NullableDemoList) Set(val *DemoList) { + v.value = val + v.isSet = true +} + +func (v NullableDemoList) IsSet() bool { + return v.isSet +} + +func (v *NullableDemoList) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableDemoList(val *DemoList) *NullableDemoList { + return &NullableDemoList{value: val, isSet: true} +} + +func (v NullableDemoList) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableDemoList) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/cli/openapi/model_environment_resource_list.go b/cli/openapi/model_environment_resource_list.go new file mode 100644 index 0000000000..e9d39ed5a1 --- /dev/null +++ b/cli/openapi/model_environment_resource_list.go @@ -0,0 +1,160 @@ +/* +TraceTest + +OpenAPI definition for TraceTest endpoint and resources + +API version: 0.2.1 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the EnvironmentResourceList type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &EnvironmentResourceList{} + +// EnvironmentResourceList struct for EnvironmentResourceList +type EnvironmentResourceList struct { + Count *int32 `json:"count,omitempty"` + Items []EnvironmentResource `json:"items,omitempty"` +} + +// NewEnvironmentResourceList instantiates a new EnvironmentResourceList object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewEnvironmentResourceList() *EnvironmentResourceList { + this := EnvironmentResourceList{} + return &this +} + +// NewEnvironmentResourceListWithDefaults instantiates a new EnvironmentResourceList object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewEnvironmentResourceListWithDefaults() *EnvironmentResourceList { + this := EnvironmentResourceList{} + return &this +} + +// GetCount returns the Count field value if set, zero value otherwise. +func (o *EnvironmentResourceList) GetCount() int32 { + if o == nil || isNil(o.Count) { + var ret int32 + return ret + } + return *o.Count +} + +// GetCountOk returns a tuple with the Count field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *EnvironmentResourceList) GetCountOk() (*int32, bool) { + if o == nil || isNil(o.Count) { + return nil, false + } + return o.Count, true +} + +// HasCount returns a boolean if a field has been set. +func (o *EnvironmentResourceList) HasCount() bool { + if o != nil && !isNil(o.Count) { + return true + } + + return false +} + +// SetCount gets a reference to the given int32 and assigns it to the Count field. +func (o *EnvironmentResourceList) SetCount(v int32) { + o.Count = &v +} + +// GetItems returns the Items field value if set, zero value otherwise. +func (o *EnvironmentResourceList) GetItems() []EnvironmentResource { + if o == nil || isNil(o.Items) { + var ret []EnvironmentResource + return ret + } + return o.Items +} + +// GetItemsOk returns a tuple with the Items field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *EnvironmentResourceList) GetItemsOk() ([]EnvironmentResource, bool) { + if o == nil || isNil(o.Items) { + return nil, false + } + return o.Items, true +} + +// HasItems returns a boolean if a field has been set. +func (o *EnvironmentResourceList) HasItems() bool { + if o != nil && !isNil(o.Items) { + return true + } + + return false +} + +// SetItems gets a reference to the given []EnvironmentResource and assigns it to the Items field. +func (o *EnvironmentResourceList) SetItems(v []EnvironmentResource) { + o.Items = v +} + +func (o EnvironmentResourceList) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o EnvironmentResourceList) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !isNil(o.Count) { + toSerialize["count"] = o.Count + } + if !isNil(o.Items) { + toSerialize["items"] = o.Items + } + return toSerialize, nil +} + +type NullableEnvironmentResourceList struct { + value *EnvironmentResourceList + isSet bool +} + +func (v NullableEnvironmentResourceList) Get() *EnvironmentResourceList { + return v.value +} + +func (v *NullableEnvironmentResourceList) Set(val *EnvironmentResourceList) { + v.value = val + v.isSet = true +} + +func (v NullableEnvironmentResourceList) IsSet() bool { + return v.isSet +} + +func (v *NullableEnvironmentResourceList) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableEnvironmentResourceList(val *EnvironmentResourceList) *NullableEnvironmentResourceList { + return &NullableEnvironmentResourceList{value: val, isSet: true} +} + +func (v NullableEnvironmentResourceList) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableEnvironmentResourceList) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/cli/utils/common.go b/cli/utils/common.go index 30c50952d7..c606cded2e 100644 --- a/cli/utils/common.go +++ b/cli/utils/common.go @@ -5,6 +5,7 @@ import ( "os" "path/filepath" "strings" + "unicode" ) func StringToIOReader(s string) io.Reader { @@ -34,3 +35,9 @@ func StringReferencesFile(path string) bool { // otherwise the user also could send a directory by mistake return info != nil && !info.IsDir() } + +func Capitalize(str string) string { + runes := []rune(str) + runes[0] = unicode.ToUpper(runes[0]) + return string(runes) +} diff --git a/server/openapi/api_resource_api_service.go b/server/openapi/api_resource_api_service.go index 1cb15e86be..d046249edc 100644 --- a/server/openapi/api_resource_api_service.go +++ b/server/openapi/api_resource_api_service.go @@ -192,8 +192,8 @@ func (s *ResourceApiApiService) ListDemos(ctx context.Context, take int32, skip // TODO - update ListDemos with the required logic for this service method. // Add api_resource_api_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - //TODO: Uncomment the next line to return response Response(200, ListDemos200Response{}) or use other options such as http.Ok ... - //return Response(200, ListDemos200Response{}), nil + //TODO: Uncomment the next line to return response Response(200, DemoList{}) or use other options such as http.Ok ... + //return Response(200, DemoList{}), nil //TODO: Uncomment the next line to return response Response(400, {}) or use other options such as http.Ok ... //return Response(400, nil),nil @@ -209,8 +209,8 @@ func (s *ResourceApiApiService) ListEnvironments(ctx context.Context, take int32 // TODO - update ListEnvironments with the required logic for this service method. // Add api_resource_api_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - //TODO: Uncomment the next line to return response Response(200, ListEnvironments200Response{}) or use other options such as http.Ok ... - //return Response(200, ListEnvironments200Response{}), nil + //TODO: Uncomment the next line to return response Response(200, EnvironmentResourceList{}) or use other options such as http.Ok ... + //return Response(200, EnvironmentResourceList{}), nil //TODO: Uncomment the next line to return response Response(400, {}) or use other options such as http.Ok ... //return Response(400, nil),nil diff --git a/server/openapi/model_demo_list.go b/server/openapi/model_demo_list.go new file mode 100644 index 0000000000..74c47f6e00 --- /dev/null +++ b/server/openapi/model_demo_list.go @@ -0,0 +1,38 @@ +/* + * TraceTest + * + * OpenAPI definition for TraceTest endpoint and resources + * + * API version: 0.2.1 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +type DemoList struct { + Count int32 `json:"count,omitempty"` + + Items []Demo `json:"items,omitempty"` +} + +// AssertDemoListRequired checks if the required fields are not zero-ed +func AssertDemoListRequired(obj DemoList) error { + for _, el := range obj.Items { + if err := AssertDemoRequired(el); err != nil { + return err + } + } + return nil +} + +// AssertRecurseDemoListRequired recursively checks if required fields are not zero-ed in a nested slice. +// Accepts only nested slice of DemoList (e.g. [][]DemoList), otherwise ErrTypeAssertionError is thrown. +func AssertRecurseDemoListRequired(objSlice interface{}) error { + return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error { + aDemoList, ok := obj.(DemoList) + if !ok { + return ErrTypeAssertionError + } + return AssertDemoListRequired(aDemoList) + }) +} diff --git a/server/openapi/model_environment_resource_list.go b/server/openapi/model_environment_resource_list.go new file mode 100644 index 0000000000..23b5d812a1 --- /dev/null +++ b/server/openapi/model_environment_resource_list.go @@ -0,0 +1,38 @@ +/* + * TraceTest + * + * OpenAPI definition for TraceTest endpoint and resources + * + * API version: 0.2.1 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +type EnvironmentResourceList struct { + Count int32 `json:"count,omitempty"` + + Items []EnvironmentResource `json:"items,omitempty"` +} + +// AssertEnvironmentResourceListRequired checks if the required fields are not zero-ed +func AssertEnvironmentResourceListRequired(obj EnvironmentResourceList) error { + for _, el := range obj.Items { + if err := AssertEnvironmentResourceRequired(el); err != nil { + return err + } + } + return nil +} + +// AssertRecurseEnvironmentResourceListRequired recursively checks if required fields are not zero-ed in a nested slice. +// Accepts only nested slice of EnvironmentResourceList (e.g. [][]EnvironmentResourceList), otherwise ErrTypeAssertionError is thrown. +func AssertRecurseEnvironmentResourceListRequired(objSlice interface{}) error { + return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error { + aEnvironmentResourceList, ok := obj.(EnvironmentResourceList) + if !ok { + return ErrTypeAssertionError + } + return AssertEnvironmentResourceListRequired(aEnvironmentResourceList) + }) +} diff --git a/web/src/types/Generated.types.ts b/web/src/types/Generated.types.ts index 8a5aa91668..e263e352f3 100644 --- a/web/src/types/Generated.types.ts +++ b/web/src/types/Generated.types.ts @@ -781,10 +781,7 @@ export interface operations { /** successful operation */ 200: { content: { - "application/json": { - count?: number; - items?: external["config.yaml"]["components"]["schemas"]["Demo"][]; - }; + "application/json": external["config.yaml"]["components"]["schemas"]["DemoList"]; "text/yaml": { count?: number; items?: external["config.yaml"]["components"]["schemas"]["Demo"][]; @@ -921,10 +918,7 @@ export interface operations { /** successful operation */ 200: { content: { - "application/json": { - count?: number; - items?: external["environments.yaml"]["components"]["schemas"]["EnvironmentResource"][]; - }; + "application/json": external["environments.yaml"]["components"]["schemas"]["EnvironmentResourceList"]; "text/yaml": { count?: number; items?: external["environments.yaml"]["components"]["schemas"]["EnvironmentResource"][]; @@ -1130,6 +1124,10 @@ export interface external { opentelemetryStore?: external["config.yaml"]["components"]["schemas"]["DemoOpenTelemetryStore"]; }; }; + DemoList: { + count?: number; + items?: external["config.yaml"]["components"]["schemas"]["Demo"][]; + }; }; }; operations: {}; @@ -1274,6 +1272,10 @@ export interface external { paths: {}; components: { schemas: { + EnvironmentResourceList: { + count?: number; + items?: external["environments.yaml"]["components"]["schemas"]["EnvironmentResource"][]; + }; /** @description Represents an environment structured into the Resources format. */ EnvironmentResource: { /**