Skip to content

Commit

Permalink
Init Error Handling Enhancement (#858)
Browse files Browse the repository at this point in the history
  • Loading branch information
kensipe committed Sep 25, 2019
1 parent 6e6b017 commit 694a4f0
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 1 deletion.
7 changes: 7 additions & 0 deletions pkg/kudoctl/clog/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,13 @@ func Init(f *pflag.FlagSet, out io.Writer) {
logging.out = out
}

// InitNoFlag initializes without CLI flag which means the level must be initialized
// useful for tests
func InitNoFlag(out io.Writer, level Level) {
logging.verbosity.set(level)
logging.out = out
}

// Printf provides default level printing for things that will always print
func Printf(format string, args ...interface{}) {
V(0).Printf(format, args...)
Expand Down
30 changes: 29 additions & 1 deletion pkg/kudoctl/cmd/init/crds.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package init

import (
"errors"
"strings"

"github.com/kudobuilder/kudo/pkg/kudoctl/clog"

apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"

"k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1"
kerrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -35,24 +38,49 @@ func installCrds(client apiextensionsclient.Interface) error {
func installOperator(client v1beta1.CustomResourceDefinitionsGetter) error {
o := generateOperator()
_, err := client.CustomResourceDefinitions().Create(o)
if isAlreadyExistsError(err) {
clog.V(4).Printf("crd %v already exists", o.Name)
return nil
}
return err

}

func isAlreadyExistsError(err error) bool {
var statusError *kerrors.StatusError
if errors.As(err, &statusError) {
return statusError.ErrStatus.Reason == "AlreadyExists"
}
return false
}

func installOperatorVersion(client v1beta1.CustomResourceDefinitionsGetter) error {
ov := generateOperatorVersion()
_, err := client.CustomResourceDefinitions().Create(ov)
if isAlreadyExistsError(err) {
clog.V(4).Printf("crd %v already exists", ov.Name)
return nil
}
return err
}

func installInstance(client v1beta1.CustomResourceDefinitionsGetter) error {
instance := generateInstance()
_, err := client.CustomResourceDefinitions().Create(instance)
if isAlreadyExistsError(err) {
clog.V(4).Printf("crd %v already exists", instance.Name)
return nil
}
return err
}

func installPlanExecution(client v1beta1.CustomResourceDefinitionsGetter) error {
pe := generatePlanExecution()
_, err := client.CustomResourceDefinitions().Create(pe)
if isAlreadyExistsError(err) {
clog.V(4).Printf("crd %v already exists", pe.Name)
return nil
}
return err
}

Expand Down
9 changes: 9 additions & 0 deletions pkg/kudoctl/cmd/init/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,21 @@ func installManager(client kubernetes.Interface, opts Options) error {
func installStatefulSet(client clientv1beta2.StatefulSetsGetter, opts Options) error {
ss := generateDeployment(opts)
_, err := client.StatefulSets(opts.Namespace).Create(ss)
if isAlreadyExistsError(err) {
clog.V(4).Printf("statefulset %v already exists", ss.Name)
return nil
}
return err
}

func installService(client corev1.ServicesGetter, opts Options) error {
s := generateService(opts)
_, err := client.Services(opts.Namespace).Create(s)
if isAlreadyExistsError(err) {
clog.V(4).Printf("service %v already exists", s.Name)
// this service considered different. If it exists and there is an init we will return the error
}

return err
}

Expand Down
18 changes: 18 additions & 0 deletions pkg/kudoctl/cmd/init/prereqs.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package init

import (
"github.com/kudobuilder/kudo/pkg/kudoctl/clog"

v1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -33,24 +35,40 @@ func installPrereqs(client kubernetes.Interface, opts Options) error {
func installSecret(client corev1.SecretsGetter, opts Options) error {
secret := generateWebHookSecret(opts)
_, err := client.Secrets(opts.Namespace).Create(secret)
if isAlreadyExistsError(err) {
clog.V(4).Printf("secret %v already exists", secret.Name)
return nil
}
return err
}

func installRoleBindings(client kubernetes.Interface, opts Options) error {
rbac := generateRoleBinding(opts)
_, err := client.RbacV1().ClusterRoleBindings().Create(rbac)
if isAlreadyExistsError(err) {
clog.V(4).Printf("role binding %v already exists", rbac.Name)
return nil
}
return err
}

func installNamespace(client corev1.NamespacesGetter, opts Options) error {
ns := generateSysNamespace(opts.Namespace)
_, err := client.Namespaces().Create(ns)
if isAlreadyExistsError(err) {
clog.V(4).Printf("namespace %v already exists", ns.Name)
return nil
}
return err
}

func installServiceAccount(client corev1.ServiceAccountsGetter, opts Options) error {
sa := generateServiceAccount(opts)
_, err := client.ServiceAccounts(opts.Namespace).Create(sa)
if isAlreadyExistsError(err) {
clog.V(4).Printf("service account %v already exists", sa.Name)
return nil
}
return err
}

Expand Down
47 changes: 47 additions & 0 deletions pkg/kudoctl/cmd/init_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import (
"context"
"log"
"os"
"strings"
"testing"

"github.com/kudobuilder/kudo/pkg/kudoctl/clog"
cmdinit "github.com/kudobuilder/kudo/pkg/kudoctl/cmd/init"
"github.com/kudobuilder/kudo/pkg/kudoctl/kube"

Expand Down Expand Up @@ -75,6 +77,51 @@ func TestIntegInitForCRDs(t *testing.T) {
assert.Nil(t, testClient.Create(context.TODO(), instance))
}

func TestNoErrorOnReInit(t *testing.T) {
// if the CRD exists and we init again there should be no error
testClient, err := testutils.NewRetryClient(testenv.Config, client.Options{
Scheme: testutils.Scheme(),
})
assert.Nil(t, err)
kclient := getKubeClient(t)

instance := testutils.NewResource("kudo.dev/v1alpha1", "Instance", "zk", "ns")
// Verify that we cannot create the instance, because the test environment is empty.
assert.IsType(t, &meta.NoKindMatchError{}, testClient.Create(context.TODO(), instance))

// Install all of the CRDs.
crds := cmdinit.CRDs()
defer deleteInitObjects(testClient)

var buf bytes.Buffer
clog.InitNoFlag(&buf, clog.Level(4))
defer func() { clog.InitNoFlag(&buf, clog.Level(0)) }()

cmd := &initCmd{
out: &buf,
fs: afero.NewMemMapFs(),
client: kclient,
crdOnly: true,
}
err = cmd.run()
assert.Nil(t, err)

// WaitForCRDs to be created... the init cmd did NOT wait
assert.Nil(t, testutils.WaitForCRDs(testenv.DiscoveryClient, crds))

// if the CRD exists and we init again there should be no error
testClient, err = testutils.NewRetryClient(testenv.Config, client.Options{
Scheme: testutils.Scheme(),
})
assert.Nil(t, err)
kclient = getKubeClient(t)

// second run will have an output that it already exists
err = cmd.run()
assert.Nil(t, err)
assert.True(t, strings.Contains(buf.String(), "crd operators.kudo.dev already exists"))
}

func deleteInitObjects(client *testutils.RetryClient) {
crds := cmdinit.CRDs()
prereqs := cmdinit.Prereq(cmdinit.NewOptions(""))
Expand Down
3 changes: 3 additions & 0 deletions pkg/kudoctl/kube/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package kube
import (
"fmt"

"github.com/kudobuilder/kudo/pkg/kudoctl/clog"

apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
Expand Down Expand Up @@ -34,6 +36,7 @@ func getRestConfig(kubeconfig string) (*rest.Config, error) {
if err != nil {
return nil, fmt.Errorf("could not get Kubernetes config using configuration %q: %s", kubeconfig, err)
}
clog.V(4).Printf("configuration from %q finds host %v", kubeconfig, config.Host)
return config, nil
}

Expand Down

0 comments on commit 694a4f0

Please sign in to comment.