Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apicurio CLI #859

Merged
merged 15 commits into from
Aug 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,21 @@
"args": [
"version"
]
}
},
{
"name": "Artifact Delete",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/cmd/rhoas",
"env": {},
"args": [
"service-registry",
"artifact",
"delete",
"--group=tgdsfgdfg",
"--yes"
]
},
]
}
14 changes: 8 additions & 6 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@ import (
"github.com/redhat-developer/app-services-cli/pkg/api/ams/amsclient"
kafkainstanceclient "github.com/redhat-developer/app-services-sdk-go/kafkainstance/apiv1internal/client"
kafkamgmtclient "github.com/redhat-developer/app-services-sdk-go/kafkamgmt/apiv1/client"
srsmgmtclient "github.com/redhat-developer/app-services-sdk-go/registrymgmt/apiv1/client"
registryinstanceclient "github.com/redhat-developer/app-services-sdk-go/registryinstance/apiv1internal/client"
registrymgmtclient "github.com/redhat-developer/app-services-sdk-go/registrymgmt/apiv1/client"
)

// API is a type which defines a number of API creator functions
type API struct {
Kafka func() kafkamgmtclient.DefaultApi
ServiceAccount func() kafkamgmtclient.SecurityApi
KafkaAdmin func(kafkaID string) (*kafkainstanceclient.APIClient, *kafkamgmtclient.KafkaRequest, error)
AccountMgmt func() amsclient.DefaultApi
Kafka func() kafkamgmtclient.DefaultApi
ServiceAccount func() kafkamgmtclient.SecurityApi
KafkaAdmin func(kafkaID string) (*kafkainstanceclient.APIClient, *kafkamgmtclient.KafkaRequest, error)
ServiceRegistryInstance func(registryID string) (*registryinstanceclient.APIClient, *registrymgmtclient.RegistryRest, error)
AccountMgmt func() amsclient.DefaultApi

ServiceRegistryMgmt func() srsmgmtclient.RegistriesApi
ServiceRegistryMgmt func() registrymgmtclient.RegistriesApi
}
70 changes: 70 additions & 0 deletions pkg/cmd/registry/artifact/artifacts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package artifact

import (
"github.com/redhat-developer/app-services-cli/pkg/cmd/factory"
"github.com/redhat-developer/app-services-cli/pkg/cmd/registry/artifact/crud/create"
"github.com/redhat-developer/app-services-cli/pkg/cmd/registry/artifact/crud/delete"
"github.com/redhat-developer/app-services-cli/pkg/cmd/registry/artifact/crud/get"
"github.com/redhat-developer/app-services-cli/pkg/cmd/registry/artifact/crud/list"
"github.com/redhat-developer/app-services-cli/pkg/cmd/registry/artifact/crud/update"
"github.com/redhat-developer/app-services-cli/pkg/cmd/registry/artifact/download"
"github.com/redhat-developer/app-services-cli/pkg/cmd/registry/artifact/metadata"
"github.com/redhat-developer/app-services-cli/pkg/cmd/registry/artifact/versions"
"github.com/spf13/cobra"
)

