Skip to content
This repository has been archived by the owner on May 26, 2023. It is now read-only.

Commit

Permalink
add set command to modify comp desc
Browse files Browse the repository at this point in the history
  • Loading branch information
mandelsoft committed Jan 10, 2022
1 parent 4ff44b4 commit 41bb384
Show file tree
Hide file tree
Showing 11 changed files with 461 additions and 10 deletions.
5 changes: 5 additions & 0 deletions pkg/commands/componentarchive/componentarchive.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ import (
pflag "github.com/spf13/pflag"

"github.com/gardener/component-cli/pkg/commands/componentarchive/componentreferences"
"github.com/gardener/component-cli/pkg/commands/componentarchive/get"
"github.com/gardener/component-cli/pkg/commands/componentarchive/remote"
"github.com/gardener/component-cli/pkg/commands/componentarchive/resources"
"github.com/gardener/component-cli/pkg/commands/componentarchive/set"
"github.com/gardener/component-cli/pkg/commands/componentarchive/sources"
ctfcmd "github.com/gardener/component-cli/pkg/commands/ctf"
"github.com/gardener/component-cli/pkg/componentarchive"
Expand Down Expand Up @@ -74,6 +76,8 @@ func NewComponentArchiveCommand(ctx context.Context) *cobra.Command {
cmd.AddCommand(resources.NewResourcesCommand(ctx))
cmd.AddCommand(componentreferences.NewCompRefCommand(ctx))
cmd.AddCommand(sources.NewSourcesCommand(ctx))
cmd.AddCommand(set.NewSetCommand(ctx))
cmd.AddCommand(get.NewGetCommand(ctx))
return cmd
}

Expand Down Expand Up @@ -110,6 +114,7 @@ func (o *ComponentArchiveOptions) Run(ctx context.Context, log logr.Logger, fs v
return fmt.Errorf("unable to add component archive to ctf: %w", err)
}
log.Info("Successfully added ctf\n")
return nil
}

// only copy essential files to the temp dir
Expand Down
6 changes: 6 additions & 0 deletions pkg/commands/componentarchive/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package componentarchive

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

Expand Down Expand Up @@ -70,6 +71,11 @@ func (o *CreateOptions) Complete(args []string) error {
}

func (o *CreateOptions) validate() error {
if o.Overwrite && len(o.Name) != 0 {
if len(o.Version) == 0 {
return errors.New("a version has to be provided for a minimal component descriptor")
}
}
return o.BuilderOptions.Validate()
}

Expand Down
113 changes: 113 additions & 0 deletions pkg/commands/componentarchive/get/get.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// SPDX-FileCopyrightText: 2020 SAP SE or an SAP affiliate company and Gardener contributors.
//
// SPDX-License-Identifier: Apache-2.0

package get

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

cdvalidation "github.com/gardener/component-spec/bindings-go/apis/v2/validation"
"github.com/go-logr/logr"
"github.com/mandelsoft/vfs/pkg/osfs"
"github.com/mandelsoft/vfs/pkg/vfs"
"github.com/spf13/cobra"
"github.com/spf13/pflag"

"github.com/gardener/component-cli/pkg/componentarchive"
"github.com/gardener/component-cli/pkg/logger"
)

// Options defines the options that are used to add resources to a component descriptor
type Options struct {
componentarchive.BuilderOptions
Property string
}

// NewGetCommand creates a command to add additional resources to a component descriptor.
func NewGetCommand(ctx context.Context) *cobra.Command {
opts := &Options{}
cmd := &cobra.Command{
Use: "get COMPONENT_ARCHIVE_PATH [options...]",
Args: cobra.MinimumNArgs(1),
Short: "set some component descriptor properties",
Long: `
the set command sets some component descriptor properies like the component name and/or version.
The component archive can be specified by the first argument, the flag "--archive" or as env var "COMPONENT_ARCHIVE_PATH".
The component archive is expected to be a filesystem archive.
`,
Run: func(cmd *cobra.Command, args []string) {
if err := opts.Complete(args); err != nil {
fmt.Println(err.Error())
os.Exit(1)
}

if err := opts.Run(ctx, logger.Log, osfs.New()); err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
},
}

opts.AddFlags(cmd.Flags())

return cmd
}

func (o *Options) Run(ctx context.Context, log logr.Logger, fs vfs.FileSystem) error {
result, err := o.Get(ctx, log, fs)
if err != nil {
return err
}
fmt.Println(result)
return nil
}

