Skip to content

Commit

Permalink
Remove Applier.Initialize()
Browse files Browse the repository at this point in the history
  • Loading branch information
ash2k committed Jun 15, 2021
1 parent e7c4eaa commit 8dc334f
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 81 deletions.
13 changes: 9 additions & 4 deletions cmd/apply/cmdapply.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ import (
"sigs.k8s.io/cli-utils/pkg/inventory"
"sigs.k8s.io/cli-utils/pkg/manifestreader"
"sigs.k8s.io/cli-utils/pkg/provider"
"sigs.k8s.io/cli-utils/pkg/util/factory"
)

func GetApplyRunner(provider provider.Provider, loader manifestreader.ManifestLoader, ioStreams genericclioptions.IOStreams) *ApplyRunner {
r := &ApplyRunner{
Applier: apply.NewApplier(provider),
ioStreams: ioStreams,
provider: provider,
loader: loader,
Expand Down Expand Up @@ -73,7 +73,6 @@ type ApplyRunner struct {
Command *cobra.Command
PreProcess func(info inventory.InventoryInfo, strategy common.DryRunStrategy) (inventory.InventoryPolicy, error)
ioStreams genericclioptions.IOStreams
Applier *apply.Applier
provider provider.Provider
loader manifestreader.ManifestLoader

Expand Down Expand Up @@ -132,13 +131,19 @@ func (r *ApplyRunner) RunE(cmd *cobra.Command, args []string) error {
return err
}
}
f := r.provider.Factory()
statusPoller, err := factory.NewStatusPoller(f)
if err != nil {
return err
}

// Run the applier. It will return a channel where we can receive updates
// to keep track of progress and any issues.
if err := r.Applier.Initialize(); err != nil {
a, err := apply.NewApplier(r.provider, statusPoller)
if err != nil {
return err
}
ch := r.Applier.Run(context.Background(), inv, objs, apply.Options{
ch := a.Run(context.Background(), inv, objs, apply.Options{
ServerSideOptions: r.serverSideOptions,
PollInterval: r.period,
ReconcileTimeout: r.reconcileTimeout,
Expand Down
21 changes: 11 additions & 10 deletions cmd/preview/cmdpreview.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"k8s.io/cli-runtime/pkg/genericclioptions"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/util/i18n"

"sigs.k8s.io/cli-utils/cmd/flagutils"
"sigs.k8s.io/cli-utils/cmd/printers"
"sigs.k8s.io/cli-utils/pkg/apply"
Expand All @@ -21,6 +20,7 @@ import (
"sigs.k8s.io/cli-utils/pkg/inventory"
"sigs.k8s.io/cli-utils/pkg/manifestreader"
"sigs.k8s.io/cli-utils/pkg/provider"
"sigs.k8s.io/cli-utils/pkg/util/factory"
)

var (
Expand All @@ -31,7 +31,6 @@ var (
// GetPreviewRunner creates and returns the PreviewRunner which stores the cobra command.
func GetPreviewRunner(provider provider.Provider, loader manifestreader.ManifestLoader, ioStreams genericclioptions.IOStreams) *PreviewRunner {
r := &PreviewRunner{
Applier: apply.NewApplier(provider),
Destroyer: apply.NewDestroyer(provider),
ioStreams: ioStreams,
provider: provider,
Expand Down Expand Up @@ -75,7 +74,6 @@ type PreviewRunner struct {
Command *cobra.Command
PreProcess func(info inventory.InventoryInfo, strategy common.DryRunStrategy) (inventory.InventoryPolicy, error)
ioStreams genericclioptions.IOStreams
Applier *apply.Applier
Destroyer *apply.Destroyer
provider provider.Provider
loader manifestreader.ManifestLoader
Expand Down Expand Up @@ -123,22 +121,25 @@ func (r *PreviewRunner) RunE(cmd *cobra.Command, args []string) error {
// if destroy flag is set in preview, transmit it to destroyer DryRunStrategy flag
// and pivot execution to destroy with dry-run
if !previewDestroy {
err = r.Applier.Initialize()
_, err = common.DemandOneDirectory(args)
if err != nil {
return err
}

// Create a context
ctx := context.Background()

_, err := common.DemandOneDirectory(args)
statusPoller, err := factory.NewStatusPoller(r.provider.Factory())
if err != nil {
return err
}
a, err := apply.NewApplier(r.provider, statusPoller)
if err != nil {
return err
}

// Create a context
ctx := context.Background()

// Run the applier. It will return a channel where we can receive updates
// to keep track of progress and any issues.
ch = r.Applier.Run(ctx, inv, objs, apply.Options{
ch = a.Run(ctx, inv, objs, apply.Options{
EmitStatusEvents: false,
NoPrune: noPrune,
DryRunStrategy: drs,
Expand Down
68 changes: 28 additions & 40 deletions pkg/apply/applier.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import (
"strings"
"time"

"github.com/go-errors/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/klog/v2"
"k8s.io/kubectl/pkg/cmd/util"
"sigs.k8s.io/cli-utils/pkg/apply/event"
"sigs.k8s.io/cli-utils/pkg/apply/info"
"sigs.k8s.io/cli-utils/pkg/apply/poller"
Expand All @@ -26,22 +26,33 @@ import (
"sigs.k8s.io/cli-utils/pkg/object"
"sigs.k8s.io/cli-utils/pkg/ordering"
"sigs.k8s.io/cli-utils/pkg/provider"
"sigs.k8s.io/cli-utils/pkg/util/factory"
)

// newApplier returns a new Applier. It will set up the ApplyOptions and
// NewApplier returns a new Applier. It will set up the ApplyOptions and
// StatusOptions which are responsible for capturing any command line flags.
// It currently requires IOStreams, but this is a legacy from when
// the ApplyOptions were responsible for printing progress. This is now
// handled by a separate printer with the KubectlPrinterAdapter bridging
// between the two.
func NewApplier(provider provider.Provider) *Applier {
func NewApplier(provider provider.Provider, statusPoller poller.Poller) (*Applier, error) {
invClient, err := provider.InventoryClient()
if err != nil {
return nil, err
}
factory := provider.Factory()
pruneOpts := prune.NewPruneOptions()
err = pruneOpts.Initialize(factory, invClient)
if err != nil {
return nil, err
}
a := &Applier{
PruneOptions: prune.NewPruneOptions(),
provider: provider,
infoHelper: info.NewInfoHelper(provider.Factory()),
pruneOptions: pruneOpts,
statusPoller: statusPoller,
factory: factory,
invClient: invClient,
infoHelper: info.NewInfoHelper(factory),
}
return a
return a, nil
}

// Applier performs the step of applying a set of resources into a cluster,
Expand All @@ -55,36 +66,13 @@ func NewApplier(provider provider.Provider) *Applier {
// parameters and/or the set of resources that needs to be applied to the
// cluster, different sets of tasks might be needed.
type Applier struct {
provider provider.Provider

PruneOptions *prune.PruneOptions
StatusPoller poller.Poller
pruneOptions *prune.PruneOptions
statusPoller poller.Poller
factory util.Factory
invClient inventory.InventoryClient
infoHelper info.InfoHelper
}

// Initialize sets up the Applier for actually doing an apply against
// a cluster. This involves validating command line inputs and configuring
// clients for communicating with the cluster.
func (a *Applier) Initialize() error {
var err error
a.invClient, err = a.provider.InventoryClient()
if err != nil {
return err
}
err = a.PruneOptions.Initialize(a.provider.Factory(), a.invClient)
if err != nil {
return errors.WrapPrefix(err, "error setting up PruneOptions", 1)
}

statusPoller, err := factory.NewStatusPoller(a.provider.Factory())
if err != nil {
return errors.WrapPrefix(err, "error creating resolver", 1)
}
a.StatusPoller = statusPoller
return nil
}

// prepareObjects returns the set of objects to apply and to prune or
// an error if one occurred.
func (a *Applier) prepareObjects(localInv inventory.InventoryInfo, localObjs []*unstructured.Unstructured) (
Expand Down Expand Up @@ -115,7 +103,7 @@ func (a *Applier) prepareObjects(localInv inventory.InventoryInfo, localObjs []*
}
}
}
pruneObjs, err := a.PruneOptions.GetPruneObjs(localInv, localObjs)
pruneObjs, err := a.pruneOptions.GetPruneObjs(localInv, localObjs)
if err != nil {
return nil, nil, err
}
Expand Down Expand Up @@ -143,18 +131,18 @@ func (a *Applier) Run(ctx context.Context, invInfo inventory.InventoryInfo, obje
handleError(eventChannel, err)
return
}
mapper, err := a.provider.Factory().ToRESTMapper()
mapper, err := a.factory.ToRESTMapper()
if err != nil {
handleError(eventChannel, err)
return
}
// Fetch the queue (channel) of tasks that should be executed.
klog.V(4).Infoln("applier building task queue...")
// TODO(seans): Remove this once Filter interface implemented.
a.PruneOptions.LocalNamespaces = localNamespaces(invInfo, object.UnstructuredsToObjMetas(objects))
a.pruneOptions.LocalNamespaces = localNamespaces(invInfo, object.UnstructuredsToObjMetas(objects))
taskBuilder := &solver.TaskQueueBuilder{
PruneOptions: a.PruneOptions,
Factory: a.provider.Factory(),
PruneOptions: a.pruneOptions,
Factory: a.factory,
InfoHelper: a.infoHelper,
Mapper: mapper,
InvClient: a.invClient,
Expand Down Expand Up @@ -186,7 +174,7 @@ func (a *Applier) Run(ctx context.Context, invInfo inventory.InventoryInfo, obje
// Create a new TaskStatusRunner to execute the taskQueue.
klog.V(4).Infoln("applier building TaskStatusRunner...")
allIds := object.UnstructuredsToObjMetas(append(applyObjs, pruneObjs...))
runner := taskrunner.NewTaskStatusRunner(allIds, a.StatusPoller)
runner := taskrunner.NewTaskStatusRunner(allIds, a.statusPoller)
klog.V(4).Infoln("applier running TaskStatusRunner...")
err = runner.Run(ctx, taskQueue.ToChannel(), eventChannel, taskrunner.Options{
PollInterval: options.PollInterval,
Expand Down
22 changes: 8 additions & 14 deletions pkg/apply/applier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/api/meta/testrestmapper"
Expand Down Expand Up @@ -595,26 +596,19 @@ func TestApplier(t *testing.T) {
tf.FakeDynamicClient = fakeDynamicClient(t, mapper, objs...)

cf := provider.NewProvider(tf)
applier := NewApplier(cf)
poller := &fakePoller{
events: tc.statusEvents,
start: make(chan struct{}),
}
applier, err := NewApplier(cf, poller)
require.NoError(t, err)
applier.infoHelper = &fakeInfoHelper{
factory: tf,
}

err = applier.Initialize()
if !assert.NoError(t, err) {
return
}
// TODO(mortent): This is not great, but at least this keeps the
// ugliness in the test code until we can find a way to wire it
// up so to avoid it.
applier.invClient.(*inventory.ClusterInventoryClient).InfoHelper = applier.infoHelper

poller := &fakePoller{
events: tc.statusEvents,
start: make(chan struct{}),
}
applier.StatusPoller = poller

ctx := context.Background()
eventChannel := applier.Run(ctx, tc.invInfo.toWrapped(), tc.resources, Options{
ReconcileTimeout: tc.reconcileTimeout,
Expand Down Expand Up @@ -783,7 +777,7 @@ func TestReadAndPrepareObjects(t *testing.T) {
scheme.Scheme.PrioritizedVersionsAllGroups()...)
// Create applier with fake inventory client, and call prepareObjects
applier := &Applier{
PruneOptions: po,
pruneOptions: po,
invClient: fakeInvClient,
}
applyObjs, pruneObjs, err := applier.prepareObjects(tc.inventory, tc.localObjs)
Expand Down
5 changes: 0 additions & 5 deletions pkg/apply/info/info_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
package info

import (
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/cli-runtime/pkg/resource"
Expand Down Expand Up @@ -62,10 +61,6 @@ func (ih *infoHelper) BuildInfo(obj *unstructured.Unstructured) (*resource.Info,
return info, err
}

func (ih *infoHelper) ToRESTMapper() (meta.RESTMapper, error) {
return ih.factory.ToRESTMapper()
}

func (ih *infoHelper) getClient(gv schema.GroupVersion) (*rest.RESTClient, error) {
cfg, err := ih.factory.ToRESTConfig()
if err != nil {
Expand Down
19 changes: 11 additions & 8 deletions test/e2e/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,7 @@ func deleteNamespace(c client.Client, namespace *v1.Namespace) {
}

func newDefaultInvApplier() *apply.Applier {
applier := apply.NewApplier(newDefaultInvProvider())
err := applier.Initialize()
Expect(err).NotTo(HaveOccurred())
return applier
return newApplierFromProvider(newDefaultInvProvider())
}

func newDefaultInvDestroyer() *apply.Destroyer {
Expand Down Expand Up @@ -245,10 +242,7 @@ func defaultInvCountVerifyFunc(c client.Client, namespace string, count int) {
}

func newCustomInvApplier() *apply.Applier {
applier := apply.NewApplier(newCustomInvProvider())
err := applier.Initialize()
Expect(err).NotTo(HaveOccurred())
return applier
return newApplierFromProvider(newCustomInvProvider())
}

func newCustomInvDestroyer() *apply.Destroyer {
Expand Down Expand Up @@ -297,3 +291,12 @@ func customInvCountVerifyFunc(c client.Client, namespace string, count int) {
Expect(err).NotTo(HaveOccurred())
Expect(len(u.Items)).To(Equal(count))
}

func newApplierFromProvider(prov provider.Provider) *apply.Applier {
statusPoller, err := factory.NewStatusPoller(prov.Factory())
Expect(err).NotTo(HaveOccurred())

a, err := apply.NewApplier(prov, statusPoller)
Expect(err).NotTo(HaveOccurred())
return a
}

0 comments on commit 8dc334f

Please sign in to comment.