Skip to content

Commit

Permalink
Merge pull request #17154 from justinsb/build_our_own_rest_config
Browse files Browse the repository at this point in the history
chore: refactor factory to accept a cluster
  • Loading branch information
k8s-ci-robot authored Dec 28, 2024
2 parents cba6360 + 859a9fd commit 51db52f
Show file tree
Hide file tree
Showing 19 changed files with 362 additions and 182 deletions.
19 changes: 14 additions & 5 deletions channels/cmd/channels/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,29 @@ limitations under the License.
package main

import (
"context"
"fmt"
"os"

"k8s.io/klog/v2"

"k8s.io/kops/channels/pkg/cmd"
"k8s.io/kops/cmd/kops/util"
)

func main() {
klog.InitFlags(nil)

f := util.NewFactory(nil)
if err := cmd.Execute(f, os.Stdout); err != nil {
if err := run(context.Background()); err != nil {
fmt.Fprintf(os.Stderr, "\n%v\n", err)
os.Exit(1)
}
}

func run(ctx context.Context) error {
klog.InitFlags(nil)

f := cmd.NewChannelsFactory()

if err := cmd.Execute(ctx, f, os.Stdout); err != nil {
return err
}
return nil
}
2 changes: 1 addition & 1 deletion channels/pkg/cmd/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"github.com/spf13/cobra"
)

