Merge pull request #224 from jackgr/vet-and-lint

Fixed go vet and golint errors.
pull/226/head
Jack Greenfield 10 years ago
commit 99ba3dd1f7

@ -30,6 +30,7 @@ import (
"github.com/kubernetes/deployment-manager/log" "github.com/kubernetes/deployment-manager/log"
) )
// ChartfileName is the default Chart file name.
const ChartfileName string = "Chart.yaml" const ChartfileName string = "Chart.yaml"
const ( const (
@ -73,7 +74,7 @@ func (c *Chart) Chartfile() *Chartfile {
return c.loader.chartfile() return c.loader.chartfile()
} }
// Dir() returns the directory where the charts are located. // Dir returns the directory where the charts are located.
func (c *Chart) Dir() string { func (c *Chart) Dir() string {
return c.loader.dir() return c.loader.dir()
} }
@ -148,7 +149,7 @@ func (t *tarChart) close() error {
return os.RemoveAll(t.tmpDir) return os.RemoveAll(t.tmpDir)
} }
// New creates a new chart in a directory. // Create creates a new chart in a directory.
// //
// Inside of dir, this will create a directory based on the name of // Inside of dir, this will create a directory based on the name of
// chartfile.Name. It will then write the Chart.yaml into this directory and // chartfile.Name. It will then write the Chart.yaml into this directory and

