mirror of https://github.com/fluxcd/cli-utils.git
161 lines
4.7 KiB
Go
161 lines
4.7 KiB
Go
// Copyright 2021 The Kubernetes Authors.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package apply
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"k8s.io/apimachinery/pkg/api/meta"
|
|
"k8s.io/cli-runtime/pkg/resource"
|
|
"k8s.io/client-go/discovery"
|
|
"k8s.io/client-go/dynamic"
|
|
"k8s.io/client-go/rest"
|
|
"k8s.io/kubectl/pkg/cmd/util"
|
|
"k8s.io/kubectl/pkg/scheme"
|
|
"sigs.k8s.io/cli-utils/pkg/apply/info"
|
|
"sigs.k8s.io/cli-utils/pkg/apply/poller"
|
|
"sigs.k8s.io/cli-utils/pkg/apply/prune"
|
|
"sigs.k8s.io/cli-utils/pkg/inventory"
|
|
"sigs.k8s.io/cli-utils/pkg/kstatus/polling"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
)
|
|
|
|
type ApplierBuilder struct {
|
|
// factory is only used to retrieve things that have not been provided explicitly.
|
|
factory util.Factory
|
|
invClient inventory.Client
|
|
client dynamic.Interface
|
|
discoClient discovery.CachedDiscoveryInterface
|
|
mapper meta.RESTMapper
|
|
restConfig *rest.Config
|
|
unstructuredClientForMapping func(*meta.RESTMapping) (resource.RESTClient, error)
|
|
statusPoller poller.Poller
|
|
}
|
|
|
|
// NewApplierBuilder returns a new ApplierBuilder.
|
|
func NewApplierBuilder() *ApplierBuilder {
|
|
return &ApplierBuilder{
|
|
// Defaults, if any, go here.
|
|
}
|
|
}
|
|
|
|
func (b *ApplierBuilder) Build() (*Applier, error) {
|
|
bx, err := b.finalize()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &Applier{
|
|
pruner: &prune.Pruner{
|
|
InvClient: bx.invClient,
|
|
Client: bx.client,
|
|
Mapper: bx.mapper,
|
|
},
|
|
statusPoller: bx.statusPoller,
|
|
invClient: bx.invClient,
|
|
client: bx.client,
|
|
openAPIGetter: bx.discoClient,
|
|
mapper: bx.mapper,
|
|
infoHelper: info.NewHelper(bx.mapper, bx.unstructuredClientForMapping),
|
|
}, nil
|
|
}
|
|
|
|
func (b *ApplierBuilder) finalize() (*ApplierBuilder, error) {
|
|
bx := *b // make a copy before mutating any fields. Shallow copy is good enough.
|
|
var err error
|
|
if bx.invClient == nil {
|
|
return nil, errors.New("inventory client must be provided")
|
|
}
|
|
if bx.client == nil {
|
|
if bx.factory == nil {
|
|
return nil, fmt.Errorf("a factory must be provided or all other options: %v", err)
|
|
}
|
|
bx.client, err = bx.factory.DynamicClient()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error getting dynamic client: %v", err)
|
|
}
|
|
}
|
|
if bx.discoClient == nil {
|
|
if bx.factory == nil {
|
|
return nil, fmt.Errorf("a factory must be provided or all other options: %v", err)
|
|
}
|
|
bx.discoClient, err = bx.factory.ToDiscoveryClient()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error getting discovery client: %v", err)
|
|
}
|
|
}
|
|
if bx.mapper == nil {
|
|
if bx.factory == nil {
|
|
return nil, fmt.Errorf("a factory must be provided or all other options: %v", err)
|
|
}
|
|
bx.mapper, err = bx.factory.ToRESTMapper()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error getting rest mapper: %v", err)
|
|
}
|
|
}
|
|
if bx.restConfig == nil {
|
|
if bx.factory == nil {
|
|
return nil, fmt.Errorf("a factory must be provided or all other options: %v", err)
|
|
}
|
|
bx.restConfig, err = bx.factory.ToRESTConfig()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error getting rest config: %v", err)
|
|
}
|
|
}
|
|
if bx.unstructuredClientForMapping == nil {
|
|
if bx.factory == nil {
|
|
return nil, fmt.Errorf("a factory must be provided or all other options: %v", err)
|
|
}
|
|
bx.unstructuredClientForMapping = bx.factory.UnstructuredClientForMapping
|
|
}
|
|
if bx.statusPoller == nil {
|
|
c, err := client.New(bx.restConfig, client.Options{Scheme: scheme.Scheme, Mapper: bx.mapper})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error creating client: %v", err)
|
|
}
|
|
bx.statusPoller = polling.NewStatusPoller(c, bx.mapper, polling.Options{})
|
|
}
|
|
return &bx, nil
|
|
}
|
|
|
|
func (b *ApplierBuilder) WithFactory(factory util.Factory) *ApplierBuilder {
|
|
b.factory = factory
|
|
return b
|
|
}
|
|
|
|
func (b *ApplierBuilder) WithInventoryClient(invClient inventory.Client) *ApplierBuilder {
|
|
b.invClient = invClient
|
|
return b
|
|
}
|
|
|
|
func (b *ApplierBuilder) WithDynamicClient(client dynamic.Interface) *ApplierBuilder {
|
|
b.client = client
|
|
return b
|
|
}
|
|
|
|
func (b *ApplierBuilder) WithDiscoveryClient(discoClient discovery.CachedDiscoveryInterface) *ApplierBuilder {
|
|
b.discoClient = discoClient
|
|
return b
|
|
}
|
|
|
|
func (b *ApplierBuilder) WithRestMapper(mapper meta.RESTMapper) *ApplierBuilder {
|
|
b.mapper = mapper
|
|
return b
|
|
}
|
|
|
|
func (b *ApplierBuilder) WithRestConfig(restConfig *rest.Config) *ApplierBuilder {
|
|
b.restConfig = restConfig
|
|
return b
|
|
}
|
|
|
|
func (b *ApplierBuilder) WithUnstructuredClientForMapping(unstructuredClientForMapping func(*meta.RESTMapping) (resource.RESTClient, error)) *ApplierBuilder {
|
|
b.unstructuredClientForMapping = unstructuredClientForMapping
|
|
return b
|
|
}
|
|
|
|
func (b *ApplierBuilder) WithStatusPoller(statusPoller poller.Poller) *ApplierBuilder {
|
|
b.statusPoller = statusPoller
|
|
return b
|
|
}
|