Skip to content

Commit 10868bd

Browse files
authored
feat: enable STDIN apply and destroy using RG inventory (#2709)
This commit enables actuation from STDIN using inventory information that is stored in a ResourceGroup file. This feature is currently behind a feature gate and will be exposed to users as a CLI flag in a future commit/PR.
1 parent 5169954 commit 10868bd

File tree

11 files changed

+401
-49
lines changed

11 files changed

+401
-49
lines changed

internal/cmdapply/cmdapply.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ type Runner struct {
108108
pruneTimeout time.Duration
109109
inventoryPolicyString string
110110
dryRun bool
111+
rgFile string
111112
printStatusEvents bool
112113

113114
inventoryPolicy inventory.InventoryPolicy
@@ -166,7 +167,7 @@ func (r *Runner) runE(c *cobra.Command, args []string) error {
166167
}
167168
}
168169

169-
objs, inv, err := live.Load(r.factory, path, c.InOrStdin())
170+
objs, inv, err := live.Load(r.factory, path, r.rgFile, c.InOrStdin())
170171
if err != nil {
171172
return err
172173
}

internal/cmddestroy/cmddestroy.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ type Runner struct {
8383
output string
8484
inventoryPolicyString string
8585
dryRun bool
86+
rgFile string
8687
printStatusEvents bool
8788

8889
inventoryPolicy inventory.InventoryPolicy
@@ -128,7 +129,7 @@ func (r *Runner) runE(c *cobra.Command, args []string) error {
128129
}
129130
}
130131

131-
_, inv, err := live.Load(r.factory, path, c.InOrStdin())
132+
_, inv, err := live.Load(r.factory, path, r.rgFile, c.InOrStdin())
132133
if err != nil {
133134
return err
134135
}

internal/cmdmigrate/migratecmd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ func (mr *MigrateRunner) migrateObjs(rgInvClient inventory.InventoryClient,
301301
}
302302
}
303303

304-
_, inv, err := live.Load(mr.factory, path, reader)
304+
_, inv, err := live.Load(mr.factory, path, mr.rgFile, reader)
305305
if err != nil {
306306
return err
307307
}

internal/pkg/pkg.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -741,23 +741,28 @@ func ReadRGFile(path, filename string) (*rgfilev1alpha1.ResourceGroup, error) {
741741
}
742742
defer f.Close()
743743

744-
rg := &rgfilev1alpha1.ResourceGroup{}
745-
c, err := io.ReadAll(f)
744+
rg, err := DecodeRGFile(f)
746745
if err != nil {
747746
return nil, &RGError{
748747
Path: types.UniquePath(path),
749748
Err: err,
750749
}
751750
}
751+
return rg, nil
752+
}
753+
754+
// DecodeRGFile converts a string reader into structured a ResourceGroup object.
755+
func DecodeRGFile(in io.Reader) (*rgfilev1alpha1.ResourceGroup, error) {
756+
rg := &rgfilev1alpha1.ResourceGroup{}
757+
c, err := io.ReadAll(in)
758+
if err != nil {
759+
return rg, err
760+
}
752761

753762
d := yaml.NewDecoder(bytes.NewBuffer(c))
754763
d.KnownFields(true)
755764
if err := d.Decode(rg); err != nil {
756-
return nil, &RGError{
757-
Path: types.UniquePath(path),
758-
Err: err,
759-
}
765+
return rg, err
760766
}
761767
return rg, nil
762-
763768
}

internal/testutil/pkgbuilder/builder.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"text/template"
2727

