mirror of https://github.com/helm/helm
parent
873a8af412
commit
e1afffbc4a
@ -1,245 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package manager
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/kubernetes/helm/pkg/common"
|
|
||||||
"github.com/kubernetes/helm/pkg/registry"
|
|
||||||
"github.com/kubernetes/helm/pkg/util"
|
|
||||||
|
|
||||||
"github.com/ghodss/yaml"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
maxURLImports = 100
|
|
||||||
schemaSuffix = ".schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TypeResolver finds Types in a Configuration which aren't yet reduceable to an import file
|
|
||||||
// or primitive, and attempts to replace them with a template from a URL.
|
|
||||||
type TypeResolver interface {
|
|
||||||
ResolveTypes(config *common.Configuration, imports []*common.ImportFile) ([]*common.ImportFile, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type typeResolver struct {
|
|
||||||
maxUrls int
|
|
||||||
rp registry.RegistryProvider
|
|
||||||
c util.HTTPClient
|
|
||||||
}
|
|
||||||
|
|
||||||
type fetchableURL struct {
|
|
||||||
reg registry.Registry
|
|
||||||
url string
|
|
||||||
}
|
|
||||||
|
|
||||||
type fetchUnit struct {
|
|
||||||
urls []fetchableURL
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewTypeResolver returns a new initialized TypeResolver.
|
|
||||||
func NewTypeResolver(rp registry.RegistryProvider, c util.HTTPClient) TypeResolver {
|
|
||||||
return &typeResolver{maxUrls: maxURLImports, rp: rp, c: c}
|
|
||||||
}
|
|
||||||
|
|
||||||
func resolverError(c *common.Configuration, err error) error {
|
|
||||||
return fmt.Errorf("cannot resolve types in configuration %s due to: \n%s\n",
|
|
||||||
c, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tr *typeResolver) performHTTPGet(d util.HTTPDoer, u string, allowMissing bool) (content string, err error) {
|
|
||||||
g := tr.c
|
|
||||||
if d != nil {
|
|
||||||
g = util.NewHTTPClient(3, d, util.NewSleeper())
|
|
||||||
}
|
|
||||||
r, code, err := g.Get(u)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
if allowMissing && code == http.StatusNotFound {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if code != http.StatusOK {
|
|
||||||
return "", fmt.Errorf(
|
|
||||||
"Received status code %d attempting to fetch Type at %s", code, u)
|
|
||||||
}
|
|
||||||
|
|
||||||
return r, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResolveTypes resolves the types in the supplied configuration and returns
|
|
||||||
// resolved type definitions in t.ImportFiles. Types can be either
|
|
||||||
// primitive (i.e., built in), resolved (i.e., already t.ImportFiles), or remote
|
|
||||||
// (i.e., described by a URL that must be fetched to resolve the type).
|
|
||||||
func (tr *typeResolver) ResolveTypes(config *common.Configuration, imports []*common.ImportFile) ([]*common.ImportFile, error) {
|
|
||||||
existing := map[string]bool{}
|
|
||||||
for _, v := range imports {
|
|
||||||
existing[v.Name] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
fetched := map[string][]*common.ImportFile{}
|
|
||||||
// TODO(vaikas): Need to account for multiple URLs being fetched for a given type.
|
|
||||||
toFetch := make([]*fetchUnit, 0, tr.maxUrls)
|
|
||||||
for _, r := range config.Resources {
|
|
||||||
// Map the type to a fetchable URL (if applicable) or skip it if it's a non-fetchable type (primitive for example).
|
|
||||||
urls, urlRegistry, err := registry.GetDownloadURLs(tr.rp, r.Type)
|
|
||||||
if err != nil {
|
|
||||||
return nil, resolverError(config, fmt.Errorf("Failed to understand download url for %s: %v", r.Type, err))
|
|
||||||
}
|
|
||||||
if !existing[r.Type] {
|
|
||||||
f := &fetchUnit{}
|
|
||||||
for _, u := range urls {
|
|
||||||
if len(u) > 0 {
|
|
||||||
f.urls = append(f.urls, fetchableURL{urlRegistry, u})
|
|
||||||
// Add to existing map so it is not fetched multiple times.
|
|
||||||
existing[r.Type] = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(f.urls) > 0 {
|
|
||||||
toFetch = append(toFetch, f)
|
|
||||||
fetched[f.urls[0].url] = append(fetched[f.urls[0].url], &common.ImportFile{Name: r.Type, Path: f.urls[0].url})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
count := 0
|
|
||||||
for len(toFetch) > 0 {
|
|
||||||
// 1. If short github URL, resolve to a download URL
|
|
||||||
// 2. Fetch import URL. Exit if no URLs left
|
|
||||||
// 3. Check/handle HTTP status
|
|
||||||
// 4. Store results in all ImportFiles from that URL
|
|
||||||
// 5. Check for the optional schema file at import URL + .schema
|
|
||||||
// 6. Repeat 2,3 for schema file
|
|
||||||
// 7. Add each schema import to fetch if not already done
|
|
||||||
// 8. Mark URL done. Return to 1.
|
|
||||||
if count >= tr.maxUrls {
|
|
||||||
return nil, resolverError(config,
|
|
||||||
fmt.Errorf("Number of imports exceeds maximum of %d", tr.maxUrls))
|
|
||||||
}
|
|
||||||
|
|
||||||
templates := []string{}
|
|
||||||
url := toFetch[0].urls[0]
|
|
||||||
for _, u := range toFetch[0].urls {
|
|
||||||
template, err := tr.performHTTPGet(u.reg, u.url, false)
|
|
||||||
if err != nil {
|
|
||||||
return nil, resolverError(config, err)
|
|
||||||
}
|
|
||||||
templates = append(templates, template)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, i := range fetched[url.url] {
|
|
||||||
template, err := parseContent(templates)
|
|
||||||
if err != nil {
|
|
||||||
return nil, resolverError(config, err)
|
|
||||||
}
|
|
||||||
i.Content = template
|
|
||||||
}
|
|
||||||
|
|
||||||
schemaURL := url.url + schemaSuffix
|
|
||||||
sch, err := tr.performHTTPGet(url.reg, schemaURL, true)
|
|
||||||
if err != nil {
|
|
||||||
return nil, resolverError(config, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if sch != "" {
|
|
||||||
var s common.Schema
|
|
||||||
if err := yaml.Unmarshal([]byte(sch), &s); err != nil {
|
|
||||||
return nil, resolverError(config, err)
|
|
||||||
}
|
|
||||||
// Here we handle any nested imports in the schema we've just fetched.
|
|
||||||
for _, v := range s.Imports {
|
|
||||||
i := &common.ImportFile{Name: v.Name}
|
|
||||||
var existingSchema string
|
|
||||||
urls, urlRegistry, conversionErr := registry.GetDownloadURLs(tr.rp, v.Path)
|
|
||||||
if conversionErr != nil {
|
|
||||||
return nil, resolverError(config, fmt.Errorf("Failed to understand download url for %s: %v", v.Path, conversionErr))
|
|
||||||
}
|
|
||||||
if len(urls) == 0 {
|
|
||||||
// If it's not a fetchable URL, we need to use the type name as is, since it is a short name
|
|
||||||
// for a schema.
|
|
||||||
urls = []string{v.Path}
|
|
||||||
}
|
|
||||||
for _, u := range urls {
|
|
||||||
if len(fetched[u]) == 0 {
|
|
||||||
// If this import URL is new to us, add it to the URLs to fetch.
|
|
||||||
toFetch = append(toFetch, &fetchUnit{[]fetchableURL{{urlRegistry, u}}})
|
|
||||||
} else {
|
|
||||||
// If this is not a new import URL and we've already fetched its contents,
|
|
||||||
// reuse them. Also, check if we also found a schema for that import URL and
|
|
||||||
// record those contents for re-use as well.
|
|
||||||
if fetched[u][0].Content != "" {
|
|
||||||
i.Content = fetched[u][0].Content
|
|
||||||
if len(fetched[u+schemaSuffix]) > 0 {
|
|
||||||
existingSchema = fetched[u+schemaSuffix][0].Content
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fetched[u] = append(fetched[u], i)
|
|
||||||
if existingSchema != "" {
|
|
||||||
fetched[u+schemaSuffix] = append(fetched[u+schemaSuffix],
|
|
||||||
&common.ImportFile{Name: v.Name + schemaSuffix, Content: existingSchema})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the schema we've fetched as the schema for any templates which used this URL.
|
|
||||||
for _, i := range fetched[url.url] {
|
|
||||||
schemaImportName := i.Name + schemaSuffix
|
|
||||||
fetched[schemaURL] = append(fetched[schemaURL],
|
|
||||||
&common.ImportFile{Name: schemaImportName, Content: sch})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
count = count + 1
|
|
||||||
toFetch = toFetch[1:]
|
|
||||||
}
|
|
||||||
|
|
||||||
ret := []*common.ImportFile{}
|
|
||||||
for _, v := range fetched {
|
|
||||||
ret = append(ret, v...)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseContent(templates []string) (string, error) {
|
|
||||||
if len(templates) == 1 {
|
|
||||||
return templates[0], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
// template representing a package out of that below.
|
|
||||||
fakeConfig := &common.Configuration{}
|
|
||||||
for _, template := range templates {
|
|
||||||
o, err := util.ParseKubernetesObject([]byte(template))
|
|
||||||
if err != nil {
|
|
||||||
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 {
|
|
||||||
return "", fmt.Errorf("Failed to marshal: %+v", fakeConfig)
|
|
||||||
}
|
|
||||||
return string(marshalled), nil
|
|
||||||
}
|
|
@ -1,328 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package manager
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"net/http"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/ghodss/yaml"
|
|
||||||
"github.com/kubernetes/helm/pkg/common"
|
|
||||||
"github.com/kubernetes/helm/pkg/registry"
|
|
||||||
)
|
|
||||||
|
|
||||||
type responseAndError struct {
|
|
||||||
err error
|
|
||||||
code int
|
|
||||||
resp string
|
|
||||||
}
|
|
||||||
|
|
||||||
type resolverTestCase struct {
|
|
||||||
config string
|
|
||||||
imports []*common.ImportFile
|
|
||||||
responses map[string]responseAndError
|
|
||||||
urlcount int
|
|
||||||
expectedErr error
|
|
||||||
importOut []*common.ImportFile
|
|
||||||
registryProvider registry.RegistryProvider
|
|
||||||
}
|
|
||||||
|
|
||||||
type testGetter struct {
|
|
||||||
responses map[string]responseAndError
|
|
||||||
count int
|
|
||||||
test *testing.T
|
|
||||||
}
|
|
||||||
|
|
||||||
var count = 0
|
|
||||||
|
|
||||||
func (tg testGetter) Get(url string) (body string, code int, err error) {
|
|
||||||
count = count + 1
|
|
||||||
ret := tg.responses[url]
|
|
||||||
return ret.resp, ret.code, ret.err
|
|
||||||
}
|
|
||||||
|
|
||||||
func testDriver(c resolverTestCase, t *testing.T) {
|
|
||||||
g := &testGetter{test: t, responses: c.responses}
|
|
||||||
count = 0
|
|
||||||
r := &typeResolver{
|
|
||||||
maxUrls: 5,
|
|
||||||
rp: c.registryProvider,
|
|
||||||
c: g,
|
|
||||||
}
|
|
||||||
|
|
||||||
conf := &common.Configuration{}
|
|
||||||
dataErr := yaml.Unmarshal([]byte(c.config), conf)
|
|
||||||
if dataErr != nil {
|
|
||||||
panic("bad test data")
|
|
||||||
}
|
|
||||||
|
|
||||||
result, err := r.ResolveTypes(conf, c.imports)
|
|
||||||
|
|
||||||
if count != c.urlcount {
|
|
||||||
t.Errorf("Expected %d url GETs but only %d found %#v", c.urlcount, g.count, g)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err != nil && c.expectedErr == nil) || (err == nil && c.expectedErr != nil) {
|
|
||||||
t.Errorf("Expected error %s but found %s", c.expectedErr, err)
|
|
||||||
} else if err != nil && !strings.Contains(err.Error(), c.expectedErr.Error()) {
|
|
||||||
t.Errorf("Expected error %s but found %s", c.expectedErr, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
resultImport := map[common.ImportFile]bool{}
|
|
||||||
expectedImport := map[common.ImportFile]bool{}
|
|
||||||
for _, i := range result {
|
|
||||||
resultImport[*i] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, i := range c.importOut {
|
|
||||||
expectedImport[*i] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(resultImport, expectedImport) {
|
|
||||||
t.Errorf("Expected imports %+v but found %+v", expectedImport, resultImport)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var simpleContent = `
|
|
||||||
resources:
|
|
||||||
- name: test
|
|
||||||
type: ReplicationController
|
|
||||||
`
|
|
||||||
|
|
||||||
func TestNoImports(t *testing.T) {
|
|
||||||
test := resolverTestCase{config: simpleContent}
|
|
||||||
testDriver(test, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
var includeImport = `
|
|
||||||
resources:
|
|
||||||
- name: foo
|
|
||||||
type: foo.py
|
|
||||||
`
|
|
||||||
|
|
||||||
func TestIncludedImport(t *testing.T) {
|
|
||||||
imports := []*common.ImportFile{{Name: "foo.py"}}
|
|
||||||
test := resolverTestCase{
|
|
||||||
config: includeImport,
|
|
||||||
imports: imports,
|
|
||||||
}
|
|
||||||
testDriver(test, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
var templateSingleURL = `
|
|
||||||
resources:
|
|
||||||
- name: foo
|
|
||||||
type: http://my-fake-url
|
|
||||||
`
|
|
||||||
|
|
||||||
func TestSingleUrl(t *testing.T) {
|
|
||||||
finalImports := []*common.ImportFile{{Name: "http://my-fake-url", Path: "http://my-fake-url", Content: "my-content"}}
|
|
||||||
|
|
||||||
responses := map[string]responseAndError{
|
|
||||||
"http://my-fake-url": {nil, http.StatusOK, "my-content"},
|
|
||||||
"http://my-fake-url.schema": {nil, http.StatusNotFound, ""},
|
|
||||||
}
|
|
||||||
|
|
||||||
test := resolverTestCase{
|
|
||||||
config: templateSingleURL,
|
|
||||||
importOut: finalImports,
|
|
||||||
urlcount: 2,
|
|
||||||
responses: responses,
|
|
||||||
}
|
|
||||||
testDriver(test, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSingleUrlWith500(t *testing.T) {
|
|
||||||
responses := map[string]responseAndError{
|
|
||||||
"http://my-fake-url": {nil, http.StatusInternalServerError, "my-content"},
|
|
||||||
}
|
|
||||||
|
|
||||||
test := resolverTestCase{
|
|
||||||
config: templateSingleURL,
|
|
||||||
urlcount: 1,
|
|
||||||
responses: responses,
|
|
||||||
expectedErr: errors.New("Received status code 500"),
|
|
||||||
}
|
|
||||||
testDriver(test, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
var schema1 = `
|
|
||||||
imports:
|
|
||||||
- path: my-next-url
|
|
||||||
name: schema-import
|
|
||||||
`
|
|
||||||
|
|
||||||
func TestSingleUrlWithSchema(t *testing.T) {
|
|
||||||
finalImports := []*common.ImportFile{
|
|
||||||
{Name: "http://my-fake-url", Path: "http://my-fake-url", Content: "my-content"},
|
|
||||||
{Name: "schema-import", Content: "schema-import"},
|
|
||||||
{Name: "http://my-fake-url.schema", Content: schema1},
|
|
||||||
}
|
|
||||||
|
|
||||||
responses := map[string]responseAndError{
|
|
||||||
"http://my-fake-url": {nil, http.StatusOK, "my-content"},
|
|
||||||
"http://my-fake-url.schema": {nil, http.StatusOK, schema1},
|
|
||||||
"my-next-url": {nil, http.StatusOK, "schema-import"},
|
|
||||||
"my-next-url.schema": {nil, http.StatusNotFound, ""},
|
|
||||||
}
|
|
||||||
|
|
||||||
test := resolverTestCase{
|
|
||||||
config: templateSingleURL,
|
|
||||||
importOut: finalImports,
|
|
||||||
urlcount: 4,
|
|
||||||
responses: responses,
|
|
||||||
}
|
|
||||||
testDriver(test, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
var templateExceedsMax = `
|
|
||||||
resources:
|
|
||||||
- name: foo
|
|
||||||
type: http://my-fake-url
|
|
||||||
- name: foo1
|
|
||||||
type: http://my-fake-url1
|
|
||||||
- name: foo2
|
|
||||||
type: http://my-fake-url2
|
|
||||||
- name: foo3
|
|
||||||
type: http://my-fake-url3
|
|
||||||
- name: foo4
|
|
||||||
type: http://my-fake-url4
|
|
||||||
- name: foo5
|
|
||||||
type: http://my-fake-url5
|
|
||||||
`
|
|
||||||
|
|
||||||
func TestTooManyImports(t *testing.T) {
|
|
||||||
responses := map[string]responseAndError{
|
|
||||||
"http://my-fake-url": {nil, http.StatusOK, "my-content"},
|
|
||||||
"http://my-fake-url.schema": {nil, http.StatusNotFound, ""},
|
|
||||||
"http://my-fake-url1": {nil, http.StatusOK, "my-content"},
|
|
||||||
"http://my-fake-url1.schema": {nil, http.StatusNotFound, ""},
|
|
||||||
"http://my-fake-url2": {nil, http.StatusOK, "my-content"},
|
|
||||||
"http://my-fake-url2.schema": {nil, http.StatusNotFound, ""},
|
|
||||||
"http://my-fake-url3": {nil, http.StatusOK, "my-content"},
|
|
||||||
"http://my-fake-url3.schema": {nil, http.StatusNotFound, ""},
|
|
||||||
"http://my-fake-url4": {nil, http.StatusOK, "my-content"},
|
|
||||||
"http://my-fake-url4.schema": {nil, http.StatusNotFound, ""},
|
|
||||||
"http://my-fake-url5": {nil, http.StatusOK, "my-content"},
|
|
||||||
"http://my-fake-url5.schema": {nil, http.StatusNotFound, ""},
|
|
||||||
}
|
|
||||||
|
|
||||||
test := resolverTestCase{
|
|
||||||
config: templateExceedsMax,
|
|
||||||
urlcount: 10,
|
|
||||||
responses: responses,
|
|
||||||
expectedErr: errors.New("Number of imports exceeds maximum of 5"),
|
|
||||||
}
|
|
||||||
|
|
||||||
testDriver(test, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
var templateSharesImport = `
|
|
||||||
resources:
|
|
||||||
- name: foo
|
|
||||||
type: http://my-fake-url
|
|
||||||
- name: foo1
|
|
||||||
type: http://my-fake-url1
|
|
||||||
`
|
|
||||||
|
|
||||||
var schema2 = `
|
|
||||||
imports:
|
|
||||||
- path: my-next-url
|
|
||||||
name: schema-import-1
|
|
||||||
`
|
|
||||||
|
|
||||||
func TestSharedImport(t *testing.T) {
|
|
||||||
finalImports := []*common.ImportFile{
|
|
||||||
{Name: "http://my-fake-url", Path: "http://my-fake-url", Content: "my-content"},
|
|
||||||
{Name: "http://my-fake-url1", Path: "http://my-fake-url1", Content: "my-content-1"},
|
|
||||||
{Name: "schema-import", Content: "schema-import"},
|
|
||||||
{Name: "schema-import-1", Content: "schema-import"},
|
|
||||||
{Name: "http://my-fake-url.schema", Content: schema1},
|
|
||||||
{Name: "http://my-fake-url1.schema", Content: schema2},
|
|
||||||
}
|
|
||||||
|
|
||||||
responses := map[string]responseAndError{
|
|
||||||
"http://my-fake-url": {nil, http.StatusOK, "my-content"},
|
|
||||||
"http://my-fake-url.schema": {nil, http.StatusOK, schema1},
|
|
||||||
"http://my-fake-url1": {nil, http.StatusOK, "my-content-1"},
|
|
||||||
"http://my-fake-url1.schema": {nil, http.StatusOK, schema2},
|
|
||||||
"my-next-url": {nil, http.StatusOK, "schema-import"},
|
|
||||||
"my-next-url.schema": {nil, http.StatusNotFound, ""},
|
|
||||||
}
|
|
||||||
|
|
||||||
test := resolverTestCase{
|
|
||||||
config: templateSharesImport,
|
|
||||||
urlcount: 6,
|
|
||||||
responses: responses,
|
|
||||||
importOut: finalImports,
|
|
||||||
}
|
|
||||||
|
|
||||||
testDriver(test, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
var templateShortGithubTemplate = `
|
|
||||||
resources:
|
|
||||||
- name: foo
|
|
||||||
type: github.com/kubernetes/application-dm-templates/common/replicatedservice:v1
|
|
||||||
- name: foo1
|
|
||||||
type: github.com/kubernetes/application-dm-templates/common/replicatedservice:v2
|
|
||||||
`
|
|
||||||
|
|
||||||
func TestShortGithubUrl(t *testing.T) {
|
|
||||||
finalImports := []*common.ImportFile{
|
|
||||||
{
|
|
||||||
Name: "github.com/kubernetes/application-dm-templates/common/replicatedservice:v1",
|
|
||||||
Path: "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v1/replicatedservice.py",
|
|
||||||
Content: "my-content"},
|
|
||||||
{
|
|
||||||
Name: "github.com/kubernetes/application-dm-templates/common/replicatedservice:v2",
|
|
||||||
Path: "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v2/replicatedservice.py",
|
|
||||||
Content: "my-content-2"},
|
|
||||||
}
|
|
||||||
|
|
||||||
downloadResponses := map[string]registry.DownloadResponse{
|
|
||||||
"https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v1/replicatedservice.py": {Err: nil, Code: http.StatusOK, Body: "my-content"},
|
|
||||||
"https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v1/replicatedservice.py.schema": {Err: nil, Code: http.StatusNotFound, Body: ""},
|
|
||||||
"https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v2/replicatedservice.py": {Err: nil, Code: http.StatusOK, Body: "my-content-2"},
|
|
||||||
"https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v2/replicatedservice.py.schema": {Err: nil, Code: http.StatusNotFound, Body: ""},
|
|
||||||
}
|
|
||||||
|
|
||||||
githubURLMaps := map[registry.Type]registry.TestURLAndError{
|
|
||||||
registry.NewTypeOrDie("common", "replicatedservice", "v1"): {URL: "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v1/replicatedservice.py", Err: nil},
|
|
||||||
registry.NewTypeOrDie("common", "replicatedservice", "v2"): {URL: "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v2/replicatedservice.py", Err: nil},
|
|
||||||
}
|
|
||||||
|
|
||||||
gcsURLMaps := map[registry.Type]registry.TestURLAndError{
|
|
||||||
registry.NewTypeOrDie("common", "replicatedservice", "v1"): {URL: "https://raw.githubusercontent.com/kubernetes/application-dm-templates/master/common/replicatedservice/v1/replicatedservice.py", Err: nil},
|
|
||||||
registry.NewTypeOrDie("common", "replicatedservice", "v2"): {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)
|
|
||||||
gcsrp := registry.NewTestGCSRegistryProvider("gs://charts", gcsURLMaps)
|
|
||||||
test := resolverTestCase{
|
|
||||||
config: templateShortGithubTemplate,
|
|
||||||
importOut: finalImports,
|
|
||||||
urlcount: 0,
|
|
||||||
responses: map[string]responseAndError{},
|
|
||||||
registryProvider: registry.NewRegistryProvider(nil, grp, gcsrp, registry.NewInmemCredentialProvider()),
|
|
||||||
}
|
|
||||||
|
|
||||||
testDriver(test, t)
|
|
||||||
}
|
|
Loading…
Reference in new issue