func NewArtifactsCommand(f *factory.Factory) *cobra.Command {
cmd := &cobra.Command{
Use: "artifact",
Short: "Manage Service Registry Artifacts",
Long: `
Apicurio Registry Artifacts enables developers to manage and share the structure of their data.
For example, client applications can dynamically push or pull the latest updates to or from the registry without needing to redeploy.
Apicurio Registry also enables developers to create rules that govern how registry content can evolve over time.
For example, this includes rules for content validation and version compatibility.

Registry commands enable client applications to manage the artifacts in the registry.
This set of commands provide create, read, update, and delete operations for schema and API artifacts, rules, versions, and metadata.
`,
Example: `
## Create artifact in my-group from schema.json file
rhoas service-registry artifact create --artifact-id=my-artifact --group=my-group artifact.json

## Get artifact content
rhoas service-registry artifact get --artifact-id=my-artifact --group=my-group file.json

## Delete artifact
rhoas service-registry artifact delete --artifact-id=my-artifact

## Get artifact metadata
rhoas service-registry artifact metadata --artifact-id=my-artifact --group=my-group

## Update artifact
rhoas service-registry artifact update --artifact-id=my-artifact artifact-new.json

## List Artifacts
rhoas service-registry artifact list --group=my-group --limit=10 page=1

## View artifact versions
rhoas service-registry artifact versions --artifact-id=my-artifact --group=my-group
`,
Args: cobra.MinimumNArgs(1),
}

// add sub-commands
cmd.AddCommand(
// CRUD
create.NewCreateCommand(f),
get.NewGetCommand(f),
delete.NewDeleteCommand(f),
list.NewListCommand(f),
update.NewUpdateCommand(f),

// Misc
metadata.NewMetadataCommand(f),
versions.NewVersionsCommand(f),
download.NewDownloadCommand(f),
)

return cmd
}
200 changes: 200 additions & 0 deletions pkg/cmd/registry/artifact/crud/create/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
package create

import (
"context"
"errors"
"fmt"
"os"

"github.com/redhat-developer/app-services-cli/pkg/connection"
"github.com/redhat-developer/app-services-cli/pkg/dump"
"github.com/redhat-developer/app-services-cli/pkg/localize"
"github.com/redhat-developer/app-services-cli/pkg/serviceregistry/registryinstanceerror"
registryinstanceclient "github.com/redhat-developer/app-services-sdk-go/registryinstance/apiv1internal/client"

"github.com/redhat-developer/app-services-cli/pkg/cmd/flag"
"github.com/redhat-developer/app-services-cli/pkg/cmd/registry/artifact/util"
flagutil "github.com/redhat-developer/app-services-cli/pkg/cmdutil/flags"

"github.com/redhat-developer/app-services-cli/pkg/iostreams"

"github.com/redhat-developer/app-services-cli/pkg/logging"

"github.com/spf13/cobra"

"github.com/redhat-developer/app-services-cli/internal/config"
"github.com/redhat-developer/app-services-cli/pkg/cmd/factory"
)

type Options struct {
artifact string
group string

file string
artifactType string

registryID string
outputFormat string

IO *iostreams.IOStreams
Config config.IConfig
Connection factory.ConnectionFunc
Logger func() (logging.Logger, error)
localizer localize.Localizer
}

var longDescription = `
Creates a new artifact by posting the artifact content to the registry.

Artifacts can be typically in JSON format for most of the supported types, but may be in another format for a few (for example, PROTOBUF).
The registry attempts to figure out what kind of artifact is being added from the following supported list:

- Avro (AVRO)
- Protobuf (PROTOBUF)
- JSON Schema (JSON)
- Kafka Connect (KCONNECT)
- OpenAPI (OPENAPI)
- AsyncAPI (ASYNCAPI)
- GraphQL (GRAPHQL)
- Web Services Description Language (WSDL)
- XML Schema (XSD)

An artifact is created using the content provided in the body of the request.
This content is created under a unique artifact ID that can be provided by user.
If not provided in the request, the server generates a unique ID for the artifact.
It is typically recommended that callers provide the ID, because this is a meaningful identifier, and for most use cases should be supplied by the caller.
If an artifact with the provided artifact ID already exists command will fail with error.


When --group parameter is missing the command will create a new artifact under the "default" group.
when --registry is missing the command will create a new artifact for currently active service registry (visible in rhoas service-registry describe)
`

