We will now assume anything not a template is a primitive.

Rather than hard-coding what a primitive is, we will only look for
templates, and let resourcifier error when kubectl fails to understand
anything else.

Adding missed new file.
pull/115/head
Brendan Melville 9 years ago
parent 19d68d096f
commit 71549bbef1

@ -19,6 +19,7 @@ import (
"github.com/kubernetes/deployment-manager/expandybird/expander" "github.com/kubernetes/deployment-manager/expandybird/expander"
"github.com/kubernetes/deployment-manager/manager/manager" "github.com/kubernetes/deployment-manager/manager/manager"
"github.com/kubernetes/deployment-manager/registry" "github.com/kubernetes/deployment-manager/registry"
"github.com/kubernetes/deployment-manager/util"
"bytes" "bytes"
"encoding/json" "encoding/json"
@ -215,7 +216,7 @@ func describeType(args []string) {
} }
func getTypeUrl(tName string) string { func getTypeUrl(tName string) string {
if isHttp(tName) { if util.IsHttpUrl(tName) {
// User can pass raw URL to template. // User can pass raw URL to template.
return tName return tName
} }

@ -21,6 +21,7 @@ import (
"net/http" "net/http"
"github.com/ghodss/yaml" "github.com/ghodss/yaml"
"github.com/kubernetes/deployment-manager/util"
) )
const ( const (
@ -96,7 +97,7 @@ func walkLayout(l *Layout, toReplace map[string]*LayoutResource) map[string]*Lay
for len(toVisit) > 0 { for len(toVisit) > 0 {
lr := toVisit[0] lr := toVisit[0]
nodeKey := lr.Resource.Name + layoutNodeKeySeparator + lr.Resource.Type nodeKey := lr.Resource.Name + layoutNodeKeySeparator + lr.Resource.Type
if len(lr.Layout.Resources) == 0 && Primitives[lr.Resource.Type] == false { if len(lr.Layout.Resources) == 0 && util.IsTemplate(lr.Resource.Type) {
ret[nodeKey] = lr ret[nodeKey] = lr
} else if toReplace[nodeKey] != nil { } else if toReplace[nodeKey] != nil {
toReplace[nodeKey].Resources = lr.Resources toReplace[nodeKey].Resources = lr.Resources

@ -138,7 +138,7 @@ var roundTripContent = `
config: config:
resources: resources:
- name: test - name: test
type: test type: test.py
properties: properties:
test: test test: test
` `
@ -146,7 +146,7 @@ config:
var roundTripExpanded = ` var roundTripExpanded = `
resources: resources:
- name: test2 - name: test2
type: test2 type: test2.py
properties: properties:
test: test test: test
` `
@ -154,12 +154,12 @@ resources:
var roundTripLayout = ` var roundTripLayout = `
resources: resources:
- name: test - name: test
type: test type: test.py
properties: properties:
test: test test: test
resources: resources:
- name: test2 - name: test2
type: test2 type: test2.py
properties: properties:
test: test test: test
` `
@ -175,7 +175,7 @@ resources:
var roundTripLayout2 = ` var roundTripLayout2 = `
resources: resources:
- name: test2 - name: test2
type: test2 type: test2.py
properties: properties:
test: test test: test
resources: resources:
@ -195,12 +195,12 @@ config:
layout: layout:
resources: resources:
- name: test - name: test
type: test type: test.py
properties: properties:
test: test test: test
resources: resources:
- name: test2 - name: test2
type: test2 type: test2.py
properties: properties:
test: test test: test
resources: resources:
@ -251,7 +251,7 @@ func TestExpandTemplate(t *testing.T) {
roundTripHandler, roundTripHandler,
&mockResolver{[][]*ImportFile{ &mockResolver{[][]*ImportFile{
{}, {},
{&ImportFile{Name: "test"}}, {&ImportFile{Name: "test.py"}},
}, t}, }, t},
roundTripResponse, roundTripResponse,
}, },

@ -87,11 +87,13 @@ func (tr *typeResolver) ResolveTypes(config *Configuration, imports []*ImportFil
fetched := map[string][]*ImportFile{} fetched := map[string][]*ImportFile{}
toFetch := make([]string, 0, tr.maxUrls) toFetch := make([]string, 0, tr.maxUrls)
for _, r := range config.Resources { for _, r := range config.Resources {
if !Primitives[r.Type] && !existing[r.Type] { // Only fetch HTTP URLs that we haven't already imported.
if util.IsHttpUrl(r.Type) && !existing[r.Type] {
toFetch = append(toFetch, r.Type) toFetch = append(toFetch, r.Type)
fetched[r.Type] = append(fetched[r.Type], &ImportFile{Name: r.Type}) fetched[r.Type] = append(fetched[r.Type], &ImportFile{Name: r.Type})
} }
} }
count := 0 count := 0
for len(toFetch) > 0 { for len(toFetch) > 0 {
//1. Fetch import URL. Exit if no URLs left //1. Fetch import URL. Exit if no URLs left

@ -117,15 +117,15 @@ func TestIncludedImport(t *testing.T) {
var templateSingleURL = ` var templateSingleURL = `
resources: resources:
- name: foo - name: foo
type: my-fake-url type: http://my-fake-url
` `
func TestSingleUrl(t *testing.T) { func TestSingleUrl(t *testing.T) {
finalImports := []*ImportFile{&ImportFile{Name: "my-fake-url", Content: "my-content"}} finalImports := []*ImportFile{&ImportFile{Name: "http://my-fake-url", Content: "my-content"}}
responses := map[string]responseAndError{ responses := map[string]responseAndError{
"my-fake-url": responseAndError{nil, http.StatusOK, "my-content"}, "http://my-fake-url": responseAndError{nil, http.StatusOK, "my-content"},
"my-fake-url.schema": responseAndError{nil, http.StatusNotFound, ""}, "http://my-fake-url.schema": responseAndError{nil, http.StatusNotFound, ""},
} }
test := resolverTestCase{ test := resolverTestCase{
@ -139,7 +139,7 @@ func TestSingleUrl(t *testing.T) {
func TestSingleUrlWith500(t *testing.T) { func TestSingleUrlWith500(t *testing.T) {
responses := map[string]responseAndError{ responses := map[string]responseAndError{
"my-fake-url": responseAndError{nil, http.StatusInternalServerError, "my-content"}, "http://my-fake-url": responseAndError{nil, http.StatusInternalServerError, "my-content"},
} }
test := resolverTestCase{ test := resolverTestCase{
@ -159,16 +159,16 @@ imports:
func TestSingleUrlWithSchema(t *testing.T) { func TestSingleUrlWithSchema(t *testing.T) {
finalImports := []*ImportFile{ finalImports := []*ImportFile{
&ImportFile{Name: "my-fake-url", Content: "my-content"}, &ImportFile{Name: "http://my-fake-url", Content: "my-content"},
&ImportFile{Name: "schema-import", Content: "schema-import"}, &ImportFile{Name: "schema-import", Content: "schema-import"},
&ImportFile{Name: "my-fake-url.schema", Content: schema1}, &ImportFile{Name: "http://my-fake-url.schema", Content: schema1},
} }
responses := map[string]responseAndError{ responses := map[string]responseAndError{
"my-fake-url": responseAndError{nil, http.StatusOK, "my-content"}, "http://my-fake-url": responseAndError{nil, http.StatusOK, "my-content"},
"my-fake-url.schema": responseAndError{nil, http.StatusOK, schema1}, "http://my-fake-url.schema": responseAndError{nil, http.StatusOK, schema1},
"my-next-url": responseAndError{nil, http.StatusOK, "schema-import"}, "my-next-url": responseAndError{nil, http.StatusOK, "schema-import"},
"my-next-url.schema": responseAndError{nil, http.StatusNotFound, ""}, "my-next-url.schema": responseAndError{nil, http.StatusNotFound, ""},
} }
test := resolverTestCase{ test := resolverTestCase{
@ -183,33 +183,33 @@ func TestSingleUrlWithSchema(t *testing.T) {
var templateExceedsMax = ` var templateExceedsMax = `
resources: resources:
- name: foo - name: foo
type: my-fake-url type: http://my-fake-url
- name: foo1 - name: foo1
type: my-fake-url1 type: http://my-fake-url1
- name: foo2 - name: foo2
type: my-fake-url2 type: http://my-fake-url2
- name: foo3 - name: foo3
type: my-fake-url3 type: http://my-fake-url3
- name: foo4 - name: foo4
type: my-fake-url4 type: http://my-fake-url4
- name: foo5 - name: foo5
type: my-fake-url5 type: http://my-fake-url5
` `
func TestTooManyImports(t *testing.T) { func TestTooManyImports(t *testing.T) {
responses := map[string]responseAndError{ responses := map[string]responseAndError{
"my-fake-url": responseAndError{nil, http.StatusOK, "my-content"}, "http://my-fake-url": responseAndError{nil, http.StatusOK, "my-content"},
"my-fake-url.schema": responseAndError{nil, http.StatusNotFound, ""}, "http://my-fake-url.schema": responseAndError{nil, http.StatusNotFound, ""},
"my-fake-url1": responseAndError{nil, http.StatusOK, "my-content"}, "http://my-fake-url1": responseAndError{nil, http.StatusOK, "my-content"},
"my-fake-url1.schema": responseAndError{nil, http.StatusNotFound, ""}, "http://my-fake-url1.schema": responseAndError{nil, http.StatusNotFound, ""},
"my-fake-url2": responseAndError{nil, http.StatusOK, "my-content"}, "http://my-fake-url2": responseAndError{nil, http.StatusOK, "my-content"},
"my-fake-url2.schema": responseAndError{nil, http.StatusNotFound, ""}, "http://my-fake-url2.schema": responseAndError{nil, http.StatusNotFound, ""},
"my-fake-url3": responseAndError{nil, http.StatusOK, "my-content"}, "http://my-fake-url3": responseAndError{nil, http.StatusOK, "my-content"},
"my-fake-url3.schema": responseAndError{nil, http.StatusNotFound, ""}, "http://my-fake-url3.schema": responseAndError{nil, http.StatusNotFound, ""},
"my-fake-url4": responseAndError{nil, http.StatusOK, "my-content"}, "http://my-fake-url4": responseAndError{nil, http.StatusOK, "my-content"},
"my-fake-url4.schema": responseAndError{nil, http.StatusNotFound, ""}, "http://my-fake-url4.schema": responseAndError{nil, http.StatusNotFound, ""},
"my-fake-url5": responseAndError{nil, http.StatusOK, "my-content"}, "http://my-fake-url5": responseAndError{nil, http.StatusOK, "my-content"},
"my-fake-url5.schema": responseAndError{nil, http.StatusNotFound, ""}, "http://my-fake-url5.schema": responseAndError{nil, http.StatusNotFound, ""},
} }
test := resolverTestCase{ test := resolverTestCase{
@ -224,9 +224,9 @@ func TestTooManyImports(t *testing.T) {
var templateSharesImport = ` var templateSharesImport = `
resources: resources:
- name: foo - name: foo
type: my-fake-url type: http://my-fake-url
- name: foo1 - name: foo1
type: my-fake-url1 type: http://my-fake-url1
` `
var schema2 = ` var schema2 = `
@ -237,21 +237,21 @@ imports:
func TestSharedImport(t *testing.T) { func TestSharedImport(t *testing.T) {
finalImports := []*ImportFile{ finalImports := []*ImportFile{
&ImportFile{Name: "my-fake-url", Content: "my-content"}, &ImportFile{Name: "http://my-fake-url", Content: "my-content"},
&ImportFile{Name: "my-fake-url1", Content: "my-content-1"}, &ImportFile{Name: "http://my-fake-url1", Content: "my-content-1"},
&ImportFile{Name: "schema-import", Content: "schema-import"}, &ImportFile{Name: "schema-import", Content: "schema-import"},
&ImportFile{Name: "schema-import-1", Content: "schema-import"}, &ImportFile{Name: "schema-import-1", Content: "schema-import"},
&ImportFile{Name: "my-fake-url.schema", Content: schema1}, &ImportFile{Name: "http://my-fake-url.schema", Content: schema1},
&ImportFile{Name: "my-fake-url1.schema", Content: schema2}, &ImportFile{Name: "http://my-fake-url1.schema", Content: schema2},
} }
responses := map[string]responseAndError{ responses := map[string]responseAndError{
"my-fake-url": responseAndError{nil, http.StatusOK, "my-content"}, "http://my-fake-url": responseAndError{nil, http.StatusOK, "my-content"},
"my-fake-url.schema": responseAndError{nil, http.StatusOK, schema1}, "http://my-fake-url.schema": responseAndError{nil, http.StatusOK, schema1},
"my-fake-url1": responseAndError{nil, http.StatusOK, "my-content-1"}, "http://my-fake-url1": responseAndError{nil, http.StatusOK, "my-content-1"},
"my-fake-url1.schema": responseAndError{nil, http.StatusOK, schema2}, "http://my-fake-url1.schema": responseAndError{nil, http.StatusOK, schema2},
"my-next-url": responseAndError{nil, http.StatusOK, "schema-import"}, "my-next-url": responseAndError{nil, http.StatusOK, "schema-import"},
"my-next-url.schema": responseAndError{nil, http.StatusNotFound, ""}, "my-next-url.schema": responseAndError{nil, http.StatusNotFound, ""},
} }
test := resolverTestCase{ test := resolverTestCase{

@ -17,19 +17,6 @@ import (
"time" "time"
) )
// This map defines the primitives that DM knows how to handle implicitly.
// TODO (iantw): Make these come from the resourcifier(?). Add more as appropriate...
var Primitives = map[string]bool{
"Pod": true,
"ReplicationController": true,
"Service": true,
"Namespace": true,
"Volume": true,
"Endpoints": true,
"PersistentVolumeClaim": true,
"PersistentVolume": true,
}
// SchemaImport represents an import as declared in a schema file. // SchemaImport represents an import as declared in a schema file.
type SchemaImport struct { type SchemaImport struct {
Path string `json:"path"` Path string `json:"path"`

@ -200,3 +200,13 @@ func ToJSONOrError(v interface{}) string {
return string(j) return string(j)
} }
// IsHttpURL returns whether a string is an HTTP URL.
func IsHttpUrl(s string) bool {
u, err := url.Parse(s)
if err != nil {
return false
}
return u.Scheme == "http" || u.Scheme == "https"
}

@ -0,0 +1,23 @@
/*
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 util
import (
"strings"
)
// IsTemplate returns whether a given type is a template.
func IsTemplate(t string) bool {
return strings.HasSuffix(t, ".py") || strings.HasSuffix(t, ".jinja")
}
Loading…
Cancel
Save