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

Commit a57b19d

Browse files
committed
add set command to modify comp desc
1 parent 4ff44b4 commit a57b19d

11 files changed

Lines changed: 462 additions & 10 deletions

File tree

pkg/commands/componentarchive/componentarchive.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ import (
1919
pflag "github.com/spf13/pflag"
2020

2121
"github.com/gardener/component-cli/pkg/commands/componentarchive/componentreferences"
22+
"github.com/gardener/component-cli/pkg/commands/componentarchive/get"
2223
"github.com/gardener/component-cli/pkg/commands/componentarchive/remote"
2324
"github.com/gardener/component-cli/pkg/commands/componentarchive/resources"
25+
"github.com/gardener/component-cli/pkg/commands/componentarchive/set"
2426
"github.com/gardener/component-cli/pkg/commands/componentarchive/sources"
2527
ctfcmd "github.com/gardener/component-cli/pkg/commands/ctf"
2628
"github.com/gardener/component-cli/pkg/componentarchive"
@@ -74,6 +76,8 @@ func NewComponentArchiveCommand(ctx context.Context) *cobra.Command {
7476
cmd.AddCommand(resources.NewResourcesCommand(ctx))
7577
cmd.AddCommand(componentreferences.NewCompRefCommand(ctx))
7678
cmd.AddCommand(sources.NewSourcesCommand(ctx))
79+
cmd.AddCommand(set.NewSetCommand(ctx))
80+
cmd.AddCommand(get.NewGetCommand(ctx))
7781
return cmd
7882
}
7983

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

115120
// only copy essential files to the temp dir

pkg/commands/componentarchive/create.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package componentarchive
66

77
import (
88
"context"
9+
"errors"
910
"fmt"
1011
"os"
1112

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

7273
func (o *CreateOptions) validate() error {
74+
if o.Overwrite && len(o.Name) != 0 {
75+
if len(o.Version) == 0 {
76+
return errors.New("a version has to be provided for a minimal component descriptor")
77+
}
78+
}
7379
return o.BuilderOptions.Validate()
7480
}
7581

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// SPDX-FileCopyrightText: 2020 SAP SE or an SAP affiliate company and Gardener contributors.
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
package get
6+
7+
import (
8+
"context"
9+
"errors"
10+
"fmt"
11+
"os"
12+
13+
cdvalidation "github.com/gardener/component-spec/bindings-go/apis/v2/validation"
14+
"github.com/go-logr/logr"
15+
"github.com/mandelsoft/vfs/pkg/osfs"
16+
"github.com/mandelsoft/vfs/pkg/vfs"
17+
"github.com/spf13/cobra"
18+
"github.com/spf13/pflag"
19+
20+
"github.com/gardener/component-cli/pkg/componentarchive"
21+
"github.com/gardener/component-cli/pkg/logger"
22+
)
23+
24+
// Options defines the options that are used to add resources to a component descriptor
25+
type Options struct {
26+
componentarchive.BuilderOptions
27+
Property string
28+
}
29+
30+
// NewGetCommand creates a command to add additional resources to a component descriptor.
31+
func NewGetCommand(ctx context.Context) *cobra.Command {
32+
opts := &Options{}
33+
cmd := &cobra.Command{
34+
Use: "get COMPONENT_ARCHIVE_PATH [options...]",
35+
Args: cobra.MinimumNArgs(1),
36+
Short: "set some component descriptor properties",
37+
Long: `
38+
the set command sets some component descriptor properies like the component name and/or version.
39+
40+
The component archive can be specified by the first argument, the flag "--archive" or as env var "COMPONENT_ARCHIVE_PATH".
41+
The component archive is expected to be a filesystem archive.
42+
`,
43+
Run: func(cmd *cobra.Command, args []string) {
44+
if err := opts.Complete(args); err != nil {
45+
fmt.Println(err.Error())
46+
os.Exit(1)
47+
}
48+
49+
if err := opts.Run(ctx, logger.Log, osfs.New()); err != nil {
50+
fmt.Println(err.Error())
51+
os.Exit(1)
52+
}
53+
},
54+
}
55+
56+
opts.AddFlags(cmd.Flags())
57+
58+
return cmd
59+
}
60+
61+
func (o *Options) Run(ctx context.Context, log logr.Logger, fs vfs.FileSystem) error {
62+
result, err := o.Get(ctx, log, fs)
63+
if err != nil {
64+
return err
65+
}
66+
fmt.Println(result)
67+
return nil
68+
}
69+
70+
func (o *Options) Get(ctx context.Context, log logr.Logger, fs vfs.FileSystem) (string, error) {
71+
o.Modify = true
72+
archive, err := o.BuilderOptions.Build(fs)
73+
if err != nil {
74+
return "", err
75+
}
76+
77+
if err := cdvalidation.Validate(archive.ComponentDescriptor); err != nil {
78+
return "", fmt.Errorf("invalid component descriptor: %w", err)
79+
}
80+
81+
switch o.Property {
82+
case "name":
83+
return archive.ComponentDescriptor.Name, nil
84+
case "version":
85+
return archive.ComponentDescriptor.Version, nil
86+
}
87+
88+
return "", nil
89+
}
90+
91+
func (o *Options) Complete(args []string) error {
92+
93+
if len(args) == 0 {
94+
return errors.New("at least a component archive path argument has to be defined")
95+
}
96+
o.BuilderOptions.ComponentArchivePath = args[0]
97+
o.BuilderOptions.Default()
98+
99+
return o.validate()
100+
}
101+
102+
func (o *Options) validate() error {
103+
if len(o.Property) == 0 {
104+
return errors.New("a property must be specified")
105+
}
106+
return o.BuilderOptions.Validate()
107+
}
108+
109+
func (o *Options) AddFlags(fs *pflag.FlagSet) {
110+
fs.StringVar(&o.Property, "property", "", "name of the property (name or version)")
111+
112+
o.BuilderOptions.AddFlags(fs)
113+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// SPDX-FileCopyrightText: 2020 SAP SE or an SAP affiliate company and Gardener contributors.
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
package get_test
6+
7+
import (
8+
"context"
9+
"testing"
10+
11+
"github.com/go-logr/logr"
12+
"github.com/mandelsoft/vfs/pkg/layerfs"
13+
"github.com/mandelsoft/vfs/pkg/memoryfs"
14+
"github.com/mandelsoft/vfs/pkg/osfs"
15+
"github.com/mandelsoft/vfs/pkg/projectionfs"
16+
"github.com/mandelsoft/vfs/pkg/vfs"
17+
. "github.com/onsi/ginkgo"
18+
. "github.com/onsi/gomega"
19+
20+
"github.com/gardener/component-cli/pkg/commands/componentarchive/get"
21+
"github.com/gardener/component-cli/pkg/componentarchive"
22+
)
23+
24+
func TestConfig(t *testing.T) {
25+
RegisterFailHandler(Fail)
26+
RunSpecs(t, "Resources Test Suite")
27+
}
28+
29+
var _ = Describe("Set", func() {
30+
31+
var testdataFs vfs.FileSystem
32+
33+
BeforeEach(func() {
34+
fs, err := projectionfs.New(osfs.New(), "./testdata")
35+
Expect(err).ToNot(HaveOccurred())
36+
testdataFs = layerfs.New(memoryfs.New(), fs)
37+
})
38+
39+
It("should get name", func() {
40+
opts := &get.Options{
41+
BuilderOptions: componentarchive.BuilderOptions{
42+
ComponentArchivePath: "./00-component",
43+
},
44+
Property: "name",
45+
}
46+
47+
Expect(opts.Get(context.TODO(), logr.Discard(), testdataFs)).To(Equal("example.com/component"))
48+
})
49+
50+
It("should get version", func() {
51+
opts := &get.Options{
52+
BuilderOptions: componentarchive.BuilderOptions{
53+
ComponentArchivePath: "./00-component",
54+
},
55+
Property: "version",
56+
}
57+
58+
Expect(opts.Get(context.TODO(), logr.Discard(), testdataFs)).To(Equal("v0.0.0"))
59+
})
60+
})
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
component:
2+
componentReferences: []
3+
name: example.com/component
4+
provider: internal
5+
repositoryContexts:
6+
- baseUrl: eu.gcr.io/gardener-project/components/dev
7+
type: ociRegistry
8+
resources:
9+
- name: 'ubuntu'
10+
version: 'v0.0.1'
11+
type: 'ociImage'
12+
relation: 'external'
13+
access:
14+
type: 'ociRegistry'
15+
imageReference: 'ubuntu:18.0'
16+
sources: []
17+
version: v0.0.0
18+
meta:
19+
schemaVersion: v2

pkg/commands/componentarchive/remote/push.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ func (o *PushOptions) Run(ctx context.Context, log logr.Logger, fs vfs.FileSyste
8585
}
8686
// update repository context
8787
if len(o.BaseUrl) != 0 {
88+
log.Info(fmt.Sprintf("Update repository context in component descriptor %q", o.BaseUrl))
8889
if err := cdv2.InjectRepositoryContext(archive.ComponentDescriptor, cdv2.NewOCIRegistryRepository(o.BaseUrl, "")); err != nil {
8990
return fmt.Errorf("unable to add repository context to component descriptor: %w", err)
9091
}
@@ -95,7 +96,12 @@ func (o *PushOptions) Run(ctx context.Context, log logr.Logger, fs vfs.FileSyste
9596
return fmt.Errorf("unable to build oci artifact for component acrchive: %w", err)
9697
}
9798

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

107113
for _, tag := range o.AdditionalTags {
108-
ref, err := components.OCIRef(archive.ComponentDescriptor.GetEffectiveRepositoryContext(), archive.ComponentDescriptor.Name, tag)
114+
log.Info(fmt.Sprintf("Push for additional tag %q", tag))
115+
ref, err := components.OCIRef(rctx, archive.ComponentDescriptor.Name, tag)
109116
if err != nil {
110117
return fmt.Errorf("invalid component reference: %w", err)
111118
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// SPDX-FileCopyrightText: 2020 SAP SE or an SAP affiliate company and Gardener contributors.
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
package set
6+
7+
import (
8+
"context"
9+
"errors"
10+
"fmt"
11+
"os"
12+
"path/filepath"
13+
14+
cdvalidation "github.com/gardener/component-spec/bindings-go/apis/v2/validation"
15+
"github.com/gardener/component-spec/bindings-go/ctf"
16+
"github.com/go-logr/logr"
17+
"github.com/mandelsoft/vfs/pkg/osfs"
18+
"github.com/mandelsoft/vfs/pkg/vfs"
19+
"github.com/spf13/cobra"
20+
"github.com/spf13/pflag"
21+
"sigs.k8s.io/yaml"
22+
23+
"github.com/gardener/component-cli/pkg/componentarchive"
24+
"github.com/gardener/component-cli/pkg/logger"
25+
)
26+
27+
// Options defines the options that are used to add resources to a component descriptor
28+
type Options struct {
29+
componentarchive.BuilderOptions
30+
}
31+
32+
// NewSetCommand creates a command to add additional resources to a component descriptor.
33+
func NewSetCommand(ctx context.Context) *cobra.Command {
34+
opts := &Options{}
35+
cmd := &cobra.Command{
36+
Use: "set COMPONENT_ARCHIVE_PATH [options...]",
37+
Args: cobra.MinimumNArgs(1),
38+
Short: "set some component descriptor properties",
39+
Long: `
40+
the set command sets some component descriptor properies like the component name and/or version.
41+
42+
The component archive can be specified by the first argument, the flag "--archive" or as env var "COMPONENT_ARCHIVE_PATH".
43+
The component archive is expected to be a filesystem archive.
44+
`,
45+
Run: func(cmd *cobra.Command, args []string) {
46+
if err := opts.Complete(args); err != nil {
47+
fmt.Println(err.Error())
48+
os.Exit(1)
49+
}
50+
51+
if err := opts.Run(ctx, logger.Log, osfs.New()); err != nil {
52+
fmt.Println(err.Error())
53+
os.Exit(1)
54+
}
55+
},
56+
}
57+
58+
opts.AddFlags(cmd.Flags())
59+
60+
return cmd
61+
}
62+
63+
func (o *Options) Run(ctx context.Context, log logr.Logger, fs vfs.FileSystem) error {
64+
compDescFilePath := filepath.Join(o.ComponentArchivePath, ctf.ComponentDescriptorFileName)
65+
66+
o.Modify = true
67+
archive, err := o.BuilderOptions.Build(fs)
68+
if err != nil {
69+
return err
70+
}
71+
72+
if len(o.Name) != 0 {
73+
archive.ComponentDescriptor.Name = o.Name
74+
}
75+
if len(o.Version) != 0 {
76+
archive.ComponentDescriptor.Version = o.Version
77+
}
78+
79+
if err := cdvalidation.Validate(archive.ComponentDescriptor); err != nil {
80+
return fmt.Errorf("invalid component descriptor: %w", err)
81+
}
82+
83+
data, err := yaml.Marshal(archive.ComponentDescriptor)
84+
if err != nil {
85+
return fmt.Errorf("unable to encode component descriptor: %w", err)
86+
}
87+
if err := vfs.WriteFile(fs, compDescFilePath, data, 0664); err != nil {
88+
return fmt.Errorf("unable to write modified comonent descriptor: %w", err)
89+
}
90+
log.V(2).Info("Successfully changed component descriptor")
91+
return nil
92+
}
93+
94+
func (o *Options) Complete(args []string) error {
95+
if len(args) == 0 {
96+
return errors.New("at least a component archive path argument has to be defined")
97+
}
98+
o.BuilderOptions.ComponentArchivePath = args[0]
99+
o.BuilderOptions.Default()
100+
101+
return o.validate()
102+
}
103+
104+
func (o *Options) validate() error {
105+
return o.BuilderOptions.Validate()
106+
}
107+
108+
func (o *Options) AddFlags(fs *pflag.FlagSet) {
109+
o.BuilderOptions.AddFlags(fs)
110+
}

0 commit comments

Comments
 (0)