Skip to content

Commit

Permalink
Deploy nerd dependencies on private clusters when necessary (#418)
Browse files Browse the repository at this point in the history
* Get catalog files and deserialize them

* Check if cluster is nerd compliant

* don't write certificate for private clusters

* clean comments and add labels again
  • Loading branch information
LilliJane committed Jun 8, 2018
1 parent 93366c5 commit 9cebcf6
Show file tree
Hide file tree
Showing 13 changed files with 482 additions and 178 deletions.
57 changes: 41 additions & 16 deletions cmd/cluster_set_default.go → cmd/cluster_use.go
@@ -1,6 +1,7 @@
package cmd

import (
"context"
"fmt"
"net/url"
"os"
Expand All @@ -14,19 +15,25 @@ import (
"github.com/nerdalize/nerd/nerd/oauth"
"github.com/nerdalize/nerd/pkg/kubeconfig"
"github.com/nerdalize/nerd/pkg/populator"
"github.com/nerdalize/nerd/svc"
"github.com/pkg/errors"
)

//ClusterSetDefault command
type ClusterSetDefault struct {
const (
//PublicCluster is a service type we get from authentication
PublicCluster = "public-kubernetes"
)

//ClusterUse command
type ClusterUse struct {
Namespace string `long:"namespace" short:"n" description:"set a specific namespace as the default one"`

*command
}

//ClusterSetDefaultFactory creates the command
func ClusterSetDefaultFactory(ui cli.Ui) cli.CommandFactory {
cmd := &ClusterSetDefault{}
//ClusterUseFactory creates the command
func ClusterUseFactory(ui cli.Ui) cli.CommandFactory {
cmd := &ClusterUse{}
cmd.command = createCommand(ui, cmd.Execute, cmd.Description, cmd.Usage, cmd, &ConfOpts{}, flags.None, "nerd cluster set-default")
t, ok := cmd.advancedOpts.(*ConfOpts)
if !ok {
Expand All @@ -40,7 +47,7 @@ func ClusterSetDefaultFactory(ui cli.Ui) cli.CommandFactory {
}

//Execute runs the command
func (cmd *ClusterSetDefault) Execute(args []string) (err error) {
func (cmd *ClusterUse) Execute(args []string) (err error) {
// TODO move this part to another func
env := os.Getenv("NERD_ENV")
if env == "staging" {
Expand All @@ -55,6 +62,10 @@ func (cmd *ClusterSetDefault) Execute(args []string) (err error) {
return errShowUsage(fmt.Sprintf(MessageNotEnoughArguments, 1, ""))
}

ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx, cmd.globalOpts.KubeOpts.Timeout)
defer cancel()

authbase, err := url.Parse(cmd.config.Auth.APIEndpoint)
if err != nil {
return errors.Wrapf(err, "auth endpoint '%v' is not a valid URL", cmd.config.Auth.APIEndpoint)
Expand Down Expand Up @@ -111,17 +122,31 @@ func (cmd *ClusterSetDefault) Execute(args []string) (err error) {
return err
}

// check if it's nerd ready (is app nlz-utils up ?)
// else apply helm chart
// - get catalogs (is it necessary ?)
// - get projects (can we have it from auth)
// - launch app
// how to get the right chart version ?
if cluster.ServiceType != PublicCluster {
deps, err := NewDeps(cmd.Logger(), cmd.globalOpts.KubeOpts)
if err != nil {
return renderConfigError(err, "failed to configure")
}
kube := svc.NewKube(deps)

ok, nerdDependencies, err := kube.IsNerdCompliant(ctx)
if err != nil {
return err
}
if !ok {
cmd.out.Info("Cluster is not nerd compliant, installing dependencies...")
// TODO move this to a new command
err = kube.AddNerdDependencies(ctx, &svc.AddNerdDependenciesInput{Dependencies: nerdDependencies})
if err != nil {
return err
}
}
}
name := cluster.Name
if name == "" {
name = cluster.ShortName
}
cmd.out.Infof("You are now using %s's config.", name)
cmd.out.Infof("You are now using '%s' config.", name)
return nil
}

Expand All @@ -147,12 +172,12 @@ func lookByName(name string, clusters []*v1authpayload.GetClusterOutput) (*v1aut
}

// Description returns long-form help text
func (cmd *ClusterSetDefault) Description() string { return cmd.Synopsis() }
func (cmd *ClusterUse) Description() string { return cmd.Synopsis() }

// Synopsis returns a one-line
func (cmd *ClusterSetDefault) Synopsis() string {
func (cmd *ClusterUse) Synopsis() string {
return "Set a specific cluster as the current one to use."
}

// Usage shows usage
func (cmd *ClusterSetDefault) Usage() string { return "nerd cluster set-default NAME [OPTIONS]" }
func (cmd *ClusterUse) Usage() string { return "nerd cluster set-default NAME [OPTIONS]" }
6 changes: 6 additions & 0 deletions cmd/flex/main.go
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/joho/godotenv"
"github.com/pkg/errors"
"k8s.io/api/core/v1"
apiext "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
certutil "k8s.io/client-go/util/cert"
Expand Down Expand Up @@ -822,3 +823,8 @@ func (deps *Deps) Namespace() string {
func (deps *Deps) Crd() crd.Interface {
return deps.crd
}

//APIExt implements the DI interface
func (deps *Deps) APIExt() apiext.Interface {
return nil
}
34 changes: 23 additions & 11 deletions cmd/opts.go
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/nerdalize/nerd/pkg/transfer/store"
"github.com/nerdalize/nerd/svc"
"github.com/pkg/errors"
apiext "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)
Expand Down Expand Up @@ -59,17 +60,18 @@ func (opts TransferOpts) TransferManager(kube *svc.Kube) (mgr transfer.Manager,

//KubeOpts can be used to create a Kubernetes service
type KubeOpts struct {
KubeConfig string `long:"kubeconfig" description:"file at which Nerd will look for Kubernetes credentials" env:"KUBECONFIG" default-mask:"~/.kube/config" default:"~/.kube/config"`
KubeConfig string `long:"kubeconfig" description:"file at which Nerd will look for Kubernetes credentials" env:"KUBECONFIG" default-mask:"~/.kube/config"`
Timeout time.Duration `long:"timeout" description:"duration for which Nerd will wait for Kubernetes" default-mask:"10s" default:"10s" required:"true"`
}

//Deps exposes dependencies
type Deps struct {
val svc.Validator
kube kubernetes.Interface
crd crd.Interface
logs svc.Logger
ns string
val svc.Validator
kube kubernetes.Interface
crd crd.Interface
apiext apiext.Interface
logs svc.Logger
ns string
}

//NewDeps uses options to setup dependencies
Expand All @@ -90,6 +92,11 @@ func NewDeps(logs svc.Logger, kopts KubeOpts) (*Deps, error) {
logs: logs,
}

d.apiext, err = apiext.NewForConfig(kcfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create Kuberntes configuration")
}

d.crd, err = crd.NewForConfig(kcfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create Kubernetes configuration")
Expand All @@ -116,27 +123,32 @@ func NewDeps(logs svc.Logger, kopts KubeOpts) (*Deps, error) {
return d, nil
}

//Kube provides the kubernetes dependency
//Kube provides the kubernetes dependency.
func (deps *Deps) Kube() kubernetes.Interface {
return deps.kube
}

//Validator provides the Validator dependency
//Validator provides the Validator dependency.
func (deps *Deps) Validator() svc.Validator {
return deps.val
}

//Logger provides the Logger dependency
//Logger provides the Logger dependency.
func (deps *Deps) Logger() svc.Logger {
return deps.logs
}

//Namespace provides the namespace dependency
//Namespace provides the namespace dependency.
func (deps *Deps) Namespace() string {
return deps.ns
}

//Crd provides the custom resource definition API
//Crd provides the custom resource definition API.
func (deps *Deps) Crd() crd.Interface {
return deps.crd
}

//APIExt provides the extensions api to create a custom resource definition.
func (deps *Deps) APIExt() apiext.Interface {
return deps.apiext
}

0 comments on commit 9cebcf6

Please sign in to comment.