Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor operator package installation #1542

Merged
merged 5 commits into from
Jun 4, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ require (
github.com/mitchellh/copystructure v1.0.0 // indirect
github.com/onsi/ginkgo v1.12.0
github.com/onsi/gomega v1.9.0
github.com/pkg/errors v0.9.1 // indirect
github.com/spf13/afero v1.2.2
github.com/spf13/cobra v1.0.0
github.com/spf13/pflag v1.0.5
Expand All @@ -24,6 +25,8 @@ require (
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a
golang.org/x/sys v0.0.0-20200408040146-ea54a3c99b9b // indirect
google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24 // indirect
google.golang.org/grpc v1.26.0 // indirect
gopkg.in/yaml.v2 v2.2.8
gotest.tools v2.2.0+incompatible
k8s.io/api v0.17.3
Expand Down
14 changes: 14 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/blang/semver v3.5.0+incompatible h1:CGxCgetQ64DKk7rdZ++Vfnb1+ogGNnB17OJKJXD2Cfs=
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41y6FOsEUvknqgXnGmJyJSbjhAWq5pO4F8=
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
Expand Down Expand Up @@ -121,6 +122,8 @@ github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkg
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk=
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M=
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
Expand Down Expand Up @@ -415,6 +418,8 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.0 h1:J8lpUdobwIeCI7OiSxHqEwJUKvJwicL5+3v1oe2Yb4k=
github.com/pkg/errors v0.9.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
Expand All @@ -426,6 +431,8 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw=
Expand Down Expand Up @@ -491,6 +498,7 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
Expand Down Expand Up @@ -652,10 +660,16 @@ google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7 h1:ZUjXAXmrAyrmmCP
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 h1:nfPFGzJkUDX6uBmpN/pSw7MbOAWegH5QDQuoXFHedLg=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24 h1:wDju+RU97qa0FZT0QnZDg9Uc2dH0Ql513kFvHocz+WM=
google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.23.1 h1:q4XQuHFC6I28BKZpo6IYyb3mNO+l7lSOxRuYTCiDfXk=
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
20 changes: 18 additions & 2 deletions pkg/kudoctl/cmd/install/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (

"github.com/kudobuilder/kudo/pkg/kudoctl/clog"
"github.com/kudobuilder/kudo/pkg/kudoctl/env"
"github.com/kudobuilder/kudo/pkg/kudoctl/packages/install"
pkgresolver "github.com/kudobuilder/kudo/pkg/kudoctl/packages/resolver"
"github.com/kudobuilder/kudo/pkg/kudoctl/util/kudo"
"github.com/kudobuilder/kudo/pkg/kudoctl/util/repo"
)

Expand Down Expand Up @@ -79,5 +79,21 @@ func installOperator(operatorArgument string, options *Options, fs afero.Fs, set
return fmt.Errorf("failed to resolve operator package for: %s %w", operatorArgument, err)
}

return kudo.InstallPackage(kc, pkg.Resources, options.SkipInstance, options.InstanceName, settings.Namespace, options.Parameters, options.Wait, options.CreateNameSpace, time.Duration(options.WaitTime)*time.Second)
installOpts := install.Options{
SkipInstance: options.SkipInstance,
CreateNamespace: options.CreateNameSpace,
}

if options.Wait {
waitDuration := time.Duration(options.WaitTime) * time.Second
installOpts.Wait = &waitDuration
}

return install.Package(
kc,
options.InstanceName,
settings.Namespace,
*pkg.Resources,
options.Parameters,
installOpts)
}
3 changes: 3 additions & 0 deletions pkg/kudoctl/packages/install/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Package install provides function to install package resources
// on a Kubernetes cluster.
package install
51 changes: 51 additions & 0 deletions pkg/kudoctl/packages/install/instance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package install

import (
"errors"
"fmt"
"time"

pollwait "k8s.io/apimachinery/pkg/util/wait"

"github.com/kudobuilder/kudo/pkg/apis/kudo/v1beta1"
"github.com/kudobuilder/kudo/pkg/kudoctl/clog"
"github.com/kudobuilder/kudo/pkg/kudoctl/util/kudo"
)

func installInstance(client *kudo.Client, instance *v1beta1.Instance) error {
existingInstance, err := client.GetInstance(instance.Name, instance.Namespace)
if err != nil {
return fmt.Errorf("failed to verify existing instance: %v", err)
}

if existingInstance != nil {
return clog.Errorf(
"cannot install instance '%s' because an instance of that name already exists in namespace %s",
instance.Name,
instance.Namespace)
}

if _, err := client.InstallInstanceObjToCluster(instance, instance.Namespace); err != nil {
return fmt.Errorf(
"failed to install instance %s/%s: %v",
instance.Namespace,
instance.Name,
err)
}

clog.Printf("instance %s/%s created", instance.Namespace, instance.Name)
return nil
}

func waitForInstance(client *kudo.Client, instance *v1beta1.Instance, timeout time.Duration) error {
err := client.WaitForInstance(instance.Name, instance.Namespace, nil, timeout)
if errors.Is(err, pollwait.ErrWaitTimeout) {
clog.Printf("timeout waiting for instance %s/%s", instance.Namespace, instance.Name)
}
if err != nil {
return fmt.Errorf("failed to wait on instance %s/%s: %v", instance.Namespace, instance.Name, err)
}

clog.Printf("instance %s/%s ready", instance.Namespace, instance.Name)
return nil
}
61 changes: 61 additions & 0 deletions pkg/kudoctl/packages/install/namespace.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package install

import (
"fmt"

"github.com/kudobuilder/kudo/pkg/engine/renderer"
"github.com/kudobuilder/kudo/pkg/kudoctl/clog"
"github.com/kudobuilder/kudo/pkg/kudoctl/packages"
"github.com/kudobuilder/kudo/pkg/kudoctl/util/kudo"
)

// installNamespace installs a namespace from package resources.
// If the resources contain a namespace manifest, it is rendered and
// applied to the namespace.
func installNamespace(
client *kudo.Client,
resources packages.Resources,
parameters map[string]string) error {
clog.V(3).Printf("creating namespace: %q", resources.Instance.Namespace)

manifest := ""
if resources.Operator.Spec.NamespaceManifest != "" {
clog.V(3).Printf(
"creating namespace with manifest named: %q",
resources.Operator.Spec.NamespaceManifest)

template, ok := resources.OperatorVersion.Spec.Templates[resources.Operator.Spec.NamespaceManifest]
if !ok {
return fmt.Errorf(
"failed to find template for namespace manifest %q",
resources.Operator.Spec.NamespaceManifest)
}

var err error
manifest, err = renderNamespaceManifest(template, resources, parameters)
if err != nil {
return fmt.Errorf(
"failed to render namespace manifest %q: %w",
resources.Operator.Spec.NamespaceManifest,
err)
}
}

return client.CreateNamespace(resources.Instance.Namespace, manifest)
}

func renderNamespaceManifest(
manifest string,
resources packages.Resources,
parameters map[string]string) (string, error) {
configs := renderer.NewVariableMap().
WithInstance("", resources.Instance.Name, resources.Instance.Namespace, "", "").
WithResource(&resources).
WithParameterStrings(parameters)
engine := renderer.New()
rendered, err := engine.Render("namespace", manifest, configs)
if err != nil {
return "", err
}
return rendered, nil
}
39 changes: 39 additions & 0 deletions pkg/kudoctl/packages/install/namespace_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package install

import (
"io/ioutil"
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
)

func TestNamespaceManifestRendering(t *testing.T) {
namespaceFile := "testdata/namespace.yaml"

ns, err := ioutil.ReadFile(namespaceFile)
assert.NoError(t, err)

params := make(map[string]string)
params["foo"] = "bar-param"

rendered, err := renderNamespaceManifest(string(ns), testResources(), params)
assert.NoError(t, err)

file := "rendered-namespace.yaml"
gf := filepath.Join("testdata", file+".golden")

if *update {
t.Log("update golden file")
if err := ioutil.WriteFile(gf, []byte(rendered), 0644); err != nil {
t.Fatalf("failed to update golden file: %s", err)
}
}

golden, err := ioutil.ReadFile(gf)
if err != nil {
t.Fatalf("failed reading .golden: %s", err)
}

assert.Equal(t, string(golden), rendered, "for golden file: %s", gf)
}
59 changes: 59 additions & 0 deletions pkg/kudoctl/packages/install/operator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package install

import (
"fmt"

"github.com/thoas/go-funk"

"github.com/kudobuilder/kudo/pkg/kudoctl/clog"
"github.com/kudobuilder/kudo/pkg/kudoctl/packages"
"github.com/kudobuilder/kudo/pkg/kudoctl/util/kudo"
)

func installOperatorAndOperatorVersion(client *kudo.Client, resources packages.Resources) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, we'll need this method for the dependencies.

if !client.OperatorExistsInCluster(resources.Operator.Name, resources.Operator.Namespace) {
if _, err := client.InstallOperatorObjToCluster(resources.Operator, resources.Operator.Namespace); err != nil {
return fmt.Errorf(
"failed to install operator %s/%s: %v",
resources.Operator.Namespace,
resources.Operator.Name,
err)
}
clog.Printf(
"operator %s/%s created",
resources.Operator.Namespace,
resources.Operator.Name)
}

versionsInstalled, err := client.OperatorVersionsInstalled(resources.Operator.Name, resources.Operator.Namespace)
if err != nil {
return fmt.Errorf(
"failed to retrieve existing operator versions of operator %s/%s: %v",
resources.Operator.Namespace,
resources.Operator.Name,
err)
}

if !funk.ContainsString(versionsInstalled, resources.OperatorVersion.Spec.Version) {
if _, err := client.InstallOperatorVersionObjToCluster(
resources.OperatorVersion,
resources.OperatorVersion.Namespace); err != nil {
return fmt.Errorf(
"failed to install operatorversion %s/%s: %v",
resources.OperatorVersion.Namespace,
resources.OperatorVersion.Name,
err)
}
clog.Printf(
"operatorversion %s/%s created",
resources.OperatorVersion.Namespace,
resources.OperatorVersion.Name)
} else {
clog.Printf(
"operatorversion %s/%s already installed",
resources.OperatorVersion.Namespace,
resources.OperatorVersion.Name)
}

return nil
}
Loading