func NewCreateCommand(f *factory.Factory) *cobra.Command {
opts := &Options{
IO: f.IOStreams,
Config: f.Config,
Connection: f.Connection,
Logger: f.Logger,
localizer: f.Localizer,
}

cmd := &cobra.Command{
Use: "create",
Short: "Creates new artifact from file or standard input",
Long: longDescription,
Example: `
# Create an artifact in default group
rhoas service-registry artifact create my-artifact.json

# Create an artifact with specified type
rhoas service-registry artifact create --type=JSON my-artifact.json
`,
Args: cobra.RangeArgs(0, 1),
RunE: func(cmd *cobra.Command, args []string) error {
validOutputFormats := flagutil.ValidOutputFormats
if opts.outputFormat != "" && !flagutil.IsValidInput(opts.outputFormat, validOutputFormats...) {
return flag.InvalidValueError("output", opts.outputFormat, validOutputFormats...)
}

if len(args) > 0 {
opts.file = args[0]
}

if opts.registryID != "" {
return runCreate(opts)
}

cfg, err := opts.Config.Load()
if err != nil {
return err
}

if opts.artifactType != "" {
if _, err = registryinstanceclient.NewArtifactTypeFromValue(opts.artifactType); err != nil {
return errors.New("invalid artifact type. Please use one of following values: " + util.GetAllowedArtifactTypeEnumValuesAsString())
}
}

if !cfg.HasServiceRegistry() {
return errors.New("no service Registry selected. Use 'rhoas service-registry use' use to select your registry")
}

opts.registryID = fmt.Sprint(cfg.Services.ServiceRegistry.InstanceID)
wtrocki marked this conversation as resolved.
Show resolved Hide resolved
return runCreate(opts)
},
}

cmd.Flags().StringVarP(&opts.outputFormat, "output", "o", "json", opts.localizer.MustLocalize("registry.cmd.flag.output.description"))
cmd.Flags().StringVarP(&opts.file, "file", "f", "", "File location of the artifact")

cmd.Flags().StringVarP(&opts.artifact, "artifact-id", "a", "", "Id of the artifact")
cmd.Flags().StringVarP(&opts.group, "group", "g", util.DefaultArtifactGroup, "Group of the artifact")
cmd.Flags().StringVarP(&opts.artifactType, "type", "t", "", "Type of artifact. Choose from: "+util.GetAllowedArtifactTypeEnumValuesAsString())
cmd.Flags().StringVarP(&opts.registryID, "instance-id", "", "", "Id of the registry to be used. By default uses currently selected registry")

flagutil.EnableOutputFlagCompletion(cmd)
_ = cmd.RegisterFlagCompletionFunc("type", func(cmd *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
return util.AllowedArtifactTypeEnumValues, cobra.ShellCompDirectiveNoSpace
})

return cmd
}

func runCreate(opts *Options) error {

logger, err := opts.Logger()
if err != nil {
return err
}

conn, err := opts.Connection(connection.DefaultConfigRequireMasAuth)
if err != nil {
return err
}

dataAPI, _, err := conn.API().ServiceRegistryInstance(opts.registryID)
if err != nil {
return err
}

if opts.group == util.DefaultArtifactGroup {
logger.Info("Group was not specified. Using", util.DefaultArtifactGroup, "artifacts group.")
opts.group = util.DefaultArtifactGroup
}

var specifiedFile *os.File
if opts.file != "" {
logger.Info("Opening file: " + opts.file)
specifiedFile, err = os.Open(opts.file)
if err != nil {
return err
}
} else {
logger.Info("Reading file content from standard input")
specifiedFile, err = util.CreateFileFromStdin()
if err != nil {
return err
}
}

ctx := context.Background()
request := dataAPI.ArtifactsApi.CreateArtifact(ctx, opts.group)
if opts.artifactType != "" {
request = request.XRegistryArtifactType(registryinstanceclient.ArtifactType(opts.artifactType))
}
if opts.artifact != "" {
request = request.XRegistryArtifactId(opts.artifact)
}

request = request.Body(specifiedFile)
metadata, _, err := request.Execute()
if err != nil {
return registryinstanceerror.TransformError(err)
}
logger.Info("Artifact created")

dump.PrintDataInFormat(opts.outputFormat, metadata, opts.IO.Out)

return nil
}
1 change: 1 addition & 0 deletions pkg/cmd/registry/artifact/crud/crud.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package crud
Loading