func NewCmdApply(f Factory, out io.Writer) *cobra.Command {
func NewCmdApply(f *ChannelsFactory, out io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "apply",
Short: "apply resources from a channel",
Expand Down
28 changes: 21 additions & 7 deletions channels/pkg/cmd/apply_channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,27 @@ import (

"github.com/blang/semver/v4"
"github.com/cert-manager/cert-manager/pkg/client/clientset/versioned"
certmanager "github.com/cert-manager/cert-manager/pkg/client/clientset/versioned"
"github.com/spf13/cobra"
"go.uber.org/multierr"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/restmapper"

"k8s.io/kops/channels/pkg/channels"
"k8s.io/kops/util/pkg/tables"
"k8s.io/kops/util/pkg/vfs"
)

type ApplyChannelOptions struct {
Yes bool

configFlags genericclioptions.ConfigFlags
}

func NewCmdApplyChannel(f Factory, out io.Writer) *cobra.Command {
func NewCmdApplyChannel(f *ChannelsFactory, out io.Writer) *cobra.Command {
var options ApplyChannelOptions

cmd := &cobra.Command{
Expand All @@ -57,20 +62,29 @@ func NewCmdApplyChannel(f Factory, out io.Writer) *cobra.Command {
return cmd
}

func RunApplyChannel(ctx context.Context, f Factory, out io.Writer, options *ApplyChannelOptions, args []string) error {
k8sClient, err := f.KubernetesClient()
func RunApplyChannel(ctx context.Context, f *ChannelsFactory, out io.Writer, options *ApplyChannelOptions, args []string) error {
restConfig, err := f.RESTConfig()
if err != nil {
return err
}

cmClient, err := f.CertManagerClient()
httpClient, err := f.HTTPClient()
if err != nil {
return err
}

k8sClient, err := kubernetes.NewForConfigAndClient(restConfig, httpClient)
if err != nil {
return fmt.Errorf("building kube client: %w", err)
}

cmClient, err := certmanager.NewForConfigAndClient(restConfig, httpClient)
if err != nil {
return fmt.Errorf("building cert manager client: %w", err)
}

dynamicClient, err := f.DynamicClient()
if err != nil {
return err
return fmt.Errorf("building dynamic client: %w", err)
}

restMapper, err := f.RESTMapper()
Expand All @@ -92,7 +106,7 @@ func RunApplyChannel(ctx context.Context, f Factory, out io.Writer, options *App
kubernetesVersion.Pre = nil

if len(args) != 1 {
return fmt.Errorf("unexpected number of arguments. Only one channel may be processed at the same time.")
return fmt.Errorf("unexpected number of arguments. Only one channel may be processed at the same time")
}

channelLocation := args[0]
Expand Down
99 changes: 90 additions & 9 deletions channels/pkg/cmd/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,101 @@ limitations under the License.
package cmd

import (
"fmt"
"net/http"

"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/restmapper"
"k8s.io/kops/util/pkg/vfs"

_ "k8s.io/client-go/plugin/pkg/client/auth"

certmanager "github.com/cert-manager/cert-manager/pkg/client/clientset/versioned"
)

type Factory interface {
VFSContext() *vfs.VFSContext
KubernetesClient() (kubernetes.Interface, error)
CertManagerClient() (certmanager.Interface, error)
RESTMapper() (*restmapper.DeferredDiscoveryRESTMapper, error)
DynamicClient() (dynamic.Interface, error)
type ChannelsFactory struct {
configFlags genericclioptions.ConfigFlags
cachedRESTConfig *rest.Config
cachedHTTPClient *http.Client
vfsContext *vfs.VFSContext
restMapper *restmapper.DeferredDiscoveryRESTMapper
dynamicClient dynamic.Interface
}

func NewChannelsFactory() *ChannelsFactory {
return &ChannelsFactory{}
}

func (f *ChannelsFactory) RESTConfig() (*rest.Config, error) {
if f.cachedRESTConfig == nil {
clientGetter := genericclioptions.NewConfigFlags(true)

restConfig, err := clientGetter.ToRESTConfig()
if err != nil {
return nil, fmt.Errorf("cannot load kubecfg settings: %w", err)
}

restConfig.UserAgent = "kops"
restConfig.Burst = 50
restConfig.QPS = 20
f.cachedRESTConfig = restConfig
}
return f.cachedRESTConfig, nil
}

func (f *ChannelsFactory) HTTPClient() (*http.Client, error) {
if f.cachedHTTPClient == nil {
restConfig, err := f.RESTConfig()
if err != nil {
return nil, err
}
httpClient, err := rest.HTTPClientFor(restConfig)
if err != nil {
return nil, fmt.Errorf("getting http client: %w", err)
}
f.cachedHTTPClient = httpClient
}
return f.cachedHTTPClient, nil
}

func (f *ChannelsFactory) RESTMapper() (*restmapper.DeferredDiscoveryRESTMapper, error) {
if f.restMapper == nil {
discoveryClient, err := f.configFlags.ToDiscoveryClient()
if err != nil {
return nil, err
}

restMapper := restmapper.NewDeferredDiscoveryRESTMapper(discoveryClient)

f.restMapper = restMapper
}

return f.restMapper, nil
}

func (f *ChannelsFactory) DynamicClient() (dynamic.Interface, error) {
if f.dynamicClient == nil {
restConfig, err := f.RESTConfig()
if err != nil {
return nil, err
}
httpClient, err := f.HTTPClient()
if err != nil {
return nil, err
}
dynamicClient, err := dynamic.NewForConfigAndClient(restConfig, httpClient)
if err != nil {
return nil, err
}
f.dynamicClient = dynamicClient
}
return f.dynamicClient, nil
}

func (f *ChannelsFactory) VFSContext() *vfs.VFSContext {
if f.vfsContext == nil {
// TODO vfs.NewVFSContext()
f.vfsContext = vfs.Context
}
return f.vfsContext
}
2 changes: 1 addition & 1 deletion channels/pkg/cmd/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"github.com/spf13/cobra"
)

func NewCmdGet(f Factory, out io.Writer) *cobra.Command {
func NewCmdGet(f *ChannelsFactory, out io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "get",
SuggestFor: []string{"list"},
Expand Down
16 changes: 13 additions & 3 deletions channels/pkg/cmd/get_addons.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,14 @@ import (
"github.com/spf13/cobra"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/kops/channels/pkg/channels"
"k8s.io/kops/util/pkg/tables"
)

type GetAddonsOptions struct{}

func NewCmdGetAddons(f Factory, out io.Writer) *cobra.Command {
func NewCmdGetAddons(f *ChannelsFactory, out io.Writer) *cobra.Command {
var options GetAddonsOptions

cmd := &cobra.Command{
Expand All @@ -70,11 +71,20 @@ type addonInfo struct {
Namespace *v1.Namespace
}

func RunGetAddons(ctx context.Context, f Factory, out io.Writer, options *GetAddonsOptions) error {
k8sClient, err := f.KubernetesClient()
func RunGetAddons(ctx context.Context, f *ChannelsFactory, out io.Writer, options *GetAddonsOptions) error {
restConfig, err := f.RESTConfig()
if err != nil {
return err
}
httpClient, err := f.HTTPClient()
if err != nil {
return err
}

k8sClient, err := kubernetes.NewForConfigAndClient(restConfig, httpClient)
if err != nil {
return fmt.Errorf("building kube client: %w", err)
}

namespaces, err := k8sClient.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})
if err != nil {
Expand Down
7 changes: 4 additions & 3 deletions channels/pkg/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package cmd

import (
"context"
goflag "flag"
"fmt"
"io"
Expand All @@ -29,17 +30,17 @@ type CmdRootOptions struct {
configFile string
}

func Execute(f Factory, out io.Writer) error {
func Execute(ctx context.Context, f *ChannelsFactory, out io.Writer) error {
cobra.OnInitialize(initConfig)

cmd := NewCmdRoot(f, out)

goflag.Set("logtostderr", "true")
goflag.CommandLine.Parse([]string{})
return cmd.Execute()
return cmd.ExecuteContext(ctx)
}

func NewCmdRoot(f Factory, out io.Writer) *cobra.Command {
func NewCmdRoot(f *ChannelsFactory, out io.Writer) *cobra.Command {
options := &CmdRootOptions{}

cmd := &cobra.Command{
Expand Down
Loading

0 comments on commit 51db52f

Please sign in to comment.