Skip to content

Commit

Permalink
KfConfig - Internal data structure for holding config info (kubeflow#…
Browse files Browse the repository at this point in the history
…4210)

* KfctlConfig init

* add more fields

* add status and cache

* link to gcp

* add GetPluginSpec

* add condition access funcs

* add condition helper

* add plugin access funcs

* add plugin spec writer

* remove functiosn from kfdef v1beta1

* remove kfloader

* add sourceVersion

* LoadConfigFromURI init

* WriteConfigToFile init

* copy applications

* copy secrets

* copy repos

* copy plugins

* add runtime fields

* copy status

* beta transformer

* temp commit

* updates

* serialize plugins

* serialize secrets

* serialize repos

* serialize cache

* add interface

* finish v1alpha1

* change naming

* v1beta1 converter

* test init

* v1alpha1 test

* updates

* beta test init

* finish test

* fix

* remove temp files

* fix

* KfConfig converter

* appDir

* write file

* rename

* fix test

* remove temp codes

* remove unused field

* fix

* add fields

* fill in new fields in v1alpha1

* fix tests

* fill fields in v1beta1
  • Loading branch information
gabrielwen authored and k8s-ci-robot committed Oct 1, 2019
1 parent 4a1c06b commit db672b8
Show file tree
Hide file tree
Showing 21 changed files with 2,622 additions and 1,124 deletions.
10 changes: 1 addition & 9 deletions bootstrap/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,24 @@ require (
github.com/Sirupsen/logrus v0.0.0-00010101000000-000000000000 // indirect
github.com/aws/aws-sdk-go v1.15.78
github.com/cenkalti/backoff v2.1.1+incompatible
github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1 // indirect
github.com/deckarep/golang-set v1.7.1
github.com/docker/docker v1.13.1 // indirect
github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c // indirect
github.com/elazarl/goproxy v0.0.0-20190711103511-473e67f1d7d2 // indirect
github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 // indirect
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
github.com/fatih/camelcase v1.0.0 // indirect
github.com/ghodss/yaml v1.0.0
github.com/go-kit/kit v0.8.0
github.com/gogo/protobuf v1.2.1
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
github.com/golang/protobuf v1.3.1
github.com/hashicorp/go-getter v1.0.2
github.com/imdario/mergo v0.3.7
github.com/jonboulle/clockwork v0.1.0 // indirect
github.com/kr/pty v1.1.3 // indirect
github.com/kubeflow/kfctl/v3 v3.0.0-20190917231916-6ebaf60b014a
github.com/kubeflow/kubeflow/components/profile-controller/v2 v2.0.0
github.com/mitchellh/go-homedir v1.1.0
github.com/mitchellh/go-wordwrap v1.0.0 // indirect
github.com/onrik/logrus v0.2.1
github.com/otiai10/copy v1.0.1
github.com/pkg/errors v0.8.1
github.com/prometheus/client_golang v0.9.2
github.com/prometheus/common v0.2.0
github.com/russross/blackfriday v1.5.2 // indirect
github.com/sirupsen/logrus v1.3.0
github.com/spf13/afero v1.2.2
github.com/spf13/cobra v0.0.3
Expand Down
1 change: 1 addition & 0 deletions bootstrap/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,7 @@ k8s.io/utils v0.0.0-20190920012459-5008bf6f8cd6/go.mod h1:sZAwmy6armz5eXlNoLmJcl
sigs.k8s.io/controller-runtime v0.1.12 h1:ovDq28E64PeY1yR+6H7DthakIC09soiDCrKvfP2tPYo=
sigs.k8s.io/controller-runtime v0.1.12/go.mod h1:HFAYoOh6XMV+jKF1UjFwrknPbowfyHEHHRdJMf2jMX8=
sigs.k8s.io/controller-tools v0.1.9/go.mod h1:6g08p9m9G/So3sBc1AOQifHfhxH/mb6Sc4z0LMI8XMw=
sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
sigs.k8s.io/kustomize/v3 v3.1.0 h1:FnNC1UtUjZlepvWUGwaAcFHw2rjNIaZvBUPCvaXz0Fo=
sigs.k8s.io/kustomize/v3 v3.1.0/go.mod h1:ztX4zYc/QIww3gSripwF7TBOarBTm5BvyAMem0kCzOE=
Expand Down
165 changes: 165 additions & 0 deletions bootstrap/pkg/apis/apps/configconverters/converters.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
package configconverters

import (
"fmt"
"github.com/ghodss/yaml"
gogetter "github.com/hashicorp/go-getter"
kfapis "github.com/kubeflow/kubeflow/bootstrap/v3/pkg/apis"
kfconfig "github.com/kubeflow/kubeflow/bootstrap/v3/pkg/apis/apps/kfconfig"
log "github.com/sirupsen/logrus"
"io/ioutil"
netUrl "net/url"
"path"
"strings"
)

type Converter interface {
ToKfConfig(appdir string, kfdefBytes []byte) (*kfconfig.KfConfig, error)
ToKfDefSerialized(config kfconfig.KfConfig) ([]byte, error)
}

const (
KfConfigFile = "app.yaml"
Api = "kfdef.apps.kubeflow.org"
)

func isValidUrl(toTest string) bool {
_, err := netUrl.ParseRequestURI(toTest)
if err != nil {
return false
} else {
return true
}
}

func LoadConfigFromURI(configFile string) (*kfconfig.KfConfig, error) {
if configFile == "" {
return nil, fmt.Errorf("config file must be the URI of a KfDef spec")
}

// TODO(jlewi): We should check if configFile doesn't specify a protocol or the protocol
// is file:// then we can just read it rather than fetching with go-getter.
appDir, err := ioutil.TempDir("", "")
if err != nil {
return nil, fmt.Errorf("Create a temporary directory to copy the file to.")
}
// Open config file
//
// TODO(jlewi): Should we use hashicorp go-getter.GetAny here? We use that to download
// the tarballs for the repos. Maybe we should use that here as well to be consistent.
appFile := path.Join(appDir, KfConfigFile)

log.Infof("Downloading %v to %v", configFile, appFile)
configFileUri, err := netUrl.Parse(configFile)
if err != nil {
log.Errorf("could not parse configFile url")
}
if isValidUrl(configFile) {
errGet := gogetter.GetFile(appFile, configFile)
if errGet != nil {
return nil, &kfapis.KfError{
Code: int(kfapis.INVALID_ARGUMENT),
Message: fmt.Sprintf("could not fetch specified config %s: %v", configFile, err),
}
}
} else {
g := new(gogetter.FileGetter)
g.Copy = true
errGet := g.GetFile(appFile, configFileUri)
if errGet != nil {
return nil, &kfapis.KfError{
Code: int(kfapis.INVALID_ARGUMENT),
Message: fmt.Sprintf("could not fetch specified config %s: %v", configFile, err),
}
}
}

// Read contents
configFileBytes, err := ioutil.ReadFile(appFile)
if err != nil {
return nil, &kfapis.KfError{
Code: int(kfapis.INTERNAL_ERROR),
Message: fmt.Sprintf("could not read from config file %s: %v", configFile, err),
}
}

// Check API version.
var obj map[string]interface{}
if err = yaml.Unmarshal(configFileBytes, &obj); err != nil {
return nil, &kfapis.KfError{
Code: int(kfapis.INVALID_ARGUMENT),
Message: fmt.Sprintf("invalid config file format: %v", err),
}
}
apiVersion, ok := obj["apiVersion"]
if !ok {
return nil, &kfapis.KfError{
Code: int(kfapis.INVALID_ARGUMENT),
Message: "invalid config: apiVersion is not found.",
}
}
apiVersionSeparated := strings.Split(apiVersion.(string), "/")
if len(apiVersionSeparated) < 2 || apiVersionSeparated[0] != Api {
return nil, &kfapis.KfError{
Code: int(kfapis.INVALID_ARGUMENT),
Message: fmt.Sprintf("invalid config: apiVersion must be in the format of %v/<version>, got %v", Api, apiVersion),
}
}

converters := map[string]Converter{
"v1alpha1": V1alpha1{},
"v1beta1": V1beta1{},
}

converter, ok := converters[apiVersionSeparated[1]]
if !ok {
versions := []string{}
for key := range converters {
versions = append(versions, key)
}
return nil, &kfapis.KfError{
Code: int(kfapis.INVALID_ARGUMENT),
Message: fmt.Sprintf("invalid config: version not supported; supported versions: %v, got %v",
strings.Join(versions, ", "), apiVersionSeparated[1]),
}
}
return converter.ToKfConfig(appDir, configFileBytes)
}

func WriteConfigToFile(config kfconfig.KfConfig, filename string) error {
converters := map[string]Converter{
"v1alpha1": V1alpha1{},
"v1beta1": V1beta1{},
}
apiVersionSeparated := strings.Split(config.APIVersion, "/")
if len(apiVersionSeparated) < 2 || apiVersionSeparated[0] != Api {
return &kfapis.KfError{
Code: int(kfapis.INVALID_ARGUMENT),
Message: fmt.Sprintf("invalid config: apiVersion must be in the format of %v/<version>, got %v", Api, config.APIVersion),
}
}

converter, ok := converters[apiVersionSeparated[1]]
if !ok {
return &kfapis.KfError{
Code: int(kfapis.INVALID_ARGUMENT),
Message: fmt.Sprintf("invalid config: unable to find converter for version %v", config.APIVersion),
}
}

kfdefBytes, err := converter.ToKfDefSerialized(config)
if err != nil {
return &kfapis.KfError{
Code: int(kfapis.INVALID_ARGUMENT),
Message: fmt.Sprintf("error when marshaling KfDef: %v", err),
}
}
err = ioutil.WriteFile(filename, kfdefBytes, 0644)
if err != nil {
return &kfapis.KfError{
Code: int(kfapis.INTERNAL_ERROR),
Message: fmt.Sprintf("error when writing KfDef: %v", err),
}
}
return nil
}
1 change: 1 addition & 0 deletions bootstrap/pkg/apis/apps/configconverters/testdata/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package testdata
Loading

0 comments on commit db672b8

Please sign in to comment.