@ -49,7 +49,7 @@ type Dependency struct {
Location string `yaml:"location"` Location string `yaml:"location"`
} }
// Specify environmental constraints. // EnvConstraint specifies environmental constraints.
type EnvConstraint struct { type EnvConstraint struct {
Name string `yaml:"name"` Name string `yaml:"name"`
Version string `yaml:"version"` Version string `yaml:"version"`

@ -14,7 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* Package chart implements the Chart format. /*
Package chart implements the Chart format.
This package provides tools for working with the Chart format, including the This package provides tools for working with the Chart format, including the
Chartfile (chart.yaml) and compressed chart archives. Chartfile (chart.yaml) and compressed chart archives.

@ -30,6 +30,7 @@ var ErrLocal = errors.New("cannot use local Locator as remote")
// ErrRemote indicates that a remote URL was used as a local URL. // ErrRemote indicates that a remote URL was used as a local URL.
var ErrRemote = errors.New("cannot use remote Locator as local") var ErrRemote = errors.New("cannot use remote Locator as local")
// Constants defining recognized URL schemes.
const ( const (
SchemeHTTP = "http" SchemeHTTP = "http"
SchemeHTTPS = "https" SchemeHTTPS = "https"
@ -50,6 +51,7 @@ func init() {
tnregexp = regexp.MustCompile("^" + TarNameRegex + "$") tnregexp = regexp.MustCompile("^" + TarNameRegex + "$")
} }
// Locator describes the location of a Chart.
type Locator struct { type Locator struct {
// The scheme of the URL. Typically one of http, https, helm, or file. // The scheme of the URL. Typically one of http, https, helm, or file.
Scheme string Scheme string
@ -70,6 +72,7 @@ type Locator struct {
original string original string
} }
// Parse parses a URL into a Locator.
func Parse(path string) (*Locator, error) { func Parse(path string) (*Locator, error) {
u, err := url.Parse(path) u, err := url.Parse(path)
if err != nil { if err != nil {

@ -162,7 +162,7 @@ type TypeInstance struct {
// KubernetesObject represents a native 'bare' Kubernetes object. // KubernetesObject represents a native 'bare' Kubernetes object.
type KubernetesObject struct { type KubernetesObject struct {
Kind string `json:"kind"` Kind string `json:"kind"`
ApiVersion string `json:"apiVersion"` APIVersion string `json:"apiVersion"`
Metadata map[string]interface{} `json:"metadata"` Metadata map[string]interface{} `json:"metadata"`
Spec map[string]interface{} `json:"spec"` Spec map[string]interface{} `json:"spec"`
} }
@ -170,21 +170,26 @@ type KubernetesObject struct {
// KubernetesSecret represents a Kubernetes secret // KubernetesSecret represents a Kubernetes secret
type KubernetesSecret struct { type KubernetesSecret struct {
Kind string `json:"kind"` Kind string `json:"kind"`
ApiVersion string `json:"apiVersion"` APIVersion string `json:"apiVersion"`
Metadata map[string]string `json:"metadata"` Metadata map[string]string `json:"metadata"`
Data map[string]string `json:"data,omitempty"` Data map[string]string `json:"data,omitempty"`
} }
// Repository related types // Repository related types
// BasicAuthCredential holds a username and password.
type BasicAuthCredential struct { type BasicAuthCredential struct {
Username string `json:"username"` Username string `json:"username"`
Password string `json:"password"` Password string `json:"password"`
} }
// APITokenCredential defines an API token.
type APITokenCredential string type APITokenCredential string
// JWTTokenCredential defines a JWT token.
type JWTTokenCredential string type JWTTokenCredential string
// Credential used to access the repository // RegistryCredential holds a credential used to access a registry.
type RegistryCredential struct { type RegistryCredential struct {
APIToken APITokenCredential `json:"apitoken,omitempty"` APIToken APITokenCredential `json:"apitoken,omitempty"`
BasicAuth BasicAuthCredential `json:"basicauth,omitempty"` BasicAuth BasicAuthCredential `json:"basicauth,omitempty"`
@ -204,6 +209,7 @@ type Registry struct {
// RegistryType defines the technology that implements the registry // RegistryType defines the technology that implements the registry
type RegistryType string type RegistryType string
// Constants that identify the supported registry layouts.
const ( const (
GithubRegistryType RegistryType = "github" GithubRegistryType RegistryType = "github"
GCSRegistryType RegistryType = "gcs" GCSRegistryType RegistryType = "gcs"
@ -215,15 +221,17 @@ type RegistryFormat string
const ( const (
// Versioning. // Versioning.
// If a registry if versioned, then types appear under versions.
// VersionedRegistry identifies a versioned registry, where types appear under versions.
VersionedRegistry RegistryFormat = "versioned" VersionedRegistry RegistryFormat = "versioned"
// If a registry is unversioned, then types appear under their names. // UnversionedRegistry identifies an unversioned registry, where types appear under their names.
UnversionedRegistry RegistryFormat = "unversioned" UnversionedRegistry RegistryFormat = "unversioned"
// Organization. // Organization.
// In a collection registry, types are grouped into collections.
// CollectionRegistry identfies a collection registry, where types are grouped into collections.
CollectionRegistry RegistryFormat = "collection" CollectionRegistry RegistryFormat = "collection"
// In a one level registry, all types appear at the top level. // OneLevelRegistry identifies a one level registry, where all types appear at the top level.
OneLevelRegistry RegistryFormat = "onelevel" OneLevelRegistry RegistryFormat = "onelevel"
) )

@ -39,20 +39,20 @@ import (
) )
var ( var (
deployment_name = flag.String("name", "", "Name of deployment, used for deploy and update commands (defaults to template name)") deploymentName = flag.String("name", "", "Name of deployment, used for deploy and update commands (defaults to template name)")
stdin = flag.Bool("stdin", false, "Reads a configuration from the standard input") stdin = flag.Bool("stdin", false, "Reads a configuration from the standard input")
properties = flag.String("properties", "", "Properties to use when deploying a template (e.g., --properties k1=v1,k2=v2)") properties = flag.String("properties", "", "Properties to use when deploying a template (e.g., --properties k1=v1,k2=v2)")
// TODO(vaikas): CHange the default name once we figure out where the charts live. // TODO(vaikas): CHange the default name once we figure out where the charts live.
template_registry = flag.String("registry", "application-dm-templates", "Registry name") templateRegistry = flag.String("registry", "application-dm-templates", "Registry name")
service = flag.String("service", "http://localhost:8001/api/v1/proxy/namespaces/dm/services/manager-service:manager", "URL for deployment manager") service = flag.String("service", "http://localhost:8001/api/v1/proxy/namespaces/dm/services/manager-service:manager", "URL for deployment manager")
binary = flag.String("binary", "../expandybird/expansion/expansion.py", "Path to template expansion binary") binary = flag.String("binary", "../expandybird/expansion/expansion.py", "Path to template expansion binary")
timeout = flag.Int("timeout", 20, "Time in seconds to wait for response") timeout = flag.Int("timeout", 20, "Time in seconds to wait for response")
regex_string = flag.String("regex", "", "Regular expression to filter the templates listed in a template registry") regexString = flag.String("regex", "", "Regular expression to filter the templates listed in a template registry")
username = flag.String("username", "", "Github user name that overrides GITHUB_USERNAME environment variable") username = flag.String("username", "", "Github user name that overrides GITHUB_USERNAME environment variable")
password = flag.String("password", "", "Github password that overrides GITHUB_PASSWORD environment variable") password = flag.String("password", "", "Github password that overrides GITHUB_PASSWORD environment variable")
apitoken = flag.String("apitoken", "", "Github api token that overrides GITHUB_API_TOKEN environment variable") apitoken = flag.String("apitoken", "", "Github api token that overrides GITHUB_API_TOKEN environment variable")
serviceaccount = flag.String("serviceaccount", "", "Service account file containing JWT token") serviceaccount = flag.String("serviceaccount", "", "Service account file containing JWT token")
registryfile = flag.String("registryfile", "", "File containing registry specification") registryfile = flag.String("registryfile", "", "File containing registry specification")
) )
var commands = []string{ var commands = []string{
@ -165,7 +165,7 @@ func execute() {
switch args[0] { switch args[0] {
case "templates": case "templates":
path := fmt.Sprintf("registries/%s/types", *template_registry) path := fmt.Sprintf("registries/%s/types", *templateRegistry)
callService(path, "GET", "list templates", nil) callService(path, "GET", "list templates", nil)
case "describe": case "describe":
describeType(args) describeType(args)
@ -198,7 +198,7 @@ func execute() {
if err != nil { if err != nil {
panic(fmt.Errorf("Failed to create a registry from arguments: %#v", err)) panic(fmt.Errorf("Failed to create a registry from arguments: %#v", err))
} }
path := fmt.Sprintf("registries/%s", *template_registry) path := fmt.Sprintf("registries/%s", *templateRegistry)
callService(path, "POST", "create registry", ioutil.NopCloser(bytes.NewReader(reg))) callService(path, "POST", "create registry", ioutil.NopCloser(bytes.NewReader(reg)))
case "get": case "get":
if len(args) < 2 { if len(args) < 2 {
@ -253,16 +253,16 @@ func execute() {
} }
tUrls := getDownloadURLs(args[1]) tUrls := getDownloadURLs(args[1])
var tUrl = "" var tURL = ""
if len(tUrls) == 0 { if len(tUrls) == 0 {
// Type is most likely a primitive. // Type is most likely a primitive.
tUrl = args[1] tURL = args[1]
} else { } else {
// TODO(vaikas): Support packages properly. // TODO(vaikas): Support packages properly.
tUrl = tUrls[0] tURL = tUrls[0]
} }
path := fmt.Sprintf("types/%s/instances", url.QueryEscape(tUrl)) path := fmt.Sprintf("types/%s/instances", url.QueryEscape(tURL))
action := fmt.Sprintf("list deployed instances of type %s", tUrl) action := fmt.Sprintf("list deployed instances of type %s", tURL)
callService(path, "GET", action, nil) callService(path, "GET", action, nil)
case "registries": case "registries":
callService("registries", "GET", "list registries", nil) callService("registries", "GET", "list registries", nil)
@ -276,7 +276,7 @@ func execute() {
func callService(path, method, action string, reader io.ReadCloser) { func callService(path, method, action string, reader io.ReadCloser) {
u := fmt.Sprintf("%s/%s", *service, path) u := fmt.Sprintf("%s/%s", *service, path)
resp := callHttp(u, method, action, reader) resp := callHTTP(u, method, action, reader)
var j interface{} var j interface{}
if err := json.Unmarshal([]byte(resp), &j); err != nil { if err := json.Unmarshal([]byte(resp), &j); err != nil {
panic(fmt.Errorf("Failed to parse JSON response from service: %s", resp)) panic(fmt.Errorf("Failed to parse JSON response from service: %s", resp))
@ -290,7 +290,7 @@ func callService(path, method, action string, reader io.ReadCloser) {
fmt.Println(string(y)) fmt.Println(string(y))
} }
func callHttp(path, method, action string, reader io.ReadCloser) string { func callHTTP(path, method, action string, reader io.ReadCloser) string {
request, err := http.NewRequest(method, path, reader) request, err := http.NewRequest(method, path, reader)
request.Header.Add("Content-Type", "application/json") request.Header.Add("Content-Type", "application/json")
@ -334,19 +334,19 @@ func describeType(args []string) {
if !strings.Contains(tUrls[0], ".prov") { if !strings.Contains(tUrls[0], ".prov") {
// It's not a chart, so grab the schema // It's not a chart, so grab the schema
path := fmt.Sprintf("registries/%s/download?file=%s.schema", *template_registry, url.QueryEscape(tUrls[0])) path := fmt.Sprintf("registries/%s/download?file=%s.schema", *templateRegistry, url.QueryEscape(tUrls[0]))
callService(path, "GET", "get schema for type ("+tUrls[0]+")", nil) callService(path, "GET", "get schema for type ("+tUrls[0]+")", nil)
} else { } else {
// It's a chart, so grab the provenance file // It's a chart, so grab the provenance file
path := fmt.Sprintf("registries/%s/download?file=%s", *template_registry, url.QueryEscape(tUrls[0])) path := fmt.Sprintf("registries/%s/download?file=%s", *templateRegistry, url.QueryEscape(tUrls[0]))
callService(path, "GET", "get file", nil) callService(path, "GET", "get file", nil)
} }
} }
// getDownloadURLs returns URLs for a type in the given registry // getDownloadURLs returns URLs for a type in the given registry
func getDownloadURLs(tName string) []string { func getDownloadURLs(tName string) []string {
path := fmt.Sprintf("%s/registries/%s/types/%s", *service, *template_registry, url.QueryEscape(tName)) path := fmt.Sprintf("%s/registries/%s/types/%s", *service, *templateRegistry, url.QueryEscape(tName))
resp := callHttp(path, "GET", "get download urls", nil) resp := callHTTP(path, "GET", "get download urls", nil)
u := []string{} u := []string{}
if err := json.Unmarshal([]byte(resp), &u); err != nil { if err := json.Unmarshal([]byte(resp), &u); err != nil {
panic(fmt.Errorf("Failed to parse JSON response from service: %s", resp)) panic(fmt.Errorf("Failed to parse JSON response from service: %s", resp))
@ -404,8 +404,8 @@ func loadTemplate(args []string) *common.Template {
} }
// Override name if set from flags. // Override name if set from flags.
if *deployment_name != "" { if *deploymentName != "" {
template.Name = *deployment_name template.Name = *deploymentName
} }
return template return template

@ -1,4 +1,5 @@
/* Package log provides simple convenience wrappers for logging. /*
Package log provides simple convenience wrappers for logging.
Following convention, this provides functions for logging warnings, errors, information Following convention, this provides functions for logging warnings, errors, information
and debugging. and debugging.
@ -10,21 +11,21 @@ import (
"os" "os"
) )
// LogReceiver can receive log messages from this package. // Receiver can receive log messages from this package.
type LogReceiver interface { type Receiver interface {
Printf(format string, v ...interface{}) Printf(format string, v ...interface{})
} }
// Logger is the destination for this package. // Logger is the destination for this package.
// //
// The logger that this prints to. // The logger that this prints to.
var Logger LogReceiver = log.New(os.Stderr, "", log.LstdFlags) var Logger Receiver = log.New(os.Stderr, "", log.LstdFlags)
// IsDebugging controls debugging output. // IsDebugging controls debugging output.
// //
// If this is true, debugging messages will be printed. Expensive debugging // If this is true, debugging messages will be printed. Expensive debugging
// operations can be wrapped in `if log.IsDebugging {}`. // operations can be wrapped in `if log.IsDebugging {}`.
var IsDebugging bool = false var IsDebugging = false
// Err prints an error of severity ERROR to the log. // Err prints an error of severity ERROR to the log.
func Err(msg string, v ...interface{}) { func Err(msg string, v ...interface{}) {

@ -18,7 +18,6 @@ package main
import ( import (
"encoding/json" "encoding/json"
"errors"
"flag" "flag"
"fmt" "fmt"
"io" "io"
@ -237,7 +236,7 @@ func getPathVariable(w http.ResponseWriter, r *http.Request, variable, handler s
vars := mux.Vars(r) vars := mux.Vars(r)
escaped, ok := vars[variable] escaped, ok := vars[variable]
if !ok { if !ok {
e := errors.New(fmt.Sprintf("%s name not found in URL", variable)) e := fmt.Errorf("%s name not found in URL", variable)
util.LogAndReturnError(handler, http.StatusBadRequest, e, w) util.LogAndReturnError(handler, http.StatusBadRequest, e, w)
return "", e return "", e
} }
@ -254,7 +253,7 @@ func getPathVariable(w http.ResponseWriter, r *http.Request, variable, handler s
func getTemplate(w http.ResponseWriter, r *http.Request, handler string) *common.Template { func getTemplate(w http.ResponseWriter, r *http.Request, handler string) *common.Template {
util.LogHandlerEntry(handler, r) util.LogHandlerEntry(handler, r)
j, err := getJsonFromRequest(w, r, handler) j, err := getJSONFromRequest(w, r, handler)
if err != nil { if err != nil {
return nil return nil
@ -382,7 +381,7 @@ func getRegistryHandlerFunc(w http.ResponseWriter, r *http.Request) {
func getRegistry(w http.ResponseWriter, r *http.Request, handler string) *common.Registry { func getRegistry(w http.ResponseWriter, r *http.Request, handler string) *common.Registry {
util.LogHandlerEntry(handler, r) util.LogHandlerEntry(handler, r)
j, err := getJsonFromRequest(w, r, handler) j, err := getJSONFromRequest(w, r, handler)
if err != nil { if err != nil {
return nil return nil
} }
@ -506,7 +505,7 @@ func getFileHandlerFunc(w http.ResponseWriter, r *http.Request) {
func getCredential(w http.ResponseWriter, r *http.Request, handler string) *common.RegistryCredential { func getCredential(w http.ResponseWriter, r *http.Request, handler string) *common.RegistryCredential {
util.LogHandlerEntry(handler, r) util.LogHandlerEntry(handler, r)
j, err := getJsonFromRequest(w, r, handler) j, err := getJSONFromRequest(w, r, handler)
if err != nil { if err != nil {
return nil return nil
} }
@ -559,7 +558,7 @@ func getCredentialHandlerFunc(w http.ResponseWriter, r *http.Request) {
util.LogHandlerExitWithJSON(handler, w, c, http.StatusOK) util.LogHandlerExitWithJSON(handler, w, c, http.StatusOK)
} }
func getJsonFromRequest(w http.ResponseWriter, r *http.Request, handler string) ([]byte, error) { func getJSONFromRequest(w http.ResponseWriter, r *http.Request, handler string) ([]byte, error) {
util.LogHandlerEntry(handler, r) util.LogHandlerEntry(handler, r)
b := io.LimitReader(r.Body, *maxLength*1024) b := io.LimitReader(r.Body, *maxLength*1024)
y, err := ioutil.ReadAll(b) y, err := ioutil.ReadAll(b)

@ -230,23 +230,23 @@ func (repository *repositoryStub) GetManifest(d string, m string) (*common.Manif
return nil, errTest return nil, errTest
} }
func (tgr *repositoryStub) ListTypes() []string { func (repository *repositoryStub) ListTypes() []string {
tgr.ListTypesCalled = true repository.ListTypesCalled = true
return []string{} return []string{}
} }
func (tgr *repositoryStub) GetTypeInstances(t string) []*common.TypeInstance { func (repository *repositoryStub) GetTypeInstances(t string) []*common.TypeInstance {
tgr.GetTypeInstancesCalled = true repository.GetTypeInstancesCalled = true
return []*common.TypeInstance{} return []*common.TypeInstance{}
} }
func (tgr *repositoryStub) ClearTypeInstances(d string) { func (repository *repositoryStub) ClearTypeInstances(d string) {
tgr.TypeInstancesCleared = true repository.TypeInstancesCleared = true
} }
func (tgr *repositoryStub) SetTypeInstances(d string, is map[string][]*common.TypeInstance) { func (repository *repositoryStub) SetTypeInstances(d string, is map[string][]*common.TypeInstance) {
for k, _ := range is { for k := range is {
tgr.TypeInstances[d] = append(tgr.TypeInstances[d], k) repository.TypeInstances[d] = append(repository.TypeInstances[d], k)
} }
} }

@ -223,23 +223,23 @@ func (tr *typeResolver) ResolveTypes(config *common.Configuration, imports []*co
func parseContent(templates []string) (string, error) { func parseContent(templates []string) (string, error) {
if len(templates) == 1 { if len(templates) == 1 {
return templates[0], nil return templates[0], nil
} else { }
// If there are multiple URLs that need to be fetched, that implies it's a package
// of raw Kubernetes objects. We need to fetch them all as a unit and create a // If there are multiple URLs that need to be fetched, that implies it's a package
// template representing a package out of that below. // of raw Kubernetes objects. We need to fetch them all as a unit and create a
fakeConfig := &common.Configuration{} // template representing a package out of that below.
for _, template := range templates { fakeConfig := &common.Configuration{}
o, err := util.ParseKubernetesObject([]byte(template)) for _, template := range templates {
if err != nil { o, err := util.ParseKubernetesObject([]byte(template))
return "", fmt.Errorf("not a kubernetes object: %+v", template)
}
// Looks like a native Kubernetes object, create a configuration out of it
fakeConfig.Resources = append(fakeConfig.Resources, o)
}
marshalled, err := yaml.Marshal(fakeConfig)
if err != nil { if err != nil {
return "", fmt.Errorf("Failed to marshal: %+v", fakeConfig) return "", fmt.Errorf("not a kubernetes object: %+v", template)
} }
return string(marshalled), nil // Looks like a native Kubernetes object, create a configuration out of it
fakeConfig.Resources = append(fakeConfig.Resources, o)
}
marshalled, err := yaml.Marshal(fakeConfig)
if err != nil {
return "", fmt.Errorf("Failed to marshal: %+v", fakeConfig)
} }
return string(marshalled), nil
} }

@ -304,18 +304,18 @@ func TestShortGithubUrl(t *testing.T) {
"https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v2/replicatedservice.py.schema": registry.DownloadResponse{Err: nil, Code: http.StatusNotFound, Body: ""}, "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v2/replicatedservice.py.schema": registry.DownloadResponse{Err: nil, Code: http.StatusNotFound, Body: ""},
} }
githubUrlMaps := map[registry.Type]registry.TestURLAndError{ githubURLMaps := map[registry.Type]registry.TestURLAndError{
registry.NewTypeOrDie("common", "replicatedservice", "v1"): registry.TestURLAndError{URL: "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v1/replicatedservice.py", Err: nil}, registry.NewTypeOrDie("common", "replicatedservice", "v1"): registry.TestURLAndError{URL: "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v1/replicatedservice.py", Err: nil},
registry.NewTypeOrDie("common", "replicatedservice", "v2"): registry.TestURLAndError{URL: "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v2/replicatedservice.py", Err: nil}, registry.NewTypeOrDie("common", "replicatedservice", "v2"): registry.TestURLAndError{URL: "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v2/replicatedservice.py", Err: nil},
} }
gcsUrlMaps := map[registry.Type]registry.TestURLAndError{ gcsURLMaps := map[registry.Type]registry.TestURLAndError{
registry.NewTypeOrDie("common", "replicatedservice", "v1"): registry.TestURLAndError{URL: "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v1/replicatedservice.py", Err: nil}, registry.NewTypeOrDie("common", "replicatedservice", "v1"): registry.TestURLAndError{URL: "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v1/replicatedservice.py", Err: nil},
registry.NewTypeOrDie("common", "replicatedservice", "v2"): registry.TestURLAndError{URL: "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v2/replicatedservice.py", Err: nil}, registry.NewTypeOrDie("common", "replicatedservice", "v2"): registry.TestURLAndError{URL: "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v2/replicatedservice.py", Err: nil},
} }
grp := registry.NewTestGithubRegistryProviderWithDownloads("github.com/kubernetes/application-dm-templates", githubUrlMaps, downloadResponses) grp := registry.NewTestGithubRegistryProviderWithDownloads("github.com/kubernetes/application-dm-templates", githubURLMaps, downloadResponses)
gcsrp := registry.NewTestGCSRegistryProvider("gs://charts", gcsUrlMaps) gcsrp := registry.NewTestGCSRegistryProvider("gs://charts", gcsURLMaps)
test := resolverTestCase{ test := resolverTestCase{
config: templateShortGithubTemplate, config: templateShortGithubTemplate,
importOut: finalImports, importOut: finalImports,

@ -25,17 +25,19 @@ import (
"github.com/kubernetes/deployment-manager/common" "github.com/kubernetes/deployment-manager/common"
) )
// CredentialProvider provides credentials for registries. // FilebasedCredentialProvider provides credentials for registries.
type FilebasedCredentialProvider struct { type FilebasedCredentialProvider struct {
// Actual backing store // Actual backing store
backingCredentialProvider common.CredentialProvider backingCredentialProvider common.CredentialProvider
} }
// NamedRegistryCredential associates a name with a RegistryCredential.
type NamedRegistryCredential struct { type NamedRegistryCredential struct {
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
common.RegistryCredential common.RegistryCredential
} }
// NewFilebasedCredentialProvider creates a file based credential provider.
func NewFilebasedCredentialProvider(filename string) (common.CredentialProvider, error) { func NewFilebasedCredentialProvider(filename string) (common.CredentialProvider, error) {
icp := NewInmemCredentialProvider() icp := NewInmemCredentialProvider()
c, err := readCredentialsFile(filename) c, err := readCredentialsFile(filename)
@ -66,10 +68,12 @@ func parseCredentials(bytes []byte) ([]NamedRegistryCredential, error) {
return r, nil return r, nil
} }
// GetCredential returns a credential by name.
func (fcp *FilebasedCredentialProvider) GetCredential(name string) (*common.RegistryCredential, error) { func (fcp *FilebasedCredentialProvider) GetCredential(name string) (*common.RegistryCredential, error) {
return fcp.backingCredentialProvider.GetCredential(name) return fcp.backingCredentialProvider.GetCredential(name)
} }
// SetCredential sets a credential by name.
func (fcp *FilebasedCredentialProvider) SetCredential(name string, credential *common.RegistryCredential) error { func (fcp *FilebasedCredentialProvider) SetCredential(name string, credential *common.RegistryCredential) error {
return fmt.Errorf("SetCredential operation not supported with FilebasedCredentialProvider") return fmt.Errorf("SetCredential operation not supported with FilebasedCredentialProvider")
} }

@ -50,10 +50,14 @@ type GCSRegistry struct {
} }
// RE for GCS storage // RE for GCS storage
// ChartFormatMatcher matches the chart name format
var ChartFormatMatcher = regexp.MustCompile("(.*)-(.*).tgz") var ChartFormatMatcher = regexp.MustCompile("(.*)-(.*).tgz")
// URLFormatMatcher matches the GCS URL format (gs:).
var URLFormatMatcher = regexp.MustCompile("gs://(.*)") var URLFormatMatcher = regexp.MustCompile("gs://(.*)")
// NewGithubTemplateRegistry creates a GithubTemplateRegistry. // NewGCSRegistry creates a GCS registry.
func NewGCSRegistry(name, shortURL string, httpClient *http.Client, gcsService *storage.Service) (*GCSRegistry, error) { func NewGCSRegistry(name, shortURL string, httpClient *http.Client, gcsService *storage.Service) (*GCSRegistry, error) {
format := fmt.Sprintf("%s;%s", common.VersionedRegistry, common.OneLevelRegistry) format := fmt.Sprintf("%s;%s", common.VersionedRegistry, common.OneLevelRegistry)
trimmed := util.TrimURLScheme(shortURL) trimmed := util.TrimURLScheme(shortURL)
@ -73,14 +77,17 @@ func NewGCSRegistry(name, shortURL string, httpClient *http.Client, gcsService *
nil nil
} }
// GetRegistryName returns the name of the registry.
func (g GCSRegistry) GetRegistryName() string { func (g GCSRegistry) GetRegistryName() string {
return g.name return g.name
} }
// GetBucket returns the registry bucket.
func (g GCSRegistry) GetBucket() string { func (g GCSRegistry) GetBucket() string {
return g.bucket return g.bucket
} }
// GetRegistryType returns the registry type.
func (g GCSRegistry) GetRegistryType() common.RegistryType { func (g GCSRegistry) GetRegistryType() common.RegistryType {
return common.GCSRegistryType return common.GCSRegistryType
} }
@ -123,10 +130,12 @@ func (g GCSRegistry) ListTypes(regex *regexp.Regexp) ([]Type, error) {
return types, nil return types, nil
} }
// GetRegistryFormat returns the registry format.
func (g GCSRegistry) GetRegistryFormat() common.RegistryFormat { func (g GCSRegistry) GetRegistryFormat() common.RegistryFormat {
return common.CollectionRegistry return common.CollectionRegistry
} }
// GetRegistryShortURL returns the short URL for the registry.
func (g GCSRegistry) GetRegistryShortURL() string { func (g GCSRegistry) GetRegistryShortURL() string {
return g.shortURL return g.shortURL
} }
@ -152,6 +161,7 @@ func (g GCSRegistry) GetDownloadURLs(t Type) ([]*url.URL, error) {
return ret, err return ret, err
} }
// Do performs an HTTP operation on the receiver's httpClient.
func (g GCSRegistry) Do(req *http.Request) (resp *http.Response, err error) { func (g GCSRegistry) Do(req *http.Request) (resp *http.Response, err error) {
return g.httpClient.Do(req) return g.httpClient.Do(req)
} }

@ -153,6 +153,7 @@ func (g GithubPackageRegistry) MakeRepositoryPath(t Type) (string, error) {
return t.Name + "/manifests", nil return t.Name + "/manifests", nil
} }
// Do performs an HTTP operation on the receiver's httpClient.
func (g GithubPackageRegistry) Do(req *http.Request) (resp *http.Response, err error) { func (g GithubPackageRegistry) Do(req *http.Request) (resp *http.Response, err error) {
return g.httpClient.Do(req) return g.httpClient.Do(req)
} }

@ -214,6 +214,7 @@ func (g GithubTemplateRegistry) MakeRepositoryPath(t Type) (string, error) {
return p + t.Name + "/" + t.GetVersion(), nil return p + t.Name + "/" + t.GetVersion(), nil
} }
// Do performs an HTTP operation on the receiver's httpClient.
func (g GithubTemplateRegistry) Do(req *http.Request) (resp *http.Response, err error) { func (g GithubTemplateRegistry) Do(req *http.Request) (resp *http.Response, err error) {
return g.httpClient.Do(req) return g.httpClient.Do(req)
} }

@ -22,14 +22,17 @@ import (
"fmt" "fmt"
) )
// InmemCredentialProvider is a memory based credential provider.
type InmemCredentialProvider struct { type InmemCredentialProvider struct {
credentials map[string]*common.RegistryCredential credentials map[string]*common.RegistryCredential
} }
// NewInmemCredentialProvider creates a new memory based credential provider.
func NewInmemCredentialProvider() common.CredentialProvider { func NewInmemCredentialProvider() common.CredentialProvider {
return &InmemCredentialProvider{credentials: make(map[string]*common.RegistryCredential)} return &InmemCredentialProvider{credentials: make(map[string]*common.RegistryCredential)}
} }
// GetCredential returns a credential by name.
func (fcp *InmemCredentialProvider) GetCredential(name string) (*common.RegistryCredential, error) { func (fcp *InmemCredentialProvider) GetCredential(name string) (*common.RegistryCredential, error) {
if val, ok := fcp.credentials[name]; ok { if val, ok := fcp.credentials[name]; ok {
return val, nil return val, nil
@ -37,6 +40,7 @@ func (fcp *InmemCredentialProvider) GetCredential(name string) (*common.Registry
return nil, fmt.Errorf("no such credential : %s", name) return nil, fmt.Errorf("no such credential : %s", name)
} }
// SetCredential sets a credential by name.
func (fcp *InmemCredentialProvider) SetCredential(name string, credential *common.RegistryCredential) error { func (fcp *InmemCredentialProvider) SetCredential(name string, credential *common.RegistryCredential) error {
fcp.credentials[name] = &common.RegistryCredential{APIToken: credential.APIToken, BasicAuth: credential.BasicAuth, ServiceAccount: credential.ServiceAccount} fcp.credentials[name] = &common.RegistryCredential{APIToken: credential.APIToken, BasicAuth: credential.BasicAuth, ServiceAccount: credential.ServiceAccount}
return nil return nil

@ -28,6 +28,7 @@ type inmemRegistryService struct {
registries map[string]*common.Registry registries map[string]*common.Registry
} }
// NewInmemRegistryService returns a new memory based registry service.
func NewInmemRegistryService() common.RegistryService { func NewInmemRegistryService() common.RegistryService {
rs := &inmemRegistryService{ rs := &inmemRegistryService{
registries: make(map[string]*common.Registry), registries: make(map[string]*common.Registry),

@ -67,6 +67,7 @@ type ObjectStorageRegistry interface {
GetBucket() string GetBucket() string
} }
// Type describes a type stored in a registry.
type Type struct { type Type struct {
Collection string Collection string
Name string Name string

@ -48,10 +48,12 @@ type registryProvider struct {
registries map[string]Registry registries map[string]Registry
} }
// NewDefaultRegistryProvider creates a default registry provider with the supplied credential.
func NewDefaultRegistryProvider(cp common.CredentialProvider, rs common.RegistryService) RegistryProvider { func NewDefaultRegistryProvider(cp common.CredentialProvider, rs common.RegistryService) RegistryProvider {
return NewRegistryProvider(rs, NewGithubRegistryProvider(cp), NewGCSRegistryProvider(cp), cp) return NewRegistryProvider(rs, NewGithubRegistryProvider(cp), NewGCSRegistryProvider(cp), cp)
} }
// NewRegistryProvider creates a new registry provider using the supplied arguments.
func NewRegistryProvider(rs common.RegistryService, grp GithubRegistryProvider, gcsrp GCSRegistryProvider, cp common.CredentialProvider) RegistryProvider { func NewRegistryProvider(rs common.RegistryService, grp GithubRegistryProvider, gcsrp GCSRegistryProvider, cp common.CredentialProvider) RegistryProvider {
if rs == nil { if rs == nil {
rs = NewInmemRegistryService() rs = NewInmemRegistryService()
@ -86,6 +88,7 @@ func (rp *registryProvider) getRegistry(cr common.Registry) (Registry, error) {
} }
} }
// GetRegistryByShortURL returns the registry identified by a short URL.
func (rp *registryProvider) GetRegistryByShortURL(URL string) (Registry, error) { func (rp *registryProvider) GetRegistryByShortURL(URL string) (Registry, error) {
rp.RLock() rp.RLock()
defer rp.RUnlock() defer rp.RUnlock()
@ -122,6 +125,7 @@ func (rp *registryProvider) findRegistryByShortURL(URL string) Registry {
return nil return nil
} }
// GetRegistryByName returns a registry by name.
func (rp *registryProvider) GetRegistryByName(registryName string) (Registry, error) { func (rp *registryProvider) GetRegistryByName(registryName string) (Registry, error) {
rp.RLock() rp.RLock()
defer rp.RUnlock() defer rp.RUnlock()
@ -141,6 +145,7 @@ func (rp *registryProvider) GetRegistryByName(registryName string) (Registry, er
return r, nil return r, nil
} }
// ParseRegistryFormat creates a map from a registry format string.
func ParseRegistryFormat(rf common.RegistryFormat) map[common.RegistryFormat]bool { func ParseRegistryFormat(rf common.RegistryFormat) map[common.RegistryFormat]bool {
split := strings.Split(string(rf), ";") split := strings.Split(string(rf), ";")
var result = map[common.RegistryFormat]bool{} var result = map[common.RegistryFormat]bool{}
@ -315,7 +320,7 @@ func GetDownloadURLs(rp RegistryProvider, t string) ([]string, Registry, error)
return ShortTypeToPackageDownloadURLs(rp, t) return ShortTypeToPackageDownloadURLs(rp, t)
} else if IsGCSShortType(t) { } else if IsGCSShortType(t) {
return ShortTypeToGCSDownloadUrls(rp, t) return ShortTypeToGCSDownloadUrls(rp, t)
} else if util.IsHttpUrl(t) { } else if util.IsHTTPURL(t) {
result, err := url.Parse(t) result, err := url.Parse(t)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("cannot parse download URL %s: %s", t, err) return nil, nil, fmt.Errorf("cannot parse download URL %s: %s", t, err)
@ -389,6 +394,7 @@ func ShortTypeToPackageDownloadURLs(rp RegistryProvider, t string) ([]string, Re
return util.ConvertURLsToStrings(urls), r, err return util.ConvertURLsToStrings(urls), r, err
} }
// ShortTypeToGCSDownloadUrls returns the download URLs for a short type name.
func ShortTypeToGCSDownloadUrls(rp RegistryProvider, t string) ([]string, Registry, error) { func ShortTypeToGCSDownloadUrls(rp RegistryProvider, t string) ([]string, Registry, error) {
m := GCSRegistryMatcher.FindStringSubmatch(t) m := GCSRegistryMatcher.FindStringSubmatch(t)
if len(m) != 3 { if len(m) != 3 {

@ -20,7 +20,7 @@ import (
"testing" "testing"
) )
func testUrlConversionDriver(rp RegistryProvider, tests map[string]TestURLAndError, t *testing.T) { func testURLConversionDriver(rp RegistryProvider, tests map[string]TestURLAndError, t *testing.T) {
for in, expected := range tests { for in, expected := range tests {
// TODO(vaikas): Test to make sure it's the right registry. // TODO(vaikas): Test to make sure it's the right registry.
actual, _, err := GetDownloadURLs(rp, in) actual, _, err := GetDownloadURLs(rp, in)
@ -34,8 +34,8 @@ func testUrlConversionDriver(rp RegistryProvider, tests map[string]TestURLAndErr
} }
} }
func TestShortGithubUrlTemplateMapping(t *testing.T) { func TestShortGithubURLTemplateMapping(t *testing.T) {
githubUrlMaps := map[Type]TestURLAndError{ githubURLMaps := map[Type]TestURLAndError{
NewTypeOrDie("common", "replicatedservice", "v1"): TestURLAndError{"https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v1/replicatedservice.py", nil}, NewTypeOrDie("common", "replicatedservice", "v1"): TestURLAndError{"https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v1/replicatedservice.py", nil},
NewTypeOrDie("storage", "redis", "v1"): TestURLAndError{"https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/storage/redis/v1/redis.jinja", nil}, NewTypeOrDie("storage", "redis", "v1"): TestURLAndError{"https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/storage/redis/v1/redis.jinja", nil},
} }
@ -45,13 +45,13 @@ func TestShortGithubUrlTemplateMapping(t *testing.T) {
"github.com/kubernetes/application-dm-templates/storage/redis:v1": TestURLAndError{"https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/storage/redis/v1/redis.jinja", nil}, "github.com/kubernetes/application-dm-templates/storage/redis:v1": TestURLAndError{"https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/storage/redis/v1/redis.jinja", nil},
} }
grp := NewTestGithubRegistryProvider("github.com/kubernetes/application-dm-templates", githubUrlMaps) grp := NewTestGithubRegistryProvider("github.com/kubernetes/application-dm-templates", githubURLMaps)
// TODO(vaikas): XXXX FIXME Add gcsrp // TODO(vaikas): XXXX FIXME Add gcsrp
testUrlConversionDriver(NewRegistryProvider(nil, grp, nil, NewInmemCredentialProvider()), tests, t) testURLConversionDriver(NewRegistryProvider(nil, grp, nil, NewInmemCredentialProvider()), tests, t)
} }
func TestShortGithubUrlPackageMapping(t *testing.T) { func TestShortGithubURLPackageMapping(t *testing.T) {
githubUrlMaps := map[Type]TestURLAndError{ githubURLMaps := map[Type]TestURLAndError{
NewTypeOrDie("", "mongodb", ""): TestURLAndError{"https://raw.githubusercontent.com/helm/charts/master/mongodb/manifests/mongodb.yaml", nil}, NewTypeOrDie("", "mongodb", ""): TestURLAndError{"https://raw.githubusercontent.com/helm/charts/master/mongodb/manifests/mongodb.yaml", nil},
NewTypeOrDie("", "redis", ""): TestURLAndError{"https://raw.githubusercontent.com/helm/charts/master/redis/manifests/redis.yaml", nil}, NewTypeOrDie("", "redis", ""): TestURLAndError{"https://raw.githubusercontent.com/helm/charts/master/redis/manifests/redis.yaml", nil},
} }
@ -61,7 +61,7 @@ func TestShortGithubUrlPackageMapping(t *testing.T) {
"github.com/helm/charts/redis": TestURLAndError{"https://raw.githubusercontent.com/helm/charts/master/redis/manifests/redis.yaml", nil}, "github.com/helm/charts/redis": TestURLAndError{"https://raw.githubusercontent.com/helm/charts/master/redis/manifests/redis.yaml", nil},
} }
grp := NewTestGithubRegistryProvider("github.com/helm/charts", githubUrlMaps) grp := NewTestGithubRegistryProvider("github.com/helm/charts", githubURLMaps)
// TODO(vaikas): XXXX FIXME Add gcsrp // TODO(vaikas): XXXX FIXME Add gcsrp
testUrlConversionDriver(NewRegistryProvider(nil, grp, nil, NewInmemCredentialProvider()), tests, t) testURLConversionDriver(NewRegistryProvider(nil, grp, nil, NewInmemCredentialProvider()), tests, t)
} }

@ -46,12 +46,13 @@ var kubernetesConfig *util.KubernetesConfig
const secretType = "Secret" const secretType = "Secret"
// CredentialProvider provides credentials for registries. // SecretsCredentialProvider provides credentials for registries from Kubernertes secrets.
type SecretsCredentialProvider struct { type SecretsCredentialProvider struct {
// Actual object that talks to secrets service. // Actual object that talks to secrets service.
k util.Kubernetes k util.Kubernetes
} }
// NewSecretsCredentialProvider creates a new secrets credential provider.
func NewSecretsCredentialProvider() common.CredentialProvider { func NewSecretsCredentialProvider() common.CredentialProvider {
kubernetesConfig := &util.KubernetesConfig{ kubernetesConfig := &util.KubernetesConfig{
KubePath: *kubePath, KubePath: *kubePath,
@ -87,6 +88,7 @@ func parseCredential(credential string) (*common.RegistryCredential, error) {
return r, nil return r, nil
} }
// GetCredential returns a credential by name.
func (scp *SecretsCredentialProvider) GetCredential(name string) (*common.RegistryCredential, error) { func (scp *SecretsCredentialProvider) GetCredential(name string) (*common.RegistryCredential, error) {
o, err := scp.k.Get(name, secretType) o, err := scp.k.Get(name, secretType)
if err != nil { if err != nil {
@ -95,6 +97,7 @@ func (scp *SecretsCredentialProvider) GetCredential(name string) (*common.Regist
return parseCredential(o) return parseCredential(o)
} }
// SetCredential sets a credential by name.
func (scp *SecretsCredentialProvider) SetCredential(name string, credential *common.RegistryCredential) error { func (scp *SecretsCredentialProvider) SetCredential(name string, credential *common.RegistryCredential) error {
// Marshal the credential & base64 encode it. // Marshal the credential & base64 encode it.
b, err := yaml.Marshal(credential) b, err := yaml.Marshal(credential)
@ -111,7 +114,7 @@ func (scp *SecretsCredentialProvider) SetCredential(name string, credential *com
data["credential"] = enc data["credential"] = enc
obj := &common.KubernetesSecret{ obj := &common.KubernetesSecret{
Kind: secretType, Kind: secretType,
ApiVersion: "v1", APIVersion: "v1",
Metadata: metadata, Metadata: metadata,
Data: data, Data: data,
} }

@ -22,12 +22,14 @@ import (
"strings" "strings"
) )
// SemVer holds a semantic version as defined by semver.io.
type SemVer struct { type SemVer struct {
Major uint Major uint
Minor uint Minor uint
Patch uint Patch uint
} }
// ParseSemVer parses a semantic version string.
func ParseSemVer(version string) (SemVer, error) { func ParseSemVer(version string) (SemVer, error) {
var err error var err error
major, minor, patch := uint64(0), uint64(0), uint64(0) major, minor, patch := uint64(0), uint64(0), uint64(0)
@ -70,6 +72,7 @@ func ParseSemVer(version string) (SemVer, error) {
return SemVer{Major: uint(major), Minor: uint(minor), Patch: uint(patch)}, nil return SemVer{Major: uint(major), Minor: uint(minor), Patch: uint(patch)}, nil
} }
// IsZero returns true if the semantic version is zero.
func (s SemVer) IsZero() bool { func (s SemVer) IsZero() bool {
return s.Major == 0 && s.Minor == 0 && s.Patch == 0 return s.Major == 0 && s.Minor == 0 && s.Patch == 0
} }

@ -32,11 +32,13 @@ import (
"strings" "strings"
) )
// TestURLAndError associates a URL with an error string for testing.
type TestURLAndError struct { type TestURLAndError struct {
URL string URL string
Err error Err error
} }
// DownloadResponse holds a mock http reponse for testing.
type DownloadResponse struct { type DownloadResponse struct {
Err error Err error
Code int Code int
@ -55,6 +57,7 @@ type testGithubRegistry struct {
downloadResponses map[string]DownloadResponse downloadResponses map[string]DownloadResponse
} }
// NewTestGithubRegistryProvider creates a test github registry provider.
func NewTestGithubRegistryProvider(shortURL string, responses map[Type]TestURLAndError) GithubRegistryProvider { func NewTestGithubRegistryProvider(shortURL string, responses map[Type]TestURLAndError) GithubRegistryProvider {
return testGithubRegistryProvider{ return testGithubRegistryProvider{
shortURL: util.TrimURLScheme(shortURL), shortURL: util.TrimURLScheme(shortURL),
@ -62,6 +65,7 @@ func NewTestGithubRegistryProvider(shortURL string, responses map[Type]TestURLAn
} }
} }
// NewTestGithubRegistryProviderWithDownloads creates a test github registry provider with download responses.
func NewTestGithubRegistryProviderWithDownloads(shortURL string, responses map[Type]TestURLAndError, downloadResponses map[string]DownloadResponse) GithubRegistryProvider { func NewTestGithubRegistryProviderWithDownloads(shortURL string, responses map[Type]TestURLAndError, downloadResponses map[string]DownloadResponse) GithubRegistryProvider {
return testGithubRegistryProvider{ return testGithubRegistryProvider{
shortURL: util.TrimURLScheme(shortURL), shortURL: util.TrimURLScheme(shortURL),
@ -70,6 +74,7 @@ func NewTestGithubRegistryProviderWithDownloads(shortURL string, responses map[T
} }
} }
// GetGithubRegistry is a mock implementation of the same method on GithubRegistryProvider.
func (tgrp testGithubRegistryProvider) GetGithubRegistry(cr common.Registry) (GithubRegistry, error) { func (tgrp testGithubRegistryProvider) GetGithubRegistry(cr common.Registry) (GithubRegistry, error) {
trimmed := util.TrimURLScheme(cr.URL) trimmed := util.TrimURLScheme(cr.URL)
if strings.HasPrefix(trimmed, tgrp.shortURL) { if strings.HasPrefix(trimmed, tgrp.shortURL) {
@ -88,10 +93,12 @@ func (tgrp testGithubRegistryProvider) GetGithubRegistry(cr common.Registry) (Gi
panic(fmt.Errorf("unknown registry: %v", cr)) panic(fmt.Errorf("unknown registry: %v", cr))
} }
// ListTypes is a mock implementation of the same method on GithubRegistryProvider.
func (tgr testGithubRegistry) ListTypes(regex *regexp.Regexp) ([]Type, error) { func (tgr testGithubRegistry) ListTypes(regex *regexp.Regexp) ([]Type, error) {
panic(fmt.Errorf("ListTypes should not be called in the test")) panic(fmt.Errorf("ListTypes should not be called in the test"))
} }
// GetDownloadURLs is a mock implementation of the same method on GithubRegistryProvider.
func (tgr testGithubRegistry) GetDownloadURLs(t Type) ([]*url.URL, error) { func (tgr testGithubRegistry) GetDownloadURLs(t Type) ([]*url.URL, error) {
result := tgr.responses[t] result := tgr.responses[t]
URL, err := url.Parse(result.URL) URL, err := url.Parse(result.URL)
@ -102,8 +109,9 @@ func (tgr testGithubRegistry) GetDownloadURLs(t Type) ([]*url.URL, error) {
return []*url.URL{URL}, result.Err return []*url.URL{URL}, result.Err
} }
func (g testGithubRegistry) Do(req *http.Request) (resp *http.Response, err error) { // Do is a mock implementation of the same method on GithubRegistryProvider.
response := g.downloadResponses[req.URL.String()] func (tgr testGithubRegistry) Do(req *http.Request) (resp *http.Response, err error) {
response := tgr.downloadResponses[req.URL.String()]
return &http.Response{StatusCode: response.Code, Body: ioutil.NopCloser(bytes.NewBufferString(response.Body))}, response.Err return &http.Response{StatusCode: response.Code, Body: ioutil.NopCloser(bytes.NewBufferString(response.Body))}, response.Err
} }
@ -117,6 +125,7 @@ type testGCSRegistry struct {
responses map[Type]TestURLAndError responses map[Type]TestURLAndError
} }
// NewTestGCSRegistryProvider creates a test GCS registry provider.
func NewTestGCSRegistryProvider(shortURL string, responses map[Type]TestURLAndError) GCSRegistryProvider { func NewTestGCSRegistryProvider(shortURL string, responses map[Type]TestURLAndError) GCSRegistryProvider {
return testGCSRegistryProvider{ return testGCSRegistryProvider{
shortURL: util.TrimURLScheme(shortURL), shortURL: util.TrimURLScheme(shortURL),
@ -124,6 +133,7 @@ func NewTestGCSRegistryProvider(shortURL string, responses map[Type]TestURLAndEr
} }
} }
// GetDownloadURLs is a mock implementation of the same method on GCSRegistryProvider.
func (tgrp testGCSRegistryProvider) GetGCSRegistry(cr common.Registry) (ObjectStorageRegistry, error) { func (tgrp testGCSRegistryProvider) GetGCSRegistry(cr common.Registry) (ObjectStorageRegistry, error) {
trimmed := util.TrimURLScheme(cr.URL) trimmed := util.TrimURLScheme(cr.URL)
if strings.HasPrefix(trimmed, tgrp.shortURL) { if strings.HasPrefix(trimmed, tgrp.shortURL) {

@ -200,7 +200,7 @@ func getPathVariable(w http.ResponseWriter, r *http.Request, variable, handler s
vars := mux.Vars(r) vars := mux.Vars(r)
escaped, ok := vars[variable] escaped, ok := vars[variable]
if !ok { if !ok {
e := errors.New(fmt.Sprintf("%s name not found in URL", variable)) e := fmt.Errorf("%s name not found in URL", variable)
util.LogAndReturnError(handler, http.StatusBadRequest, e, w) util.LogAndReturnError(handler, http.StatusBadRequest, e, w)
return "", e return "", e
} }
@ -226,7 +226,7 @@ func getConfiguration(w http.ResponseWriter, r *http.Request, handler string) *c
// Reject the input if it exceeded the length limit, // Reject the input if it exceeded the length limit,
// since we may not have read all of it into the buffer. // since we may not have read all of it into the buffer.
if _, err = b.Read(make([]byte, 0, 1)); err != io.EOF { if _, err = b.Read(make([]byte, 0, 1)); err != io.EOF {
e := fmt.Errorf("configuration exceeds maximum length of %d KB.", *maxLength) e := fmt.Errorf("configuration exceeds maximum length of %d KB", *maxLength)
util.LogAndReturnError(handler, http.StatusBadRequest, e, w) util.LogAndReturnError(handler, http.StatusBadRequest, e, w)
return nil return nil
} }

@ -27,10 +27,12 @@ import (
"github.com/kubernetes/deployment-manager/util" "github.com/kubernetes/deployment-manager/util"
) )
// Configurator configures a Kubernetes cluster using kubectl.
type Configurator struct { type Configurator struct {
k util.Kubernetes k util.Kubernetes
} }
// NewConfigurator creates a new Configurator.
func NewConfigurator(kubernetes util.Kubernetes) *Configurator { func NewConfigurator(kubernetes util.Kubernetes) *Configurator {
return &Configurator{kubernetes} return &Configurator{kubernetes}
} }
@ -69,7 +71,7 @@ func (e *Error) appendError(err error) error {
return err return err
} }
// resource name -> set of dependencies. // DependencyMap maps a resource name to a set of dependencies.
type DependencyMap map[string]map[string]bool type DependencyMap map[string]map[string]bool
var refRe = regexp.MustCompile("\\$\\(ref\\.([^\\.]+)\\.([^\\)]+)\\)") var refRe = regexp.MustCompile("\\$\\(ref\\.([^\\.]+)\\.([^\\)]+)\\)")

@ -72,6 +72,7 @@ type httpClient struct {
sleep Sleeper sleep Sleeper
} }
// DefaultHTTPClient returns a default http client.
func DefaultHTTPClient() HTTPClient { func DefaultHTTPClient() HTTPClient {
return NewHTTPClient(3, http.DefaultClient, NewSleeper()) return NewHTTPClient(3, http.DefaultClient, NewSleeper())
} }
@ -115,6 +116,7 @@ func readBody(b io.ReadCloser, ctype string, encoding string) (body string, err
return string(bytes), err return string(bytes), err
} }
// Get does an HTTP GET on the receiver.
func (client httpClient) Get(url string) (body string, code int, err error) { func (client httpClient) Get(url string) (body string, code int, err error) {
retryCount := client.retries retryCount := client.retries
numRetries := uint(0) numRetries := uint(0)

@ -233,8 +233,8 @@ func ToJSONOrError(v interface{}) string {
return string(j) return string(j)
} }
// IsHttpURL returns whether a string is an HTTP URL. // IsHTTPURL returns true if a string is an HTTP URL.
func IsHttpUrl(s string) bool { func IsHTTPURL(s string) bool {
u, err := url.Parse(s) u, err := url.Parse(s)
if err != nil { if err != nil {
return false return false

@ -16,7 +16,7 @@ limitations under the License.
package util package util
// KubernetesConfiguration defines the configuration options for talking to Kubernetes master // KubernetesConfig defines the configuration options for talking to Kubernetes master
type KubernetesConfig struct { type KubernetesConfig struct {
KubePath string // The path to kubectl binary KubePath string // The path to kubectl binary
KubeService string // DNS name of the kubernetes service KubeService string // DNS name of the kubernetes service

@ -33,6 +33,7 @@ type KubernetesKubectl struct {
Arguments []string Arguments []string
} }
// NewKubernetesKubectl creates a new Kubernetes kubectl wrapper.
func NewKubernetesKubectl(config *KubernetesConfig) Kubernetes { func NewKubernetesKubectl(config *KubernetesConfig) Kubernetes {
if config.KubePath == "" { if config.KubePath == "" {
log.Fatalf("kubectl path cannot be empty") log.Fatalf("kubectl path cannot be empty")
@ -85,6 +86,7 @@ func NewKubernetesKubectl(config *KubernetesConfig) Kubernetes {
return &KubernetesKubectl{config.KubePath, args} return &KubernetesKubectl{config.KubePath, args}
} }
// Get runs a kubectl get command for a named resource of a given type.
func (k *KubernetesKubectl) Get(name string, resourceType string) (string, error) { func (k *KubernetesKubectl) Get(name string, resourceType string) (string, error) {
// Specify output as json rather than human readable for easier machine parsing // Specify output as json rather than human readable for easier machine parsing
args := []string{"get", args := []string{"get",
@ -95,16 +97,19 @@ func (k *KubernetesKubectl) Get(name string, resourceType string) (string, error
return k.execute(args, "") return k.execute(args, "")
} }
// Create runs a kubectl create command for a given resource.
func (k *KubernetesKubectl) Create(resource string) (string, error) { func (k *KubernetesKubectl) Create(resource string) (string, error) {
args := []string{"create"} args := []string{"create"}
return k.execute(args, resource) return k.execute(args, resource)
} }
// Delete runs a kubectl delete command for a given resource.
func (k *KubernetesKubectl) Delete(resource string) (string, error) { func (k *KubernetesKubectl) Delete(resource string) (string, error) {
args := []string{"delete"} args := []string{"delete"}
return k.execute(args, resource) return k.execute(args, resource)
} }
// Replace runs a kubectl replace command for a given resource.
func (k *KubernetesKubectl) Replace(resource string) (string, error) { func (k *KubernetesKubectl) Replace(resource string) (string, error) {
args := []string{"replace"} args := []string{"replace"}
return k.execute(args, resource) return k.execute(args, resource)

@ -6,7 +6,7 @@ you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -24,6 +24,7 @@ import (
"github.com/kubernetes/deployment-manager/common" "github.com/kubernetes/deployment-manager/common"
) )
// ParseKubernetesObject parses a Kubernetes API object in YAML format.
func ParseKubernetesObject(object []byte) (*common.Resource, error) { func ParseKubernetesObject(object []byte) (*common.Resource, error) {
o := &common.KubernetesObject{} o := &common.KubernetesObject{}
if err := yaml.Unmarshal(object, &o); err != nil { if err := yaml.Unmarshal(object, &o); err != nil {

Loading…
Cancel
Save