func (o *Options) Get(ctx context.Context, log logr.Logger, fs vfs.FileSystem) (string, error) {
o.Modify = true
archive, err := o.BuilderOptions.Build(fs)
if err != nil {
return "", err
}

if err := cdvalidation.Validate(archive.ComponentDescriptor); err != nil {
return "", fmt.Errorf("invalid component descriptor: %w", err)
}

switch o.Property {
case "name":
return archive.ComponentDescriptor.Name, nil
case "version":
return archive.ComponentDescriptor.Version, nil
}

return "", nil
}

func (o *Options) Complete(args []string) error {

if len(args) == 0 {
return errors.New("at least a component archive path argument has to be defined")
}
o.BuilderOptions.ComponentArchivePath = args[0]
o.BuilderOptions.Default()

return o.validate()
}

func (o *Options) validate() error {
if len(o.Property) == 0 {
return errors.New("a property must be specified")
}
return o.BuilderOptions.Validate()
}

func (o *Options) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&o.Property, "property", "", "name of the property (name or version)")

o.BuilderOptions.AddFlags(fs)
}
59 changes: 59 additions & 0 deletions pkg/commands/componentarchive/get/get_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// SPDX-FileCopyrightText: 2020 SAP SE or an SAP affiliate company and Gardener contributors.
//
// SPDX-License-Identifier: Apache-2.0

package get_test

