Merge pull request #538 from karlkfi/karl-lint-upgrade

chore: Upgrade golint, replace deprecated linters, and fix new lint errors
This commit is contained in:
Kubernetes Prow Robot 2022-02-15 22:10:36 -08:00 committed by GitHub
commit f155aaf7fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
87 changed files with 651 additions and 649 deletions

View File

@ -15,13 +15,13 @@ linters:
- dogsled - dogsled
- dupl - dupl
- errcheck - errcheck
- exportloopref
- gochecknoinits - gochecknoinits
- goconst - goconst
- gocritic - gocritic
- gocyclo - gocyclo
- gofmt - gofmt
- goimports - goimports
- golint
- gosec - gosec
- gosimple - gosimple
- govet - govet
@ -30,10 +30,10 @@ linters:
- lll - lll
- misspell - misspell
- nakedret - nakedret
- scopelint
- staticcheck - staticcheck
- structcheck - structcheck
- stylecheck - stylecheck
- revive
- typecheck - typecheck
- unconvert - unconvert
- unparam - unparam
@ -49,8 +49,6 @@ linters-settings:
line-length: 170 line-length: 170
gocyclo: gocyclo:
min-complexity: 30 min-complexity: 30
golint:
min-confidence: 0.85
issues: issues:
# List of regexps of issue texts to exclude, empty list by default. # List of regexps of issue texts to exclude, empty list by default.

View File

@ -33,7 +33,7 @@ install-addlicense:
(which $(GOPATH)/bin/addlicense || go install github.com/google/addlicense@v1.0.0) (which $(GOPATH)/bin/addlicense || go install github.com/google/addlicense@v1.0.0)
install-lint: install-lint:
(which $(GOPATH)/bin/golangci-lint || go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.40.1) (which $(GOPATH)/bin/golangci-lint || go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.44.0)
install-deepcopy-gen: install-deepcopy-gen:
(which $(GOPATH)/bin/deepcopy-gen || go install k8s.io/code-generator/cmd/deepcopy-gen@v0.23.3) (which $(GOPATH)/bin/deepcopy-gen || go install k8s.io/code-generator/cmd/deepcopy-gen@v0.23.3)

View File

