Skip to content

Commit

Permalink
Merge pull request #7749 from tstromberg/storageclass-kapi
Browse files Browse the repository at this point in the history
Unify Kubernetes client creation around kapi.Client
  • Loading branch information
medyagh authored Apr 17, 2020
2 parents 74e34c0 + 8fc8abb commit 14b6582
Show file tree
Hide file tree
Showing 11 changed files with 59 additions and 144 deletions.
6 changes: 6 additions & 0 deletions cmd/minikube/cmd/config/configure.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,11 @@ var addonsConfigureCmd = &cobra.Command{
acrPassword = AskForPasswordValue("-- Enter service principal password to access Azure Container Registry: ")
}

cname := ClusterFlagValue()

// Create ECR Secret
err := service.CreateSecret(
cname,
"kube-system",
"registry-creds-ecr",
map[string]string{
Expand All @@ -124,6 +127,7 @@ var addonsConfigureCmd = &cobra.Command{

// Create GCR Secret
err = service.CreateSecret(
cname,
"kube-system",
"registry-creds-gcr",
map[string]string{
Expand All @@ -142,6 +146,7 @@ var addonsConfigureCmd = &cobra.Command{

// Create Docker Secret
err = service.CreateSecret(
cname,
"kube-system",
"registry-creds-dpr",
map[string]string{
Expand All @@ -161,6 +166,7 @@ var addonsConfigureCmd = &cobra.Command{

// Create Azure Container Registry Secret
err = service.CreateSecret(
cname,
"kube-system",
"registry-creds-acr",
map[string]string{
Expand Down
4 changes: 2 additions & 2 deletions cmd/minikube/cmd/config/open.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ minikube addons enable {{.name}}`, out.V{"name": addonName})
namespace := "kube-system"
key := "kubernetes.io/minikube-addons-endpoint"

serviceList, err := service.GetServiceListByLabel(namespace, key, addonName)
serviceList, err := service.GetServiceListByLabel(cname, namespace, key, addonName)
if err != nil {
exit.WithCodeT(exit.Unavailable, "Error getting service with namespace: {{.namespace}} and labels {{.labelName}}:{{.addonName}}: {{.error}}", out.V{"namespace": namespace, "labelName": key, "addonName": addonName, "error": err})
}
Expand All @@ -89,7 +89,7 @@ You can add one by annotating a service with the label {{.labelName}}:{{.addonNa
svc := serviceList.Items[i].ObjectMeta.Name
var urlString []string

if urlString, err = service.WaitForService(co.API, namespace, svc, addonsURLTemplate, addonsURLMode, https, wait, interval); err != nil {
if urlString, err = service.WaitForService(co.API, co.Config.Name, namespace, svc, addonsURLTemplate, addonsURLMode, https, wait, interval); err != nil {
exit.WithCodeT(exit.Unavailable, "Wait failed: {{.error}}", out.V{"error": err})
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/minikube/cmd/dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ var dashboardCmd = &cobra.Command{
ns := "kubernetes-dashboard"
svc := "kubernetes-dashboard"
out.ErrT(out.Verifying, "Verifying dashboard health ...")
checkSVC := func() error { return service.CheckService(ns, svc) }
checkSVC := func() error { return service.CheckService(cname, ns, svc) }
// for slow machines or parallels in CI to avoid #7503
if err = retry.Expo(checkSVC, 100*time.Microsecond, time.Minute*10); err != nil {
exit.WithCodeT(exit.Unavailable, "dashboard service is not running: {{.error}}", out.V{"error": err})
Expand Down
5 changes: 3 additions & 2 deletions cmd/minikube/cmd/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"github.com/spf13/cobra"

"k8s.io/minikube/pkg/drivers/kic/oci"
"k8s.io/minikube/pkg/kapi"
"k8s.io/minikube/pkg/minikube/browser"
"k8s.io/minikube/pkg/minikube/driver"
"k8s.io/minikube/pkg/minikube/exit"
Expand Down Expand Up @@ -84,7 +85,7 @@ var serviceCmd = &cobra.Command{
return
}

urls, err := service.WaitForService(co.API, namespace, svc, serviceURLTemplate, serviceURLMode, https, wait, interval)
urls, err := service.WaitForService(co.API, co.Config.Name, namespace, svc, serviceURLTemplate, serviceURLMode, https, wait, interval)
if err != nil {
var s *service.SVCNotFoundError
if errors.As(err, &s) {
Expand Down Expand Up @@ -113,7 +114,7 @@ func startKicServiceTunnel(svc, configName string) {
ctrlC := make(chan os.Signal, 1)
signal.Notify(ctrlC, os.Interrupt)

clientset, err := service.K8s.GetClientset(1 * time.Second)
clientset, err := kapi.Client(configName)
if err != nil {
exit.WithError("error creating clientset", err)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/minikube/cmd/service_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ var serviceListCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
co := mustload.Healthy(ClusterFlagValue())

serviceURLs, err := service.GetServiceURLs(co.API, serviceListNamespace, serviceURLTemplate)
serviceURLs, err := service.GetServiceURLs(co.API, co.Config.Name, serviceListNamespace, serviceURLTemplate)
if err != nil {
out.FatalT("Failed to get service URL: {{.error}}", out.V{"error": err})
out.ErrT(out.Notice, "Check that minikube is running and that you have specified the correct namespace (-n flag) if required.")
Expand Down
5 changes: 2 additions & 3 deletions cmd/minikube/cmd/tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,17 @@ import (
"os/signal"
"path/filepath"
"strconv"
"time"

"github.com/golang/glog"
"github.com/spf13/cobra"

"k8s.io/minikube/pkg/drivers/kic/oci"
"k8s.io/minikube/pkg/kapi"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/driver"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/localpath"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/service"
"k8s.io/minikube/pkg/minikube/tunnel"
"k8s.io/minikube/pkg/minikube/tunnel/kic"
)
Expand Down Expand Up @@ -65,7 +64,7 @@ var tunnelCmd = &cobra.Command{
// We define the tunnel and minikube error free if the API server responds within a second.
// This also contributes to better UX, the tunnel status check can happen every second and
// doesn't hang on the API server call during startup and shutdown time or if there is a temporary error.
clientset, err := service.K8s.GetClientset(1 * time.Second)
clientset, err := kapi.Client(cname)
if err != nil {
exit.WithError("error creating clientset", err)
}
Expand Down
9 changes: 5 additions & 4 deletions pkg/addons/addons.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,10 +259,6 @@ func enableOrDisableStorageClasses(cc *config.ClusterConfig, name string, val st
if name == "storage-provisioner-gluster" {
class = "glusterfile"
}
storagev1, err := storageclass.GetStoragev1()
if err != nil {
return errors.Wrapf(err, "Error getting storagev1 interface %v ", err)
}

api, err := machine.NewAPIClient()
if err != nil {
Expand All @@ -279,6 +275,11 @@ func enableOrDisableStorageClasses(cc *config.ClusterConfig, name string, val st
return enableOrDisableAddon(cc, name, val)
}

storagev1, err := storageclass.GetStoragev1(cc.Name)
if err != nil {
return errors.Wrapf(err, "Error getting storagev1 interface %v ", err)
}

if enable {
// Only StorageClass for 'name' should be marked as default
err = storageclass.SetDefaultStorageClass(storagev1, class)
Expand Down
80 changes: 24 additions & 56 deletions pkg/minikube/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,17 @@ import (
"github.com/golang/glog"
"github.com/olekukonko/tablewriter"
"github.com/pkg/errors"
"github.com/spf13/viper"
core "k8s.io/api/core/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/kubernetes"
typed_core "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/kapi"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/proxy"
"k8s.io/minikube/pkg/util/retry"
)

const (
defaultK8sClientTimeout = 60 * time.Second
// DefaultWait is the default wait time, in seconds
DefaultWait = 2
// DefaultInterval is the default interval, in seconds
Expand All @@ -56,8 +50,7 @@ const (

// K8sClient represents a kubernetes client
type K8sClient interface {
GetCoreClient() (typed_core.CoreV1Interface, error)
GetClientset(timeout time.Duration) (*kubernetes.Clientset, error)
GetCoreClient(string) (typed_core.CoreV1Interface, error)
}

// K8sClientGetter can get a K8sClient
Expand All @@ -71,39 +64,14 @@ func init() {
}

// GetCoreClient returns a core client
func (k *K8sClientGetter) GetCoreClient() (typed_core.CoreV1Interface, error) {
client, err := k.GetClientset(defaultK8sClientTimeout)
func (k *K8sClientGetter) GetCoreClient(context string) (typed_core.CoreV1Interface, error) {
client, err := kapi.Client(context)
if err != nil {
return nil, errors.Wrap(err, "getting clientset")
return nil, errors.Wrap(err, "client")
}
return client.CoreV1(), nil
}

// GetClientset returns a clientset
func (*K8sClientGetter) GetClientset(timeout time.Duration) (*kubernetes.Clientset, error) {
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
profile := viper.GetString(config.ProfileName)
configOverrides := &clientcmd.ConfigOverrides{
Context: clientcmdapi.Context{
Cluster: profile,
AuthInfo: profile,
},
}
kubeConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, configOverrides)
clientConfig, err := kubeConfig.ClientConfig()
if err != nil {
return nil, fmt.Errorf("kubeConfig: %v", err)
}
clientConfig.Timeout = timeout
clientConfig = proxy.UpdateTransport(clientConfig)
client, err := kubernetes.NewForConfig(clientConfig)
if err != nil {
return nil, errors.Wrap(err, "client from config")
}

return client, nil
}

// SvcURL represents a service URL. Each item in the URLs field combines the service URL with one of the configured
// node ports. The PortNames field contains the configured names of the ports in the URLs field (sorted correspondingly -
// first item in PortNames belongs to the first item in URLs).
Expand All @@ -119,8 +87,8 @@ type URLs []SvcURL

// GetServiceURLs returns a SvcURL object for every service in a particular namespace.
// Accepts a template for formatting
func GetServiceURLs(api libmachine.API, namespace string, t *template.Template) (URLs, error) {
host, err := machine.LoadHost(api, viper.GetString(config.ProfileName))
func GetServiceURLs(api libmachine.API, cname string, namespace string, t *template.Template) (URLs, error) {
host, err := machine.LoadHost(api, cname)
if err != nil {
return nil, err
}
Expand All @@ -130,7 +98,7 @@ func GetServiceURLs(api libmachine.API, namespace string, t *template.Template)
return nil, err
}

client, err := K8s.GetCoreClient()
client, err := K8s.GetCoreClient(cname)
if err != nil {
return nil, err
}
Expand All @@ -155,8 +123,8 @@ func GetServiceURLs(api libmachine.API, namespace string, t *template.Template)
}

// GetServiceURLsForService returns a SvcUrl object for a service in a namespace. Supports optional formatting.
func GetServiceURLsForService(api libmachine.API, namespace, service string, t *template.Template) (SvcURL, error) {
host, err := machine.LoadHost(api, viper.GetString(config.ProfileName))
func GetServiceURLsForService(api libmachine.API, cname string, namespace, service string, t *template.Template) (SvcURL, error) {
host, err := machine.LoadHost(api, cname)
if err != nil {
return SvcURL{}, errors.Wrap(err, "Error checking if api exist and loading it")
}
Expand All @@ -166,7 +134,7 @@ func GetServiceURLsForService(api libmachine.API, namespace, service string, t *
return SvcURL{}, errors.Wrap(err, "Error getting ip from host")
}

client, err := K8s.GetCoreClient()
client, err := K8s.GetCoreClient(cname)
if err != nil {
return SvcURL{}, err
}
Expand Down Expand Up @@ -226,8 +194,8 @@ func printURLsForService(c typed_core.CoreV1Interface, ip, service, namespace st
}

// CheckService checks if a service is listening on a port.
func CheckService(namespace string, service string) error {
client, err := K8s.GetCoreClient()
func CheckService(cname string, namespace string, service string) error {
client, err := K8s.GetCoreClient(cname)
if err != nil {
return errors.Wrap(err, "Error getting kubernetes client")
}
Expand Down Expand Up @@ -283,26 +251,26 @@ func (t SVCNotFoundError) Error() string {
}

// WaitForService waits for a service, and return the urls when available
func WaitForService(api libmachine.API, namespace string, service string, urlTemplate *template.Template, urlMode bool, https bool,
func WaitForService(api libmachine.API, cname string, namespace string, service string, urlTemplate *template.Template, urlMode bool, https bool,
wait int, interval int) ([]string, error) {
var urlList []string
// Convert "Amount of time to wait" and "interval of each check" to attempts
if interval == 0 {
interval = 1
}

err := CheckService(namespace, service)
err := CheckService(cname, namespace, service)
if err != nil {
return nil, &SVCNotFoundError{err}
}

chkSVC := func() error { return CheckService(namespace, service) }
chkSVC := func() error { return CheckService(cname, namespace, service) }

if err := retry.Expo(chkSVC, time.Duration(interval)*time.Second, time.Duration(wait)*time.Second); err != nil {
return nil, &SVCNotFoundError{err}
}

serviceURL, err := GetServiceURLsForService(api, namespace, service, urlTemplate)
serviceURL, err := GetServiceURLsForService(api, cname, namespace, service, urlTemplate)
if err != nil {
return urlList, errors.Wrap(err, "Check that minikube is running and that you have specified the correct namespace")
}
Expand Down Expand Up @@ -330,8 +298,8 @@ func WaitForService(api libmachine.API, namespace string, service string, urlTem
}

// GetServiceListByLabel returns a ServiceList by label
func GetServiceListByLabel(namespace string, key string, value string) (*core.ServiceList, error) {
client, err := K8s.GetCoreClient()
func GetServiceListByLabel(cname string, namespace string, key string, value string) (*core.ServiceList, error) {
client, err := K8s.GetCoreClient(cname)
if err != nil {
return &core.ServiceList{}, &retry.RetriableError{Err: err}
}
Expand All @@ -349,8 +317,8 @@ func getServiceListFromServicesByLabel(services typed_core.ServiceInterface, key
}

// CreateSecret creates or modifies secrets
func CreateSecret(namespace, name string, dataValues map[string]string, labels map[string]string) error {
client, err := K8s.GetCoreClient()
func CreateSecret(cname string, namespace, name string, dataValues map[string]string, labels map[string]string) error {
client, err := K8s.GetCoreClient(cname)
if err != nil {
return &retry.RetriableError{Err: err}
}
Expand All @@ -363,7 +331,7 @@ func CreateSecret(namespace, name string, dataValues map[string]string, labels m

// Delete existing secret
if len(secret.Name) > 0 {
err = DeleteSecret(namespace, name)
err = DeleteSecret(cname, namespace, name)
if err != nil {
return &retry.RetriableError{Err: err}
}
Expand Down Expand Up @@ -394,8 +362,8 @@ func CreateSecret(namespace, name string, dataValues map[string]string, labels m
}

// DeleteSecret deletes a secret from a namespace
func DeleteSecret(namespace, name string) error {
client, err := K8s.GetCoreClient()
func DeleteSecret(cname string, namespace, name string) error {
client, err := K8s.GetCoreClient(cname)
if err != nil {
return &retry.RetriableError{Err: err}
}
Expand Down
Loading

0 comments on commit 14b6582

Please sign in to comment.