import (
"context"
"testing"

"github.com/gardener/component-cli/pkg/commands/componentarchive/get"
"github.com/gardener/component-cli/pkg/componentarchive"
"github.com/go-logr/logr"
"github.com/mandelsoft/vfs/pkg/layerfs"
"github.com/mandelsoft/vfs/pkg/memoryfs"
"github.com/mandelsoft/vfs/pkg/osfs"
"github.com/mandelsoft/vfs/pkg/projectionfs"
"github.com/mandelsoft/vfs/pkg/vfs"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

func TestConfig(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Resources Test Suite")
}

var _ = Describe("Set", func() {

var testdataFs vfs.FileSystem

BeforeEach(func() {
fs, err := projectionfs.New(osfs.New(), "./testdata")
Expect(err).ToNot(HaveOccurred())
testdataFs = layerfs.New(memoryfs.New(), fs)
})

It("should get name", func() {
opts := &get.Options{
BuilderOptions: componentarchive.BuilderOptions{
ComponentArchivePath: "./00-component",
},
Property: "name",
}

Expect(opts.Get(context.TODO(), logr.Discard(), testdataFs)).To(Equal("example.com/component"))
})

It("should get version", func() {
opts := &get.Options{
BuilderOptions: componentarchive.BuilderOptions{
ComponentArchivePath: "./00-component",
},
Property: "version",
}

Expect(opts.Get(context.TODO(), logr.Discard(), testdataFs)).To(Equal("v0.0.0"))
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
component:
componentReferences: []
name: example.com/component
provider: internal
repositoryContexts:
- baseUrl: eu.gcr.io/gardener-project/components/dev
type: ociRegistry
resources:
- name: 'ubuntu'
version: 'v0.0.1'
type: 'ociImage'
relation: 'external'
access:
type: 'ociRegistry'
imageReference: 'ubuntu:18.0'
sources: []
version: v0.0.0
meta:
schemaVersion: v2
11 changes: 9 additions & 2 deletions pkg/commands/componentarchive/remote/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ func (o *PushOptions) Run(ctx context.Context, log logr.Logger, fs vfs.FileSyste
}
// update repository context
if len(o.BaseUrl) != 0 {
log.Info(fmt.Sprintf("Update repository context in component descriptor %q", o.BaseUrl))
if err := cdv2.InjectRepositoryContext(archive.ComponentDescriptor, cdv2.NewOCIRegistryRepository(o.BaseUrl, "")); err != nil {
return fmt.Errorf("unable to add repository context to component descriptor: %w", err)
}
Expand All @@ -95,7 +96,12 @@ func (o *PushOptions) Run(ctx context.Context, log logr.Logger, fs vfs.FileSyste
return fmt.Errorf("unable to build oci artifact for component acrchive: %w", err)
}

ref, err := components.OCIRef(archive.ComponentDescriptor.GetEffectiveRepositoryContext(), archive.ComponentDescriptor.Name, archive.ComponentDescriptor.Version)
rctx := archive.ComponentDescriptor.GetEffectiveRepositoryContext()
if rctx == nil {
return fmt.Errorf("no repository context given")
}
// attention nil struct pointer passed to interface parameter (non-nil value)
ref, err := components.OCIRef(rctx, archive.ComponentDescriptor.Name, archive.ComponentDescriptor.Version)
if err != nil {
return fmt.Errorf("invalid component reference: %w", err)
}
Expand All @@ -105,7 +111,8 @@ func (o *PushOptions) Run(ctx context.Context, log logr.Logger, fs vfs.FileSyste
log.Info(fmt.Sprintf("Successfully uploaded component descriptor at %q", ref))

for _, tag := range o.AdditionalTags {
ref, err := components.OCIRef(archive.ComponentDescriptor.GetEffectiveRepositoryContext(), archive.ComponentDescriptor.Name, tag)
log.Info(fmt.Sprintf("Push for additional tag %q", tag))
ref, err := components.OCIRef(rctx, archive.ComponentDescriptor.Name, tag)
if err != nil {
return fmt.Errorf("invalid component reference: %w", err)
}
Expand Down
110 changes: 110 additions & 0 deletions pkg/commands/componentarchive/set/set.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// SPDX-FileCopyrightText: 2020 SAP SE or an SAP affiliate company and Gardener contributors.
//
// SPDX-License-Identifier: Apache-2.0

package set

import (
"context"
"errors"
"fmt"
"os"
"path/filepath"

cdvalidation "github.com/gardener/component-spec/bindings-go/apis/v2/validation"
"github.com/gardener/component-spec/bindings-go/ctf"
"github.com/go-logr/logr"
"github.com/mandelsoft/vfs/pkg/osfs"
"github.com/mandelsoft/vfs/pkg/vfs"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"sigs.k8s.io/yaml"

"github.com/gardener/component-cli/pkg/componentarchive"
"github.com/gardener/component-cli/pkg/logger"
)

// Options defines the options that are used to add resources to a component descriptor
type Options struct {
componentarchive.BuilderOptions
}

// NewSetCommand creates a command to add additional resources to a component descriptor.
func NewSetCommand(ctx context.Context) *cobra.Command {
opts := &Options{}
cmd := &cobra.Command{
Use: "set COMPONENT_ARCHIVE_PATH [options...]",
Args: cobra.MinimumNArgs(1),
Short: "set some component descriptor properties",
Long: `
the set command sets some component descriptor properies like the component name and/or version.
The component archive can be specified by the first argument, the flag "--archive" or as env var "COMPONENT_ARCHIVE_PATH".
The component archive is expected to be a filesystem archive.
`,
Run: func(cmd *cobra.Command, args []string) {
if err := opts.Complete(args); err != nil {
fmt.Println(err.Error())
os.Exit(1)
}

if err := opts.Run(ctx, logger.Log, osfs.New()); err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
},
}

opts.AddFlags(cmd.Flags())

return cmd
}

func (o *Options) Run(ctx context.Context, log logr.Logger, fs vfs.FileSystem) error {
compDescFilePath := filepath.Join(o.ComponentArchivePath, ctf.ComponentDescriptorFileName)

o.Modify = true
archive, err := o.BuilderOptions.Build(fs)
if err != nil {
return err
}

if len(o.Name) != 0 {
archive.ComponentDescriptor.Name = o.Name
}
if len(o.Version) != 0 {
archive.ComponentDescriptor.Version = o.Version
}

if err := cdvalidation.Validate(archive.ComponentDescriptor); err != nil {
return fmt.Errorf("invalid component descriptor: %w", err)
}

data, err := yaml.Marshal(archive.ComponentDescriptor)
if err != nil {
return fmt.Errorf("unable to encode component descriptor: %w", err)
}
if err := vfs.WriteFile(fs, compDescFilePath, data, 0664); err != nil {
return fmt.Errorf("unable to write modified comonent descriptor: %w", err)
}
log.V(2).Info("Successfully changed component descriptor")
return nil
}

func (o *Options) Complete(args []string) error {
if len(args) == 0 {
return errors.New("at least a component archive path argument has to be defined")
}
o.BuilderOptions.ComponentArchivePath = args[0]
o.BuilderOptions.Default()

return o.validate()
}

func (o *Options) validate() error {
return o.BuilderOptions.Validate()
}

func (o *Options) AddFlags(fs *pflag.FlagSet) {
o.BuilderOptions.AddFlags(fs)
}
Loading

0 comments on commit 41bb384

Please sign in to comment.