@ -21,9 +21,9 @@ import (
"sigs.k8s.io/cli-utils/pkg/printers" "sigs.k8s.io/cli-utils/pkg/printers"
) )
func GetApplyRunner(factory cmdutil.Factory, invFactory inventory.InventoryClientFactory, func GetRunner(factory cmdutil.Factory, invFactory inventory.ClientFactory,
loader manifestreader.ManifestLoader, ioStreams genericclioptions.IOStreams) *ApplyRunner { loader manifestreader.ManifestLoader, ioStreams genericclioptions.IOStreams) *Runner {
r := &ApplyRunner{ r := &Runner{
ioStreams: ioStreams, ioStreams: ioStreams,
factory: factory, factory: factory,
invFactory: invFactory, invFactory: invFactory,
@ -67,16 +67,16 @@ func GetApplyRunner(factory cmdutil.Factory, invFactory inventory.InventoryClien
return r return r
} }
func ApplyCommand(f cmdutil.Factory, invFactory inventory.InventoryClientFactory, loader manifestreader.ManifestLoader, func Command(f cmdutil.Factory, invFactory inventory.ClientFactory, loader manifestreader.ManifestLoader,
ioStreams genericclioptions.IOStreams) *cobra.Command { ioStreams genericclioptions.IOStreams) *cobra.Command {
return GetApplyRunner(f, invFactory, loader, ioStreams).Command return GetRunner(f, invFactory, loader, ioStreams).Command
} }
type ApplyRunner struct { type Runner struct {
Command *cobra.Command Command *cobra.Command
ioStreams genericclioptions.IOStreams ioStreams genericclioptions.IOStreams
factory cmdutil.Factory factory cmdutil.Factory
invFactory inventory.InventoryClientFactory invFactory inventory.ClientFactory
loader manifestreader.ManifestLoader loader manifestreader.ManifestLoader
serverSideOptions common.ServerSideOptions serverSideOptions common.ServerSideOptions
@ -91,7 +91,7 @@ type ApplyRunner struct {
printStatusEvents bool printStatusEvents bool
} }
func (r *ApplyRunner) RunE(cmd *cobra.Command, args []string) error { func (r *Runner) RunE(cmd *cobra.Command, args []string) error {
ctx := cmd.Context() ctx := cmd.Context()
// If specified, cancel with timeout. // If specified, cancel with timeout.
if r.timeout != 0 { if r.timeout != 0 {
@ -134,7 +134,7 @@ func (r *ApplyRunner) RunE(cmd *cobra.Command, args []string) error {
} }
inv := inventory.WrapInventoryInfoObj(invObj) inv := inventory.WrapInventoryInfoObj(invObj)
invClient, err := r.invFactory.NewInventoryClient(r.factory) invClient, err := r.invFactory.NewClient(r.factory)
if err != nil { if err != nil {
return err return err
} }

View File

@ -21,10 +21,10 @@ import (
"sigs.k8s.io/cli-utils/pkg/printers" "sigs.k8s.io/cli-utils/pkg/printers"
) )
// GetDestroyRunner creates and returns the DestroyRunner which stores the cobra command. // GetRunner creates and returns the Runner which stores the cobra command.
func GetDestroyRunner(factory cmdutil.Factory, invFactory inventory.InventoryClientFactory, func GetRunner(factory cmdutil.Factory, invFactory inventory.ClientFactory,
loader manifestreader.ManifestLoader, ioStreams genericclioptions.IOStreams) *DestroyRunner { loader manifestreader.ManifestLoader, ioStreams genericclioptions.IOStreams) *Runner {
r := &DestroyRunner{ r := &Runner{
ioStreams: ioStreams, ioStreams: ioStreams,
factory: factory, factory: factory,
invFactory: invFactory, invFactory: invFactory,
@ -55,18 +55,18 @@ func GetDestroyRunner(factory cmdutil.Factory, invFactory inventory.InventoryCli
return r return r
} }
// DestroyCommand creates the DestroyRunner, returning the cobra command associated with it. // Command creates the Runner, returning the cobra command associated with it.
func DestroyCommand(f cmdutil.Factory, invFactory inventory.InventoryClientFactory, loader manifestreader.ManifestLoader, func Command(f cmdutil.Factory, invFactory inventory.ClientFactory, loader manifestreader.ManifestLoader,
ioStreams genericclioptions.IOStreams) *cobra.Command { ioStreams genericclioptions.IOStreams) *cobra.Command {
return GetDestroyRunner(f, invFactory, loader, ioStreams).Command return GetRunner(f, invFactory, loader, ioStreams).Command
} }
// DestroyRunner encapsulates data necessary to run the destroy command. // Runner encapsulates data necessary to run the destroy command.
type DestroyRunner struct { type Runner struct {
Command *cobra.Command Command *cobra.Command
ioStreams genericclioptions.IOStreams ioStreams genericclioptions.IOStreams
factory cmdutil.Factory factory cmdutil.Factory
invFactory inventory.InventoryClientFactory invFactory inventory.ClientFactory
loader manifestreader.ManifestLoader loader manifestreader.ManifestLoader
output string output string
@ -77,7 +77,7 @@ type DestroyRunner struct {
printStatusEvents bool printStatusEvents bool
} }
func (r *DestroyRunner) RunE(cmd *cobra.Command, args []string) error { func (r *Runner) RunE(cmd *cobra.Command, args []string) error {
ctx := cmd.Context() ctx := cmd.Context()
// If specified, cancel with timeout. // If specified, cancel with timeout.
if r.timeout != 0 { if r.timeout != 0 {
@ -114,7 +114,7 @@ func (r *DestroyRunner) RunE(cmd *cobra.Command, args []string) error {
} }
inv := inventory.WrapInventoryInfoObj(invObj) inv := inventory.WrapInventoryInfoObj(invObj)
invClient, err := r.invFactory.NewInventoryClient(r.factory) invClient, err := r.invFactory.NewClient(r.factory)
if err != nil { if err != nil {
return err return err
} }

View File

@ -19,10 +19,10 @@ import (
const tmpDirPrefix = "diff-cmd" const tmpDirPrefix = "diff-cmd"
// NewCmdDiff returns cobra command to implement client-side diff of package // NewCommand returns cobra command to implement client-side diff of package
// directory. For each local config file, get the resource in the cluster // directory. For each local config file, get the resource in the cluster
// and diff the local config resource against the resource in the cluster. // and diff the local config resource against the resource in the cluster.
func NewCmdDiff(f util.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { func NewCommand(f util.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := diff.NewDiffOptions(ioStreams) options := diff.NewDiffOptions(ioStreams)
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "diff (DIRECTORY | STDIN)", Use: "diff (DIRECTORY | STDIN)",

View File

@ -33,16 +33,16 @@ func ConvertPropagationPolicy(propagationPolicy string) (metav1.DeletionPropagat
} }
} }
func ConvertInventoryPolicy(policy string) (inventory.InventoryPolicy, error) { func ConvertInventoryPolicy(policy string) (inventory.Policy, error) {
switch policy { switch policy {
case InventoryPolicyStrict: case InventoryPolicyStrict:
return inventory.InventoryPolicyMustMatch, nil return inventory.PolicyMustMatch, nil
case InventoryPolicyAdopt: case InventoryPolicyAdopt:
return inventory.AdoptIfNoInventory, nil return inventory.PolicyAdoptIfNoInventory, nil
case InventoryPolicyForceAdopt: case InventoryPolicyForceAdopt:
return inventory.AdoptAll, nil return inventory.PolicyAdoptAll, nil
default: default:
return inventory.InventoryPolicyMustMatch, fmt.Errorf( return inventory.PolicyMustMatch, fmt.Errorf(
"inventory policy must be one of strict, adopt") "inventory policy must be one of strict, adopt")
} }
} }

View File

@ -13,20 +13,20 @@ import (
func TestConvertInventoryPolicy(t *testing.T) { func TestConvertInventoryPolicy(t *testing.T) {
testcases := []struct { testcases := []struct {
value string value string
policy inventory.InventoryPolicy policy inventory.Policy
err error err error
}{ }{
{ {
value: "strict", value: "strict",
policy: inventory.InventoryPolicyMustMatch, policy: inventory.PolicyMustMatch,
}, },
{ {
value: "adopt", value: "adopt",
policy: inventory.AdoptIfNoInventory, policy: inventory.PolicyAdoptIfNoInventory,
}, },
{ {
value: "force-adopt", value: "force-adopt",
policy: inventory.AdoptAll, policy: inventory.PolicyAdoptAll,
}, },
{ {
value: "random", value: "random",

View File

@ -56,16 +56,16 @@ func main() {
initCmd := initcmd.NewCmdInit(f, ioStreams) initCmd := initcmd.NewCmdInit(f, ioStreams)
updateHelp(names, initCmd) updateHelp(names, initCmd)
loader := manifestreader.NewManifestLoader(f) loader := manifestreader.NewManifestLoader(f)
invFactory := inventory.ClusterInventoryClientFactory{} invFactory := inventory.ClusterClientFactory{}
applyCmd := apply.ApplyCommand(f, invFactory, loader, ioStreams) applyCmd := apply.Command(f, invFactory, loader, ioStreams)
updateHelp(names, applyCmd) updateHelp(names, applyCmd)
previewCmd := preview.PreviewCommand(f, invFactory, loader, ioStreams) previewCmd := preview.Command(f, invFactory, loader, ioStreams)
updateHelp(names, previewCmd) updateHelp(names, previewCmd)
diffCmd := diff.NewCmdDiff(f, ioStreams) diffCmd := diff.NewCommand(f, ioStreams)
updateHelp(names, diffCmd) updateHelp(names, diffCmd)
destroyCmd := destroy.DestroyCommand(f, invFactory, loader, ioStreams) destroyCmd := destroy.Command(f, invFactory, loader, ioStreams)
updateHelp(names, destroyCmd) updateHelp(names, destroyCmd)
statusCmd := status.StatusCommand(f, invFactory, loader) statusCmd := status.Command(f, invFactory, loader)
updateHelp(names, statusCmd) updateHelp(names, statusCmd)
cmd.AddCommand(initCmd, applyCmd, diffCmd, destroyCmd, previewCmd, statusCmd) cmd.AddCommand(initCmd, applyCmd, diffCmd, destroyCmd, previewCmd, statusCmd)

View File

@ -27,10 +27,10 @@ var (
previewDestroy = false previewDestroy = false
) )
// GetPreviewRunner creates and returns the PreviewRunner which stores the cobra command. // GetRunner creates and returns the Runner which stores the cobra command.
func GetPreviewRunner(factory cmdutil.Factory, invFactory inventory.InventoryClientFactory, func GetRunner(factory cmdutil.Factory, invFactory inventory.ClientFactory,
loader manifestreader.ManifestLoader, ioStreams genericclioptions.IOStreams) *PreviewRunner { loader manifestreader.ManifestLoader, ioStreams genericclioptions.IOStreams) *Runner {
r := &PreviewRunner{ r := &Runner{
factory: factory, factory: factory,
invFactory: invFactory, invFactory: invFactory,
loader: loader, loader: loader,
@ -64,17 +64,17 @@ func GetPreviewRunner(factory cmdutil.Factory, invFactory inventory.InventoryCli
return r return r
} }
// PreviewCommand creates the PreviewRunner, returning the cobra command associated with it. // Command creates the Runner, returning the cobra command associated with it.
func PreviewCommand(f cmdutil.Factory, invFactory inventory.InventoryClientFactory, loader manifestreader.ManifestLoader, func Command(f cmdutil.Factory, invFactory inventory.ClientFactory, loader manifestreader.ManifestLoader,
ioStreams genericclioptions.IOStreams) *cobra.Command { ioStreams genericclioptions.IOStreams) *cobra.Command {
return GetPreviewRunner(f, invFactory, loader, ioStreams).Command return GetRunner(f, invFactory, loader, ioStreams).Command
} }
// PreviewRunner encapsulates data necessary to run the preview command. // Runner encapsulates data necessary to run the preview command.
type PreviewRunner struct { type Runner struct {
Command *cobra.Command Command *cobra.Command
factory cmdutil.Factory factory cmdutil.Factory
invFactory inventory.InventoryClientFactory invFactory inventory.ClientFactory
loader manifestreader.ManifestLoader loader manifestreader.ManifestLoader
ioStreams genericclioptions.IOStreams ioStreams genericclioptions.IOStreams
@ -85,7 +85,7 @@ type PreviewRunner struct {
} }
// RunE is the function run from the cobra command. // RunE is the function run from the cobra command.
func (r *PreviewRunner) RunE(cmd *cobra.Command, args []string) error { func (r *Runner) RunE(cmd *cobra.Command, args []string) error {
ctx := cmd.Context() ctx := cmd.Context()
// If specified, cancel with timeout. // If specified, cancel with timeout.
if r.timeout != 0 { if r.timeout != 0 {
@ -126,7 +126,7 @@ func (r *PreviewRunner) RunE(cmd *cobra.Command, args []string) error {
} }
inv := inventory.WrapInventoryInfoObj(invObj) inv := inventory.WrapInventoryInfoObj(invObj)
invClient, err := r.invFactory.NewInventoryClient(r.factory) invClient, err := r.invFactory.NewClient(r.factory)
if err != nil { if err != nil {
return err return err
} }

View File

@ -24,8 +24,8 @@ import (
"sigs.k8s.io/cli-utils/pkg/manifestreader" "sigs.k8s.io/cli-utils/pkg/manifestreader"
) )
func GetStatusRunner(factory cmdutil.Factory, invFactory inventory.InventoryClientFactory, loader manifestreader.ManifestLoader) *StatusRunner { func GetRunner(factory cmdutil.Factory, invFactory inventory.ClientFactory, loader manifestreader.ManifestLoader) *Runner {
r := &StatusRunner{ r := &Runner{
factory: factory, factory: factory,
invFactory: invFactory, invFactory: invFactory,
loader: loader, loader: loader,
@ -47,16 +47,16 @@ func GetStatusRunner(factory cmdutil.Factory, invFactory inventory.InventoryClie
return r return r
} }
func StatusCommand(f cmdutil.Factory, invFactory inventory.InventoryClientFactory, loader manifestreader.ManifestLoader) *cobra.Command { func Command(f cmdutil.Factory, invFactory inventory.ClientFactory, loader manifestreader.ManifestLoader) *cobra.Command {
return GetStatusRunner(f, invFactory, loader).Command return GetRunner(f, invFactory, loader).Command
} }
// StatusRunner captures the parameters for the command and contains // Runner captures the parameters for the command and contains
// the run function. // the run function.
type StatusRunner struct { type Runner struct {
Command *cobra.Command Command *cobra.Command
factory cmdutil.Factory factory cmdutil.Factory
invFactory inventory.InventoryClientFactory invFactory inventory.ClientFactory
loader manifestreader.ManifestLoader loader manifestreader.ManifestLoader
period time.Duration period time.Duration
@ -70,7 +70,7 @@ type StatusRunner struct {
// runE implements the logic of the command and will delegate to the // runE implements the logic of the command and will delegate to the
// poller to compute status for each of the resources. One of the printer // poller to compute status for each of the resources. One of the printer
// implementations takes care of printing the output. // implementations takes care of printing the output.
func (r *StatusRunner) runE(cmd *cobra.Command, args []string) error { func (r *Runner) runE(cmd *cobra.Command, args []string) error {
_, err := common.DemandOneDirectory(args) _, err := common.DemandOneDirectory(args)
if err != nil { if err != nil {
return err return err
@ -91,7 +91,7 @@ func (r *StatusRunner) runE(cmd *cobra.Command, args []string) error {
} }
inv := inventory.WrapInventoryInfoObj(invObj) inv := inventory.WrapInventoryInfoObj(invObj)
invClient, err := r.invFactory.NewInventoryClient(r.factory) invClient, err := r.invFactory.NewClient(r.factory)
if err != nil { if err != nil {
return err return err
} }

View File

@ -53,7 +53,7 @@ metadata:
} }
) )
func TestStatusCommand(t *testing.T) { func TestCommand(t *testing.T) {
testCases := map[string]struct { testCases := map[string]struct {
pollUntil string pollUntil string
printer string printer string
@ -78,7 +78,7 @@ func TestStatusCommand(t *testing.T) {
}, },
events: []pollevent.Event{ events: []pollevent.Event{
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: depObject, Identifier: depObject,
Status: status.InProgressStatus, Status: status.InProgressStatus,
@ -86,7 +86,7 @@ func TestStatusCommand(t *testing.T) {
}, },
}, },
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: stsObject, Identifier: stsObject,
Status: status.CurrentStatus, Status: status.CurrentStatus,
@ -109,7 +109,7 @@ statefulset.apps/bar is Current: current
}, },
events: []pollevent.Event{ events: []pollevent.Event{
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: depObject, Identifier: depObject,
Status: status.InProgressStatus, Status: status.InProgressStatus,
@ -117,7 +117,7 @@ statefulset.apps/bar is Current: current
}, },
}, },
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: stsObject, Identifier: stsObject,
Status: status.InProgressStatus, Status: status.InProgressStatus,
@ -125,7 +125,7 @@ statefulset.apps/bar is Current: current
}, },
}, },
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: stsObject, Identifier: stsObject,
Status: status.CurrentStatus, Status: status.CurrentStatus,
@ -133,7 +133,7 @@ statefulset.apps/bar is Current: current
}, },
}, },
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: depObject, Identifier: depObject,
Status: status.CurrentStatus, Status: status.CurrentStatus,
@ -158,7 +158,7 @@ deployment.apps/foo is Current: current
}, },
events: []pollevent.Event{ events: []pollevent.Event{
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: stsObject, Identifier: stsObject,
Status: status.NotFoundStatus, Status: status.NotFoundStatus,
@ -166,7 +166,7 @@ deployment.apps/foo is Current: current
}, },
}, },
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: depObject, Identifier: depObject,
Status: status.NotFoundStatus, Status: status.NotFoundStatus,
@ -190,7 +190,7 @@ deployment.apps/foo is NotFound: notFound
}, },
events: []pollevent.Event{ events: []pollevent.Event{
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: stsObject, Identifier: stsObject,
Status: status.InProgressStatus, Status: status.InProgressStatus,
@ -198,7 +198,7 @@ deployment.apps/foo is NotFound: notFound
}, },
}, },
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: depObject, Identifier: depObject,
Status: status.InProgressStatus, Status: status.InProgressStatus,
@ -219,9 +219,9 @@ deployment.apps/foo is InProgress: inProgress
defer tf.Cleanup() defer tf.Cleanup()
loader := manifestreader.NewFakeLoader(tf, tc.inventory) loader := manifestreader.NewFakeLoader(tf, tc.inventory)
runner := &StatusRunner{ runner := &Runner{
factory: tf, factory: tf,
invFactory: inventory.FakeInventoryClientFactory(tc.inventory), invFactory: inventory.FakeClientFactory(tc.inventory),
loader: loader, loader: loader,
pollerFactoryFunc: func(c cmdutil.Factory) (poller.Poller, error) { pollerFactoryFunc: func(c cmdutil.Factory) (poller.Poller, error) {
return &fakePoller{tc.events}, nil return &fakePoller{tc.events}, nil

View File

@ -14,16 +14,16 @@ import (
"sigs.k8s.io/cli-utils/pkg/object" "sigs.k8s.io/cli-utils/pkg/object"
) )
// eventPrinter implements the Printer interface and outputs the resource // Printer implements the Printer interface and outputs the resource
// status information as a list of events as they happen. // status information as a list of events as they happen.
type eventPrinter struct { type Printer struct {
ioStreams genericclioptions.IOStreams IOStreams genericclioptions.IOStreams
} }
// NewEventPrinter returns a new instance of the eventPrinter. // NewPrinter returns a new instance of the eventPrinter.
func NewEventPrinter(ioStreams genericclioptions.IOStreams) *eventPrinter { func NewPrinter(ioStreams genericclioptions.IOStreams) *Printer {
return &eventPrinter{ return &Printer{
ioStreams: ioStreams, IOStreams: ioStreams,
} }
} }
@ -31,7 +31,7 @@ func NewEventPrinter(ioStreams genericclioptions.IOStreams) *eventPrinter {
// until the channel is closed. The provided cancelFunc is consulted on // until the channel is closed. The provided cancelFunc is consulted on
// every event and is responsible for stopping the poller when appropriate. // every event and is responsible for stopping the poller when appropriate.
// This function will block. // This function will block.
func (ep *eventPrinter) Print(ch <-chan pollevent.Event, identifiers object.ObjMetadataSet, func (ep *Printer) Print(ch <-chan pollevent.Event, identifiers object.ObjMetadataSet,
cancelFunc collector.ObserverFunc) error { cancelFunc collector.ObserverFunc) error {
coll := collector.NewResourceStatusCollector(identifiers) coll := collector.NewResourceStatusCollector(identifiers)
// The actual work is done by the collector, which will invoke the // The actual work is done by the collector, which will invoke the
@ -52,15 +52,15 @@ func (ep *eventPrinter) Print(ch <-chan pollevent.Event, identifiers object.ObjM
return err return err
} }
func (ep *eventPrinter) printStatusEvent(se pollevent.Event) { func (ep *Printer) printStatusEvent(se pollevent.Event) {
switch se.EventType { switch se.Type {
case pollevent.ResourceUpdateEvent: case pollevent.ResourceUpdateEvent:
id := se.Resource.Identifier id := se.Resource.Identifier
printResourceStatus(id, se, ep.ioStreams) printResourceStatus(id, se, ep.IOStreams)
case pollevent.ErrorEvent: case pollevent.ErrorEvent:
id := se.Resource.Identifier id := se.Resource.Identifier
gk := id.GroupKind gk := id.GroupKind
fmt.Fprintf(ep.ioStreams.Out, "%s error: %s\n", resourceIDToString(gk, id.Name), fmt.Fprintf(ep.IOStreams.Out, "%s error: %s\n", resourceIDToString(gk, id.Name),
se.Error.Error()) se.Error.Error())
} }
} }

View File

@ -16,8 +16,8 @@ import (
func CreatePrinter(printerType string, ioStreams genericclioptions.IOStreams) (printer.Printer, error) { func CreatePrinter(printerType string, ioStreams genericclioptions.IOStreams) (printer.Printer, error) {
switch printerType { switch printerType {
case "table": case "table":
return table.NewTablePrinter(ioStreams), nil return table.NewPrinter(ioStreams), nil
default: default:
return event.NewEventPrinter(ioStreams), nil return event.NewPrinter(ioStreams), nil
} }
} }

View File

@ -18,22 +18,22 @@ const (
updateInterval = 1 * time.Second updateInterval = 1 * time.Second
) )
// tablePrinter is an implementation of the Printer interface that outputs // Printer is an implementation of the Printer interface that outputs
// status information about resources in a table format with in-place updates. // status information about resources in a table format with in-place updates.
type tablePrinter struct { type Printer struct {
ioStreams genericclioptions.IOStreams IOStreams genericclioptions.IOStreams
} }
// NewTablePrinter returns a new instance of the tablePrinter. // NewPrinter returns a new instance of the tablePrinter.
func NewTablePrinter(ioStreams genericclioptions.IOStreams) *tablePrinter { func NewPrinter(ioStreams genericclioptions.IOStreams) *Printer {
return &tablePrinter{ return &Printer{
ioStreams: ioStreams, IOStreams: ioStreams,
} }
} }
// Print take an event channel and outputs the status events on the channel // Print take an event channel and outputs the status events on the channel
// until the channel is closed . // until the channel is closed .
func (t *tablePrinter) Print(ch <-chan event.Event, identifiers object.ObjMetadataSet, func (t *Printer) Print(ch <-chan event.Event, identifiers object.ObjMetadataSet,
cancelFunc collector.ObserverFunc) error { cancelFunc collector.ObserverFunc) error {
coll := collector.NewResourceStatusCollector(identifiers) coll := collector.NewResourceStatusCollector(identifiers)
stop := make(chan struct{}) stop := make(chan struct{})
@ -76,11 +76,11 @@ var columns = []table.ColumnDefinition{
// Print prints the table of resources with their statuses until the // Print prints the table of resources with their statuses until the
// provided stop channel is closed. // provided stop channel is closed.
func (t *tablePrinter) runPrintLoop(coll *CollectorAdapter, stop <-chan struct{}) <-chan struct{} { func (t *Printer) runPrintLoop(coll *CollectorAdapter, stop <-chan struct{}) <-chan struct{} {
finished := make(chan struct{}) finished := make(chan struct{})
baseTablePrinter := table.BaseTablePrinter{ baseTablePrinter := table.BaseTablePrinter{
IOStreams: t.ioStreams, IOStreams: t.IOStreams,
Columns: columns, Columns: columns,
} }

View File

@ -79,6 +79,7 @@ type ObjectStatus struct {
Generation int64 `json:"generation,omitempty"` Generation int64 `json:"generation,omitempty"`
} }
//nolint:revive // consistent prefix improves tab-completion for enums
//go:generate stringer -type=ActuationStrategy -linecomment //go:generate stringer -type=ActuationStrategy -linecomment
type ActuationStrategy int type ActuationStrategy int
@ -87,6 +88,7 @@ const (
ActuationStrategyDelete // Delete ActuationStrategyDelete // Delete
) )
//nolint:revive // consistent prefix improves tab-completion for enums
//go:generate stringer -type=ActuationStatus -linecomment //go:generate stringer -type=ActuationStatus -linecomment
type ActuationStatus int type ActuationStatus int

View File

@ -44,16 +44,16 @@ const defaultPollInterval = 2 * time.Second
type Applier struct { type Applier struct {
pruner *prune.Pruner pruner *prune.Pruner
statusPoller poller.Poller statusPoller poller.Poller
invClient inventory.InventoryClient invClient inventory.Client
client dynamic.Interface client dynamic.Interface
openAPIGetter discovery.OpenAPISchemaInterface openAPIGetter discovery.OpenAPISchemaInterface
mapper meta.RESTMapper mapper meta.RESTMapper
infoHelper info.InfoHelper infoHelper info.Helper
} }
// prepareObjects returns the set of objects to apply and to prune or // prepareObjects returns the set of objects to apply and to prune or
// an error if one occurred. // an error if one occurred.
func (a *Applier) prepareObjects(localInv inventory.InventoryInfo, localObjs object.UnstructuredSet, func (a *Applier) prepareObjects(localInv inventory.Info, localObjs object.UnstructuredSet,
o ApplierOptions) (object.UnstructuredSet, object.UnstructuredSet, error) { o ApplierOptions) (object.UnstructuredSet, object.UnstructuredSet, error) {
if localInv == nil { if localInv == nil {
return nil, nil, fmt.Errorf("the local inventory can't be nil") return nil, nil, fmt.Errorf("the local inventory can't be nil")
@ -102,7 +102,7 @@ func (a *Applier) prepareObjects(localInv inventory.InventoryInfo, localObjs obj
// before all the given resources have been applied to the cluster. Any // before all the given resources have been applied to the cluster. Any
// cancellation or timeout will only affect how long we Wait for the // cancellation or timeout will only affect how long we Wait for the
// resources to become current. // resources to become current.
func (a *Applier) Run(ctx context.Context, invInfo inventory.InventoryInfo, objects object.UnstructuredSet, options ApplierOptions) <-chan event.Event { func (a *Applier) Run(ctx context.Context, invInfo inventory.Info, objects object.UnstructuredSet, options ApplierOptions) <-chan event.Event {
klog.V(4).Infof("apply run for %d objects", len(objects)) klog.V(4).Infof("apply run for %d objects", len(objects))
eventChannel := make(chan event.Event) eventChannel := make(chan event.Event)
setDefaults(&options) setDefaults(&options)
@ -274,7 +274,7 @@ type ApplierOptions struct {
PruneTimeout time.Duration PruneTimeout time.Duration
// InventoryPolicy defines the inventory policy of apply. // InventoryPolicy defines the inventory policy of apply.
InventoryPolicy inventory.InventoryPolicy InventoryPolicy inventory.Policy
// ValidationPolicy defines how to handle invalid objects. // ValidationPolicy defines how to handle invalid objects.
ValidationPolicy validation.Policy ValidationPolicy validation.Policy
@ -304,7 +304,7 @@ func handleError(eventChannel chan event.Event, err error) {
// for the passed non cluster-scoped localObjs, plus the namespace // for the passed non cluster-scoped localObjs, plus the namespace
// of the passed inventory object. This is used to skip deleting // of the passed inventory object. This is used to skip deleting
// namespaces which have currently applied objects in them. // namespaces which have currently applied objects in them.
func localNamespaces(localInv inventory.InventoryInfo, localObjs []object.ObjMetadata) sets.String { func localNamespaces(localInv inventory.Info, localObjs []object.ObjMetadata) sets.String {
namespaces := sets.NewString() namespaces := sets.NewString()
for _, obj := range localObjs { for _, obj := range localObjs {
if obj.Namespace != "" { if obj.Namespace != "" {

View File

@ -25,7 +25,7 @@ import (
type ApplierBuilder struct { type ApplierBuilder struct {
// factory is only used to retrieve things that have not been provided explicitly. // factory is only used to retrieve things that have not been provided explicitly.
factory util.Factory factory util.Factory
invClient inventory.InventoryClient invClient inventory.Client
client dynamic.Interface client dynamic.Interface
discoClient discovery.CachedDiscoveryInterface discoClient discovery.CachedDiscoveryInterface
mapper meta.RESTMapper mapper meta.RESTMapper
@ -57,7 +57,7 @@ func (b *ApplierBuilder) Build() (*Applier, error) {
client: bx.client, client: bx.client,
openAPIGetter: bx.discoClient, openAPIGetter: bx.discoClient,
mapper: bx.mapper, mapper: bx.mapper,
infoHelper: info.NewInfoHelper(bx.mapper, bx.unstructuredClientForMapping), infoHelper: info.NewHelper(bx.mapper, bx.unstructuredClientForMapping),
}, nil }, nil
} }
@ -124,7 +124,7 @@ func (b *ApplierBuilder) WithFactory(factory util.Factory) *ApplierBuilder {
return b return b
} }
func (b *ApplierBuilder) WithInventoryClient(invClient inventory.InventoryClient) *ApplierBuilder { func (b *ApplierBuilder) WithInventoryClient(invClient inventory.Client) *ApplierBuilder {
b.invClient = invClient b.invClient = invClient
return b return b
} }

View File

@ -122,7 +122,7 @@ func TestApplier(t *testing.T) {
clusterObjs: object.UnstructuredSet{}, clusterObjs: object.UnstructuredSet{},
options: ApplierOptions{ options: ApplierOptions{
NoPrune: true, NoPrune: true,
InventoryPolicy: inventory.InventoryPolicyMustMatch, InventoryPolicy: inventory.PolicyMustMatch,
}, },
expectedEvents: []testutil.ExpEvent{ expectedEvents: []testutil.ExpEvent{
{ {
@ -229,12 +229,12 @@ func TestApplier(t *testing.T) {
clusterObjs: object.UnstructuredSet{}, clusterObjs: object.UnstructuredSet{},
options: ApplierOptions{ options: ApplierOptions{
ReconcileTimeout: time.Minute, ReconcileTimeout: time.Minute,
InventoryPolicy: inventory.InventoryPolicyMustMatch, InventoryPolicy: inventory.PolicyMustMatch,
EmitStatusEvents: true, EmitStatusEvents: true,
}, },
statusEvents: []pollevent.Event{ statusEvents: []pollevent.Event{
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: testutil.ToIdentifier(t, resources["deployment"]), Identifier: testutil.ToIdentifier(t, resources["deployment"]),
Status: status.InProgressStatus, Status: status.InProgressStatus,
@ -242,7 +242,7 @@ func TestApplier(t *testing.T) {
}, },
}, },
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: testutil.ToIdentifier(t, resources["deployment"]), Identifier: testutil.ToIdentifier(t, resources["deployment"]),
Status: status.CurrentStatus, Status: status.CurrentStatus,
@ -250,7 +250,7 @@ func TestApplier(t *testing.T) {
}, },
}, },
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: testutil.ToIdentifier(t, resources["secret"]), Identifier: testutil.ToIdentifier(t, resources["secret"]),
Status: status.CurrentStatus, Status: status.CurrentStatus,
@ -425,12 +425,12 @@ func TestApplier(t *testing.T) {
}, },
options: ApplierOptions{ options: ApplierOptions{
ReconcileTimeout: time.Minute, ReconcileTimeout: time.Minute,
InventoryPolicy: inventory.AdoptIfNoInventory, InventoryPolicy: inventory.PolicyAdoptIfNoInventory,
EmitStatusEvents: true, EmitStatusEvents: true,
}, },
statusEvents: []pollevent.Event{ statusEvents: []pollevent.Event{
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: testutil.ToIdentifier(t, resources["deployment"]), Identifier: testutil.ToIdentifier(t, resources["deployment"]),
Status: status.CurrentStatus, Status: status.CurrentStatus,
@ -438,7 +438,7 @@ func TestApplier(t *testing.T) {
}, },
}, },
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: testutil.ToIdentifier(t, resources["secret"]), Identifier: testutil.ToIdentifier(t, resources["secret"]),
Status: status.CurrentStatus, Status: status.CurrentStatus,
@ -606,33 +606,33 @@ func TestApplier(t *testing.T) {
testutil.Unstructured(t, resources["secret"], testutil.AddOwningInv(t, "test")), testutil.Unstructured(t, resources["secret"], testutil.AddOwningInv(t, "test")),
}, },
options: ApplierOptions{ options: ApplierOptions{
InventoryPolicy: inventory.InventoryPolicyMustMatch, InventoryPolicy: inventory.PolicyMustMatch,
EmitStatusEvents: true, EmitStatusEvents: true,
}, },
statusEvents: []pollevent.Event{ statusEvents: []pollevent.Event{
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: testutil.ToIdentifier(t, resources["deployment"]), Identifier: testutil.ToIdentifier(t, resources["deployment"]),
Status: status.InProgressStatus, Status: status.InProgressStatus,
}, },
}, },
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: testutil.ToIdentifier(t, resources["secret"]), Identifier: testutil.ToIdentifier(t, resources["secret"]),
Status: status.InProgressStatus, Status: status.InProgressStatus,
}, },
}, },
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: testutil.ToIdentifier(t, resources["deployment"]), Identifier: testutil.ToIdentifier(t, resources["deployment"]),
Status: status.NotFoundStatus, Status: status.NotFoundStatus,
}, },
}, },
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: testutil.ToIdentifier(t, resources["secret"]), Identifier: testutil.ToIdentifier(t, resources["secret"]),
Status: status.NotFoundStatus, Status: status.NotFoundStatus,
@ -806,19 +806,19 @@ func TestApplier(t *testing.T) {
}, },
options: ApplierOptions{ options: ApplierOptions{
ReconcileTimeout: time.Minute, ReconcileTimeout: time.Minute,
InventoryPolicy: inventory.InventoryPolicyMustMatch, InventoryPolicy: inventory.PolicyMustMatch,
EmitStatusEvents: true, EmitStatusEvents: true,
}, },
statusEvents: []pollevent.Event{ statusEvents: []pollevent.Event{
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: testutil.ToIdentifier(t, resources["deployment"]), Identifier: testutil.ToIdentifier(t, resources["deployment"]),
Status: status.InProgressStatus, Status: status.InProgressStatus,
}, },
}, },
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: testutil.ToIdentifier(t, resources["deployment"]), Identifier: testutil.ToIdentifier(t, resources["deployment"]),
Status: status.CurrentStatus, Status: status.CurrentStatus,
@ -945,7 +945,7 @@ func TestApplier(t *testing.T) {
testutil.Unstructured(t, resources["deployment"], testutil.AddOwningInv(t, "unmatched")), testutil.Unstructured(t, resources["deployment"], testutil.AddOwningInv(t, "unmatched")),
}, },
options: ApplierOptions{ options: ApplierOptions{
InventoryPolicy: inventory.InventoryPolicyMustMatch, InventoryPolicy: inventory.PolicyMustMatch,
EmitStatusEvents: true, EmitStatusEvents: true,
}, },
expectedEvents: []testutil.ExpEvent{ expectedEvents: []testutil.ExpEvent{
@ -1052,19 +1052,19 @@ func TestApplier(t *testing.T) {
testutil.Unstructured(t, resources["deployment"], testutil.AddOwningInv(t, "test")), testutil.Unstructured(t, resources["deployment"], testutil.AddOwningInv(t, "test")),
}, },
options: ApplierOptions{ options: ApplierOptions{
InventoryPolicy: inventory.InventoryPolicyMustMatch, InventoryPolicy: inventory.PolicyMustMatch,
EmitStatusEvents: true, EmitStatusEvents: true,
}, },
statusEvents: []pollevent.Event{ statusEvents: []pollevent.Event{
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: testutil.ToIdentifier(t, resources["deployment"]), Identifier: testutil.ToIdentifier(t, resources["deployment"]),
Status: status.InProgressStatus, Status: status.InProgressStatus,
}, },
}, },
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: testutil.ToIdentifier(t, resources["deployment"]), Identifier: testutil.ToIdentifier(t, resources["deployment"]),
Status: status.NotFoundStatus, Status: status.NotFoundStatus,
@ -1201,13 +1201,13 @@ func TestApplier(t *testing.T) {
clusterObjs: object.UnstructuredSet{}, clusterObjs: object.UnstructuredSet{},
options: ApplierOptions{ options: ApplierOptions{
ReconcileTimeout: time.Minute, ReconcileTimeout: time.Minute,
InventoryPolicy: inventory.AdoptIfNoInventory, InventoryPolicy: inventory.PolicyAdoptIfNoInventory,
EmitStatusEvents: true, EmitStatusEvents: true,
ValidationPolicy: validation.SkipInvalid, ValidationPolicy: validation.SkipInvalid,
}, },
statusEvents: []pollevent.Event{ statusEvents: []pollevent.Event{
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: testutil.ToIdentifier(t, resources["secret"]), Identifier: testutil.ToIdentifier(t, resources["secret"]),
Status: status.CurrentStatus, Status: status.CurrentStatus,
@ -1382,7 +1382,7 @@ func TestApplier(t *testing.T) {
clusterObjs: object.UnstructuredSet{}, clusterObjs: object.UnstructuredSet{},
options: ApplierOptions{ options: ApplierOptions{
ReconcileTimeout: time.Minute, ReconcileTimeout: time.Minute,
InventoryPolicy: inventory.AdoptIfNoInventory, InventoryPolicy: inventory.PolicyAdoptIfNoInventory,
EmitStatusEvents: true, EmitStatusEvents: true,
ValidationPolicy: validation.ExitEarly, ValidationPolicy: validation.ExitEarly,
}, },
@ -1562,13 +1562,13 @@ func TestApplierCancel(t *testing.T) {
// EmitStatusEvents required to test event output // EmitStatusEvents required to test event output
EmitStatusEvents: true, EmitStatusEvents: true,
NoPrune: true, NoPrune: true,
InventoryPolicy: inventory.InventoryPolicyMustMatch, InventoryPolicy: inventory.PolicyMustMatch,
// ReconcileTimeout required to enable WaitTasks // ReconcileTimeout required to enable WaitTasks
ReconcileTimeout: 1 * time.Minute, ReconcileTimeout: 1 * time.Minute,
}, },
statusEvents: []pollevent.Event{ statusEvents: []pollevent.Event{
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: testutil.ToIdentifier(t, resources["deployment"]), Identifier: testutil.ToIdentifier(t, resources["deployment"]),
Status: status.InProgressStatus, Status: status.InProgressStatus,
@ -1576,7 +1576,7 @@ func TestApplierCancel(t *testing.T) {
}, },
}, },
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: testutil.ToIdentifier(t, resources["deployment"]), Identifier: testutil.ToIdentifier(t, resources["deployment"]),
Status: status.InProgressStatus, Status: status.InProgressStatus,
@ -1720,13 +1720,13 @@ func TestApplierCancel(t *testing.T) {
// EmitStatusEvents required to test event output // EmitStatusEvents required to test event output
EmitStatusEvents: true, EmitStatusEvents: true,
NoPrune: true, NoPrune: true,
InventoryPolicy: inventory.InventoryPolicyMustMatch, InventoryPolicy: inventory.PolicyMustMatch,
// ReconcileTimeout required to enable WaitTasks // ReconcileTimeout required to enable WaitTasks
ReconcileTimeout: 1 * time.Minute, ReconcileTimeout: 1 * time.Minute,
}, },
statusEvents: []pollevent.Event{ statusEvents: []pollevent.Event{
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: testutil.ToIdentifier(t, resources["deployment"]), Identifier: testutil.ToIdentifier(t, resources["deployment"]),
Status: status.InProgressStatus, Status: status.InProgressStatus,
@ -1734,7 +1734,7 @@ func TestApplierCancel(t *testing.T) {
}, },
}, },
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: testutil.ToIdentifier(t, resources["deployment"]), Identifier: testutil.ToIdentifier(t, resources["deployment"]),
Status: status.CurrentStatus, Status: status.CurrentStatus,

View File

@ -65,7 +65,7 @@ func (i inventoryInfo) toUnstructured() *unstructured.Unstructured {
} }
} }
func (i inventoryInfo) toWrapped() inventory.InventoryInfo { func (i inventoryInfo) toWrapped() inventory.Info {
return inventory.WrapInventoryInfoObj(i.toUnstructured()) return inventory.WrapInventoryInfoObj(i.toUnstructured())
} }
@ -120,10 +120,10 @@ func newTestDestroyer(
func newTestInventory( func newTestInventory(
t *testing.T, t *testing.T,
tf *cmdtesting.TestFactory, tf *cmdtesting.TestFactory,
) inventory.InventoryClient { ) inventory.Client {
// Use an InventoryClient with a fakeInfoHelper to allow generating Info // Use an Client with a fakeInfoHelper to allow generating Info
// objects that use the FakeRESTClient as the UnstructuredClient. // objects that use the FakeRESTClient as the UnstructuredClient.
invClient, err := inventory.ClusterInventoryClientFactory{}.NewInventoryClient(tf) invClient, err := inventory.ClusterClientFactory{}.NewClient(tf)
require.NoError(t, err) require.NoError(t, err)
return invClient return invClient
} }

View File

@ -32,7 +32,7 @@ import (
// the ApplyOptions were responsible for printing progress. This is now // the ApplyOptions were responsible for printing progress. This is now
// handled by a separate printer with the KubectlPrinterAdapter bridging // handled by a separate printer with the KubectlPrinterAdapter bridging
// between the two. // between the two.
func NewDestroyer(factory cmdutil.Factory, invClient inventory.InventoryClient) (*Destroyer, error) { func NewDestroyer(factory cmdutil.Factory, invClient inventory.Client) (*Destroyer, error) {
pruner, err := prune.NewPruner(factory, invClient) pruner, err := prune.NewPruner(factory, invClient)
if err != nil { if err != nil {
return nil, fmt.Errorf("error setting up PruneOptions: %w", err) return nil, fmt.Errorf("error setting up PruneOptions: %w", err)
@ -55,12 +55,12 @@ type Destroyer struct {
pruner *prune.Pruner pruner *prune.Pruner
StatusPoller poller.Poller StatusPoller poller.Poller
factory cmdutil.Factory factory cmdutil.Factory
invClient inventory.InventoryClient invClient inventory.Client
} }
type DestroyerOptions struct { type DestroyerOptions struct {
// InventoryPolicy defines the inventory policy of apply. // InventoryPolicy defines the inventory policy of apply.
InventoryPolicy inventory.InventoryPolicy InventoryPolicy inventory.Policy
// DryRunStrategy defines whether changes should actually be performed, // DryRunStrategy defines whether changes should actually be performed,
// or if it is just talk and no action. // or if it is just talk and no action.
@ -99,7 +99,7 @@ func setDestroyerDefaults(o *DestroyerOptions) {
// Run performs the destroy step. Passes the inventory object. This // Run performs the destroy step. Passes the inventory object. This
// happens asynchronously on progress and any errors are reported // happens asynchronously on progress and any errors are reported
// back on the event channel. // back on the event channel.
func (d *Destroyer) Run(ctx context.Context, inv inventory.InventoryInfo, options DestroyerOptions) <-chan event.Event { func (d *Destroyer) Run(ctx context.Context, inv inventory.Info, options DestroyerOptions) <-chan event.Event {
eventChannel := make(chan event.Event) eventChannel := make(chan event.Event)
setDestroyerDefaults(&options) setDestroyerDefaults(&options)
go func() { go func() {
@ -139,7 +139,7 @@ func (d *Destroyer) Run(ctx context.Context, inv inventory.InventoryInfo, option
Pruner: d.pruner, Pruner: d.pruner,
DynamicClient: dynamicClient, DynamicClient: dynamicClient,
OpenAPIGetter: d.factory.OpenAPIGetter(), OpenAPIGetter: d.factory.OpenAPIGetter(),
InfoHelper: info.NewInfoHelper(mapper, d.factory.UnstructuredClientForMapping), InfoHelper: info.NewHelper(mapper, d.factory.UnstructuredClientForMapping),
Mapper: mapper, Mapper: mapper,
InvClient: d.invClient, InvClient: d.invClient,
Destroy: true, Destroy: true,

View File

@ -62,7 +62,7 @@ func TestDestroyerCancel(t *testing.T) {
}, },
statusEvents: []pollevent.Event{ statusEvents: []pollevent.Event{
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: testutil.ToIdentifier(t, resources["deployment"]), Identifier: testutil.ToIdentifier(t, resources["deployment"]),
Status: status.InProgressStatus, Status: status.InProgressStatus,
@ -70,7 +70,7 @@ func TestDestroyerCancel(t *testing.T) {
}, },
}, },
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: testutil.ToIdentifier(t, resources["deployment"]), Identifier: testutil.ToIdentifier(t, resources["deployment"]),
Status: status.InProgressStatus, Status: status.InProgressStatus,
@ -184,7 +184,7 @@ func TestDestroyerCancel(t *testing.T) {
}, },
statusEvents: []pollevent.Event{ statusEvents: []pollevent.Event{
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: testutil.ToIdentifier(t, resources["deployment"]), Identifier: testutil.ToIdentifier(t, resources["deployment"]),
Status: status.InProgressStatus, Status: status.InProgressStatus,
@ -192,7 +192,7 @@ func TestDestroyerCancel(t *testing.T) {
}, },
}, },
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: testutil.ToIdentifier(t, resources["deployment"]), Identifier: testutil.ToIdentifier(t, resources["deployment"]),
Status: status.NotFoundStatus, Status: status.NotFoundStatus,

View File

@ -22,8 +22,8 @@ import (
type InventoryPolicyApplyFilter struct { type InventoryPolicyApplyFilter struct {
Client dynamic.Interface Client dynamic.Interface
Mapper meta.RESTMapper Mapper meta.RESTMapper
Inv inventory.InventoryInfo Inv inventory.Info
InvPolicy inventory.InventoryPolicy InvPolicy inventory.Policy
} }
// Name returns a filter identifier for logging. // Name returns a filter identifier for logging.
@ -38,7 +38,7 @@ func (ipaf InventoryPolicyApplyFilter) Filter(obj *unstructured.Unstructured) (b
if obj == nil { if obj == nil {
return true, "missing object", nil return true, "missing object", nil
} }
if ipaf.InvPolicy == inventory.AdoptAll { if ipaf.InvPolicy == inventory.PolicyAdoptAll {
return false, "", nil return false, "", nil
} }
// Object must be retrieved from the cluster to get the inventory id. // Object must be retrieved from the cluster to get the inventory id.
@ -54,7 +54,7 @@ func (ipaf InventoryPolicyApplyFilter) Filter(obj *unstructured.Unstructured) (b
// if an object should be applied. // if an object should be applied.
canApply, err := inventory.CanApply(ipaf.Inv, clusterObj, ipaf.InvPolicy) canApply, err := inventory.CanApply(ipaf.Inv, clusterObj, ipaf.InvPolicy)
if !canApply { if !canApply {
invMatch := inventory.InventoryIDMatch(ipaf.Inv, clusterObj) invMatch := inventory.IDMatch(ipaf.Inv, clusterObj)
reason := fmt.Sprintf("inventory policy prevented apply (inventoryIDMatchStatus: %q, inventoryPolicy: %q)", reason := fmt.Sprintf("inventory policy prevented apply (inventoryIDMatchStatus: %q, inventoryPolicy: %q)",
invMatch, ipaf.InvPolicy) invMatch, ipaf.InvPolicy)
return true, reason, err return true, reason, err

View File

@ -29,56 +29,56 @@ func TestInventoryPolicyApplyFilter(t *testing.T) {
tests := map[string]struct { tests := map[string]struct {
inventoryID string inventoryID string
objInventoryID string objInventoryID string
policy inventory.InventoryPolicy policy inventory.Policy
filtered bool filtered bool
isError bool isError bool
}{ }{
"inventory and object ids match, not filtered": { "inventory and object ids match, not filtered": {
inventoryID: "foo", inventoryID: "foo",
objInventoryID: "foo", objInventoryID: "foo",
policy: inventory.InventoryPolicyMustMatch, policy: inventory.PolicyMustMatch,
filtered: false, filtered: false,
isError: false, isError: false,
}, },
"inventory and object ids match and adopt, not filtered": { "inventory and object ids match and adopt, not filtered": {
inventoryID: "foo", inventoryID: "foo",
objInventoryID: "foo", objInventoryID: "foo",
policy: inventory.AdoptIfNoInventory, policy: inventory.PolicyAdoptIfNoInventory,
filtered: false, filtered: false,
isError: false, isError: false,
}, },
"inventory and object ids do no match and policy must match, filtered and error": { "inventory and object ids do no match and policy must match, filtered and error": {
inventoryID: "foo", inventoryID: "foo",
objInventoryID: "bar", objInventoryID: "bar",
policy: inventory.InventoryPolicyMustMatch, policy: inventory.PolicyMustMatch,
filtered: true, filtered: true,
isError: true, isError: true,
}, },
"inventory and object ids do no match and adopt if no inventory, filtered and error": { "inventory and object ids do no match and adopt if no inventory, filtered and error": {
inventoryID: "foo", inventoryID: "foo",
objInventoryID: "bar", objInventoryID: "bar",
policy: inventory.AdoptIfNoInventory, policy: inventory.PolicyAdoptIfNoInventory,
filtered: true, filtered: true,
isError: true, isError: true,
}, },
"inventory and object ids do no match and adopt all, not filtered": { "inventory and object ids do no match and adopt all, not filtered": {
inventoryID: "foo", inventoryID: "foo",
objInventoryID: "bar", objInventoryID: "bar",
policy: inventory.AdoptAll, policy: inventory.PolicyAdoptAll,
filtered: false, filtered: false,
isError: false, isError: false,
}, },
"object id empty and adopt all, not filtered": { "object id empty and adopt all, not filtered": {
inventoryID: "foo", inventoryID: "foo",
objInventoryID: "", objInventoryID: "",
policy: inventory.AdoptAll, policy: inventory.PolicyAdoptAll,
filtered: false, filtered: false,
isError: false, isError: false,
}, },
"object id empty and policy must match, filtered and error": { "object id empty and policy must match, filtered and error": {
inventoryID: "foo", inventoryID: "foo",
objInventoryID: "", objInventoryID: "",
policy: inventory.InventoryPolicyMustMatch, policy: inventory.PolicyMustMatch,
filtered: true, filtered: true,
isError: true, isError: true,
}, },

View File

@ -14,8 +14,8 @@ import (
// if an object should be pruned (deleted) because of the InventoryPolicy // if an object should be pruned (deleted) because of the InventoryPolicy
// and if the objects owning inventory identifier matchs the inventory id. // and if the objects owning inventory identifier matchs the inventory id.
type InventoryPolicyFilter struct { type InventoryPolicyFilter struct {
Inv inventory.InventoryInfo Inv inventory.Info
InvPolicy inventory.InventoryPolicy InvPolicy inventory.Policy
} }
// Name returns a filter identifier for logging. // Name returns a filter identifier for logging.
@ -30,7 +30,7 @@ func (ipf InventoryPolicyFilter) Filter(obj *unstructured.Unstructured) (bool, s
// Check the inventory id "match" and the adopt policy to determine // Check the inventory id "match" and the adopt policy to determine
// if an object should be pruned (deleted). // if an object should be pruned (deleted).
if !inventory.CanPrune(ipf.Inv, obj, ipf.InvPolicy) { if !inventory.CanPrune(ipf.Inv, obj, ipf.InvPolicy) {
invMatch := inventory.InventoryIDMatch(ipf.Inv, obj) invMatch := inventory.IDMatch(ipf.Inv, obj)
reason := fmt.Sprintf("inventory policy prevented deletion (inventoryIDMatchStatus: %q, inventoryPolicy: %q)", reason := fmt.Sprintf("inventory policy prevented deletion (inventoryIDMatchStatus: %q, inventoryPolicy: %q)",
invMatch, ipf.InvPolicy) invMatch, ipf.InvPolicy)
return true, reason, nil return true, reason, nil

View File

@ -26,49 +26,49 @@ func TestInventoryPolicyFilter(t *testing.T) {
tests := map[string]struct { tests := map[string]struct {
inventoryID string inventoryID string
objInventoryID string objInventoryID string
policy inventory.InventoryPolicy policy inventory.Policy
filtered bool filtered bool
}{ }{
"inventory and object ids match, not filtered": { "inventory and object ids match, not filtered": {
inventoryID: "foo", inventoryID: "foo",
objInventoryID: "foo", objInventoryID: "foo",
policy: inventory.InventoryPolicyMustMatch, policy: inventory.PolicyMustMatch,
filtered: false, filtered: false,
}, },
"inventory and object ids match and adopt, not filtered": { "inventory and object ids match and adopt, not filtered": {
inventoryID: "foo", inventoryID: "foo",
objInventoryID: "foo", objInventoryID: "foo",
policy: inventory.AdoptIfNoInventory, policy: inventory.PolicyAdoptIfNoInventory,
filtered: false, filtered: false,
}, },
"inventory and object ids do no match and policy must match, filtered": { "inventory and object ids do no match and policy must match, filtered": {
inventoryID: "foo", inventoryID: "foo",
objInventoryID: "bar", objInventoryID: "bar",
policy: inventory.InventoryPolicyMustMatch, policy: inventory.PolicyMustMatch,
filtered: true, filtered: true,
}, },
"inventory and object ids do no match and adopt if no inventory, filtered": { "inventory and object ids do no match and adopt if no inventory, filtered": {
inventoryID: "foo", inventoryID: "foo",
objInventoryID: "bar", objInventoryID: "bar",
policy: inventory.AdoptIfNoInventory, policy: inventory.PolicyAdoptIfNoInventory,
filtered: true, filtered: true,
}, },
"inventory and object ids do no match and adopt all, not filtered": { "inventory and object ids do no match and adopt all, not filtered": {
inventoryID: "foo", inventoryID: "foo",
objInventoryID: "bar", objInventoryID: "bar",
policy: inventory.AdoptAll, policy: inventory.PolicyAdoptAll,
filtered: false, filtered: false,
}, },
"object id empty and adopt all, not filtered": { "object id empty and adopt all, not filtered": {
inventoryID: "foo", inventoryID: "foo",
objInventoryID: "", objInventoryID: "",
policy: inventory.AdoptAll, policy: inventory.PolicyAdoptAll,
filtered: false, filtered: false,
}, },
"object id empty and policy must match, filtered": { "object id empty and policy must match, filtered": {
inventoryID: "foo", inventoryID: "foo",
objInventoryID: "", objInventoryID: "",
policy: inventory.InventoryPolicyMustMatch, policy: inventory.PolicyMustMatch,
filtered: true, filtered: true,
}, },
} }

View File

@ -10,8 +10,8 @@ import (
"sigs.k8s.io/cli-utils/pkg/object" "sigs.k8s.io/cli-utils/pkg/object"
) )
// InfoHelper provides functions for interacting with Info objects. // Helper provides functions for interacting with Info objects.
type InfoHelper interface { type Helper interface {
// UpdateInfo sets the mapping and client for the provided Info // UpdateInfo sets the mapping and client for the provided Info
// object. This must be called at a time when all needed resource // object. This must be called at a time when all needed resource
// types are available in the RESTMapper. // types are available in the RESTMapper.
@ -20,19 +20,19 @@ type InfoHelper interface {
BuildInfo(obj *unstructured.Unstructured) (*resource.Info, error) BuildInfo(obj *unstructured.Unstructured) (*resource.Info, error)
} }
func NewInfoHelper(mapper meta.RESTMapper, unstructuredClientForMapping func(*meta.RESTMapping) (resource.RESTClient, error)) *infoHelper { func NewHelper(mapper meta.RESTMapper, unstructuredClientForMapping func(*meta.RESTMapping) (resource.RESTClient, error)) Helper {
return &infoHelper{ return &helper{
mapper: mapper, mapper: mapper,
unstructuredClientForMapping: unstructuredClientForMapping, unstructuredClientForMapping: unstructuredClientForMapping,
} }
} }
type infoHelper struct { type helper struct {
mapper meta.RESTMapper mapper meta.RESTMapper
unstructuredClientForMapping func(*meta.RESTMapping) (resource.RESTClient, error) unstructuredClientForMapping func(*meta.RESTMapping) (resource.RESTClient, error)
} }
func (ih *infoHelper) UpdateInfo(info *resource.Info) error { func (ih *helper) UpdateInfo(info *resource.Info) error {
gvk := info.Object.GetObjectKind().GroupVersionKind() gvk := info.Object.GetObjectKind().GroupVersionKind()
mapping, err := ih.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) mapping, err := ih.mapper.RESTMapping(gvk.GroupKind(), gvk.Version)
if err != nil { if err != nil {
@ -48,7 +48,7 @@ func (ih *infoHelper) UpdateInfo(info *resource.Info) error {
return nil return nil
} }
func (ih *infoHelper) BuildInfo(obj *unstructured.Unstructured) (*resource.Info, error) { func (ih *helper) BuildInfo(obj *unstructured.Unstructured) (*resource.Info, error) {
info, err := object.UnstructuredToInfo(obj) info, err := object.UnstructuredToInfo(obj)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -33,6 +33,7 @@ func CreateEventFactory(isDelete bool, groupName string) EventFactory {
// PruneEventFactory implements EventFactory interface as a concrete // PruneEventFactory implements EventFactory interface as a concrete
// representation of for prune events. // representation of for prune events.
//nolint:revive // stuttering ok because Prune is a type of PruneEvent
type PruneEventFactory struct { type PruneEventFactory struct {
groupName string groupName string
} }

View File

@ -31,14 +31,14 @@ import (
// Pruner implements GetPruneObjs to calculate which objects to prune and Prune // Pruner implements GetPruneObjs to calculate which objects to prune and Prune
// to delete them. // to delete them.
type Pruner struct { type Pruner struct {
InvClient inventory.InventoryClient InvClient inventory.Client
Client dynamic.Interface Client dynamic.Interface
Mapper meta.RESTMapper Mapper meta.RESTMapper
} }
// NewPruner returns a new Pruner. // NewPruner returns a new Pruner.
// Returns an error if dependency injection fails using the factory. // Returns an error if dependency injection fails using the factory.
func NewPruner(factory util.Factory, invClient inventory.InventoryClient) (*Pruner, error) { func NewPruner(factory util.Factory, invClient inventory.Client) (*Pruner, error) {
// Client/Builder fields from the Factory. // Client/Builder fields from the Factory.
client, err := factory.DynamicClient() client, err := factory.DynamicClient()
if err != nil { if err != nil {
@ -204,7 +204,7 @@ func (p *Pruner) removeInventoryAnnotation(obj *unstructured.Unstructured) (*uns
// objects minus the set of currently applied objects. Returns an error // objects minus the set of currently applied objects. Returns an error
// if one occurs. // if one occurs.
func (p *Pruner) GetPruneObjs( func (p *Pruner) GetPruneObjs(
inv inventory.InventoryInfo, inv inventory.Info,
objs object.UnstructuredSet, objs object.UnstructuredSet,
opts Options, opts Options,
) (object.UnstructuredSet, error) { ) (object.UnstructuredSet, error) {

View File

@ -122,7 +122,7 @@ metadata:
// Returns a inventory object with the inventory set from // Returns a inventory object with the inventory set from
// the passed "children". // the passed "children".
func createInventoryInfo(children ...*unstructured.Unstructured) inventory.InventoryInfo { func createInventoryInfo(children ...*unstructured.Unstructured) inventory.Info {
inventoryObjCopy := inventoryObj.DeepCopy() inventoryObjCopy := inventoryObj.DeepCopy()
wrappedInv := inventory.WrapInventoryObj(inventoryObjCopy) wrappedInv := inventory.WrapInventoryObj(inventoryObjCopy)
objs := object.UnstructuredSetToObjMetadataSet(children) objs := object.UnstructuredSetToObjMetadataSet(children)
@ -455,7 +455,7 @@ func TestPrune(t *testing.T) {
} }
pruneIds := object.UnstructuredSetToObjMetadataSet(tc.pruneObjs) pruneIds := object.UnstructuredSetToObjMetadataSet(tc.pruneObjs)
po := Pruner{ po := Pruner{
InvClient: inventory.NewFakeInventoryClient(pruneIds), InvClient: inventory.NewFakeClient(pruneIds),
Client: fake.NewSimpleDynamicClient(scheme.Scheme, objs...), Client: fake.NewSimpleDynamicClient(scheme.Scheme, objs...),
Mapper: testrestmapper.TestOnlyStaticRESTMapper(scheme.Scheme, Mapper: testrestmapper.TestOnlyStaticRESTMapper(scheme.Scheme,
scheme.Scheme.PrioritizedVersionsAllGroups()...), scheme.Scheme.PrioritizedVersionsAllGroups()...),
@ -535,7 +535,7 @@ func TestPruneDeletionPrevention(t *testing.T) {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
pruneID := object.UnstructuredToObjMetadata(tc.pruneObj) pruneID := object.UnstructuredToObjMetadata(tc.pruneObj)
po := Pruner{ po := Pruner{
InvClient: inventory.NewFakeInventoryClient(object.ObjMetadataSet{pruneID}), InvClient: inventory.NewFakeClient(object.ObjMetadataSet{pruneID}),
Client: fake.NewSimpleDynamicClient(scheme.Scheme, tc.pruneObj), Client: fake.NewSimpleDynamicClient(scheme.Scheme, tc.pruneObj),
Mapper: testrestmapper.TestOnlyStaticRESTMapper(scheme.Scheme, Mapper: testrestmapper.TestOnlyStaticRESTMapper(scheme.Scheme,
scheme.Scheme.PrioritizedVersionsAllGroups()...), scheme.Scheme.PrioritizedVersionsAllGroups()...),
@ -629,7 +629,7 @@ func TestPruneWithErrors(t *testing.T) {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
pruneIds := object.UnstructuredSetToObjMetadataSet(tc.pruneObjs) pruneIds := object.UnstructuredSetToObjMetadataSet(tc.pruneObjs)
po := Pruner{ po := Pruner{
InvClient: inventory.NewFakeInventoryClient(pruneIds), InvClient: inventory.NewFakeClient(pruneIds),
// Set up the fake dynamic client to recognize all objects, and the RESTMapper. // Set up the fake dynamic client to recognize all objects, and the RESTMapper.
Client: &fakeDynamicClient{ Client: &fakeDynamicClient{
resourceInterface: &failureNamespaceClient{}, resourceInterface: &failureNamespaceClient{},
@ -720,7 +720,7 @@ func TestGetPruneObjs(t *testing.T) {
objs = append(objs, obj) objs = append(objs, obj)
} }
po := Pruner{ po := Pruner{
InvClient: inventory.NewFakeInventoryClient(object.UnstructuredSetToObjMetadataSet(tc.prevInventory)), InvClient: inventory.NewFakeClient(object.UnstructuredSetToObjMetadataSet(tc.prevInventory)),
Client: fake.NewSimpleDynamicClient(scheme.Scheme, objs...), Client: fake.NewSimpleDynamicClient(scheme.Scheme, objs...),
Mapper: testrestmapper.TestOnlyStaticRESTMapper(scheme.Scheme, Mapper: testrestmapper.TestOnlyStaticRESTMapper(scheme.Scheme,
scheme.Scheme.PrioritizedVersionsAllGroups()...), scheme.Scheme.PrioritizedVersionsAllGroups()...),
@ -834,7 +834,7 @@ func TestPrune_PropagationPolicy(t *testing.T) {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
captureClient := &optionsCaptureNamespaceClient{} captureClient := &optionsCaptureNamespaceClient{}
po := Pruner{ po := Pruner{
InvClient: inventory.NewFakeInventoryClient(object.ObjMetadataSet{}), InvClient: inventory.NewFakeClient(object.ObjMetadataSet{}),
Client: &fakeDynamicClient{ Client: &fakeDynamicClient{
resourceInterface: captureClient, resourceInterface: captureClient,
}, },

View File

@ -41,9 +41,9 @@ type TaskQueueBuilder struct {
Pruner *prune.Pruner Pruner *prune.Pruner
DynamicClient dynamic.Interface DynamicClient dynamic.Interface
OpenAPIGetter discovery.OpenAPISchemaInterface OpenAPIGetter discovery.OpenAPISchemaInterface
InfoHelper info.InfoHelper InfoHelper info.Helper
Mapper meta.RESTMapper Mapper meta.RESTMapper
InvClient inventory.InventoryClient InvClient inventory.Client
// Collector is used to collect validation errors and invalid objects. // Collector is used to collect validation errors and invalid objects.
// Invalid objects will be filtered and not be injected into tasks. // Invalid objects will be filtered and not be injected into tasks.
Collector *validation.Collector Collector *validation.Collector
@ -92,7 +92,7 @@ type Options struct {
DryRunStrategy common.DryRunStrategy DryRunStrategy common.DryRunStrategy
PrunePropagationPolicy metav1.DeletionPropagation PrunePropagationPolicy metav1.DeletionPropagation
PruneTimeout time.Duration PruneTimeout time.Duration
InventoryPolicy inventory.InventoryPolicy InventoryPolicy inventory.Policy
} }
// Build returns the queue of tasks that have been created // Build returns the queue of tasks that have been created
@ -102,7 +102,7 @@ func (t *TaskQueueBuilder) Build() *TaskQueue {
// AppendInvAddTask appends an inventory add task to the task queue. // AppendInvAddTask appends an inventory add task to the task queue.
// Returns a pointer to the Builder to chain function calls. // Returns a pointer to the Builder to chain function calls.
func (t *TaskQueueBuilder) AppendInvAddTask(inv inventory.InventoryInfo, applyObjs object.UnstructuredSet, func (t *TaskQueueBuilder) AppendInvAddTask(inv inventory.Info, applyObjs object.UnstructuredSet,
dryRun common.DryRunStrategy) *TaskQueueBuilder { dryRun common.DryRunStrategy) *TaskQueueBuilder {
applyObjs = t.Collector.FilterInvalidObjects(applyObjs) applyObjs = t.Collector.FilterInvalidObjects(applyObjs)
klog.V(2).Infoln("adding inventory add task (%d objects)", len(applyObjs)) klog.V(2).Infoln("adding inventory add task (%d objects)", len(applyObjs))
@ -113,13 +113,13 @@ func (t *TaskQueueBuilder) AppendInvAddTask(inv inventory.InventoryInfo, applyOb
Objects: applyObjs, Objects: applyObjs,
DryRun: dryRun, DryRun: dryRun,
}) })
t.invAddCounter += 1 t.invAddCounter++
return t return t
} }
// AppendInvSetTask appends an inventory set task to the task queue. // AppendInvSetTask appends an inventory set task to the task queue.
// Returns a pointer to the Builder to chain function calls. // Returns a pointer to the Builder to chain function calls.
func (t *TaskQueueBuilder) AppendInvSetTask(inv inventory.InventoryInfo, dryRun common.DryRunStrategy) *TaskQueueBuilder { func (t *TaskQueueBuilder) AppendInvSetTask(inv inventory.Info, dryRun common.DryRunStrategy) *TaskQueueBuilder {
klog.V(2).Infoln("adding inventory set task") klog.V(2).Infoln("adding inventory set task")
prevInvIds, _ := t.InvClient.GetClusterObjs(inv) prevInvIds, _ := t.InvClient.GetClusterObjs(inv)
t.tasks = append(t.tasks, &task.InvSetTask{ t.tasks = append(t.tasks, &task.InvSetTask{
@ -129,13 +129,13 @@ func (t *TaskQueueBuilder) AppendInvSetTask(inv inventory.InventoryInfo, dryRun
PrevInventory: prevInvIds, PrevInventory: prevInvIds,
DryRun: dryRun, DryRun: dryRun,
}) })
t.invSetCounter += 1 t.invSetCounter++
return t return t
} }
// AppendDeleteInvTask appends to the task queue a task to delete the inventory object. // AppendDeleteInvTask appends to the task queue a task to delete the inventory object.
// Returns a pointer to the Builder to chain function calls. // Returns a pointer to the Builder to chain function calls.
func (t *TaskQueueBuilder) AppendDeleteInvTask(inv inventory.InventoryInfo, dryRun common.DryRunStrategy) *TaskQueueBuilder { func (t *TaskQueueBuilder) AppendDeleteInvTask(inv inventory.Info, dryRun common.DryRunStrategy) *TaskQueueBuilder {
klog.V(2).Infoln("adding delete inventory task") klog.V(2).Infoln("adding delete inventory task")
t.tasks = append(t.tasks, &task.DeleteInvTask{ t.tasks = append(t.tasks, &task.DeleteInvTask{
TaskName: fmt.Sprintf("delete-inventory-%d", t.deleteInvCounter), TaskName: fmt.Sprintf("delete-inventory-%d", t.deleteInvCounter),
@ -143,7 +143,7 @@ func (t *TaskQueueBuilder) AppendDeleteInvTask(inv inventory.InventoryInfo, dryR
InvInfo: inv, InvInfo: inv,
DryRun: dryRun, DryRun: dryRun,
}) })
t.deleteInvCounter += 1 t.deleteInvCounter++
return t return t
} }
@ -165,7 +165,7 @@ func (t *TaskQueueBuilder) AppendApplyTask(applyObjs object.UnstructuredSet,
InfoHelper: t.InfoHelper, InfoHelper: t.InfoHelper,
Mapper: t.Mapper, Mapper: t.Mapper,
}) })
t.applyCounter += 1 t.applyCounter++
return t return t
} }
@ -182,7 +182,7 @@ func (t *TaskQueueBuilder) AppendWaitTask(waitIds object.ObjMetadataSet, conditi
waitTimeout, waitTimeout,
t.Mapper), t.Mapper),
) )
t.waitCounter += 1 t.waitCounter++
return t return t
} }
@ -203,7 +203,7 @@ func (t *TaskQueueBuilder) AppendPruneTask(pruneObjs object.UnstructuredSet,
Destroy: t.Destroy, Destroy: t.Destroy,
}, },
) )
t.pruneCounter += 1 t.pruneCounter++
return t return t
} }

View File

@ -421,7 +421,7 @@ func TestTaskQueueBuilder_AppendApplyWaitTasks(t *testing.T) {
} }
applyIds := object.UnstructuredSetToObjMetadataSet(tc.applyObjs) applyIds := object.UnstructuredSetToObjMetadataSet(tc.applyObjs)
fakeInvClient := inventory.NewFakeInventoryClient(applyIds) fakeInvClient := inventory.NewFakeClient(applyIds)
vCollector := &validation.Collector{} vCollector := &validation.Collector{}
tqb := TaskQueueBuilder{ tqb := TaskQueueBuilder{
Pruner: pruner, Pruner: pruner,
@ -786,7 +786,7 @@ func TestTaskQueueBuilder_AppendPruneWaitTasks(t *testing.T) {
} }
pruneIds := object.UnstructuredSetToObjMetadataSet(tc.pruneObjs) pruneIds := object.UnstructuredSetToObjMetadataSet(tc.pruneObjs)
fakeInvClient := inventory.NewFakeInventoryClient(pruneIds) fakeInvClient := inventory.NewFakeClient(pruneIds)
vCollector := &validation.Collector{} vCollector := &validation.Collector{}
tqb := TaskQueueBuilder{ tqb := TaskQueueBuilder{
Pruner: pruner, Pruner: pruner,

View File

@ -49,7 +49,7 @@ type ApplyTask struct {
DynamicClient dynamic.Interface DynamicClient dynamic.Interface
OpenAPIGetter discovery.OpenAPISchemaInterface OpenAPIGetter discovery.OpenAPISchemaInterface
InfoHelper info.InfoHelper InfoHelper info.Helper
Mapper meta.RESTMapper Mapper meta.RESTMapper
Objects object.UnstructuredSet Objects object.UnstructuredSet
Filters []filter.ValidationFilter Filters []filter.ValidationFilter

View File

@ -19,8 +19,8 @@ import (
// resources have been deleted. // resources have been deleted.
type DeleteInvTask struct { type DeleteInvTask struct {
TaskName string TaskName string
InvClient inventory.InventoryClient InvClient inventory.Client
InvInfo inventory.InventoryInfo InvInfo inventory.Info
DryRun common.DryRunStrategy DryRun common.DryRunStrategy
} }

View File

@ -37,7 +37,7 @@ func TestDeleteInvTask(t *testing.T) {
} }
for name, tc := range testCases { for name, tc := range testCases {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
client := inventory.NewFakeInventoryClient(object.ObjMetadataSet{}) client := inventory.NewFakeClient(object.ObjMetadataSet{})
client.Err = tc.err client.Err = tc.err
eventChannel := make(chan event.Event) eventChannel := make(chan event.Event)
resourceCache := cache.NewResourceCacheMap() resourceCache := cache.NewResourceCacheMap()

View File

@ -23,8 +23,8 @@ var (
// before the actual object is applied. // before the actual object is applied.
type InvAddTask struct { type InvAddTask struct {
TaskName string TaskName string
InvClient inventory.InventoryClient InvClient inventory.Client
InvInfo inventory.InventoryInfo InvInfo inventory.Info
Objects object.UnstructuredSet Objects object.UnstructuredSet
DryRun common.DryRunStrategy DryRun common.DryRunStrategy
} }
@ -74,7 +74,7 @@ func (i *InvAddTask) StatusUpdate(_ *taskrunner.TaskContext, _ object.ObjMetadat
// inventoryNamespaceInSet returns the the namespace the passed inventory // inventoryNamespaceInSet returns the the namespace the passed inventory
// object will be applied to, or nil if this namespace object does not exist // object will be applied to, or nil if this namespace object does not exist
// in the passed slice "infos" or the inventory object is cluster-scoped. // in the passed slice "infos" or the inventory object is cluster-scoped.
func inventoryNamespaceInSet(inv inventory.InventoryInfo, objs object.UnstructuredSet) *unstructured.Unstructured { func inventoryNamespaceInSet(inv inventory.Info, objs object.UnstructuredSet) *unstructured.Unstructured {
if inv == nil { if inv == nil {
return nil return nil
} }

View File

@ -107,7 +107,7 @@ func TestInvAddTask(t *testing.T) {
for name, tc := range tests { for name, tc := range tests {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
client := inventory.NewFakeInventoryClient(tc.initialObjs) client := inventory.NewFakeClient(tc.initialObjs)
eventChannel := make(chan event.Event) eventChannel := make(chan event.Event)
resourceCache := cache.NewResourceCacheMap() resourceCache := cache.NewResourceCacheMap()
context := taskrunner.NewTaskContext(eventChannel, resourceCache) context := taskrunner.NewTaskContext(eventChannel, resourceCache)
@ -142,7 +142,7 @@ func TestInventoryNamespaceInSet(t *testing.T) {
inventoryNamespace := createNamespace(namespace) inventoryNamespace := createNamespace(namespace)
tests := map[string]struct { tests := map[string]struct {
inv inventory.InventoryInfo inv inventory.Info
objects []*unstructured.Unstructured objects []*unstructured.Unstructured
namespace *unstructured.Unstructured namespace *unstructured.Unstructured
}{ }{

View File

@ -16,8 +16,8 @@ import (
// inventory references at the end of the apply/prune. // inventory references at the end of the apply/prune.
type InvSetTask struct { type InvSetTask struct {
TaskName string TaskName string
InvClient inventory.InventoryClient InvClient inventory.Client
InvInfo inventory.InventoryInfo InvInfo inventory.Info
PrevInventory object.ObjMetadataSet PrevInventory object.ObjMetadataSet
DryRun common.DryRunStrategy DryRun common.DryRunStrategy
} }

View File

@ -163,7 +163,7 @@ func TestInvSetTask(t *testing.T) {
for name, tc := range tests { for name, tc := range tests {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
client := inventory.NewFakeInventoryClient(object.ObjMetadataSet{}) client := inventory.NewFakeClient(object.ObjMetadataSet{})
eventChannel := make(chan event.Event) eventChannel := make(chan event.Event)
resourceCache := cache.NewResourceCacheMap() resourceCache := cache.NewResourceCacheMap()
context := taskrunner.NewTaskContext(eventChannel, resourceCache) context := taskrunner.NewTaskContext(eventChannel, resourceCache)

View File

@ -17,19 +17,19 @@ import (
) )
// NewTaskStatusRunner returns a new TaskStatusRunner. // NewTaskStatusRunner returns a new TaskStatusRunner.
func NewTaskStatusRunner(identifiers object.ObjMetadataSet, statusPoller poller.Poller) *taskStatusRunner { func NewTaskStatusRunner(identifiers object.ObjMetadataSet, statusPoller poller.Poller) *TaskStatusRunner {
return &taskStatusRunner{ return &TaskStatusRunner{
identifiers: identifiers, Identifiers: identifiers,
statusPoller: statusPoller, StatusPoller: statusPoller,
} }
} }
// taskStatusRunner is a taskRunner that executes a set of // TaskStatusRunner is a taskRunner that executes a set of
// tasks while at the same time uses the statusPoller to // tasks while at the same time uses the statusPoller to
// keep track of the status of the resources. // keep track of the status of the resources.
type taskStatusRunner struct { type TaskStatusRunner struct {
identifiers object.ObjMetadataSet Identifiers object.ObjMetadataSet
statusPoller poller.Poller StatusPoller poller.Poller
} }
// Options defines properties that is passed along to // Options defines properties that is passed along to
@ -49,7 +49,7 @@ type Options struct {
// validation of wait conditions. // validation of wait conditions.
// - eventChannel is written to with events based on status updates, if // - eventChannel is written to with events based on status updates, if
// emitStatusEvents is true. // emitStatusEvents is true.
func (tsr *taskStatusRunner) Run( func (tsr *TaskStatusRunner) Run(
ctx context.Context, ctx context.Context,
taskContext *TaskContext, taskContext *TaskContext,
taskQueue chan Task, taskQueue chan Task,
@ -59,7 +59,7 @@ func (tsr *taskStatusRunner) Run(
// If taskStatusRunner.Run is cancelled, baseRunner.run will exit early, // If taskStatusRunner.Run is cancelled, baseRunner.run will exit early,
// causing the poller to be cancelled. // causing the poller to be cancelled.
statusCtx, cancelFunc := context.WithCancel(context.Background()) statusCtx, cancelFunc := context.WithCancel(context.Background())
statusChannel := tsr.statusPoller.Poll(statusCtx, tsr.identifiers, polling.PollOptions{ statusChannel := tsr.StatusPoller.Poll(statusCtx, tsr.Identifiers, polling.PollOptions{
PollInterval: opts.PollInterval, PollInterval: opts.PollInterval,
}) })
@ -113,7 +113,7 @@ func (tsr *taskStatusRunner) Run(
// An error event on the statusChannel means the StatusPoller // An error event on the statusChannel means the StatusPoller
// has encountered a problem so it can't continue. This means // has encountered a problem so it can't continue. This means
// the statusChannel will be closed soon. // the statusChannel will be closed soon.
if statusEvent.EventType == pollevent.ErrorEvent { if statusEvent.Type == pollevent.ErrorEvent {
abort = true abort = true
abortReason = fmt.Errorf("polling for status failed: %v", abortReason = fmt.Errorf("polling for status failed: %v",
statusEvent.Error) statusEvent.Error)

View File

@ -68,14 +68,14 @@ func TestBaseRunner(t *testing.T) {
statusEventsDelay: 5 * time.Second, statusEventsDelay: 5 * time.Second,
statusEvents: []pollevent.Event{ statusEvents: []pollevent.Event{
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: cmID, Identifier: cmID,
Status: status.CurrentStatus, Status: status.CurrentStatus,
}, },
}, },
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: depID, Identifier: depID,
Status: status.CurrentStatus, Status: status.CurrentStatus,
@ -129,7 +129,7 @@ func TestBaseRunner(t *testing.T) {
statusEventsDelay: time.Second, statusEventsDelay: time.Second,
statusEvents: []pollevent.Event{ statusEvents: []pollevent.Event{
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: cmID, Identifier: cmID,
Status: status.CurrentStatus, Status: status.CurrentStatus,
@ -176,14 +176,14 @@ func TestBaseRunner(t *testing.T) {
statusEventsDelay: time.Second, statusEventsDelay: time.Second,
statusEvents: []pollevent.Event{ statusEvents: []pollevent.Event{
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: cmID, Identifier: cmID,
Status: status.CurrentStatus, Status: status.CurrentStatus,
}, },
}, },
{ {
EventType: pollevent.ResourceUpdateEvent, Type: pollevent.ResourceUpdateEvent,
Resource: &pollevent.ResourceStatus{ Resource: &pollevent.ResourceStatus{
Identifier: depID, Identifier: depID,
Status: status.InProgressStatus, Status: status.InProgressStatus,
@ -427,7 +427,7 @@ func TestBaseRunnerCancellation(t *testing.T) {
statusEventsDelay: 2 * time.Second, statusEventsDelay: 2 * time.Second,
statusEvents: []pollevent.Event{ statusEvents: []pollevent.Event{
{ {
EventType: pollevent.ErrorEvent, Type: pollevent.ErrorEvent,
Error: testError, Error: testError,
}, },
}, },

View File

@ -10,33 +10,33 @@ import (
"sigs.k8s.io/cli-utils/pkg/object" "sigs.k8s.io/cli-utils/pkg/object"
) )
// FakeInventoryClient is a testing implementation of the InventoryClient interface. // FakeClient is a testing implementation of the Client interface.
type FakeInventoryClient struct { type FakeClient struct {
Objs object.ObjMetadataSet Objs object.ObjMetadataSet
Err error Err error
} }
var ( var (
_ InventoryClient = &FakeInventoryClient{} _ Client = &FakeClient{}
_ InventoryClientFactory = FakeInventoryClientFactory{} _ ClientFactory = FakeClientFactory{}
) )
type FakeInventoryClientFactory object.ObjMetadataSet type FakeClientFactory object.ObjMetadataSet
func (f FakeInventoryClientFactory) NewInventoryClient(cmdutil.Factory) (InventoryClient, error) { func (f FakeClientFactory) NewClient(cmdutil.Factory) (Client, error) {
return NewFakeInventoryClient(object.ObjMetadataSet(f)), nil return NewFakeClient(object.ObjMetadataSet(f)), nil
} }
// NewFakeInventoryClient returns a FakeInventoryClient. // NewFakeClient returns a FakeClient.
func NewFakeInventoryClient(initObjs object.ObjMetadataSet) *FakeInventoryClient { func NewFakeClient(initObjs object.ObjMetadataSet) *FakeClient {
return &FakeInventoryClient{ return &FakeClient{
Objs: initObjs, Objs: initObjs,
Err: nil, Err: nil,
} }
} }
// GetClusterObjs returns currently stored set of objects. // GetClusterObjs returns currently stored set of objects.
func (fic *FakeInventoryClient) GetClusterObjs(InventoryInfo) (object.ObjMetadataSet, error) { func (fic *FakeClient) GetClusterObjs(Info) (object.ObjMetadataSet, error) {
if fic.Err != nil { if fic.Err != nil {
return object.ObjMetadataSet{}, fic.Err return object.ObjMetadataSet{}, fic.Err
} }
@ -46,7 +46,7 @@ func (fic *FakeInventoryClient) GetClusterObjs(InventoryInfo) (object.ObjMetadat
// Merge stores the passed objects with the current stored cluster inventory // Merge stores the passed objects with the current stored cluster inventory
// objects. Returns the set difference of the current set of objects minus // objects. Returns the set difference of the current set of objects minus
// the passed set of objects, or an error if one is set up. // the passed set of objects, or an error if one is set up.
func (fic *FakeInventoryClient) Merge(_ InventoryInfo, objs object.ObjMetadataSet, _ common.DryRunStrategy) (object.ObjMetadataSet, error) { func (fic *FakeClient) Merge(_ Info, objs object.ObjMetadataSet, _ common.DryRunStrategy) (object.ObjMetadataSet, error) {
if fic.Err != nil { if fic.Err != nil {
return object.ObjMetadataSet{}, fic.Err return object.ObjMetadataSet{}, fic.Err
} }
@ -58,7 +58,7 @@ func (fic *FakeInventoryClient) Merge(_ InventoryInfo, objs object.ObjMetadataSe
// Replace the stored cluster inventory objs with the passed obj, or an // Replace the stored cluster inventory objs with the passed obj, or an
// error if one is set up. // error if one is set up.
func (fic *FakeInventoryClient) Replace(_ InventoryInfo, objs object.ObjMetadataSet, _ common.DryRunStrategy) error { func (fic *FakeClient) Replace(_ Info, objs object.ObjMetadataSet, _ common.DryRunStrategy) error {
if fic.Err != nil { if fic.Err != nil {
return fic.Err return fic.Err
} }
@ -67,14 +67,14 @@ func (fic *FakeInventoryClient) Replace(_ InventoryInfo, objs object.ObjMetadata
} }
// DeleteInventoryObj returns an error if one is forced; does nothing otherwise. // DeleteInventoryObj returns an error if one is forced; does nothing otherwise.
func (fic *FakeInventoryClient) DeleteInventoryObj(InventoryInfo, common.DryRunStrategy) error { func (fic *FakeClient) DeleteInventoryObj(Info, common.DryRunStrategy) error {
if fic.Err != nil { if fic.Err != nil {
return fic.Err return fic.Err
} }
return nil return nil
} }
func (fic *FakeInventoryClient) ApplyInventoryNamespace(*unstructured.Unstructured, common.DryRunStrategy) error { func (fic *FakeClient) ApplyInventoryNamespace(*unstructured.Unstructured, common.DryRunStrategy) error {
if fic.Err != nil { if fic.Err != nil {
return fic.Err return fic.Err
} }
@ -82,19 +82,19 @@ func (fic *FakeInventoryClient) ApplyInventoryNamespace(*unstructured.Unstructur
} }
// SetError forces an error on the subsequent client call if it returns an error. // SetError forces an error on the subsequent client call if it returns an error.
func (fic *FakeInventoryClient) SetError(err error) { func (fic *FakeClient) SetError(err error) {
fic.Err = err fic.Err = err
} }
// ClearError clears the force error // ClearError clears the force error
func (fic *FakeInventoryClient) ClearError() { func (fic *FakeClient) ClearError() {
fic.Err = nil fic.Err = nil
} }
func (fic *FakeInventoryClient) GetClusterInventoryInfo(InventoryInfo) (*unstructured.Unstructured, error) { func (fic *FakeClient) GetClusterInventoryInfo(Info) (*unstructured.Unstructured, error) {
return nil, nil return nil, nil
} }
func (fic *FakeInventoryClient) GetClusterInventoryObjs(_ InventoryInfo) (object.UnstructuredSet, error) { func (fic *FakeClient) GetClusterInventoryObjs(_ Info) (object.UnstructuredSet, error) {
return object.UnstructuredSet{}, nil return object.UnstructuredSet{}, nil
} }

View File

@ -0,0 +1,25 @@
// Code generated by "stringer -type=IDMatchStatus"; DO NOT EDIT.
package inventory
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[Empty-0]
_ = x[Match-1]
_ = x[NoMatch-2]
}
const _IDMatchStatus_name = "EmptyMatchNoMatch"
var _IDMatchStatus_index = [...]uint8{0, 5, 10, 17}
func (i IDMatchStatus) String() string {
if i < 0 || i >= IDMatchStatus(len(_IDMatchStatus_index)-1) {
return "IDMatchStatus(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _IDMatchStatus_name[_IDMatchStatus_index[i]:_IDMatchStatus_index[i+1]]
}

View File

@ -6,18 +6,18 @@ package inventory
import cmdutil "k8s.io/kubectl/pkg/cmd/util" import cmdutil "k8s.io/kubectl/pkg/cmd/util"
var ( var (
_ InventoryClientFactory = ClusterInventoryClientFactory{} _ ClientFactory = ClusterClientFactory{}
) )
// InventoryClientFactory is a factory that constructs new InventoryClient instances. // ClientFactory is a factory that constructs new Client instances.
type InventoryClientFactory interface { type ClientFactory interface {
NewInventoryClient(factory cmdutil.Factory) (InventoryClient, error) NewClient(factory cmdutil.Factory) (Client, error)
} }
// ClusterInventoryClientFactory is a factory that creates instances of ClusterInventoryClient inventory client. // ClusterClientFactory is a factory that creates instances of ClusterClient inventory client.
type ClusterInventoryClientFactory struct { type ClusterClientFactory struct {
} }
func (ClusterInventoryClientFactory) NewInventoryClient(factory cmdutil.Factory) (InventoryClient, error) { func (ClusterClientFactory) NewClient(factory cmdutil.Factory) (Client, error) {
return NewInventoryClient(factory, WrapInventoryObj, InvInfoToConfigMap) return NewClient(factory, WrapInventoryObj, InvInfoToConfigMap)
} }

View File

@ -20,49 +20,48 @@ import (
"sigs.k8s.io/cli-utils/pkg/object" "sigs.k8s.io/cli-utils/pkg/object"
) )
// InventoryClient expresses an interface for interacting with // Client expresses an interface for interacting with
// objects which store references to objects (inventory objects). // objects which store references to objects (inventory objects).
type InventoryClient interface { type Client interface {
// GetClusterObjs returns the set of previously applied objects as ObjMetadata, // GetClusterObjs returns the set of previously applied objects as ObjMetadata,
// or an error if one occurred. This set of previously applied object references // or an error if one occurred. This set of previously applied object references
// is stored in the inventory objects living in the cluster. // is stored in the inventory objects living in the cluster.
GetClusterObjs(inv InventoryInfo) (object.ObjMetadataSet, error) GetClusterObjs(inv Info) (object.ObjMetadataSet, error)
// Merge applies the union of the passed objects with the currently // Merge applies the union of the passed objects with the currently
// stored objects in the inventory object. Returns the set of // stored objects in the inventory object. Returns the set of
// objects which are not in the passed objects (objects to be pruned). // objects which are not in the passed objects (objects to be pruned).
// Otherwise, returns an error if one happened. // Otherwise, returns an error if one happened.
Merge(inv InventoryInfo, objs object.ObjMetadataSet, dryRun common.DryRunStrategy) (object.ObjMetadataSet, error) Merge(inv Info, objs object.ObjMetadataSet, dryRun common.DryRunStrategy) (object.ObjMetadataSet, error)
// Replace replaces the set of objects stored in the inventory // Replace replaces the set of objects stored in the inventory
// object with the passed set of objects, or an error if one occurs. // object with the passed set of objects, or an error if one occurs.
Replace(inv InventoryInfo, objs object.ObjMetadataSet, dryRun common.DryRunStrategy) error Replace(inv Info, objs object.ObjMetadataSet, dryRun common.DryRunStrategy) error
// DeleteInventoryObj deletes the passed inventory object from the APIServer. // DeleteInventoryObj deletes the passed inventory object from the APIServer.
DeleteInventoryObj(inv InventoryInfo, dryRun common.DryRunStrategy) error DeleteInventoryObj(inv Info, dryRun common.DryRunStrategy) error
// ApplyInventoryNamespace applies the Namespace that the inventory object should be in. // ApplyInventoryNamespace applies the Namespace that the inventory object should be in.
ApplyInventoryNamespace(invNamespace *unstructured.Unstructured, dryRun common.DryRunStrategy) error ApplyInventoryNamespace(invNamespace *unstructured.Unstructured, dryRun common.DryRunStrategy) error
// GetClusterInventoryInfo returns the cluster inventory object. // GetClusterInventoryInfo returns the cluster inventory object.
GetClusterInventoryInfo(inv InventoryInfo) (*unstructured.Unstructured, error) GetClusterInventoryInfo(inv Info) (*unstructured.Unstructured, error)
// GetClusterInventoryObjs looks up the inventory objects from the cluster. // GetClusterInventoryObjs looks up the inventory objects from the cluster.
GetClusterInventoryObjs(inv InventoryInfo) (object.UnstructuredSet, error) GetClusterInventoryObjs(inv Info) (object.UnstructuredSet, error)
} }
// ClusterInventoryClient is a concrete implementation of the // ClusterClient is a concrete implementation of the
// InventoryClient interface. // Client interface.
type ClusterInventoryClient struct { type ClusterClient struct {
dc dynamic.Interface dc dynamic.Interface
discoveryClient discovery.CachedDiscoveryInterface discoveryClient discovery.CachedDiscoveryInterface
mapper meta.RESTMapper mapper meta.RESTMapper
InventoryFactoryFunc StorageFactoryFunc InventoryFactoryFunc StorageFactoryFunc
invToUnstructuredFunc InventoryToUnstructuredFunc invToUnstructuredFunc ToUnstructuredFunc
} }
var _ InventoryClient = &ClusterInventoryClient{} var _ Client = &ClusterClient{}
var _ InventoryClient = &ClusterInventoryClient{}
// NewInventoryClient returns a concrete implementation of the // NewClient returns a concrete implementation of the
// InventoryClient interface or an error. // Client interface or an error.
func NewInventoryClient(factory cmdutil.Factory, func NewClient(factory cmdutil.Factory,
invFunc StorageFactoryFunc, invFunc StorageFactoryFunc,
invToUnstructuredFunc InventoryToUnstructuredFunc) (*ClusterInventoryClient, error) { invToUnstructuredFunc ToUnstructuredFunc) (*ClusterClient, error) {
dc, err := factory.DynamicClient() dc, err := factory.DynamicClient()
if err != nil { if err != nil {
return nil, err return nil, err
@ -75,14 +74,14 @@ func NewInventoryClient(factory cmdutil.Factory,
if err != nil { if err != nil {
return nil, err return nil, err
} }
clusterInventoryClient := ClusterInventoryClient{ clusterClient := ClusterClient{
dc: dc, dc: dc,
discoveryClient: discoveryClinet, discoveryClient: discoveryClinet,
mapper: mapper, mapper: mapper,
InventoryFactoryFunc: invFunc, InventoryFactoryFunc: invFunc,
invToUnstructuredFunc: invToUnstructuredFunc, invToUnstructuredFunc: invToUnstructuredFunc,
} }
return &clusterInventoryClient, nil return &clusterClient, nil
} }
// Merge stores the union of the passed objects with the objects currently // Merge stores the union of the passed objects with the objects currently
@ -92,7 +91,7 @@ func NewInventoryClient(factory cmdutil.Factory,
// to prune. Creates the initial cluster inventory object storing the passed // to prune. Creates the initial cluster inventory object storing the passed
// objects if an inventory object does not exist. Returns an error if one // objects if an inventory object does not exist. Returns an error if one
// occurred. // occurred.
func (cic *ClusterInventoryClient) Merge(localInv InventoryInfo, objs object.ObjMetadataSet, dryRun common.DryRunStrategy) (object.ObjMetadataSet, error) { func (cic *ClusterClient) Merge(localInv Info, objs object.ObjMetadataSet, dryRun common.DryRunStrategy) (object.ObjMetadataSet, error) {
pruneIds := object.ObjMetadataSet{} pruneIds := object.ObjMetadataSet{}
invObj := cic.invToUnstructuredFunc(localInv) invObj := cic.invToUnstructuredFunc(localInv)
clusterInv, err := cic.GetClusterInventoryInfo(localInv) clusterInv, err := cic.GetClusterInventoryInfo(localInv)
@ -159,7 +158,7 @@ func (cic *ClusterInventoryClient) Merge(localInv InventoryInfo, objs object.Obj
// Replace stores the passed objects in the cluster inventory object, or // Replace stores the passed objects in the cluster inventory object, or
// an error if one occurred. // an error if one occurred.
func (cic *ClusterInventoryClient) Replace(localInv InventoryInfo, objs object.ObjMetadataSet, dryRun common.DryRunStrategy) error { func (cic *ClusterClient) Replace(localInv Info, objs object.ObjMetadataSet, dryRun common.DryRunStrategy) error {
// Skip entire function for dry-run. // Skip entire function for dry-run.
if dryRun.ClientOrServerDryRun() { if dryRun.ClientOrServerDryRun() {
klog.V(4).Infoln("dry-run replace inventory object: not applied") klog.V(4).Infoln("dry-run replace inventory object: not applied")
@ -194,7 +193,7 @@ func (cic *ClusterInventoryClient) Replace(localInv InventoryInfo, objs object.O
} }
// replaceInventory stores the passed objects into the passed inventory object. // replaceInventory stores the passed objects into the passed inventory object.
func (cic *ClusterInventoryClient) replaceInventory(inv *unstructured.Unstructured, objs object.ObjMetadataSet) (*unstructured.Unstructured, error) { func (cic *ClusterClient) replaceInventory(inv *unstructured.Unstructured, objs object.ObjMetadataSet) (*unstructured.Unstructured, error) {
wrappedInv := cic.InventoryFactoryFunc(inv) wrappedInv := cic.InventoryFactoryFunc(inv)
if err := wrappedInv.Store(objs); err != nil { if err := wrappedInv.Store(objs); err != nil {
return nil, err return nil, err
@ -207,7 +206,7 @@ func (cic *ClusterInventoryClient) replaceInventory(inv *unstructured.Unstructur
} }
// DeleteInventoryObj deletes the inventory object from the cluster. // DeleteInventoryObj deletes the inventory object from the cluster.
func (cic *ClusterInventoryClient) DeleteInventoryObj(localInv InventoryInfo, dryRun common.DryRunStrategy) error { func (cic *ClusterClient) DeleteInventoryObj(localInv Info, dryRun common.DryRunStrategy) error {
if localInv == nil { if localInv == nil {
return fmt.Errorf("retrieving cluster inventory object with nil local inventory") return fmt.Errorf("retrieving cluster inventory object with nil local inventory")
} }
@ -221,7 +220,7 @@ func (cic *ClusterInventoryClient) DeleteInventoryObj(localInv InventoryInfo, dr
} }
} }
func (cic *ClusterInventoryClient) deleteInventoryObjsByLabel(inv InventoryInfo, dryRun common.DryRunStrategy) error { func (cic *ClusterClient) deleteInventoryObjsByLabel(inv Info, dryRun common.DryRunStrategy) error {
clusterInvObjs, err := cic.getClusterInventoryObjsByLabel(inv) clusterInvObjs, err := cic.getClusterInventoryObjsByLabel(inv)
if err != nil { if err != nil {
return err return err
@ -236,7 +235,7 @@ func (cic *ClusterInventoryClient) deleteInventoryObjsByLabel(inv InventoryInfo,
// GetClusterObjs returns the objects stored in the cluster inventory object, or // GetClusterObjs returns the objects stored in the cluster inventory object, or
// an error if one occurred. // an error if one occurred.
func (cic *ClusterInventoryClient) GetClusterObjs(localInv InventoryInfo) (object.ObjMetadataSet, error) { func (cic *ClusterClient) GetClusterObjs(localInv Info) (object.ObjMetadataSet, error) {
var objs object.ObjMetadataSet var objs object.ObjMetadataSet
clusterInv, err := cic.GetClusterInventoryInfo(localInv) clusterInv, err := cic.GetClusterInventoryInfo(localInv)
if err != nil { if err != nil {
@ -259,7 +258,7 @@ func (cic *ClusterInventoryClient) GetClusterObjs(localInv InventoryInfo) (objec
// //
// TODO(seans3): Remove the special case code to merge multiple cluster inventory // TODO(seans3): Remove the special case code to merge multiple cluster inventory
// objects once we've determined that this case is no longer possible. // objects once we've determined that this case is no longer possible.
func (cic *ClusterInventoryClient) GetClusterInventoryInfo(inv InventoryInfo) (*unstructured.Unstructured, error) { func (cic *ClusterClient) GetClusterInventoryInfo(inv Info) (*unstructured.Unstructured, error) {
clusterInvObjects, err := cic.GetClusterInventoryObjs(inv) clusterInvObjects, err := cic.GetClusterInventoryObjs(inv)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to read inventory objects from cluster: %w", err) return nil, fmt.Errorf("failed to read inventory objects from cluster: %w", err)
@ -274,7 +273,7 @@ func (cic *ClusterInventoryClient) GetClusterInventoryInfo(inv InventoryInfo) (*
return clusterInv, nil return clusterInv, nil
} }
func (cic *ClusterInventoryClient) getClusterInventoryObjsByLabel(inv InventoryInfo) (object.UnstructuredSet, error) { func (cic *ClusterClient) getClusterInventoryObjsByLabel(inv Info) (object.UnstructuredSet, error) {
localInv := cic.invToUnstructuredFunc(inv) localInv := cic.invToUnstructuredFunc(inv)
if localInv == nil { if localInv == nil {
return nil, fmt.Errorf("retrieving cluster inventory object with nil local inventory") return nil, fmt.Errorf("retrieving cluster inventory object with nil local inventory")
@ -306,7 +305,7 @@ func (cic *ClusterInventoryClient) getClusterInventoryObjsByLabel(inv InventoryI
return invList, nil return invList, nil
} }
func (cic *ClusterInventoryClient) getClusterInventoryObjsByName(inv InventoryInfo) (object.UnstructuredSet, error) { func (cic *ClusterClient) getClusterInventoryObjsByName(inv Info) (object.UnstructuredSet, error) {
localInv := cic.invToUnstructuredFunc(inv) localInv := cic.invToUnstructuredFunc(inv)
if localInv == nil { if localInv == nil {
return nil, fmt.Errorf("retrieving cluster inventory object with nil local inventory") return nil, fmt.Errorf("retrieving cluster inventory object with nil local inventory")
@ -329,7 +328,7 @@ func (cic *ClusterInventoryClient) getClusterInventoryObjsByName(inv InventoryIn
return object.UnstructuredSet{clusterInv}, nil return object.UnstructuredSet{clusterInv}, nil
} }
func (cic *ClusterInventoryClient) GetClusterInventoryObjs(inv InventoryInfo) (object.UnstructuredSet, error) { func (cic *ClusterClient) GetClusterInventoryObjs(inv Info) (object.UnstructuredSet, error) {
if inv == nil { if inv == nil {
return nil, fmt.Errorf("inventoryInfo must be specified") return nil, fmt.Errorf("inventoryInfo must be specified")
} }
@ -348,7 +347,7 @@ func (cic *ClusterInventoryClient) GetClusterInventoryObjs(inv InventoryInfo) (o
} }
// applyInventoryObj applies the passed inventory object to the APIServer. // applyInventoryObj applies the passed inventory object to the APIServer.
func (cic *ClusterInventoryClient) applyInventoryObj(obj *unstructured.Unstructured, dryRun common.DryRunStrategy) (*unstructured.Unstructured, error) { func (cic *ClusterClient) applyInventoryObj(obj *unstructured.Unstructured, dryRun common.DryRunStrategy) (*unstructured.Unstructured, error) {
if dryRun.ClientOrServerDryRun() { if dryRun.ClientOrServerDryRun() {
klog.V(4).Infof("dry-run apply inventory object: not applied") klog.V(4).Infof("dry-run apply inventory object: not applied")
return obj.DeepCopy(), nil return obj.DeepCopy(), nil
@ -368,7 +367,7 @@ func (cic *ClusterInventoryClient) applyInventoryObj(obj *unstructured.Unstructu
} }
// createInventoryObj creates the passed inventory object on the APIServer. // createInventoryObj creates the passed inventory object on the APIServer.
func (cic *ClusterInventoryClient) createInventoryObj(obj *unstructured.Unstructured, dryRun common.DryRunStrategy) (*unstructured.Unstructured, error) { func (cic *ClusterClient) createInventoryObj(obj *unstructured.Unstructured, dryRun common.DryRunStrategy) (*unstructured.Unstructured, error) {
if dryRun.ClientOrServerDryRun() { if dryRun.ClientOrServerDryRun() {
klog.V(4).Infof("dry-run create inventory object: not created") klog.V(4).Infof("dry-run create inventory object: not created")
return obj.DeepCopy(), nil return obj.DeepCopy(), nil
@ -395,7 +394,7 @@ func (cic *ClusterInventoryClient) createInventoryObj(obj *unstructured.Unstruct
// deleteInventoryObjByName deletes the passed inventory object from the APIServer, or // deleteInventoryObjByName deletes the passed inventory object from the APIServer, or
// an error if one occurs. // an error if one occurs.
func (cic *ClusterInventoryClient) deleteInventoryObjByName(obj *unstructured.Unstructured, dryRun common.DryRunStrategy) error { func (cic *ClusterClient) deleteInventoryObjByName(obj *unstructured.Unstructured, dryRun common.DryRunStrategy) error {
if dryRun.ClientOrServerDryRun() { if dryRun.ClientOrServerDryRun() {
klog.V(4).Infof("dry-run delete inventory object: not deleted") klog.V(4).Infof("dry-run delete inventory object: not deleted")
return nil return nil
@ -416,7 +415,7 @@ func (cic *ClusterInventoryClient) deleteInventoryObjByName(obj *unstructured.Un
// ApplyInventoryNamespace creates the passed namespace if it does not already // ApplyInventoryNamespace creates the passed namespace if it does not already
// exist, or returns an error if one happened. NOTE: No error if already exists. // exist, or returns an error if one happened. NOTE: No error if already exists.
func (cic *ClusterInventoryClient) ApplyInventoryNamespace(obj *unstructured.Unstructured, dryRun common.DryRunStrategy) error { func (cic *ClusterClient) ApplyInventoryNamespace(obj *unstructured.Unstructured, dryRun common.DryRunStrategy) error {
if dryRun.ClientOrServerDryRun() { if dryRun.ClientOrServerDryRun() {
klog.V(4).Infof("dry-run apply inventory namespace (%s): not applied", obj.GetName()) klog.V(4).Infof("dry-run apply inventory namespace (%s): not applied", obj.GetName())
return nil return nil
@ -439,11 +438,11 @@ func (cic *ClusterInventoryClient) ApplyInventoryNamespace(obj *unstructured.Uns
} }
// getMapping returns the RESTMapping for the provided resource. // getMapping returns the RESTMapping for the provided resource.
func (cic *ClusterInventoryClient) getMapping(obj *unstructured.Unstructured) (*meta.RESTMapping, error) { func (cic *ClusterClient) getMapping(obj *unstructured.Unstructured) (*meta.RESTMapping, error) {
return cic.mapper.RESTMapping(obj.GroupVersionKind().GroupKind(), obj.GroupVersionKind().Version) return cic.mapper.RESTMapping(obj.GroupVersionKind().GroupKind(), obj.GroupVersionKind().Version)
} }
func (cic *ClusterInventoryClient) updateStatus(obj *unstructured.Unstructured, dryRun common.DryRunStrategy) error { func (cic *ClusterClient) updateStatus(obj *unstructured.Unstructured, dryRun common.DryRunStrategy) error {
if dryRun.ClientOrServerDryRun() { if dryRun.ClientOrServerDryRun() {
klog.V(4).Infof("dry-run update inventory status: not updated") klog.V(4).Infof("dry-run update inventory status: not updated")
return nil return nil
@ -481,7 +480,7 @@ func (cic *ClusterInventoryClient) updateStatus(obj *unstructured.Unstructured,
} }
// hasSubResource checks if a resource has the given subresource using the discovery client. // hasSubResource checks if a resource has the given subresource using the discovery client.
func (cic *ClusterInventoryClient) hasSubResource(groupVersion, resource, subresource string) (bool, error) { func (cic *ClusterClient) hasSubResource(groupVersion, resource, subresource string) (bool, error) {
resources, err := cic.discoveryClient.ServerResourcesForGroupVersion(groupVersion) resources, err := cic.discoveryClient.ServerResourcesForGroupVersion(groupVersion)
if err != nil { if err != nil {
return false, err return false, err

View File

@ -19,7 +19,7 @@ import (
func TestGetClusterInventoryInfo(t *testing.T) { func TestGetClusterInventoryInfo(t *testing.T) {
tests := map[string]struct { tests := map[string]struct {
inv InventoryInfo inv Info
localObjs object.ObjMetadataSet localObjs object.ObjMetadataSet
isError bool isError bool
}{ }{
@ -55,7 +55,7 @@ func TestGetClusterInventoryInfo(t *testing.T) {
for name, tc := range tests { for name, tc := range tests {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
invClient, err := NewInventoryClient(tf, invClient, err := NewClient(tf,
WrapInventoryObj, InvInfoToConfigMap) WrapInventoryObj, InvInfoToConfigMap)
require.NoError(t, err) require.NoError(t, err)
@ -89,7 +89,7 @@ func TestGetClusterInventoryInfo(t *testing.T) {
func TestMerge(t *testing.T) { func TestMerge(t *testing.T) {
tests := map[string]struct { tests := map[string]struct {
localInv InventoryInfo localInv Info
localObjs object.ObjMetadataSet localObjs object.ObjMetadataSet
clusterObjs object.ObjMetadataSet clusterObjs object.ObjMetadataSet
pruneObjs object.ObjMetadataSet pruneObjs object.ObjMetadataSet
@ -160,7 +160,7 @@ func TestMerge(t *testing.T) {
tf.FakeDynamicClient.PrependReactor("list", "configmaps", toReactionFunc(tc.clusterObjs)) tf.FakeDynamicClient.PrependReactor("list", "configmaps", toReactionFunc(tc.clusterObjs))
// Create the local inventory object storing "tc.localObjs" // Create the local inventory object storing "tc.localObjs"
invClient, err := NewInventoryClient(tf, invClient, err := NewClient(tf,
WrapInventoryObj, InvInfoToConfigMap) WrapInventoryObj, InvInfoToConfigMap)
require.NoError(t, err) require.NoError(t, err)
@ -185,7 +185,7 @@ func TestMerge(t *testing.T) {
func TestCreateInventory(t *testing.T) { func TestCreateInventory(t *testing.T) {
tests := map[string]struct { tests := map[string]struct {
inv InventoryInfo inv Info
localObjs object.ObjMetadataSet localObjs object.ObjMetadataSet
error string error string
}{ }{
@ -225,7 +225,7 @@ func TestCreateInventory(t *testing.T) {
return true, nil, nil return true, nil, nil
}) })
invClient, err := NewInventoryClient(tf, invClient, err := NewClient(tf,
WrapInventoryObj, InvInfoToConfigMap) WrapInventoryObj, InvInfoToConfigMap)
require.NoError(t, err) require.NoError(t, err)
inv := invClient.invToUnstructuredFunc(tc.inv) inv := invClient.invToUnstructuredFunc(tc.inv)
@ -289,7 +289,7 @@ func TestReplace(t *testing.T) {
defer tf.Cleanup() defer tf.Cleanup()
// Client and server dry-run do not throw errors. // Client and server dry-run do not throw errors.
invClient, err := NewInventoryClient(tf, WrapInventoryObj, InvInfoToConfigMap) invClient, err := NewClient(tf, WrapInventoryObj, InvInfoToConfigMap)
require.NoError(t, err) require.NoError(t, err)
err = invClient.Replace(copyInventory(), object.ObjMetadataSet{}, common.DryRunClient) err = invClient.Replace(copyInventory(), object.ObjMetadataSet{}, common.DryRunClient)
if err != nil { if err != nil {
@ -303,7 +303,7 @@ func TestReplace(t *testing.T) {
for name, tc := range tests { for name, tc := range tests {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
// Create inventory client, and store the cluster objs in the inventory object. // Create inventory client, and store the cluster objs in the inventory object.
invClient, err := NewInventoryClient(tf, invClient, err := NewClient(tf,
WrapInventoryObj, InvInfoToConfigMap) WrapInventoryObj, InvInfoToConfigMap)
require.NoError(t, err) require.NoError(t, err)
wrappedInv := invClient.InventoryFactoryFunc(inventoryObj) wrappedInv := invClient.InventoryFactoryFunc(inventoryObj)
@ -334,7 +334,7 @@ func TestReplace(t *testing.T) {
func TestGetClusterObjs(t *testing.T) { func TestGetClusterObjs(t *testing.T) {
tests := map[string]struct { tests := map[string]struct {
localInv InventoryInfo localInv Info
clusterObjs object.ObjMetadataSet clusterObjs object.ObjMetadataSet
isError bool isError bool
}{ }{
@ -366,7 +366,7 @@ func TestGetClusterObjs(t *testing.T) {
defer tf.Cleanup() defer tf.Cleanup()
tf.FakeDynamicClient.PrependReactor("list", "configmaps", toReactionFunc(tc.clusterObjs)) tf.FakeDynamicClient.PrependReactor("list", "configmaps", toReactionFunc(tc.clusterObjs))
invClient, err := NewInventoryClient(tf, invClient, err := NewClient(tf,
WrapInventoryObj, InvInfoToConfigMap) WrapInventoryObj, InvInfoToConfigMap)
require.NoError(t, err) require.NoError(t, err)
clusterObjs, err := invClient.GetClusterObjs(tc.localInv) clusterObjs, err := invClient.GetClusterObjs(tc.localInv)
@ -388,7 +388,7 @@ func TestGetClusterObjs(t *testing.T) {
func TestDeleteInventoryObj(t *testing.T) { func TestDeleteInventoryObj(t *testing.T) {
tests := map[string]struct { tests := map[string]struct {
inv InventoryInfo inv Info
localObjs object.ObjMetadataSet localObjs object.ObjMetadataSet
}{ }{
"Nil local inventory object is an error": { "Nil local inventory object is an error": {
@ -421,7 +421,7 @@ func TestDeleteInventoryObj(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace(testNamespace) tf := cmdtesting.NewTestFactory().WithNamespace(testNamespace)
defer tf.Cleanup() defer tf.Cleanup()
invClient, err := NewInventoryClient(tf, invClient, err := NewClient(tf,
WrapInventoryObj, InvInfoToConfigMap) WrapInventoryObj, InvInfoToConfigMap)
require.NoError(t, err) require.NoError(t, err)
inv := invClient.invToUnstructuredFunc(tc.inv) inv := invClient.invToUnstructuredFunc(tc.inv)

View File

@ -3,19 +3,19 @@
package inventory package inventory
type InventoryStrategy string type Strategy string
const ( const (
NameStrategy InventoryStrategy = "name" NameStrategy Strategy = "name"
LabelStrategy InventoryStrategy = "label" LabelStrategy Strategy = "label"
) )
// InventoryInfo provides the minimal information for the applier // Info provides the minimal information for the applier
// to create, look up and update an inventory. // to create, look up and update an inventory.
// The inventory object can be any type, the Provider in the applier // The inventory object can be any type, the Provider in the applier
// needs to know how to create, look up and update it based // needs to know how to create, look up and update it based
// on the InventoryInfo. // on the Info.
type InventoryInfo interface { type Info interface {
// Namespace of the inventory object. // Namespace of the inventory object.
// It should be the value of the field .metadata.namespace. // It should be the value of the field .metadata.namespace.
Namespace() string Namespace() string
@ -29,5 +29,5 @@ type InventoryInfo interface {
// if the Id is necessary and how to use it for pruning objects. // if the Id is necessary and how to use it for pruning objects.
ID() string ID() string
Strategy() InventoryStrategy Strategy() Strategy
} }

View File

@ -40,9 +40,9 @@ type Storage interface {
// interface from the passed info object. // interface from the passed info object.
type StorageFactoryFunc func(*unstructured.Unstructured) Storage type StorageFactoryFunc func(*unstructured.Unstructured) Storage
// InventoryToUnstructuredFunc returns the unstructured object for the // ToUnstructuredFunc returns the unstructured object for the
// given InventoryInfo. // given Info.
type InventoryToUnstructuredFunc func(InventoryInfo) *unstructured.Unstructured type ToUnstructuredFunc func(Info) *unstructured.Unstructured
// FindInventoryObj returns the "Inventory" object (ConfigMap with // FindInventoryObj returns the "Inventory" object (ConfigMap with
// inventory label) if it exists, or nil if it does not exist. // inventory label) if it exists, or nil if it does not exist.

View File

@ -39,6 +39,7 @@ func (g MultipleInventoryObjError) Error() string {
return multipleInventoryErrorStr return multipleInventoryErrorStr
} }
//nolint:revive // redundant name in exported error ok
type InventoryNamespaceInSet struct { type InventoryNamespaceInSet struct {
Namespace string Namespace string
} }
@ -46,3 +47,28 @@ type InventoryNamespaceInSet struct {
func (g InventoryNamespaceInSet) Error() string { func (g InventoryNamespaceInSet) Error() string {
return inventoryNamespaceInSet return inventoryNamespaceInSet
} }
//nolint:revive // redundant name in exported error ok
type InventoryOverlapError struct {
err error
}
func (e *InventoryOverlapError) Error() string {
return e.err.Error()
}
func NewInventoryOverlapError(err error) *InventoryOverlapError {
return &InventoryOverlapError{err: err}
}
type NeedAdoptionError struct {
err error
}
func (e *NeedAdoptionError) Error() string {
return e.err.Error()
}
func NewNeedAdoptionError(err error) *NeedAdoptionError {
return &NeedAdoptionError{err: err}
}

View File

@ -416,12 +416,12 @@ func copyInventoryInfo() *unstructured.Unstructured {
return inventoryObj.DeepCopy() return inventoryObj.DeepCopy()
} }
func copyInventory() InventoryInfo { func copyInventory() Info {
u := inventoryObj.DeepCopy() u := inventoryObj.DeepCopy()
return WrapInventoryInfoObj(u) return WrapInventoryInfoObj(u)
} }
func storeObjsInInventory(info InventoryInfo, objs object.ObjMetadataSet) *unstructured.Unstructured { func storeObjsInInventory(info Info, objs object.ObjMetadataSet) *unstructured.Unstructured {
wrapped := WrapInventoryObj(InvInfoToConfigMap(info)) wrapped := WrapInventoryObj(InvInfoToConfigMap(info))
_ = wrapped.Store(objs) _ = wrapped.Store(objs)
inv, _ := wrapped.GetObject() inv, _ := wrapped.GetObject()

View File

@ -1,8 +1,8 @@
// Copyright 2020 The Kubernetes Authors. // Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// //
// Introduces the InventoryConfigMap struct which implements // Introduces the ConfigMap struct which implements
// the Inventory interface. The InventoryConfigMap wraps a // the Inventory interface. The ConfigMap wraps a
// ConfigMap resource which stores the set of inventory // ConfigMap resource which stores the set of inventory
// (object metadata). // (object metadata).
@ -17,62 +17,62 @@ import (
) )
// WrapInventoryObj takes a passed ConfigMap (as a resource.Info), // WrapInventoryObj takes a passed ConfigMap (as a resource.Info),
// wraps it with the InventoryConfigMap and upcasts the wrapper as // wraps it with the ConfigMap and upcasts the wrapper as
// an the Inventory interface. // an the Inventory interface.
func WrapInventoryObj(inv *unstructured.Unstructured) Storage { func WrapInventoryObj(inv *unstructured.Unstructured) Storage {
return &InventoryConfigMap{inv: inv} return &ConfigMap{inv: inv}
} }
// WrapInventoryInfoObj takes a passed ConfigMap (as a resource.Info), // WrapInventoryInfoObj takes a passed ConfigMap (as a resource.Info),
// wraps it with the InventoryConfigMap and upcasts the wrapper as // wraps it with the ConfigMap and upcasts the wrapper as
// an the InventoryInfo interface. // an the Info interface.
func WrapInventoryInfoObj(inv *unstructured.Unstructured) InventoryInfo { func WrapInventoryInfoObj(inv *unstructured.Unstructured) Info {
return &InventoryConfigMap{inv: inv} return &ConfigMap{inv: inv}
} }
func InvInfoToConfigMap(inv InventoryInfo) *unstructured.Unstructured { func InvInfoToConfigMap(inv Info) *unstructured.Unstructured {
icm, ok := inv.(*InventoryConfigMap) icm, ok := inv.(*ConfigMap)
if ok { if ok {
return icm.inv return icm.inv
} }
return nil return nil
} }
// InventoryConfigMap wraps a ConfigMap resource and implements // ConfigMap wraps a ConfigMap resource and implements
// the Inventory interface. This wrapper loads and stores the // the Inventory interface. This wrapper loads and stores the
// object metadata (inventory) to and from the wrapped ConfigMap. // object metadata (inventory) to and from the wrapped ConfigMap.
type InventoryConfigMap struct { type ConfigMap struct {
inv *unstructured.Unstructured inv *unstructured.Unstructured
objMetas object.ObjMetadataSet objMetas object.ObjMetadataSet
} }
var _ InventoryInfo = &InventoryConfigMap{} var _ Info = &ConfigMap{}
var _ Storage = &InventoryConfigMap{} var _ Storage = &ConfigMap{}
func (icm *InventoryConfigMap) Name() string { func (icm *ConfigMap) Name() string {
return icm.inv.GetName() return icm.inv.GetName()
} }
func (icm *InventoryConfigMap) Namespace() string { func (icm *ConfigMap) Namespace() string {
return icm.inv.GetNamespace() return icm.inv.GetNamespace()
} }
func (icm *InventoryConfigMap) ID() string { func (icm *ConfigMap) ID() string {
// Empty string if not set. // Empty string if not set.
return icm.inv.GetLabels()[common.InventoryLabel] return icm.inv.GetLabels()[common.InventoryLabel]
} }
func (icm *InventoryConfigMap) Strategy() InventoryStrategy { func (icm *ConfigMap) Strategy() Strategy {
return LabelStrategy return LabelStrategy
} }
func (icm *InventoryConfigMap) UnstructuredInventory() *unstructured.Unstructured { func (icm *ConfigMap) UnstructuredInventory() *unstructured.Unstructured {
return icm.inv return icm.inv
} }
// Load is an Inventory interface function returning the set of // Load is an Inventory interface function returning the set of
// object metadata from the wrapped ConfigMap, or an error. // object metadata from the wrapped ConfigMap, or an error.
func (icm *InventoryConfigMap) Load() (object.ObjMetadataSet, error) { func (icm *ConfigMap) Load() (object.ObjMetadataSet, error) {
objs := object.ObjMetadataSet{} objs := object.ObjMetadataSet{}
objMap, exists, err := unstructured.NestedStringMap(icm.inv.Object, "data") objMap, exists, err := unstructured.NestedStringMap(icm.inv.Object, "data")
if err != nil { if err != nil {
@ -94,14 +94,14 @@ func (icm *InventoryConfigMap) Load() (object.ObjMetadataSet, error) {
// Store is an Inventory interface function implemented to store // Store is an Inventory interface function implemented to store
// the object metadata in the wrapped ConfigMap. Actual storing // the object metadata in the wrapped ConfigMap. Actual storing
// happens in "GetObject". // happens in "GetObject".
func (icm *InventoryConfigMap) Store(objMetas object.ObjMetadataSet) error { func (icm *ConfigMap) Store(objMetas object.ObjMetadataSet) error {
icm.objMetas = objMetas icm.objMetas = objMetas
return nil return nil
} }
// GetObject returns the wrapped object (ConfigMap) as a resource.Info // GetObject returns the wrapped object (ConfigMap) as a resource.Info
// or an error if one occurs. // or an error if one occurs.
func (icm *InventoryConfigMap) GetObject() (*unstructured.Unstructured, error) { func (icm *ConfigMap) GetObject() (*unstructured.Unstructured, error) {
// Create the objMap of all the resources, and compute the hash. // Create the objMap of all the resources, and compute the hash.
objMap := buildObjMap(icm.objMetas) objMap := buildObjMap(icm.objMetas)
// Create the inventory object by copying the template. // Create the inventory object by copying the template.

View File

@ -1,25 +0,0 @@
// Code generated by "stringer -type=inventoryIDMatchStatus"; DO NOT EDIT.
package inventory
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[Empty-0]
_ = x[Match-1]
_ = x[NoMatch-2]
}
const _inventoryIDMatchStatus_name = "EmptyMatchNoMatch"
var _inventoryIDMatchStatus_index = [...]uint8{0, 5, 10, 17}
func (i inventoryIDMatchStatus) String() string {
if i < 0 || i >= inventoryIDMatchStatus(len(_inventoryIDMatchStatus_index)-1) {
return "inventoryIDMatchStatus(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _inventoryIDMatchStatus_name[_inventoryIDMatchStatus_index[i]:_inventoryIDMatchStatus_index[i+1]]
}

View File

@ -1,25 +0,0 @@
// Code generated by "stringer -type=InventoryPolicy"; DO NOT EDIT.
package inventory
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[InventoryPolicyMustMatch-0]
_ = x[AdoptIfNoInventory-1]
_ = x[AdoptAll-2]
}
const _InventoryPolicy_name = "InventoryPolicyMustMatchAdoptIfNoInventoryAdoptAll"
var _InventoryPolicy_index = [...]uint8{0, 24, 42, 50}
func (i InventoryPolicy) String() string {
if i < 0 || i >= InventoryPolicy(len(_InventoryPolicy_index)-1) {
return "InventoryPolicy(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _InventoryPolicy_name[_InventoryPolicy_index[i]:_InventoryPolicy_index[i+1]]
}

View File

@ -9,18 +9,18 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
) )
// InventoryPolicy defines if an inventory object can take over // Policy defines if an inventory object can take over
// objects that belong to another inventory object or don't // objects that belong to another inventory object or don't
// belong to any inventory object. // belong to any inventory object.
// This is done by determining if the apply/prune operation // This is done by determining if the apply/prune operation
// can go through for a resource based on the comparison // can go through for a resource based on the comparison
// the inventory-id value in the package and the owning-inventory // the inventory-id value in the package and the owning-inventory
// annotation in the live object. // annotation in the live object.
//go:generate stringer -type=InventoryPolicy //go:generate stringer -type=Policy -linecomment
type InventoryPolicy int type Policy int
const ( const (
// InvnetoryPolicyMustMatch: This policy enforces that the resources being applied can not // PolicyMustMatch: This policy enforces that the resources being applied can not
// have any overlap with objects in other inventories or objects that already exist // have any overlap with objects in other inventories or objects that already exist
// in the cluster but don't belong to an inventory. // in the cluster but don't belong to an inventory.
// //
@ -33,9 +33,9 @@ const (
// The prune operation can go through when // The prune operation can go through when
// - The owning-inventory annotation in the live object match with that // - The owning-inventory annotation in the live object match with that
// in the package. // in the package.
InventoryPolicyMustMatch InventoryPolicy = iota PolicyMustMatch Policy = iota // MustMatch
// AdoptIfNoInventory: This policy enforces that resources being applied // PolicyAdoptIfNoInventory: This policy enforces that resources being applied
// can not have any overlap with objects in other inventories, but are // can not have any overlap with objects in other inventories, but are
// permitted to take ownership of objects that don't belong to any inventories. // permitted to take ownership of objects that don't belong to any inventories.
// //
@ -52,9 +52,9 @@ const (
// - The owning-inventory annotation in the live object match with that // - The owning-inventory annotation in the live object match with that
// in the package. // in the package.
// - The live object doesn't have the owning-inventory annotation. // - The live object doesn't have the owning-inventory annotation.
AdoptIfNoInventory PolicyAdoptIfNoInventory // AdoptIfNoInventory
// AdoptAll: This policy will let the current inventory take ownership of any objects. // PolicyAdoptAll: This policy will let the current inventory take ownership of any objects.
// //
// The apply operation can go through for any resource in the package even if the // The apply operation can go through for any resource in the package even if the
// live object has an unmatched owning-inventory annotation. // live object has an unmatched owning-inventory annotation.
@ -63,24 +63,24 @@ const (
// - The owning-inventory annotation in the live object match or doesn't match with that // - The owning-inventory annotation in the live object match or doesn't match with that
// in the package. // in the package.
// - The live object doesn't have the owning-inventory annotation. // - The live object doesn't have the owning-inventory annotation.
AdoptAll PolicyAdoptAll // AdoptAll
) )
// OwningInventoryKey is the annotation key indicating the inventory owning an object. // OwningInventoryKey is the annotation key indicating the inventory owning an object.
const OwningInventoryKey = "config.k8s.io/owning-inventory" const OwningInventoryKey = "config.k8s.io/owning-inventory"
// inventoryIDMatchStatus represents the result of comparing the // IDMatchStatus represents the result of comparing the
// id from current inventory info and the inventory-id from a live object. // id from current inventory info and the inventory-id from a live object.
//go:generate stringer -type=inventoryIDMatchStatus //go:generate stringer -type=IDMatchStatus
type inventoryIDMatchStatus int type IDMatchStatus int
const ( const (
Empty inventoryIDMatchStatus = iota Empty IDMatchStatus = iota
Match Match
NoMatch NoMatch
) )
func InventoryIDMatch(inv InventoryInfo, obj *unstructured.Unstructured) inventoryIDMatchStatus { func IDMatch(inv Info, obj *unstructured.Unstructured) IDMatchStatus {
annotations := obj.GetAnnotations() annotations := obj.GetAnnotations()
value, found := annotations[OwningInventoryKey] value, found := annotations[OwningInventoryKey]
if !found { if !found {
@ -92,14 +92,14 @@ func InventoryIDMatch(inv InventoryInfo, obj *unstructured.Unstructured) invento
return NoMatch return NoMatch
} }
func CanApply(inv InventoryInfo, obj *unstructured.Unstructured, policy InventoryPolicy) (bool, error) { func CanApply(inv Info, obj *unstructured.Unstructured, policy Policy) (bool, error) {
if obj == nil { if obj == nil {
return true, nil return true, nil
} }
matchStatus := InventoryIDMatch(inv, obj) matchStatus := IDMatch(inv, obj)
switch matchStatus { switch matchStatus {
case Empty: case Empty:
if policy != InventoryPolicyMustMatch { if policy != PolicyMustMatch {
return true, nil return true, nil
} }
err := fmt.Errorf("can't adopt an object without the annotation %s", OwningInventoryKey) err := fmt.Errorf("can't adopt an object without the annotation %s", OwningInventoryKey)
@ -107,7 +107,7 @@ func CanApply(inv InventoryInfo, obj *unstructured.Unstructured, policy Inventor
case Match: case Match:
return true, nil return true, nil
case NoMatch: case NoMatch:
if policy == AdoptAll { if policy == PolicyAdoptAll {
return true, nil return true, nil
} }
err := fmt.Errorf("can't apply the resource since its annotation %s is a different inventory object", OwningInventoryKey) err := fmt.Errorf("can't apply the resource since its annotation %s is a different inventory object", OwningInventoryKey)
@ -117,23 +117,23 @@ func CanApply(inv InventoryInfo, obj *unstructured.Unstructured, policy Inventor
return false, nil return false, nil
} }
func CanPrune(inv InventoryInfo, obj *unstructured.Unstructured, policy InventoryPolicy) bool { func CanPrune(inv Info, obj *unstructured.Unstructured, policy Policy) bool {
if obj == nil { if obj == nil {
return false return false
} }
matchStatus := InventoryIDMatch(inv, obj) matchStatus := IDMatch(inv, obj)
switch matchStatus { switch matchStatus {
case Empty: case Empty:
return policy == AdoptIfNoInventory || policy == AdoptAll return policy == PolicyAdoptIfNoInventory || policy == PolicyAdoptAll
case Match: case Match:
return true return true
case NoMatch: case NoMatch:
return policy == AdoptAll return policy == PolicyAdoptAll
} }
return false return false
} }
func AddInventoryIDAnnotation(obj *unstructured.Unstructured, inv InventoryInfo) { func AddInventoryIDAnnotation(obj *unstructured.Unstructured, inv Info) {
annotations := obj.GetAnnotations() annotations := obj.GetAnnotations()
if annotations == nil { if annotations == nil {
annotations = make(map[string]string) annotations = make(map[string]string)
@ -141,27 +141,3 @@ func AddInventoryIDAnnotation(obj *unstructured.Unstructured, inv InventoryInfo)
annotations[OwningInventoryKey] = inv.ID() annotations[OwningInventoryKey] = inv.ID()
obj.SetAnnotations(annotations) obj.SetAnnotations(annotations)
} }
type InventoryOverlapError struct {
err error
}
func (e *InventoryOverlapError) Error() string {
return e.err.Error()
}
func NewInventoryOverlapError(err error) *InventoryOverlapError {
return &InventoryOverlapError{err: err}
}
type NeedAdoptionError struct {
err error
}
func (e *NeedAdoptionError) Error() string {
return e.err.Error()
}
func NewNeedAdoptionError(err error) *NeedAdoptionError {
return &NeedAdoptionError{err: err}
}

View File

@ -0,0 +1,25 @@
// Code generated by "stringer -type=Policy -linecomment"; DO NOT EDIT.
package inventory
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[PolicyMustMatch-0]
_ = x[PolicyAdoptIfNoInventory-1]
_ = x[PolicyAdoptAll-2]
}
const _Policy_name = "MustMatchAdoptIfNoInventoryAdoptAll"
var _Policy_index = [...]uint8{0, 9, 27, 35}
func (i Policy) String() string {
if i < 0 || i >= Policy(len(_Policy_index)-1) {
return "Policy(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _Policy_name[_Policy_index[i]:_Policy_index[i+1]]
}

View File

@ -25,7 +25,7 @@ func (i *fakeInventoryInfo) ID() string {
return i.id return i.id
} }
func (i *fakeInventoryInfo) Strategy() InventoryStrategy { func (i *fakeInventoryInfo) Strategy() Strategy {
return NameStrategy return NameStrategy
} }
@ -52,8 +52,8 @@ func TestInventoryIDMatch(t *testing.T) {
testcases := []struct { testcases := []struct {
name string name string
obj *unstructured.Unstructured obj *unstructured.Unstructured
inv InventoryInfo inv Info
expected inventoryIDMatchStatus expected IDMatchStatus
}{ }{
{ {
name: "empty", name: "empty",
@ -75,7 +75,7 @@ func TestInventoryIDMatch(t *testing.T) {
}, },
} }
for _, tc := range testcases { for _, tc := range testcases {
actual := InventoryIDMatch(tc.inv, tc.obj) actual := IDMatch(tc.inv, tc.obj)
if actual != tc.expected { if actual != tc.expected {
t.Errorf("expected %v, but got %v", tc.expected, actual) t.Errorf("expected %v, but got %v", tc.expected, actual)
} }
@ -86,8 +86,8 @@ func TestCanApply(t *testing.T) {
testcases := []struct { testcases := []struct {
name string name string
obj *unstructured.Unstructured obj *unstructured.Unstructured
inv InventoryInfo inv Info
policy InventoryPolicy policy Policy
canApply bool canApply bool
}{ }{
{ {
@ -100,63 +100,63 @@ func TestCanApply(t *testing.T) {
name: "empty with AdoptIfNoInventory", name: "empty with AdoptIfNoInventory",
obj: testObjectWithAnnotation("", ""), obj: testObjectWithAnnotation("", ""),
inv: &fakeInventoryInfo{id: "random-id"}, inv: &fakeInventoryInfo{id: "random-id"},
policy: AdoptIfNoInventory, policy: PolicyAdoptIfNoInventory,
canApply: true, canApply: true,
}, },
{ {
name: "empty with AdoptAll", name: "empty with AdoptAll",
obj: testObjectWithAnnotation("", ""), obj: testObjectWithAnnotation("", ""),
inv: &fakeInventoryInfo{id: "random-id"}, inv: &fakeInventoryInfo{id: "random-id"},
policy: AdoptAll, policy: PolicyAdoptAll,
canApply: true, canApply: true,
}, },
{ {
name: "empty with InventoryPolicyMustMatch", name: "empty with InventoryPolicyMustMatch",
obj: testObjectWithAnnotation("", ""), obj: testObjectWithAnnotation("", ""),
inv: &fakeInventoryInfo{id: "random-id"}, inv: &fakeInventoryInfo{id: "random-id"},
policy: InventoryPolicyMustMatch, policy: PolicyMustMatch,
canApply: false, canApply: false,
}, },
{ {
name: "matched with InventoryPolicyMustMatch", name: "matched with InventoryPolicyMustMatch",
obj: testObjectWithAnnotation(OwningInventoryKey, "matched"), obj: testObjectWithAnnotation(OwningInventoryKey, "matched"),
inv: &fakeInventoryInfo{id: "matched"}, inv: &fakeInventoryInfo{id: "matched"},
policy: InventoryPolicyMustMatch, policy: PolicyMustMatch,
canApply: true, canApply: true,
}, },
{ {
name: "matched with AdoptIfNoInventory", name: "matched with AdoptIfNoInventory",
obj: testObjectWithAnnotation(OwningInventoryKey, "matched"), obj: testObjectWithAnnotation(OwningInventoryKey, "matched"),
inv: &fakeInventoryInfo{id: "matched"}, inv: &fakeInventoryInfo{id: "matched"},
policy: AdoptIfNoInventory, policy: PolicyAdoptIfNoInventory,
canApply: true, canApply: true,
}, },
{ {
name: "matched with AloptAll", name: "matched with AloptAll",
obj: testObjectWithAnnotation(OwningInventoryKey, "matched"), obj: testObjectWithAnnotation(OwningInventoryKey, "matched"),
inv: &fakeInventoryInfo{id: "matched"}, inv: &fakeInventoryInfo{id: "matched"},
policy: AdoptAll, policy: PolicyAdoptAll,
canApply: true, canApply: true,
}, },
{ {
name: "unmatched with InventoryPolicyMustMatch", name: "unmatched with InventoryPolicyMustMatch",
obj: testObjectWithAnnotation(OwningInventoryKey, "unmatched"), obj: testObjectWithAnnotation(OwningInventoryKey, "unmatched"),
inv: &fakeInventoryInfo{id: "random-id"}, inv: &fakeInventoryInfo{id: "random-id"},
policy: InventoryPolicyMustMatch, policy: PolicyMustMatch,
canApply: false, canApply: false,
}, },
{ {
name: "unmatched with AdoptIfNoInventory", name: "unmatched with AdoptIfNoInventory",
obj: testObjectWithAnnotation(OwningInventoryKey, "unmatched"), obj: testObjectWithAnnotation(OwningInventoryKey, "unmatched"),
inv: &fakeInventoryInfo{id: "random-id"}, inv: &fakeInventoryInfo{id: "random-id"},
policy: AdoptIfNoInventory, policy: PolicyAdoptIfNoInventory,
canApply: false, canApply: false,
}, },
{ {
name: "unmatched with AdoptAll", name: "unmatched with AdoptAll",
obj: testObjectWithAnnotation(OwningInventoryKey, "unmatched"), obj: testObjectWithAnnotation(OwningInventoryKey, "unmatched"),
inv: &fakeInventoryInfo{id: "random-id"}, inv: &fakeInventoryInfo{id: "random-id"},
policy: AdoptAll, policy: PolicyAdoptAll,
canApply: true, canApply: true,
}, },
} }
@ -172,8 +172,8 @@ func TestCanPrune(t *testing.T) {
testcases := []struct { testcases := []struct {
name string name string
obj *unstructured.Unstructured obj *unstructured.Unstructured
inv InventoryInfo inv Info
policy InventoryPolicy policy Policy
canPrune bool canPrune bool
}{ }{
{ {
@ -186,63 +186,63 @@ func TestCanPrune(t *testing.T) {
name: "empty with AdoptIfNoInventory", name: "empty with AdoptIfNoInventory",
obj: testObjectWithAnnotation("", ""), obj: testObjectWithAnnotation("", ""),
inv: &fakeInventoryInfo{id: "random-id"}, inv: &fakeInventoryInfo{id: "random-id"},
policy: AdoptIfNoInventory, policy: PolicyAdoptIfNoInventory,
canPrune: true, canPrune: true,
}, },
{ {
name: "empty with AdoptAll", name: "empty with AdoptAll",
obj: testObjectWithAnnotation("", ""), obj: testObjectWithAnnotation("", ""),
inv: &fakeInventoryInfo{id: "random-id"}, inv: &fakeInventoryInfo{id: "random-id"},
policy: AdoptAll, policy: PolicyAdoptAll,
canPrune: true, canPrune: true,
}, },
{ {
name: "empty with InventoryPolicyMustMatch", name: "empty with InventoryPolicyMustMatch",
obj: testObjectWithAnnotation("", ""), obj: testObjectWithAnnotation("", ""),
inv: &fakeInventoryInfo{id: "random-id"}, inv: &fakeInventoryInfo{id: "random-id"},
policy: InventoryPolicyMustMatch, policy: PolicyMustMatch,
canPrune: false, canPrune: false,
}, },
{ {
name: "matched with InventoryPolicyMustMatch", name: "matched with InventoryPolicyMustMatch",
obj: testObjectWithAnnotation(OwningInventoryKey, "matched"), obj: testObjectWithAnnotation(OwningInventoryKey, "matched"),
inv: &fakeInventoryInfo{id: "matched"}, inv: &fakeInventoryInfo{id: "matched"},
policy: InventoryPolicyMustMatch, policy: PolicyMustMatch,
canPrune: true, canPrune: true,
}, },
{ {
name: "matched with AdoptIfNoInventory", name: "matched with AdoptIfNoInventory",
obj: testObjectWithAnnotation(OwningInventoryKey, "matched"), obj: testObjectWithAnnotation(OwningInventoryKey, "matched"),
inv: &fakeInventoryInfo{id: "matched"}, inv: &fakeInventoryInfo{id: "matched"},
policy: AdoptIfNoInventory, policy: PolicyAdoptIfNoInventory,
canPrune: true, canPrune: true,
}, },
{ {
name: "matched with AloptAll", name: "matched with AloptAll",
obj: testObjectWithAnnotation(OwningInventoryKey, "matched"), obj: testObjectWithAnnotation(OwningInventoryKey, "matched"),
inv: &fakeInventoryInfo{id: "matched"}, inv: &fakeInventoryInfo{id: "matched"},
policy: AdoptAll, policy: PolicyAdoptAll,
canPrune: true, canPrune: true,
}, },
{ {
name: "unmatched with InventoryPolicyMustMatch", name: "unmatched with InventoryPolicyMustMatch",
obj: testObjectWithAnnotation(OwningInventoryKey, "unmatched"), obj: testObjectWithAnnotation(OwningInventoryKey, "unmatched"),
inv: &fakeInventoryInfo{id: "random-id"}, inv: &fakeInventoryInfo{id: "random-id"},
policy: InventoryPolicyMustMatch, policy: PolicyMustMatch,
canPrune: false, canPrune: false,
}, },
{ {
name: "unmatched with AdoptIfNoInventory", name: "unmatched with AdoptIfNoInventory",
obj: testObjectWithAnnotation(OwningInventoryKey, "unmatched"), obj: testObjectWithAnnotation(OwningInventoryKey, "unmatched"),
inv: &fakeInventoryInfo{id: "random-id"}, inv: &fakeInventoryInfo{id: "random-id"},
policy: AdoptIfNoInventory, policy: PolicyAdoptIfNoInventory,
canPrune: false, canPrune: false,
}, },
{ {
name: "unmatched with AdoptAll", name: "unmatched with AdoptAll",
obj: testObjectWithAnnotation(OwningInventoryKey, "unmatched"), obj: testObjectWithAnnotation(OwningInventoryKey, "unmatched"),
inv: &fakeInventoryInfo{id: "random-id"}, inv: &fakeInventoryInfo{id: "random-id"},
policy: AdoptAll, policy: PolicyAdoptAll,
canPrune: true, canPrune: true,
}, },
} }

View File

@ -11,7 +11,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
) )
type FakeClusterReader struct { type ClusterReader struct {
NoopClusterReader NoopClusterReader
GetResource *unstructured.Unstructured GetResource *unstructured.Unstructured
@ -23,21 +23,21 @@ type FakeClusterReader struct {
SyncErr error SyncErr error
} }
func (f *FakeClusterReader) Get(_ context.Context, _ client.ObjectKey, u *unstructured.Unstructured) error { func (f *ClusterReader) Get(_ context.Context, _ client.ObjectKey, u *unstructured.Unstructured) error {
if f.GetResource != nil { if f.GetResource != nil {
u.Object = f.GetResource.Object u.Object = f.GetResource.Object
} }
return f.GetErr return f.GetErr
} }
func (f *FakeClusterReader) ListNamespaceScoped(_ context.Context, list *unstructured.UnstructuredList, _ string, _ labels.Selector) error { func (f *ClusterReader) ListNamespaceScoped(_ context.Context, list *unstructured.UnstructuredList, _ string, _ labels.Selector) error {
if f.ListResources != nil { if f.ListResources != nil {
list.Items = f.ListResources.Items list.Items = f.ListResources.Items
} }
return f.ListErr return f.ListErr
} }
func (f *FakeClusterReader) Sync(_ context.Context) error { func (f *ClusterReader) Sync(_ context.Context) error {
return f.SyncErr return f.SyncErr
} }

View File

@ -51,7 +51,7 @@ func (o ObserverFunc) Notify(rsc *ResourceStatusCollector, e event.Event) {
type ResourceStatusCollector struct { type ResourceStatusCollector struct {
mux sync.RWMutex mux sync.RWMutex
LastEventType event.EventType LastEventType event.Type
ResourceStatuses map[object.ObjMetadata]*event.ResourceStatus ResourceStatuses map[object.ObjMetadata]*event.ResourceStatus
@ -99,12 +99,12 @@ func (o *ResourceStatusCollector) ListenWithObserver(eventChannel <-chan event.E
func (o *ResourceStatusCollector) processEvent(e event.Event) error { func (o *ResourceStatusCollector) processEvent(e event.Event) error {
o.mux.Lock() o.mux.Lock()
defer o.mux.Unlock() defer o.mux.Unlock()
o.LastEventType = e.EventType o.LastEventType = e.Type
if e.EventType == event.ErrorEvent { if e.Type == event.ErrorEvent {
o.Error = e.Error o.Error = e.Error
return e.Error return e.Error
} }
if e.EventType == event.ResourceUpdateEvent { if e.Type == event.ResourceUpdateEvent {
resourceStatus := e.Resource resourceStatus := e.Resource
o.ResourceStatuses[resourceStatus.Identifier] = resourceStatus o.ResourceStatuses[resourceStatus.Identifier] = resourceStatus
} }
@ -114,7 +114,7 @@ func (o *ResourceStatusCollector) processEvent(e event.Event) error {
// Observation contains the latest state known by the collector as returned // Observation contains the latest state known by the collector as returned
// by a call to the LatestObservation function. // by a call to the LatestObservation function.
type Observation struct { type Observation struct {
LastEventType event.EventType LastEventType event.Type
ResourceStatuses []*event.ResourceStatus ResourceStatuses []*event.ResourceStatus

View File

@ -49,7 +49,7 @@ func TestCollectorWithFatalError(t *testing.T) {
exampleErr := fmt.Errorf("this is a test error") exampleErr := fmt.Errorf("this is a test error")
eventCh <- event.Event{ eventCh <- event.Event{
EventType: event.ErrorEvent, Type: event.ErrorEvent,
Error: exampleErr, Error: exampleErr,
} }
@ -101,7 +101,7 @@ func TestCollectorEventProcessing(t *testing.T) {
}, },
events: []event.Event{ events: []event.Event{
{ {
EventType: event.ResourceUpdateEvent, Type: event.ResourceUpdateEvent,
Resource: &event.ResourceStatus{ Resource: &event.ResourceStatus{
Identifier: resourceIdentifiers["deployment"], Identifier: resourceIdentifiers["deployment"],
}, },
@ -115,25 +115,25 @@ func TestCollectorEventProcessing(t *testing.T) {
}, },
events: []event.Event{ events: []event.Event{
{ {
EventType: event.ResourceUpdateEvent, Type: event.ResourceUpdateEvent,
Resource: &event.ResourceStatus{ Resource: &event.ResourceStatus{
Identifier: resourceIdentifiers["deployment"], Identifier: resourceIdentifiers["deployment"],
}, },
}, },
{ {
EventType: event.ResourceUpdateEvent, Type: event.ResourceUpdateEvent,
Resource: &event.ResourceStatus{ Resource: &event.ResourceStatus{
Identifier: resourceIdentifiers["statefulSet"], Identifier: resourceIdentifiers["statefulSet"],
}, },
}, },
{ {
EventType: event.ResourceUpdateEvent, Type: event.ResourceUpdateEvent,
Resource: &event.ResourceStatus{ Resource: &event.ResourceStatus{
Identifier: resourceIdentifiers["deployment"], Identifier: resourceIdentifiers["deployment"],
}, },
}, },
{ {
EventType: event.ResourceUpdateEvent, Type: event.ResourceUpdateEvent,
Resource: &event.ResourceStatus{ Resource: &event.ResourceStatus{
Identifier: resourceIdentifiers["statefulSet"], Identifier: resourceIdentifiers["statefulSet"],
}, },
@ -169,7 +169,7 @@ func TestCollectorEventProcessing(t *testing.T) {
var expectedObservation *Observation var expectedObservation *Observation
if latestEvent != nil { if latestEvent != nil {
expectedObservation = &Observation{ expectedObservation = &Observation{
LastEventType: latestEvent.EventType, LastEventType: latestEvent.Type,
} }
} else { } else {
expectedObservation = &Observation{} expectedObservation = &Observation{}

View File

@ -78,7 +78,7 @@ func (s *PollerEngine) Poll(ctx context.Context, identifiers object.ObjMetadataS
func handleError(eventChannel chan event.Event, err error) { func handleError(eventChannel chan event.Event, err error) {
eventChannel <- event.Event{ eventChannel <- event.Event{
EventType: event.ErrorEvent, Type: event.ErrorEvent,
Error: err, Error: err,
} }
} }
@ -197,7 +197,7 @@ func (r *statusPollerRunner) handleSyncAndPollErr(err error) {
return return
} }
r.eventChannel <- event.Event{ r.eventChannel <- event.Event{
EventType: event.ErrorEvent, Type: event.ErrorEvent,
Error: err, Error: err,
} }
} }
@ -236,7 +236,7 @@ func (r *statusPollerRunner) pollStatusForAllResources() error {
if r.isUpdatedResourceStatus(resourceStatus) { if r.isUpdatedResourceStatus(resourceStatus) {
r.previousResourceStatuses[id] = resourceStatus r.previousResourceStatuses[id] = resourceStatus
r.eventChannel <- event.Event{ r.eventChannel <- event.Event{
EventType: event.ResourceUpdateEvent, Type: event.ResourceUpdateEvent,
Resource: resourceStatus, Resource: resourceStatus,
} }
} }

View File

@ -27,7 +27,7 @@ func TestStatusPollerRunner(t *testing.T) {
testCases := map[string]struct { testCases := map[string]struct {
identifiers object.ObjMetadataSet identifiers object.ObjMetadataSet
defaultStatusReader StatusReader defaultStatusReader StatusReader
expectedEventTypes []event.EventType expectedEventTypes []event.Type
}{ }{
"single resource": { "single resource": {
identifiers: object.ObjMetadataSet{ identifiers: object.ObjMetadataSet{
@ -49,7 +49,7 @@ func TestStatusPollerRunner(t *testing.T) {
}, },
resourceStatusCount: make(map[schema.GroupKind]int), resourceStatusCount: make(map[schema.GroupKind]int),
}, },
expectedEventTypes: []event.EventType{ expectedEventTypes: []event.Type{
event.ResourceUpdateEvent, event.ResourceUpdateEvent,
event.ResourceUpdateEvent, event.ResourceUpdateEvent,
}, },
@ -87,7 +87,7 @@ func TestStatusPollerRunner(t *testing.T) {
}, },
resourceStatusCount: make(map[schema.GroupKind]int), resourceStatusCount: make(map[schema.GroupKind]int),
}, },
expectedEventTypes: []event.EventType{ expectedEventTypes: []event.Type{
event.ResourceUpdateEvent, event.ResourceUpdateEvent,
event.ResourceUpdateEvent, event.ResourceUpdateEvent,
event.ResourceUpdateEvent, event.ResourceUpdateEvent,
@ -123,9 +123,9 @@ func TestStatusPollerRunner(t *testing.T) {
eventChannel := engine.Poll(ctx, identifiers, options) eventChannel := engine.Poll(ctx, identifiers, options)
var eventTypes []event.EventType var eventTypes []event.Type
for ch := range eventChannel { for ch := range eventChannel {
eventTypes = append(eventTypes, ch.EventType) eventTypes = append(eventTypes, ch.Type)
if len(eventTypes) == len(tc.expectedEventTypes) { if len(eventTypes) == len(tc.expectedEventTypes) {
cancel() cancel()
} }
@ -201,7 +201,7 @@ func TestNewStatusPollerRunnerCancellationWithMultipleResources(t *testing.T) {
engine := PollerEngine{ engine := PollerEngine{
Mapper: fakeMapper, Mapper: fakeMapper,
ClusterReaderFactory: ClusterReaderFactoryFunc(func(client.Reader, meta.RESTMapper, object.ObjMetadataSet) (ClusterReader, error) { ClusterReaderFactory: ClusterReaderFactoryFunc(func(client.Reader, meta.RESTMapper, object.ObjMetadataSet) (ClusterReader, error) {
return &fakecr.FakeClusterReader{ return &fakecr.ClusterReader{
SyncErr: context.Canceled, SyncErr: context.Canceled,
}, nil }, nil
}), }),
@ -257,8 +257,8 @@ func TestNewStatusPollerRunnerIdentifierValidation(t *testing.T) {
defer timer.Stop() defer timer.Stop()
select { select {
case e := <-eventChannel: case e := <-eventChannel:
if e.EventType != event.ErrorEvent { if e.Type != event.ErrorEvent {
t.Errorf("expected an error event, but got %s", e.EventType.String()) t.Errorf("expected an error event, but got %s", e.Type.String())
return return
} }
err := e.Error err := e.Error

View File

@ -9,15 +9,15 @@ import (
"sigs.k8s.io/cli-utils/pkg/object" "sigs.k8s.io/cli-utils/pkg/object"
) )
// EventType is the type that describes the type of an Event that is passed back to the caller // Type is the type that describes the type of an Event that is passed back to the caller
// as resources in the cluster are being polled. // as resources in the cluster are being polled.
// //
//go:generate stringer -type=EventType //go:generate stringer -type=Type
type EventType int type Type int
const ( const (
// ResourceUpdateEvent describes events related to a change in the status of one of the polled resources. // ResourceUpdateEvent describes events related to a change in the status of one of the polled resources.
ResourceUpdateEvent EventType = iota ResourceUpdateEvent Type = iota
// ErrorEvent signals that the engine has encountered an error that it can not recover from. The engine // ErrorEvent signals that the engine has encountered an error that it can not recover from. The engine
// is shutting down and the event channel will be closed after this event. // is shutting down and the event channel will be closed after this event.
ErrorEvent ErrorEvent
@ -26,8 +26,8 @@ const (
// Event defines that type that is passed back through the event channel to notify the caller of changes // Event defines that type that is passed back through the event channel to notify the caller of changes
// as resources are being polled. // as resources are being polled.
type Event struct { type Event struct {
// EventType defines the type of event. // Type defines the type of event.
EventType EventType Type Type
// Resource is only available for ResourceUpdateEvents. It includes information about the resource, // Resource is only available for ResourceUpdateEvents. It includes information about the resource,
// including the resource status, any errors and the resource itself (as an unstructured). // including the resource status, any errors and the resource itself (as an unstructured).

View File

@ -1,24 +0,0 @@
// Code generated by "stringer -type=EventType"; DO NOT EDIT.
package event
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[ResourceUpdateEvent-0]
_ = x[ErrorEvent-1]
}
const _EventType_name = "ResourceUpdateEventErrorEvent"
var _EventType_index = [...]uint8{0, 19, 29}
func (i EventType) String() string {
if i < 0 || i >= EventType(len(_EventType_index)-1) {
return "EventType(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _EventType_name[_EventType_index[i]:_EventType_index[i+1]]
}

View File

@ -0,0 +1,24 @@
// Code generated by "stringer -type=Type"; DO NOT EDIT.
package event
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[ResourceUpdateEvent-0]
_ = x[ErrorEvent-1]
}
const _Type_name = "ResourceUpdateEventErrorEvent"
var _Type_index = [...]uint8{0, 19, 29}
func (i Type) String() string {
if i < 0 || i >= Type(len(_Type_index)-1) {
return "Type(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _Type_name[_Type_index[i]:_Type_index[i+1]]
}

View File

@ -80,7 +80,7 @@ func TestLookupResource(t *testing.T) {
for tn, tc := range testCases { for tn, tc := range testCases {
t.Run(tn, func(t *testing.T) { t.Run(tn, func(t *testing.T) {
fakeReader := &fakecr.FakeClusterReader{ fakeReader := &fakecr.ClusterReader{
GetErr: tc.readerErr, GetErr: tc.readerErr,
} }
fakeMapper := fakemapper.NewFakeRESTMapper(deploymentGVK) fakeMapper := fakemapper.NewFakeRESTMapper(deploymentGVK)
@ -201,14 +201,14 @@ spec:
for tn, tc := range testCases { for tn, tc := range testCases {
t.Run(tn, func(t *testing.T) { t.Run(tn, func(t *testing.T) {
fakeClusterReader := &fakecr.FakeClusterReader{ fakeClusterReader := &fakecr.ClusterReader{
ListResources: &unstructured.UnstructuredList{ ListResources: &unstructured.UnstructuredList{
Items: tc.listObjects, Items: tc.listObjects,
}, },
ListErr: tc.listErr, ListErr: tc.listErr,
} }
fakeMapper := fakemapper.NewFakeRESTMapper(rsGVK) fakeMapper := fakemapper.NewFakeRESTMapper(rsGVK)
fakeStatusReader := &fakesr.FakeStatusReader{} fakeStatusReader := &fakesr.StatusReader{}
object := testutil.YamlToUnstructured(t, tc.manifest) object := testutil.YamlToUnstructured(t, tc.manifest)

View File

@ -85,13 +85,13 @@ func TestReadStatus(t *testing.T) {
for tn := range testCases { for tn := range testCases {
tc := testCases[tn] tc := testCases[tn]
t.Run(tn, func(t *testing.T) { t.Run(tn, func(t *testing.T) {
fakeReader := &fakecr.FakeClusterReader{ fakeReader := &fakecr.ClusterReader{
GetResource: tc.readerResource, GetResource: tc.readerResource,
GetErr: tc.readerErr, GetErr: tc.readerErr,
} }
fakeMapper := fakemapper.NewFakeRESTMapper(deploymentGVK, replicaSetGVK) fakeMapper := fakemapper.NewFakeRESTMapper(deploymentGVK, replicaSetGVK)
fakeStatusReader := &fake.FakeStatusReader{} fakeStatusReader := &fake.StatusReader{}
statusReader := NewDeploymentResourceReader(fakeMapper, fakeStatusReader) statusReader := NewDeploymentResourceReader(fakeMapper, fakeStatusReader)
rs, err := statusReader.ReadStatus(context.Background(), fakeReader, tc.identifier) rs, err := statusReader.ReadStatus(context.Background(), fakeReader, tc.identifier)

View File

@ -13,17 +13,17 @@ import (
"sigs.k8s.io/cli-utils/pkg/object" "sigs.k8s.io/cli-utils/pkg/object"
) )
type FakeStatusReader struct{} type StatusReader struct{}
func (f *FakeStatusReader) Supports(schema.GroupKind) bool { func (f *StatusReader) Supports(schema.GroupKind) bool {
return true return true
} }
func (f *FakeStatusReader) ReadStatus(_ context.Context, _ engine.ClusterReader, _ object.ObjMetadata) (*event.ResourceStatus, error) { func (f *StatusReader) ReadStatus(_ context.Context, _ engine.ClusterReader, _ object.ObjMetadata) (*event.ResourceStatus, error) {
return nil, nil return nil, nil
} }
func (f *FakeStatusReader) ReadStatusForObject(_ context.Context, _ engine.ClusterReader, obj *unstructured.Unstructured) (*event.ResourceStatus, error) { func (f *StatusReader) ReadStatusForObject(_ context.Context, _ engine.ClusterReader, obj *unstructured.Unstructured) (*event.ResourceStatus, error) {
identifier := object.UnstructuredToObjMetadata(obj) identifier := object.UnstructuredToObjMetadata(obj)
return &event.ResourceStatus{ return &event.ResourceStatus{
Identifier: identifier, Identifier: identifier,

View File

@ -13,22 +13,22 @@ import (
"sigs.k8s.io/cli-utils/pkg/object" "sigs.k8s.io/cli-utils/pkg/object"
) )
type fakeLoader struct { type FakeLoader struct {
factory util.Factory Factory util.Factory
InvClient *inventory.FakeInventoryClient InvClient *inventory.FakeClient
} }
var _ ManifestLoader = &fakeLoader{} var _ ManifestLoader = &FakeLoader{}
func NewFakeLoader(f util.Factory, objs object.ObjMetadataSet) *fakeLoader { func NewFakeLoader(f util.Factory, objs object.ObjMetadataSet) *FakeLoader {
return &fakeLoader{ return &FakeLoader{
factory: f, Factory: f,
InvClient: inventory.NewFakeInventoryClient(objs), InvClient: inventory.NewFakeClient(objs),
} }
} }
func (f *fakeLoader) ManifestReader(reader io.Reader, _ string) (ManifestReader, error) { func (f *FakeLoader) ManifestReader(reader io.Reader, _ string) (ManifestReader, error) {
mapper, err := f.factory.ToRESTMapper() mapper, err := f.Factory.ToRESTMapper()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -44,7 +44,7 @@ func (f *fakeLoader) ManifestReader(reader io.Reader, _ string) (ManifestReader,
}, nil }, nil
} }
func (f *fakeLoader) InventoryInfo(objs []*unstructured.Unstructured) (inventory.InventoryInfo, []*unstructured.Unstructured, error) { func (f *FakeLoader) InventoryInfo(objs []*unstructured.Unstructured) (inventory.Info, []*unstructured.Unstructured, error) {
inv, objs, err := inventory.SplitUnstructureds(objs) inv, objs, err := inventory.SplitUnstructureds(objs)
return inventory.WrapInventoryInfoObj(inv), objs, err return inventory.WrapInventoryInfoObj(inv), objs, err
} }

View File

@ -170,7 +170,7 @@ var (
if err != nil { if err != nil {
return realLength, err return realLength, err
} }
realLength += 1 realLength++
} }
} }
return realLength, nil return realLength, nil

View File

@ -20,8 +20,8 @@ import (
const InvalidStatus status.Status = "Invalid" const InvalidStatus status.Status = "Invalid"
func newResourceStateCollector(resourceGroups []event.ActionGroup) *ResourceStateCollector { func newResourceStateCollector(resourceGroups []event.ActionGroup) *resourceStateCollector {
resourceInfos := make(map[object.ObjMetadata]*ResourceInfo) resourceInfos := make(map[object.ObjMetadata]*resourceInfo)
for _, group := range resourceGroups { for _, group := range resourceGroups {
action := group.Action action := group.Action
// Keep the action that describes the operation for the resource // Keep the action that describes the operation for the resource
@ -30,7 +30,7 @@ func newResourceStateCollector(resourceGroups []event.ActionGroup) *ResourceStat
continue continue
} }
for _, identifier := range group.Identifiers { for _, identifier := range group.Identifiers {
resourceInfos[identifier] = &ResourceInfo{ resourceInfos[identifier] = &resourceInfo{
identifier: identifier, identifier: identifier,
resourceStatus: &pe.ResourceStatus{ resourceStatus: &pe.ResourceStatus{
Identifier: identifier, Identifier: identifier,
@ -40,31 +40,31 @@ func newResourceStateCollector(resourceGroups []event.ActionGroup) *ResourceStat
} }
} }
} }
return &ResourceStateCollector{ return &resourceStateCollector{
resourceInfos: resourceInfos, resourceInfos: resourceInfos,
} }
} }
// ResourceStateCollector consumes the events from the applier // resourceStateCollector consumes the events from the applier
// eventChannel and keeps track of the latest state for all resources. // eventChannel and keeps track of the latest state for all resources.
// It also provides functionality for fetching the latest seen // It also provides functionality for fetching the latest seen
// state and return it in format that can be used by the // state and return it in format that can be used by the
// BaseTablePrinter. // BaseTablePrinter.
type ResourceStateCollector struct { type resourceStateCollector struct {
mux sync.RWMutex mux sync.RWMutex
// resourceInfos contains a mapping from the unique // resourceInfos contains a mapping from the unique
// resource identifier to a ResourceInfo object that captures // resource identifier to a ResourceInfo object that captures
// the latest state for the given resource. // the latest state for the given resource.
resourceInfos map[object.ObjMetadata]*ResourceInfo resourceInfos map[object.ObjMetadata]*resourceInfo
err error err error
} }
// ResourceInfo captures the latest seen state of a single resource. // resourceInfo captures the latest seen state of a single resource.
// This is used for top-level resources that have a ResourceAction // This is used for top-level resources that have a ResourceAction
// associated with them. // associated with them.
type ResourceInfo struct { type resourceInfo struct {
// identifier contains the information that identifies a // identifier contains the information that identifies a
// single resource. // single resource.
identifier object.ObjMetadata identifier object.ObjMetadata
@ -100,55 +100,55 @@ type ResourceInfo struct {
} }
// Identifier returns the identifier for the given resource. // Identifier returns the identifier for the given resource.
func (r *ResourceInfo) Identifier() object.ObjMetadata { func (r *resourceInfo) Identifier() object.ObjMetadata {
return r.identifier return r.identifier
} }
// ResourceStatus returns the latest seen status for the // ResourceStatus returns the latest seen status for the
// resource. // resource.
func (r *ResourceInfo) ResourceStatus() *pe.ResourceStatus { func (r *resourceInfo) ResourceStatus() *pe.ResourceStatus {
return r.resourceStatus return r.resourceStatus
} }
// SubResources returns a slice of Resource which contains // SubResources returns a slice of Resource which contains
// any resources created and managed by this resource. // any resources created and managed by this resource.
func (r *ResourceInfo) SubResources() []table.Resource { func (r *resourceInfo) SubResources() []table.Resource {
var resources []table.Resource var resources []table.Resource
for _, res := range r.resourceStatus.GeneratedResources { for _, res := range r.resourceStatus.GeneratedResources {
resources = append(resources, &SubResourceInfo{ resources = append(resources, &subResourceInfo{
resourceStatus: res, resourceStatus: res,
}) })
} }
return resources return resources
} }
// SubResourceInfo captures the latest seen state of a // subResourceInfo captures the latest seen state of a
// single subResource, i.e. resources that are created and // single subResource, i.e. resources that are created and
// managed by one of the top-level resources we either apply // managed by one of the top-level resources we either apply
// or prune. // or prune.
type SubResourceInfo struct { type subResourceInfo struct {
// resourceStatus contains the latest status information // resourceStatus contains the latest status information
// about the subResource. // about the subResource.
resourceStatus *pe.ResourceStatus resourceStatus *pe.ResourceStatus
} }
// Identifier returns the identifier for the given subResource. // Identifier returns the identifier for the given subResource.
func (r *SubResourceInfo) Identifier() object.ObjMetadata { func (r *subResourceInfo) Identifier() object.ObjMetadata {
return r.resourceStatus.Identifier return r.resourceStatus.Identifier
} }
// ResourceStatus returns the latest seen status for the // ResourceStatus returns the latest seen status for the
// subResource. // subResource.
func (r *SubResourceInfo) ResourceStatus() *pe.ResourceStatus { func (r *subResourceInfo) ResourceStatus() *pe.ResourceStatus {
return r.resourceStatus return r.resourceStatus
} }
// SubResources returns a slice of Resource which contains // SubResources returns a slice of Resource which contains
// any resources created and managed by this resource. // any resources created and managed by this resource.
func (r *SubResourceInfo) SubResources() []table.Resource { func (r *subResourceInfo) SubResources() []table.Resource {
var resources []table.Resource var resources []table.Resource
for _, res := range r.resourceStatus.GeneratedResources { for _, res := range r.resourceStatus.GeneratedResources {
resources = append(resources, &SubResourceInfo{ resources = append(resources, &subResourceInfo{
resourceStatus: res, resourceStatus: res,
}) })
} }
@ -162,7 +162,7 @@ func (r *SubResourceInfo) SubResources() []table.Resource {
// The function returns a channel. When this channel is closed, the // The function returns a channel. When this channel is closed, the
// goroutine has processed all events in the eventChannel and // goroutine has processed all events in the eventChannel and
// exited. // exited.
func (r *ResourceStateCollector) Listen(eventChannel <-chan event.Event) <-chan listenerResult { func (r *resourceStateCollector) Listen(eventChannel <-chan event.Event) <-chan listenerResult {
completed := make(chan listenerResult) completed := make(chan listenerResult)
go func() { go func() {
defer close(completed) defer close(completed)
@ -181,7 +181,7 @@ type listenerResult struct {
} }
// processEvent processes an event and updates the state. // processEvent processes an event and updates the state.
func (r *ResourceStateCollector) processEvent(ev event.Event) error { func (r *resourceStateCollector) processEvent(ev event.Event) error {
r.mux.Lock() r.mux.Lock()
defer r.mux.Unlock() defer r.mux.Unlock()
switch ev.Type { switch ev.Type {
@ -203,7 +203,7 @@ func (r *ResourceStateCollector) processEvent(ev event.Event) error {
// processValidationEvent handles events pertaining to a validation error // processValidationEvent handles events pertaining to a validation error
// for a resource. // for a resource.
func (r *ResourceStateCollector) processValidationEvent(e event.ValidationEvent) error { func (r *resourceStateCollector) processValidationEvent(e event.ValidationEvent) error {
klog.V(7).Infoln("processing validation event") klog.V(7).Infoln("processing validation event")
// unwrap validation errors // unwrap validation errors
err := e.Error err := e.Error
@ -231,7 +231,7 @@ func (r *ResourceStateCollector) processValidationEvent(e event.ValidationEvent)
// processStatusEvent handles events pertaining to a status // processStatusEvent handles events pertaining to a status
// update for a resource. // update for a resource.
func (r *ResourceStateCollector) processStatusEvent(e event.StatusEvent) { func (r *resourceStateCollector) processStatusEvent(e event.StatusEvent) {
klog.V(7).Infoln("processing status event") klog.V(7).Infoln("processing status event")
previous, found := r.resourceInfos[e.Identifier] previous, found := r.resourceInfos[e.Identifier]
if !found { if !found {
@ -242,7 +242,7 @@ func (r *ResourceStateCollector) processStatusEvent(e event.StatusEvent) {
} }
// processApplyEvent handles events relating to apply operations // processApplyEvent handles events relating to apply operations
func (r *ResourceStateCollector) processApplyEvent(e event.ApplyEvent) { func (r *resourceStateCollector) processApplyEvent(e event.ApplyEvent) {
identifier := e.Identifier identifier := e.Identifier
klog.V(7).Infof("processing apply event for %s", identifier) klog.V(7).Infof("processing apply event for %s", identifier)
previous, found := r.resourceInfos[identifier] previous, found := r.resourceInfos[identifier]
@ -257,7 +257,7 @@ func (r *ResourceStateCollector) processApplyEvent(e event.ApplyEvent) {
} }
// processPruneEvent handles event related to prune operations. // processPruneEvent handles event related to prune operations.
func (r *ResourceStateCollector) processPruneEvent(e event.PruneEvent) { func (r *resourceStateCollector) processPruneEvent(e event.PruneEvent) {
identifier := e.Identifier identifier := e.Identifier
klog.V(7).Infof("processing prune event for %s", identifier) klog.V(7).Infof("processing prune event for %s", identifier)
previous, found := r.resourceInfos[identifier] previous, found := r.resourceInfos[identifier]
@ -272,7 +272,7 @@ func (r *ResourceStateCollector) processPruneEvent(e event.PruneEvent) {
} }
// processPruneEvent handles event related to prune operations. // processPruneEvent handles event related to prune operations.
func (r *ResourceStateCollector) processWaitEvent(e event.WaitEvent) { func (r *resourceStateCollector) processWaitEvent(e event.WaitEvent) {
identifier := e.Identifier identifier := e.Identifier
klog.V(7).Infof("processing wait event for %s", identifier) klog.V(7).Infof("processing wait event for %s", identifier)
previous, found := r.resourceInfos[identifier] previous, found := r.resourceInfos[identifier]
@ -306,13 +306,13 @@ func (r *ResourceState) Error() error {
// LatestState returns a ResourceState object that contains // LatestState returns a ResourceState object that contains
// a copy of the latest state for all resources. // a copy of the latest state for all resources.
func (r *ResourceStateCollector) LatestState() *ResourceState { func (r *resourceStateCollector) LatestState() *ResourceState {
r.mux.RLock() r.mux.RLock()
defer r.mux.RUnlock() defer r.mux.RUnlock()
var resourceInfos ResourceInfos var resourceInfos ResourceInfos
for _, ri := range r.resourceInfos { for _, ri := range r.resourceInfos {
resourceInfos = append(resourceInfos, &ResourceInfo{ resourceInfos = append(resourceInfos, &resourceInfo{
identifier: ri.identifier, identifier: ri.identifier,
resourceStatus: ri.resourceStatus, resourceStatus: ri.resourceStatus,
ResourceAction: ri.ResourceAction, ResourceAction: ri.ResourceAction,
@ -332,7 +332,7 @@ func (r *ResourceStateCollector) LatestState() *ResourceState {
// Stats returns a summary of the results from the actuation operation // Stats returns a summary of the results from the actuation operation
// as a stats.Stats object. // as a stats.Stats object.
func (r *ResourceStateCollector) Stats() stats.Stats { func (r *resourceStateCollector) Stats() stats.Stats {
var s stats.Stats var s stats.Stats
for _, res := range r.resourceInfos { for _, res := range r.resourceInfos {
switch res.ResourceAction { switch res.ResourceAction {
@ -357,7 +357,7 @@ func (r *ResourceStateCollector) Stats() stats.Stats {
return s return s
} }
type ResourceInfos []*ResourceInfo type ResourceInfos []*resourceInfo
func (g ResourceInfos) Len() int { func (g ResourceInfos) Len() int {
return len(g) return len(g)

View File

@ -48,11 +48,11 @@ const testMessage = "test message for ResourceStatus"
func TestResourceStateCollector_New(t *testing.T) { func TestResourceStateCollector_New(t *testing.T) {
testCases := map[string]struct { testCases := map[string]struct {
resourceGroups []event.ActionGroup resourceGroups []event.ActionGroup
resourceInfos map[object.ObjMetadata]*ResourceInfo resourceInfos map[object.ObjMetadata]*resourceInfo
}{ }{
"no resources": { "no resources": {
resourceGroups: []event.ActionGroup{}, resourceGroups: []event.ActionGroup{},
resourceInfos: map[object.ObjMetadata]*ResourceInfo{}, resourceInfos: map[object.ObjMetadata]*resourceInfo{},
}, },
"several resources for apply": { "several resources for apply": {
resourceGroups: []event.ActionGroup{ resourceGroups: []event.ActionGroup{
@ -63,7 +63,7 @@ func TestResourceStateCollector_New(t *testing.T) {
}, },
}, },
}, },
resourceInfos: map[object.ObjMetadata]*ResourceInfo{ resourceInfos: map[object.ObjMetadata]*resourceInfo{
depID: { depID: {
ResourceAction: event.ApplyAction, ResourceAction: event.ApplyAction,
}, },
@ -87,7 +87,7 @@ func TestResourceStateCollector_New(t *testing.T) {
}, },
}, },
}, },
resourceInfos: map[object.ObjMetadata]*ResourceInfo{ resourceInfos: map[object.ObjMetadata]*resourceInfo{
depID: { depID: {
ResourceAction: event.PruneAction, ResourceAction: event.PruneAction,
}, },

View File

@ -85,9 +85,9 @@ var (
ColumnWidth: 12, ColumnWidth: 12,
PrintResourceFunc: func(w io.Writer, width int, r table.Resource) (int, PrintResourceFunc: func(w io.Writer, width int, r table.Resource) (int,
error) { error) {
var resInfo *ResourceInfo var resInfo *resourceInfo
switch res := r.(type) { switch res := r.(type) {
case *ResourceInfo: case *resourceInfo:
resInfo = res resInfo = res
default: default:
return 0, nil return 0, nil
@ -122,9 +122,9 @@ var (
int, int,
error, error,
) { ) {
var resInfo *ResourceInfo var resInfo *resourceInfo
switch res := r.(type) { switch res := r.(type) {
case *ResourceInfo: case *resourceInfo:
resInfo = res resInfo = res
default: default:
return 0, nil return 0, nil
@ -158,7 +158,7 @@ var (
// runPrintLoop starts a new goroutine that will regularly fetch the // runPrintLoop starts a new goroutine that will regularly fetch the
// latest state from the collector and update the table. // latest state from the collector and update the table.
func (t *Printer) runPrintLoop(coll *ResourceStateCollector, stop chan struct{}) chan struct{} { func (t *Printer) runPrintLoop(coll *resourceStateCollector, stop chan struct{}) chan struct{} {
finished := make(chan struct{}) finished := make(chan struct{})
baseTablePrinter := table.BaseTablePrinter{ baseTablePrinter := table.BaseTablePrinter{

View File

@ -26,17 +26,17 @@ func TestActionColumnDef(t *testing.T) {
expectedOutput string expectedOutput string
}{ }{
"unexpected implementation of Resource interface": { "unexpected implementation of Resource interface": {
resource: &SubResourceInfo{}, resource: &subResourceInfo{},
columnWidth: 15, columnWidth: 15,
expectedOutput: "", expectedOutput: "",
}, },
"neither applied nor pruned": { "neither applied nor pruned": {
resource: &ResourceInfo{}, resource: &resourceInfo{},
columnWidth: 15, columnWidth: 15,
expectedOutput: "", expectedOutput: "",
}, },
"applied": { "applied": {
resource: &ResourceInfo{ resource: &resourceInfo{
ResourceAction: event.ApplyAction, ResourceAction: event.ApplyAction,
ApplyOpResult: createdOpResult, ApplyOpResult: createdOpResult,
}, },
@ -44,7 +44,7 @@ func TestActionColumnDef(t *testing.T) {
expectedOutput: "Created", expectedOutput: "Created",
}, },
"pruned": { "pruned": {
resource: &ResourceInfo{ resource: &resourceInfo{
ResourceAction: event.PruneAction, ResourceAction: event.PruneAction,
PruneOpResult: prunedOpResult, PruneOpResult: prunedOpResult,
}, },
@ -52,7 +52,7 @@ func TestActionColumnDef(t *testing.T) {
expectedOutput: "Pruned", expectedOutput: "Pruned",
}, },
"trimmed output": { "trimmed output": {
resource: &ResourceInfo{ resource: &resourceInfo{
ResourceAction: event.ApplyAction, ResourceAction: event.ApplyAction,
ApplyOpResult: createdOpResult, ApplyOpResult: createdOpResult,
}, },

View File

@ -89,7 +89,7 @@ func VerifyEvents(expEvents []ExpEvent, events []event.Event) error {
e := events[i] e := events[i]
ee := expEvents[expEventIndex] ee := expEvents[expEventIndex]
if isMatch(ee, e) { if isMatch(ee, e) {
expEventIndex += 1 expEventIndex++
if expEventIndex >= len(expEvents) { if expEventIndex >= len(expEvents) {
return nil return nil
} }

View File

@ -57,7 +57,7 @@ func indent(in string, indentation uint) string {
// any error with the same type as the supplied error. // any error with the same type as the supplied error.
// //
// Use with testutil.Equal to handle error comparisons. // Use with testutil.Equal to handle error comparisons.
func EqualErrorType(err error) equalErrorType { func EqualErrorType(err error) error {
return equalErrorType{ return equalErrorType{
err: err, err: err,
} }
@ -86,7 +86,7 @@ func (e equalErrorType) Unwrap() error {
// any error with the same Error() as the supplied string value. // any error with the same Error() as the supplied string value.
// //
// Use with testutil.Equal to handle error comparisons. // Use with testutil.Equal to handle error comparisons.
func EqualErrorString(err string) equalErrorString { func EqualErrorString(err string) error {
return equalErrorString{ return equalErrorString{
err: err, err: err,
} }

View File

@ -192,7 +192,7 @@ func applyAndDestroyTest(ctx context.Context, c client.Client, invConfig Invento
By("Destroy resources") By("Destroy resources")
destroyer := invConfig.DestroyerFactoryFunc() destroyer := invConfig.DestroyerFactoryFunc()
options := apply.DestroyerOptions{InventoryPolicy: inventory.AdoptIfNoInventory} options := apply.DestroyerOptions{InventoryPolicy: inventory.PolicyAdoptIfNoInventory}
destroyerEvents := runCollect(destroyer.Run(ctx, inventoryInfo, options)) destroyerEvents := runCollect(destroyer.Run(ctx, inventoryInfo, options))
expEvents = []testutil.ExpEvent{ expEvents = []testutil.ExpEvent{
@ -291,13 +291,13 @@ func applyAndDestroyTest(ctx context.Context, c client.Client, invConfig Invento
assertUnstructuredDoesNotExist(ctx, c, deployment1Obj) assertUnstructuredDoesNotExist(ctx, c, deployment1Obj)
} }
func createInventoryInfo(invConfig InventoryConfig, inventoryName, namespaceName, inventoryID string) inventory.InventoryInfo { func createInventoryInfo(invConfig InventoryConfig, inventoryName, namespaceName, inventoryID string) inventory.Info {
switch invConfig.InventoryStrategy { switch invConfig.Strategy {
case inventory.NameStrategy: case inventory.NameStrategy:
return invConfig.InvWrapperFunc(invConfig.InventoryFactoryFunc(inventoryName, namespaceName, randomString("inventory-"))) return invConfig.InvWrapperFunc(invConfig.FactoryFunc(inventoryName, namespaceName, randomString("inventory-")))
case inventory.LabelStrategy: case inventory.LabelStrategy:
return invConfig.InvWrapperFunc(invConfig.InventoryFactoryFunc(randomString("inventory-"), namespaceName, inventoryID)) return invConfig.InvWrapperFunc(invConfig.FactoryFunc(randomString("inventory-"), namespaceName, inventoryID))
default: default:
panic(fmt.Errorf("unknown inventory strategy %q", invConfig.InventoryStrategy)) panic(fmt.Errorf("unknown inventory strategy %q", invConfig.Strategy))
} }
} }

View File

@ -23,7 +23,7 @@ func continueOnErrorTest(ctx context.Context, c client.Client, invConfig Invento
By("apply an invalid CRD") By("apply an invalid CRD")
applier := invConfig.ApplierFactoryFunc() applier := invConfig.ApplierFactoryFunc()
inv := invConfig.InvWrapperFunc(invConfig.InventoryFactoryFunc(inventoryName, namespaceName, "test")) inv := invConfig.InvWrapperFunc(invConfig.FactoryFunc(inventoryName, namespaceName, "test"))
invalidCrdObj := manifestToUnstructured(invalidCrd) invalidCrdObj := manifestToUnstructured(invalidCrd)
pod1Obj := withNamespace(manifestToUnstructured(pod1), namespaceName) pod1Obj := withNamespace(manifestToUnstructured(pod1), namespaceName)

View File

@ -24,7 +24,7 @@ func crdTest(ctx context.Context, _ client.Client, invConfig InventoryConfig, in
By("apply a set of resources that includes both a crd and a cr") By("apply a set of resources that includes both a crd and a cr")
applier := invConfig.ApplierFactoryFunc() applier := invConfig.ApplierFactoryFunc()
inv := invConfig.InvWrapperFunc(invConfig.InventoryFactoryFunc(inventoryName, namespaceName, "test")) inv := invConfig.InvWrapperFunc(invConfig.FactoryFunc(inventoryName, namespaceName, "test"))
crdObj := manifestToUnstructured(crd) crdObj := manifestToUnstructured(crd)
crObj := manifestToUnstructured(cr) crObj := manifestToUnstructured(cr)
@ -214,7 +214,7 @@ func crdTest(ctx context.Context, _ client.Client, invConfig InventoryConfig, in
By("destroy the resources, including the crd") By("destroy the resources, including the crd")
destroyer := invConfig.DestroyerFactoryFunc() destroyer := invConfig.DestroyerFactoryFunc()
options := apply.DestroyerOptions{InventoryPolicy: inventory.AdoptIfNoInventory} options := apply.DestroyerOptions{InventoryPolicy: inventory.PolicyAdoptIfNoInventory}
destroyerEvents := runCollect(destroyer.Run(ctx, inv, options)) destroyerEvents := runCollect(destroyer.Run(ctx, inv, options))
expEvents = []testutil.ExpEvent{ expEvents = []testutil.ExpEvent{

View File

@ -74,16 +74,16 @@ var InventoryGVK = schema.GroupVersionKind{
Kind: "Inventory", Kind: "Inventory",
} }
var _ inventory.InventoryClientFactory = CustomInventoryClientFactory{} var _ inventory.ClientFactory = CustomClientFactory{}
type CustomInventoryClientFactory struct { type CustomClientFactory struct {
} }
func (CustomInventoryClientFactory) NewInventoryClient(factory util.Factory) (inventory.InventoryClient, error) { func (CustomClientFactory) NewClient(factory util.Factory) (inventory.Client, error) {
return inventory.NewInventoryClient(factory, WrapInventoryObj, invToUnstructuredFunc) return inventory.NewClient(factory, WrapInventoryObj, invToUnstructuredFunc)
} }
func invToUnstructuredFunc(inv inventory.InventoryInfo) *unstructured.Unstructured { func invToUnstructuredFunc(inv inventory.Info) *unstructured.Unstructured {
switch invInfo := inv.(type) { switch invInfo := inv.(type) {
case *InventoryCustomType: case *InventoryCustomType:
return invInfo.inv return invInfo.inv
@ -96,12 +96,12 @@ func WrapInventoryObj(obj *unstructured.Unstructured) inventory.Storage {
return &InventoryCustomType{inv: obj} return &InventoryCustomType{inv: obj}
} }
func WrapInventoryInfoObj(obj *unstructured.Unstructured) inventory.InventoryInfo { func WrapInventoryInfoObj(obj *unstructured.Unstructured) inventory.Info {
return &InventoryCustomType{inv: obj} return &InventoryCustomType{inv: obj}
} }
var _ inventory.Storage = &InventoryCustomType{} var _ inventory.Storage = &InventoryCustomType{}
var _ inventory.InventoryInfo = &InventoryCustomType{} var _ inventory.Info = &InventoryCustomType{}
type InventoryCustomType struct { type InventoryCustomType struct {
inv *unstructured.Unstructured inv *unstructured.Unstructured
@ -115,7 +115,7 @@ func (i InventoryCustomType) Name() string {
return i.inv.GetName() return i.inv.GetName()
} }
func (i InventoryCustomType) Strategy() inventory.InventoryStrategy { func (i InventoryCustomType) Strategy() inventory.Strategy {
return inventory.NameStrategy return inventory.NameStrategy
} }

View File

@ -22,7 +22,7 @@ func dependsOnTest(ctx context.Context, c client.Client, invConfig InventoryConf
By("apply resources in order based on depends-on annotation") By("apply resources in order based on depends-on annotation")
applier := invConfig.ApplierFactoryFunc() applier := invConfig.ApplierFactoryFunc()
inv := invConfig.InvWrapperFunc(invConfig.InventoryFactoryFunc(inventoryName, namespaceName, "test")) inv := invConfig.InvWrapperFunc(invConfig.FactoryFunc(inventoryName, namespaceName, "test"))
pod1Obj := withDependsOn(withNamespace(manifestToUnstructured(pod1), namespaceName), fmt.Sprintf("/namespaces/%s/Pod/pod3", namespaceName)) pod1Obj := withDependsOn(withNamespace(manifestToUnstructured(pod1), namespaceName), fmt.Sprintf("/namespaces/%s/Pod/pod3", namespaceName))
pod2Obj := withNamespace(manifestToUnstructured(pod2), namespaceName) pod2Obj := withNamespace(manifestToUnstructured(pod2), namespaceName)
@ -300,7 +300,7 @@ func dependsOnTest(ctx context.Context, c client.Client, invConfig InventoryConf
By("destroy resources in opposite order") By("destroy resources in opposite order")
destroyer := invConfig.DestroyerFactoryFunc() destroyer := invConfig.DestroyerFactoryFunc()
options := apply.DestroyerOptions{InventoryPolicy: inventory.AdoptIfNoInventory} options := apply.DestroyerOptions{InventoryPolicy: inventory.PolicyAdoptIfNoInventory}
destroyerEvents := runCollect(destroyer.Run(ctx, inv, options)) destroyerEvents := runCollect(destroyer.Run(ctx, inv, options))
expEvents = []testutil.ExpEvent{ expEvents = []testutil.ExpEvent{

View File

@ -31,15 +31,15 @@ import (
) )
type inventoryFactoryFunc func(name, namespace, id string) *unstructured.Unstructured type inventoryFactoryFunc func(name, namespace, id string) *unstructured.Unstructured
type invWrapperFunc func(*unstructured.Unstructured) inventory.InventoryInfo type invWrapperFunc func(*unstructured.Unstructured) inventory.Info
type applierFactoryFunc func() *apply.Applier type applierFactoryFunc func() *apply.Applier
type destroyerFactoryFunc func() *apply.Destroyer type destroyerFactoryFunc func() *apply.Destroyer
type invSizeVerifyFunc func(ctx context.Context, c client.Client, name, namespace, id string, count int) type invSizeVerifyFunc func(ctx context.Context, c client.Client, name, namespace, id string, count int)
type invCountVerifyFunc func(ctx context.Context, c client.Client, namespace string, count int) type invCountVerifyFunc func(ctx context.Context, c client.Client, namespace string, count int)
type InventoryConfig struct { type InventoryConfig struct {
InventoryStrategy inventory.InventoryStrategy Strategy inventory.Strategy
InventoryFactoryFunc inventoryFactoryFunc FactoryFunc inventoryFactoryFunc
InvWrapperFunc invWrapperFunc InvWrapperFunc invWrapperFunc
ApplierFactoryFunc applierFactoryFunc ApplierFactoryFunc applierFactoryFunc
DestroyerFactoryFunc destroyerFactoryFunc DestroyerFactoryFunc destroyerFactoryFunc
@ -54,8 +54,8 @@ const (
var inventoryConfigs = map[string]InventoryConfig{ var inventoryConfigs = map[string]InventoryConfig{
ConfigMapTypeInvConfig: { ConfigMapTypeInvConfig: {
InventoryStrategy: inventory.LabelStrategy, Strategy: inventory.LabelStrategy,
InventoryFactoryFunc: cmInventoryManifest, FactoryFunc: cmInventoryManifest,
InvWrapperFunc: inventory.WrapInventoryInfoObj, InvWrapperFunc: inventory.WrapInventoryInfoObj,
ApplierFactoryFunc: newDefaultInvApplier, ApplierFactoryFunc: newDefaultInvApplier,
DestroyerFactoryFunc: newDefaultInvDestroyer, DestroyerFactoryFunc: newDefaultInvDestroyer,
@ -63,8 +63,8 @@ var inventoryConfigs = map[string]InventoryConfig{
InvCountVerifyFunc: defaultInvCountVerifyFunc, InvCountVerifyFunc: defaultInvCountVerifyFunc,
}, },
CustomTypeInvConfig: { CustomTypeInvConfig: {
InventoryStrategy: inventory.NameStrategy, Strategy: inventory.NameStrategy,
InventoryFactoryFunc: customInventoryManifest, FactoryFunc: customInventoryManifest,
InvWrapperFunc: customprovider.WrapInventoryInfoObj, InvWrapperFunc: customprovider.WrapInventoryInfoObj,
ApplierFactoryFunc: newCustomInvApplier, ApplierFactoryFunc: newCustomInvApplier,
DestroyerFactoryFunc: newCustomInvDestroyer, DestroyerFactoryFunc: newCustomInvDestroyer,
@ -243,7 +243,7 @@ var _ = Describe("Applier", func() {
}) })
} }
Context("InventoryStrategy: Name", func() { Context("Strategy: Name", func() {
var namespace *v1.Namespace var namespace *v1.Namespace
var inventoryName string var inventoryName string
var ctx context.Context var ctx context.Context
@ -325,11 +325,11 @@ func deleteNamespace(ctx context.Context, c client.Client, namespace *v1.Namespa
} }
func newDefaultInvApplier() *apply.Applier { func newDefaultInvApplier() *apply.Applier {
return newApplierFromInvFactory(inventory.ClusterInventoryClientFactory{}) return newApplierFromInvFactory(inventory.ClusterClientFactory{})
} }
func newDefaultInvDestroyer() *apply.Destroyer { func newDefaultInvDestroyer() *apply.Destroyer {
return newDestroyerFromInvFactory(inventory.ClusterInventoryClientFactory{}) return newDestroyerFromInvFactory(inventory.ClusterClientFactory{})
} }
func defaultInvSizeVerifyFunc(ctx context.Context, c client.Client, name, namespace, id string, count int) { func defaultInvSizeVerifyFunc(ctx context.Context, c client.Client, name, namespace, id string, count int) {
@ -355,11 +355,11 @@ func defaultInvCountVerifyFunc(ctx context.Context, c client.Client, namespace s
} }
func newCustomInvApplier() *apply.Applier { func newCustomInvApplier() *apply.Applier {
return newApplierFromInvFactory(customprovider.CustomInventoryClientFactory{}) return newApplierFromInvFactory(customprovider.CustomClientFactory{})
} }
func newCustomInvDestroyer() *apply.Destroyer { func newCustomInvDestroyer() *apply.Destroyer {
return newDestroyerFromInvFactory(customprovider.CustomInventoryClientFactory{}) return newDestroyerFromInvFactory(customprovider.CustomClientFactory{})
} }
func newFactory() util.Factory { func newFactory() util.Factory {
@ -396,9 +396,9 @@ func customInvCountVerifyFunc(ctx context.Context, c client.Client, namespace st
Expect(len(u.Items)).To(Equal(count)) Expect(len(u.Items)).To(Equal(count))
} }
func newApplierFromInvFactory(invFactory inventory.InventoryClientFactory) *apply.Applier { func newApplierFromInvFactory(invFactory inventory.ClientFactory) *apply.Applier {
f := newFactory() f := newFactory()
invClient, err := invFactory.NewInventoryClient(f) invClient, err := invFactory.NewClient(f)
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
a, err := apply.NewApplierBuilder(). a, err := apply.NewApplierBuilder().
@ -409,9 +409,9 @@ func newApplierFromInvFactory(invFactory inventory.InventoryClientFactory) *appl
return a return a
} }
func newDestroyerFromInvFactory(invFactory inventory.InventoryClientFactory) *apply.Destroyer { func newDestroyerFromInvFactory(invFactory inventory.ClientFactory) *apply.Destroyer {
f := newFactory() f := newFactory()
invClient, err := invFactory.NewInventoryClient(f) invClient, err := invFactory.NewClient(f)
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
d, err := apply.NewDestroyer(f, invClient) d, err := apply.NewDestroyer(f, invClient)

View File

@ -23,7 +23,7 @@ func exitEarlyTest(ctx context.Context, c client.Client, invConfig InventoryConf
By("exit early on invalid object") By("exit early on invalid object")
applier := invConfig.ApplierFactoryFunc() applier := invConfig.ApplierFactoryFunc()
inv := invConfig.InvWrapperFunc(invConfig.InventoryFactoryFunc(inventoryName, namespaceName, "test")) inv := invConfig.InvWrapperFunc(invConfig.FactoryFunc(inventoryName, namespaceName, "test"))
fields := struct{ Namespace string }{Namespace: namespaceName} fields := struct{ Namespace string }{Namespace: namespaceName}
// valid pod // valid pod

View File

@ -25,7 +25,7 @@ func inventoryPolicyMustMatchTest(ctx context.Context, c client.Client, invConfi
applier := invConfig.ApplierFactoryFunc() applier := invConfig.ApplierFactoryFunc()
firstInvName := randomString("first-inv-") firstInvName := randomString("first-inv-")
firstInv := invConfig.InvWrapperFunc(invConfig.InventoryFactoryFunc(firstInvName, namespaceName, firstInvName)) firstInv := invConfig.InvWrapperFunc(invConfig.FactoryFunc(firstInvName, namespaceName, firstInvName))
deployment1Obj := withNamespace(manifestToUnstructured(deployment1), namespaceName) deployment1Obj := withNamespace(manifestToUnstructured(deployment1), namespaceName)
firstResources := []*unstructured.Unstructured{ firstResources := []*unstructured.Unstructured{
deployment1Obj, deployment1Obj,
@ -38,7 +38,7 @@ func inventoryPolicyMustMatchTest(ctx context.Context, c client.Client, invConfi
By("Apply second set of resources") By("Apply second set of resources")
secondInvName := randomString("second-inv-") secondInvName := randomString("second-inv-")
secondInv := invConfig.InvWrapperFunc(invConfig.InventoryFactoryFunc(secondInvName, namespaceName, secondInvName)) secondInv := invConfig.InvWrapperFunc(invConfig.FactoryFunc(secondInvName, namespaceName, secondInvName))
deployment1Obj = withNamespace(manifestToUnstructured(deployment1), namespaceName) deployment1Obj = withNamespace(manifestToUnstructured(deployment1), namespaceName)
secondResources := []*unstructured.Unstructured{ secondResources := []*unstructured.Unstructured{
withReplicas(deployment1Obj, 6), withReplicas(deployment1Obj, 6),
@ -47,7 +47,7 @@ func inventoryPolicyMustMatchTest(ctx context.Context, c client.Client, invConfi
applierEvents := runCollect(applier.Run(ctx, secondInv, secondResources, apply.ApplierOptions{ applierEvents := runCollect(applier.Run(ctx, secondInv, secondResources, apply.ApplierOptions{
ReconcileTimeout: 2 * time.Minute, ReconcileTimeout: 2 * time.Minute,
EmitStatusEvents: true, EmitStatusEvents: true,
InventoryPolicy: inventory.InventoryPolicyMustMatch, InventoryPolicy: inventory.PolicyMustMatch,
})) }))
By("Verify the events") By("Verify the events")
@ -196,7 +196,7 @@ func inventoryPolicyAdoptIfNoInventoryTest(ctx context.Context, c client.Client,
applier := invConfig.ApplierFactoryFunc() applier := invConfig.ApplierFactoryFunc()
invName := randomString("test-inv-") invName := randomString("test-inv-")
inv := invConfig.InvWrapperFunc(invConfig.InventoryFactoryFunc(invName, namespaceName, invName)) inv := invConfig.InvWrapperFunc(invConfig.FactoryFunc(invName, namespaceName, invName))
deployment1Obj = withNamespace(manifestToUnstructured(deployment1), namespaceName) deployment1Obj = withNamespace(manifestToUnstructured(deployment1), namespaceName)
resources := []*unstructured.Unstructured{ resources := []*unstructured.Unstructured{
withReplicas(deployment1Obj, 6), withReplicas(deployment1Obj, 6),
@ -205,7 +205,7 @@ func inventoryPolicyAdoptIfNoInventoryTest(ctx context.Context, c client.Client,
applierEvents := runCollect(applier.Run(ctx, inv, resources, apply.ApplierOptions{ applierEvents := runCollect(applier.Run(ctx, inv, resources, apply.ApplierOptions{
ReconcileTimeout: 2 * time.Minute, ReconcileTimeout: 2 * time.Minute,
EmitStatusEvents: true, EmitStatusEvents: true,
InventoryPolicy: inventory.AdoptIfNoInventory, InventoryPolicy: inventory.PolicyAdoptIfNoInventory,
})) }))
By("Verify the events") By("Verify the events")
@ -365,7 +365,7 @@ func inventoryPolicyAdoptAllTest(ctx context.Context, c client.Client, invConfig
applier := invConfig.ApplierFactoryFunc() applier := invConfig.ApplierFactoryFunc()
firstInvName := randomString("first-inv-") firstInvName := randomString("first-inv-")
firstInv := invConfig.InvWrapperFunc(invConfig.InventoryFactoryFunc(firstInvName, namespaceName, firstInvName)) firstInv := invConfig.InvWrapperFunc(invConfig.FactoryFunc(firstInvName, namespaceName, firstInvName))
deployment1Obj := withNamespace(manifestToUnstructured(deployment1), namespaceName) deployment1Obj := withNamespace(manifestToUnstructured(deployment1), namespaceName)
firstResources := []*unstructured.Unstructured{ firstResources := []*unstructured.Unstructured{
deployment1Obj, deployment1Obj,
@ -378,7 +378,7 @@ func inventoryPolicyAdoptAllTest(ctx context.Context, c client.Client, invConfig
By("Apply resources") By("Apply resources")
secondInvName := randomString("test-inv-") secondInvName := randomString("test-inv-")
secondInv := invConfig.InvWrapperFunc(invConfig.InventoryFactoryFunc(secondInvName, namespaceName, secondInvName)) secondInv := invConfig.InvWrapperFunc(invConfig.FactoryFunc(secondInvName, namespaceName, secondInvName))
deployment1Obj = withNamespace(manifestToUnstructured(deployment1), namespaceName) deployment1Obj = withNamespace(manifestToUnstructured(deployment1), namespaceName)
secondResources := []*unstructured.Unstructured{ secondResources := []*unstructured.Unstructured{
withReplicas(deployment1Obj, 6), withReplicas(deployment1Obj, 6),
@ -387,7 +387,7 @@ func inventoryPolicyAdoptAllTest(ctx context.Context, c client.Client, invConfig
applierEvents := runCollect(applier.Run(ctx, secondInv, secondResources, apply.ApplierOptions{ applierEvents := runCollect(applier.Run(ctx, secondInv, secondResources, apply.ApplierOptions{
ReconcileTimeout: 2 * time.Minute, ReconcileTimeout: 2 * time.Minute,
EmitStatusEvents: true, EmitStatusEvents: true,
InventoryPolicy: inventory.AdoptAll, InventoryPolicy: inventory.PolicyAdoptAll,
})) }))
By("Verify the events") By("Verify the events")

View File

@ -36,7 +36,7 @@ func mutationTest(ctx context.Context, c client.Client, invConfig InventoryConfi
By("apply resources in order with substitutions based on apply-time-mutation annotation") By("apply resources in order with substitutions based on apply-time-mutation annotation")
applier := invConfig.ApplierFactoryFunc() applier := invConfig.ApplierFactoryFunc()
inv := invConfig.InvWrapperFunc(invConfig.InventoryFactoryFunc(inventoryName, namespaceName, "test")) inv := invConfig.InvWrapperFunc(invConfig.FactoryFunc(inventoryName, namespaceName, "test"))
fields := struct{ Namespace string }{Namespace: namespaceName} fields := struct{ Namespace string }{Namespace: namespaceName}
podAObj := templateToUnstructured(podATemplate, fields) podAObj := templateToUnstructured(podATemplate, fields)
@ -256,7 +256,7 @@ func mutationTest(ctx context.Context, c client.Client, invConfig InventoryConfi
By("destroy resources in opposite order") By("destroy resources in opposite order")
destroyer := invConfig.DestroyerFactoryFunc() destroyer := invConfig.DestroyerFactoryFunc()
options := apply.DestroyerOptions{InventoryPolicy: inventory.AdoptIfNoInventory} options := apply.DestroyerOptions{InventoryPolicy: inventory.PolicyAdoptIfNoInventory}
destroyerEvents := runCollect(destroyer.Run(ctx, inv, options)) destroyerEvents := runCollect(destroyer.Run(ctx, inv, options))
expEvents = []testutil.ExpEvent{ expEvents = []testutil.ExpEvent{

View File

@ -20,7 +20,7 @@ func applyWithExistingInvTest(ctx context.Context, c client.Client, invConfig In
applier := invConfig.ApplierFactoryFunc() applier := invConfig.ApplierFactoryFunc()
orgInventoryID := fmt.Sprintf("%s-%s", inventoryName, namespaceName) orgInventoryID := fmt.Sprintf("%s-%s", inventoryName, namespaceName)
orgApplyInv := invConfig.InvWrapperFunc(invConfig.InventoryFactoryFunc(inventoryName, namespaceName, orgInventoryID)) orgApplyInv := invConfig.InvWrapperFunc(invConfig.FactoryFunc(inventoryName, namespaceName, orgInventoryID))
resources := []*unstructured.Unstructured{ resources := []*unstructured.Unstructured{
withNamespace(manifestToUnstructured(deployment1), namespaceName), withNamespace(manifestToUnstructured(deployment1), namespaceName),
@ -36,7 +36,7 @@ func applyWithExistingInvTest(ctx context.Context, c client.Client, invConfig In
By("Apply second set of resources, using same inventory name but different ID") By("Apply second set of resources, using same inventory name but different ID")
secondInventoryID := fmt.Sprintf("%s-%s-2", inventoryName, namespaceName) secondInventoryID := fmt.Sprintf("%s-%s-2", inventoryName, namespaceName)
secondApplyInv := invConfig.InvWrapperFunc(invConfig.InventoryFactoryFunc(inventoryName, namespaceName, secondInventoryID)) secondApplyInv := invConfig.InvWrapperFunc(invConfig.FactoryFunc(inventoryName, namespaceName, secondInventoryID))
err := run(applier.Run(ctx, secondApplyInv, resources, apply.ApplierOptions{ err := run(applier.Run(ctx, secondApplyInv, resources, apply.ApplierOptions{
ReconcileTimeout: 2 * time.Minute, ReconcileTimeout: 2 * time.Minute,

View File

@ -296,7 +296,7 @@ func pruneRetrieveErrorTest(ctx context.Context, c client.Client, invConfig Inve
By("Destroy resources") By("Destroy resources")
destroyer := invConfig.DestroyerFactoryFunc() destroyer := invConfig.DestroyerFactoryFunc()
options := apply.DestroyerOptions{InventoryPolicy: inventory.AdoptIfNoInventory} options := apply.DestroyerOptions{InventoryPolicy: inventory.PolicyAdoptIfNoInventory}
destroyerEvents := runCollect(destroyer.Run(ctx, inv, options)) destroyerEvents := runCollect(destroyer.Run(ctx, inv, options))
expEvents3 := []testutil.ExpEvent{ expEvents3 := []testutil.ExpEvent{

View File

@ -21,7 +21,7 @@ func serversideApplyTest(ctx context.Context, c client.Client, invConfig Invento
By("Apply a Deployment and an APIService by server-side apply") By("Apply a Deployment and an APIService by server-side apply")
applier := invConfig.ApplierFactoryFunc() applier := invConfig.ApplierFactoryFunc()
inv := invConfig.InvWrapperFunc(invConfig.InventoryFactoryFunc(inventoryName, namespaceName, "test")) inv := invConfig.InvWrapperFunc(invConfig.FactoryFunc(inventoryName, namespaceName, "test"))
firstResources := []*unstructured.Unstructured{ firstResources := []*unstructured.Unstructured{
withNamespace(manifestToUnstructured(deployment1), namespaceName), withNamespace(manifestToUnstructured(deployment1), namespaceName),
manifestToUnstructured(apiservice1), manifestToUnstructured(apiservice1),

View File

@ -28,7 +28,7 @@ func skipInvalidTest(ctx context.Context, c client.Client, invConfig InventoryCo
By("apply valid objects and skip invalid objects") By("apply valid objects and skip invalid objects")
applier := invConfig.ApplierFactoryFunc() applier := invConfig.ApplierFactoryFunc()
inv := invConfig.InvWrapperFunc(invConfig.InventoryFactoryFunc(inventoryName, namespaceName, "test")) inv := invConfig.InvWrapperFunc(invConfig.FactoryFunc(inventoryName, namespaceName, "test"))
fields := struct{ Namespace string }{Namespace: namespaceName} fields := struct{ Namespace string }{Namespace: namespaceName}
// valid pod // valid pod
@ -345,7 +345,7 @@ func skipInvalidTest(ctx context.Context, c client.Client, invConfig InventoryCo
By("destroy valid objects and skip invalid objects") By("destroy valid objects and skip invalid objects")
destroyer := invConfig.DestroyerFactoryFunc() destroyer := invConfig.DestroyerFactoryFunc()
destroyerEvents := runCollect(destroyer.Run(ctx, inv, apply.DestroyerOptions{ destroyerEvents := runCollect(destroyer.Run(ctx, inv, apply.DestroyerOptions{
InventoryPolicy: inventory.AdoptIfNoInventory, InventoryPolicy: inventory.PolicyAdoptIfNoInventory,
ValidationPolicy: validation.SkipInvalid, ValidationPolicy: validation.SkipInvalid,
})) }))