2828
kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1"
29+
rgfilev1alpha1 "github.com/GoogleContainerTools/kpt/pkg/api/resourcegroup/v1alpha1"
2930
"github.com/stretchr/testify/assert"
3031
"sigs.k8s.io/kustomize/kyaml/yaml"
3132
)
@@ -92,13 +93,21 @@ var (
9293
type pkg struct {
9394
Kptfile *Kptfile
9495

96+
RGFile *RGFile
97+
9598
resources []resourceInfoWithMutators
9699

97100
files map[string]string
98101

99102
subPkgs []*SubPkg
100103
}
101104

105+
// WithRGFile configures the current package to have a resourcegroup file.
106+
func (rp *RootPkg) WithRGFile(rg *RGFile) *RootPkg {
107+
rp.pkg.RGFile = rg
108+
return rp
109+
}
110+
102111
// withKptfile configures the current package to have a Kptfile. Only
103112
// zero or one Kptfiles are accepted.
104113
func (p *pkg) withKptfile(kf ...*Kptfile) {
@@ -300,6 +309,22 @@ func (sp *SubPkg) WithSubPackages(ps ...*SubPkg) *SubPkg {
300309
return sp
301310
}
302311

312+
// RGFile represents a minimal resourcegroup.
313+
type RGFile struct {
314+
Name, Namespace, ID string
315+
}
316+
317+
func NewRGFile() *RGFile {
318+
return &RGFile{}
319+
}
320+
321+
func (rg *RGFile) WithInventory(inv Inventory) *RGFile {
322+
rg.Name = inv.Name
323+
rg.Namespace = inv.Namespace
324+
rg.ID = inv.ID
325+
return rg
326+
}
327+
303328
// Kptfile represents the Kptfile of a package.
304329
type Kptfile struct {
305330
Upstream *Upstream
@@ -476,6 +501,16 @@ func buildPkg(pkgPath string, pkg *pkg, pkgName string, reposInfo ReposInfo) err
476501
}
477502
}
478503

504+
if pkg.RGFile != nil {
505+
content := buildRGFile(pkg)
506+
507+
err := ioutil.WriteFile(filepath.Join(pkgPath, rgfilev1alpha1.RGFileName),
508+
[]byte(content), 0600)
509+
if err != nil {
510+
return err
511+
}
512+
}
513+
479514
for _, ri := range pkg.resources {
480515
m := ri.resourceInfo.manifest
481516
r := yaml.MustParse(m)
@@ -510,6 +545,23 @@ func buildPkg(pkgPath string, pkg *pkg, pkgName string, reposInfo ReposInfo) err
510545
return nil
511546
}
512547

548+
// buildRGFile creates a ResourceGroup inventory file.
549+
func buildRGFile(pkg *pkg) string {
550+
tmp := rgfilev1alpha1.ResourceGroup{ResourceMeta: rgfilev1alpha1.DefaultMeta}
551+
tmp.ObjectMeta.Name = pkg.RGFile.Name
552+
tmp.ObjectMeta.Namespace = pkg.RGFile.Namespace
553+
if pkg.RGFile.ID != "" {
554+
tmp.ObjectMeta.Labels = map[string]string{rgfilev1alpha1.RGInventoryIDLabel: pkg.RGFile.ID}
555+
}
556+
557+
b, err := yaml.MarshalWithOptions(tmp, &yaml.EncoderOptions{SeqIndent: yaml.WideSequenceStyle})
558+
if err != nil {
559+
panic(err)
560+
}
561+
562+
return string(b)
563+
}
564+
513565
// TODO: Consider using the Kptfile struct for this instead of a template.
514566
var kptfileTemplate = `apiVersion: kpt.dev/v1
515567
kind: Kptfile

pkg/api/kptfile/v1/types.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,3 +326,10 @@ type Inventory struct {
326326
Labels map[string]string `yaml:"labels,omitempty" json:"labels,omitempty"`
327327
Annotations map[string]string `yaml:"annotations,omitempty" json:"annotations,omitempty"`
328328
}
329+
330+
func (i Inventory) IsValid() bool {
331+
// Name and Namespace are required inventory fields, so we check these 2 fields.
332+
// InventoryID is an optional field since we only store it locally if the user
333+
// specifies one.
334+
return i.Name != "" && i.Namespace != ""
335+
}

0 commit comments

Comments
 (0)