Commit 51bbfafc authored by Jack Greenfield's avatar Jack Greenfield

Merge pull request #440 from jackgr/manager

Second round of refactoring for Manager
parents 91a007cf 3da6a66c
This diff is collapsed.
......@@ -43,8 +43,17 @@ type Expander interface {
ExpandTemplate(t *common.Template) (*ExpandedTemplate, error)
}
// TODO: Remove mockResolver when type resolver is completely excised
type mockResolver struct {
}
func (r *mockResolver) ResolveTypes(c *common.Configuration, i []*common.ImportFile) ([]*common.ImportFile, error) {
return nil, nil
}
// NewExpander returns a new initialized Expander.
func NewExpander(url string, tr TypeResolver) Expander {
func NewExpander(url string) Expander {
tr := &mockResolver{}
return &expander{url, tr}
}
......@@ -53,6 +62,12 @@ type expander struct {
typeResolver TypeResolver
}
// 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)
}
func (e *expander) getBaseURL() string {
return fmt.Sprintf("%s/expand", e.expanderURL)
}
......
......@@ -32,21 +32,6 @@ import (
"github.com/ghodss/yaml"
)
type mockResolver struct {
responses [][]*common.ImportFile
t *testing.T
}
func (r *mockResolver) ResolveTypes(c *common.Configuration, i []*common.ImportFile) ([]*common.ImportFile, error) {
if len(r.responses) < 1 {
return nil, nil
}
ret := r.responses[0]
r.responses = r.responses[1:]
return ret, nil
}
var validTemplateTestCaseData = common.Template{
Name: "TestTemplate",
Content: string(validContentTestCaseData),
......@@ -232,7 +217,6 @@ type ExpanderTestCase struct {
Description string
Error string
Handler func(w http.ResponseWriter, r *http.Request)
Resolver TypeResolver
ValidResponse *ExpandedTemplate
}
......@@ -247,33 +231,21 @@ func TestExpandTemplate(t *testing.T) {
"expect success for ExpandTemplate",
"",
expanderSuccessHandler,
&mockResolver{},
getValidResponse(t, "expect success for ExpandTemplate"),
},
{
"expect error for ExpandTemplate",
"cannot expand template",
expanderErrorHandler,
&mockResolver{},
nil,
},
{
"expect success for ExpandTemplate with two expansions",
"",
roundTripHandler,
&mockResolver{[][]*common.ImportFile{
{},
{&common.ImportFile{Name: "test.py"}},
}, t},
roundTripResponse,
},
}
for _, etc := range tests {
ts := httptest.NewServer(http.HandlerFunc(etc.Handler))
defer ts.Close()
expander := NewExpander(ts.URL, etc.Resolver)
expander := NewExpander(ts.URL)
actualResponse, err := expander.ExpandTemplate(&validTemplateTestCaseData)
if err != nil {
message := err.Error()
......
This diff is collapsed.
......@@ -17,13 +17,13 @@ limitations under the License.
package manager
import (
"github.com/kubernetes/helm/pkg/common"
"github.com/kubernetes/helm/pkg/repo"
"errors"
"reflect"
"strings"
"testing"
"github.com/kubernetes/helm/pkg/common"
"github.com/kubernetes/helm/pkg/registry"
)
var template = common.Template{Name: "test", Content: "test"}
......@@ -128,17 +128,17 @@ func (deployer *deployerStub) PutConfiguration(configuration *common.Configurati
}
type repositoryStub struct {
FailListDeployments bool
Created []string
ManifestAdd map[string]*common.Manifest
ManifestSet map[string]*common.Manifest
Deleted []string
GetValid []string
TypeInstances map[string][]string
TypeInstancesCleared bool
GetTypeInstancesCalled bool
ListTypesCalled bool
DeploymentStates []*common.DeploymentState
FailListDeployments bool
Created []string
ManifestAdd map[string]*common.Manifest
ManifestSet map[string]*common.Manifest
Deleted []string
GetValid []string
ChartInstances map[string][]string
ChartInstancesCleared bool
GetChartInstancesCalled bool
ListTypesCalled bool
DeploymentStates []*common.DeploymentState
}
func (repository *repositoryStub) reset() {
......@@ -148,9 +148,9 @@ func (repository *repositoryStub) reset() {
repository.ManifestSet = make(map[string]*common.Manifest)
repository.Deleted = make([]string, 0)
repository.GetValid = make([]string, 0)
repository.TypeInstances = make(map[string][]string)
repository.TypeInstancesCleared = false
repository.GetTypeInstancesCalled = false
repository.ChartInstances = make(map[string][]string)
repository.ChartInstancesCleared = false
repository.GetChartInstancesCalled = false
repository.ListTypesCalled = false
repository.DeploymentStates = []*common.DeploymentState{}
}
......@@ -233,26 +233,26 @@ func (repository *repositoryStub) GetLatestManifest(d string) (*common.Manifest,
}
// Types.
func (repository *repositoryStub) ListTypes() ([]string, error) {
func (repository *repositoryStub) ListCharts() ([]string, error) {
repository.ListTypesCalled = true
return []string{}, nil
}
func (repository *repositoryStub) GetTypeInstances(t string) ([]*common.TypeInstance, error) {
repository.GetTypeInstancesCalled = true
return []*common.TypeInstance{}, nil
func (repository *repositoryStub) GetChartInstances(t string) ([]*common.ChartInstance, error) {
repository.GetChartInstancesCalled = true
return []*common.ChartInstance{}, nil
}
func (repository *repositoryStub) ClearTypeInstancesForDeployment(d string) error {
repository.TypeInstancesCleared = true
func (repository *repositoryStub) ClearChartInstancesForDeployment(d string) error {
repository.ChartInstancesCleared = true
return nil
}
func (repository *repositoryStub) AddTypeInstances(is map[string][]*common.TypeInstance) error {
func (repository *repositoryStub) AddChartInstances(is map[string][]*common.ChartInstance) error {
for t, instances := range is {
for _, instance := range instances {
d := instance.Deployment
repository.TypeInstances[d] = append(repository.TypeInstances[d], t)
repository.ChartInstances[d] = append(repository.ChartInstances[d], t)
}
}
......@@ -264,10 +264,10 @@ func (repository *repositoryStub) Close() {}
var testExpander = &expanderStub{}
var testRepository = newRepositoryStub()
var testDeployer = newDeployerStub()
var testRegistryService = registry.NewInmemRegistryService()
var testCredentialProvider = registry.NewInmemCredentialProvider()
var testProvider = registry.NewRegistryProvider(nil, registry.NewTestGithubRegistryProvider("", nil), registry.NewTestGCSRegistryProvider("", nil), testCredentialProvider)
var testManager = NewManager(testExpander, testDeployer, testRepository, testProvider, testRegistryService, testCredentialProvider)
var testRepoService = repo.NewInmemRepoService()
var testCredentialProvider = repo.NewInmemCredentialProvider()
var testProvider = repo.NewRepoProvider(nil, repo.NewGCSRepoProvider(testCredentialProvider), testCredentialProvider)
var testManager = NewManager(testExpander, testDeployer, testRepository, testProvider, testRepoService, testCredentialProvider)
func TestListDeployments(t *testing.T) {
testRepository.reset()
......@@ -363,12 +363,12 @@ func TestCreateDeployment(t *testing.T) {
t.Fatal("CreateDeployment success did not mark deployment as deployed")
}
if !testRepository.TypeInstancesCleared {
if !testRepository.ChartInstancesCleared {
t.Fatal("Repository did not clear type instances during creation")
}
if !reflect.DeepEqual(testRepository.TypeInstances, typeInstMap) {
t.Fatalf("Unexpected type instances after CreateDeployment: %s", testRepository.TypeInstances)
if !reflect.DeepEqual(testRepository.ChartInstances, typeInstMap) {
t.Fatalf("Unexpected type instances after CreateDeployment: %s", testRepository.ChartInstances)
}
}
......@@ -397,7 +397,7 @@ func TestCreateDeploymentCreationFailure(t *testing.T) {
"Received: %v, %s. Expected: %s, %s.", d, err, "nil", errTest)
}
if testRepository.TypeInstancesCleared {
if testRepository.ChartInstancesCleared {
t.Fatal("Unexpected change to type instances during CreateDeployment failure.")
}
}
......@@ -437,7 +437,7 @@ func TestCreateDeploymentCreationResourceFailure(t *testing.T) {
"Received: %v, %v. Expected: %v, %v.", d, err, &deployment, "nil")
}
if !testRepository.TypeInstancesCleared {
if !testRepository.ChartInstancesCleared {
t.Fatal("Repository did not clear type instances during creation")
}
}
......@@ -486,7 +486,7 @@ func TestDeleteDeploymentForget(t *testing.T) {
}
}
if !testRepository.TypeInstancesCleared {
if !testRepository.ChartInstancesCleared {
t.Fatal("Expected type instances to be cleared during DeleteDeployment.")
}
}
......@@ -521,29 +521,29 @@ func TestExpand(t *testing.T) {
func TestListTypes(t *testing.T) {
testRepository.reset()
testManager.ListTypes()
testManager.ListCharts()
if !testRepository.ListTypesCalled {
t.Fatal("expected repository ListTypes() call.")
t.Fatal("expected repository ListCharts() call.")
}
}
func TestListInstances(t *testing.T) {
testRepository.reset()
testManager.ListInstances("all")
testManager.ListChartInstances("all")
if !testRepository.GetTypeInstancesCalled {
t.Fatal("expected repository GetTypeInstances() call.")
if !testRepository.GetChartInstancesCalled {
t.Fatal("expected repository GetChartInstances() call.")
}
}
// TODO(jackgr): Implement TestListRegistryTypes
func TestListRegistryTypes(t *testing.T) {
// TODO(jackgr): Implement TestListRepoCharts
func TestListRepoCharts(t *testing.T) {
/*
types, err := testManager.ListRegistryTypes("", nil)
types, err := testManager.ListRepoCharts("", nil)
if err != nil {
t.Fatalf("cannot list registry types: %s", err)
t.Fatalf("cannot list repository types: %s", err)
}
*/
}
......@@ -551,7 +551,7 @@ func TestListRegistryTypes(t *testing.T) {
// TODO(jackgr): Implement TestGetDownloadURLs
func TestGetDownloadURLs(t *testing.T) {
/*
urls, err := testManager.GetDownloadURLs("", registry.Type{})
urls, err := testManager.GetDownloadURLs("", repo.Type{})
if err != nil {
t.Fatalf("cannot list get download urls: %s", err)
}
......
/*
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
}
This diff is collapsed.
......@@ -44,7 +44,7 @@ type pManifest struct {
type pInstance struct {
ID string `bson:"_id"`
common.TypeInstance
common.ChartInstance
}
type pRepository struct {
......@@ -428,8 +428,8 @@ func (r *pRepository) removeManifestsForDeployment(d *common.Deployment) error {
return nil
}
// ListTypes returns all types known from existing instances.
func (r *pRepository) ListTypes() ([]string, error) {
// ListCharts returns all types known from existing instances.
func (r *pRepository) ListCharts() ([]string, error) {
var result []string
if err := r.Instances.Find(nil).Distinct("typeinstance.type", &result); err != nil {
return nil, fmt.Errorf("cannot list type instances: %s", err)
......@@ -438,9 +438,9 @@ func (r *pRepository) ListTypes() ([]string, error) {
return result, nil
}
// GetTypeInstances returns all instances of a given type. If typeName is empty
// GetChartInstances returns all instances of a given type. If typeName is empty
// or equal to "all", returns all instances of all types.
func (r *pRepository) GetTypeInstances(typeName string) ([]*common.TypeInstance, error) {
func (r *pRepository) GetChartInstances(typeName string) ([]*common.ChartInstance, error) {
query := bson.M{"typeinstance.type": typeName}
if typeName == "" || typeName == "all" {
query = nil
......@@ -451,17 +451,17 @@ func (r *pRepository) GetTypeInstances(typeName string) ([]*common.TypeInstance,
return nil, fmt.Errorf("cannot get instances of type %s: %s", typeName, err)
}
instances := []*common.TypeInstance{}
instances := []*common.ChartInstance{}
for _, pi := range result {
instances = append(instances, &pi.TypeInstance)
instances = append(instances, &pi.ChartInstance)
}
return instances, nil
}
// ClearTypeInstancesForDeployment deletes all type instances associated with the given
// ClearChartInstancesForDeployment deletes all type instances associated with the given
// deployment from the repository.
func (r *pRepository) ClearTypeInstancesForDeployment(deploymentName string) error {
func (r *pRepository) ClearChartInstancesForDeployment(deploymentName string) error {
if deploymentName != "" {
query := bson.M{"typeinstance.deployment": deploymentName}
if _, err := r.Instances.RemoveAll(query); err != nil {
......@@ -472,12 +472,12 @@ func (r *pRepository) ClearTypeInstancesForDeployment(deploymentName string) err
return nil
}
// AddTypeInstances adds the supplied type instances to the repository.
func (r *pRepository) AddTypeInstances(instances map[string][]*common.TypeInstance) error {
// AddChartInstances adds the supplied type instances to the repository.
func (r *pRepository) AddChartInstances(instances map[string][]*common.ChartInstance) error {
for _, is := range instances {
for _, i := range is {
key := fmt.Sprintf("%s.%s.%s", i.Deployment, i.Type, i.Name)
wrapper := pInstance{ID: key, TypeInstance: *i}
wrapper := pInstance{ID: key, ChartInstance: *i}
if err := r.Instances.Insert(&wrapper); err != nil {
return fmt.Errorf("cannot insert type instance %v: %s", wrapper, err)
}
......
......@@ -102,9 +102,9 @@ func TestRepositoryDeleteDeploymentWorksForget(t *testing.T) {
}
}
func TestRepositoryTypeInstances(t *testing.T) {
func TestRepositoryChartInstances(t *testing.T) {
if r := createRepository(); r != nil {
defer resetRepository(t, r)
repository.TestRepositoryTypeInstances(t, r)
repository.TestRepositoryChartInstances(t, r)
}
}
......@@ -40,10 +40,10 @@ type Repository interface {
GetLatestManifest(deploymentName string) (*common.Manifest, error)
// Types.
ListTypes() ([]string, error)
GetTypeInstances(typeName string) ([]*common.TypeInstance, error)
ClearTypeInstancesForDeployment(deploymentName string) error
AddTypeInstances(instances map[string][]*common.TypeInstance) error
ListCharts() ([]string, error)
GetChartInstances(chartName string) ([]*common.ChartInstance, error)
ClearChartInstancesForDeployment(deploymentName string) error
AddChartInstances(instances map[string][]*common.ChartInstance) error
Close()
}
......@@ -210,9 +210,9 @@ func TestRepositoryDeleteDeploymentWorksForget(t *testing.T, r Repository) {
}
}
// TestRepositoryTypeInstances checks that type instances can be listed and retrieved successfully.
func TestRepositoryTypeInstances(t *testing.T, r Repository) {
d1Map := map[string][]*common.TypeInstance{
// TestRepositoryChartInstances checks that type instances can be listed and retrieved successfully.
func TestRepositoryChartInstances(t *testing.T, r Repository) {
d1Map := map[string][]*common.ChartInstance{
"t1": {
{
Name: "i1",
......@@ -224,7 +224,7 @@ func TestRepositoryTypeInstances(t *testing.T, r Repository) {
},
}
d2Map := map[string][]*common.TypeInstance{
d2Map := map[string][]*common.ChartInstance{
"t2": {
{
Name: "i2",
......@@ -236,7 +236,7 @@ func TestRepositoryTypeInstances(t *testing.T, r Repository) {
},
}
d3Map := map[string][]*common.TypeInstance{
d3Map := map[string][]*common.ChartInstance{
"t2": {
{
Name: "i3",
......@@ -248,7 +248,7 @@ func TestRepositoryTypeInstances(t *testing.T, r Repository) {
},
}
instances, err := r.GetTypeInstances("noinstances")
instances, err := r.GetChartInstances("noinstances")
if err != nil {
t.Fatal(err)
}
......@@ -257,7 +257,7 @@ func TestRepositoryTypeInstances(t *testing.T, r Repository) {
t.Fatalf("expected no instances: %v", instances)
}
types, err := r.ListTypes()
types, err := r.ListCharts()
if err != nil {
t.Fatal(err)
}
......@@ -266,11 +266,11 @@ func TestRepositoryTypeInstances(t *testing.T, r Repository) {
t.Fatalf("expected no types: %v", types)
}
r.AddTypeInstances(d1Map)
r.AddTypeInstances(d2Map)
r.AddTypeInstances(d3Map)
r.AddChartInstances(d1Map)
r.AddChartInstances(d2Map)
r.AddChartInstances(d3Map)
instances, err = r.GetTypeInstances("unknowntype")
instances, err = r.GetChartInstances("unknowntype")
if err != nil {
t.Fatal(err)
}
......@@ -279,7 +279,7 @@ func TestRepositoryTypeInstances(t *testing.T, r Repository) {
t.Fatalf("expected no instances: %v", instances)
}
instances, err = r.GetTypeInstances("t1")
instances, err = r.GetChartInstances("t1")
if err != nil {
t.Fatal(err)
}
......@@ -288,7 +288,7 @@ func TestRepositoryTypeInstances(t *testing.T, r Repository) {
t.Fatalf("expected one instance: %v", instances)
}
instances, err = r.GetTypeInstances("t2")
instances, err = r.GetChartInstances("t2")
if err != nil {
t.Fatal(err)
}
......@@ -297,7 +297,7 @@ func TestRepositoryTypeInstances(t *testing.T, r Repository) {
t.Fatalf("expected two instances: %v", instances)
}
instances, err = r.GetTypeInstances("all")
instances, err = r.GetChartInstances("all")
if err != nil {
t.Fatal(err)
}
......@@ -306,7 +306,7 @@ func TestRepositoryTypeInstances(t *testing.T, r Repository) {
t.Fatalf("expected three total instances: %v", instances)
}
types, err = r.ListTypes()
types, err = r.ListCharts()
if err != nil {
t.Fatal(err)
}
......@@ -315,12 +315,12 @@ func TestRepositoryTypeInstances(t *testing.T, r Repository) {
t.Fatalf("expected two total types: %v", types)
}
err = r.ClearTypeInstancesForDeployment("d1")
err = r.ClearChartInstancesForDeployment("d1")
if err != nil {
t.Fatal(err)
}
instances, err = r.GetTypeInstances("t1")
instances, err = r.GetChartInstances("t1")
if err != nil {
t.Fatal(err)
}
......@@ -329,7 +329,7 @@ func TestRepositoryTypeInstances(t *testing.T, r Repository) {
t.Fatalf("expected no instances after clear: %v", instances)
}
types, err = r.ListTypes()
types, err = r.ListCharts()
if err != nil {
t.Fatal(err)
}
......
......@@ -27,16 +27,16 @@ import (
"github.com/kubernetes/helm/pkg/common"
)
// deploymentTypeInstanceMap stores type instances mapped by deployment name.
// deploymentChartInstanceMap stores type instances mapped by deployment name.
// This allows for simple updating and deleting of per-deployment instances
// when deployments are created/updated/deleted.
type deploymentTypeInstanceMap map[string][]*common.TypeInstance
type deploymentChartInstanceMap map[string][]*common.ChartInstance
type tRepository struct {
sync.RWMutex
deployments map[string]common.Deployment
manifests map[string]map[string]*common.Manifest
instances map[string]deploymentTypeInstanceMap
instances map[string]deploymentChartInstanceMap
}
// NewRepository returns a new transient repository. Its lifetime is coupled
......@@ -46,14 +46,14 @@ func NewRepository() repository.Repository {
return &tRepository{
deployments: make(map[string]common.Deployment, 0),
manifests: make(map[string]map[string]*common.Manifest, 0),
instances: make(map[string]deploymentTypeInstanceMap, 0),
instances: make(map[string]deploymentChartInstanceMap, 0),
}
}
func (r *tRepository) Close() {
r.deployments = make(map[string]common.Deployment, 0)
r.manifests = make(map[string]map[string]*common.Manifest, 0)
r.instances = make(map[string]deploymentTypeInstanceMap, 0)
r.instances = make(map[string]deploymentChartInstanceMap, 0)
}
// ListDeployments returns of all of the deployments in the repository.
......@@ -258,8 +258,8 @@ func (r *tRepository) GetLatestManifest(deploymentName string) (*common.Manifest
return r.getManifestForDeployment(deploymentName, d.LatestManifest)
}
// ListTypes returns all types known from existing instances.
func (r *tRepository) ListTypes() ([]string, error) {
// ListCharts returns all types known from existing instances.
func (r *tRepository) ListCharts() ([]string, error) {
var keys []string
for k := range r.instances {
keys = append(keys, k)
......@@ -268,10 +268,10 @@ func (r *tRepository) ListTypes() ([]string, error) {
return keys, nil
}
// GetTypeInstances returns all instances of a given type. If type is empty,
// GetChartInstances returns all instances of a given type. If type is empty,
// returns all instances for all types.
func (r *tRepository) GetTypeInstances(typeName string) ([]*common.TypeInstance, error) {
var instances []*common.TypeInstance
func (r *tRepository) GetChartInstances(typeName string) ([]*common.ChartInstance, error) {
var instances []*common.ChartInstance
for t, dInstMap := range r.instances {
if t == typeName || typeName == "" || typeName == "all" {
for _, i := range dInstMap {
......@@ -283,9 +283,9 @@ func (r *tRepository) GetTypeInstances(typeName string) ([]*common.TypeInstance,
return instances, nil
}
// ClearTypeInstancesForDeployment deletes all type instances associated with the given
// ClearChartInstancesForDeployment deletes all type instances associated with the given
// deployment from the repository.
func (r *tRepository) ClearTypeInstancesForDeployment(deploymentName string) error {
func (r *tRepository) ClearChartInstancesForDeployment(deploymentName string) error {
r.Lock()
defer r.Unlock()
......@@ -299,22 +299,22 @@ func (r *tRepository) ClearTypeInstancesForDeployment(deploymentName string) err
return nil
}
// AddTypeInstances adds the supplied type instances to the repository.
func (r *tRepository) AddTypeInstances(instances map[string][]*common.TypeInstance) error {
// AddChartInstances adds the supplied type instances to the repository.
func (r *tRepository) AddChartInstances(instances map[string][]*common.ChartInstance) error {
r.Lock()
defer r.Unlock()
// Add instances to the appropriate type and deployment maps.
for t, is := range instances {
if r.instances[t] == nil {
r.instances[t] = make(deploymentTypeInstanceMap)
r.instances[t] = make(deploymentChartInstanceMap)
}
tmap := r.instances[t]
for _, instance := range is {
deployment := instance.Deployment
if tmap[deployment] == nil {
tmap[deployment] = make([]*common.TypeInstance, 0)
tmap[deployment] = make([]*common.ChartInstance, 0)
}
tmap[deployment] = append(tmap[deployment], instance)
......
......@@ -50,6 +50,6 @@ func TestRepositoryDeleteDeploymentWorksForget(t *testing.T) {
repository.TestRepositoryDeleteDeploymentWorksForget(t, NewRepository())
}
func TestRepositoryTypeInstances(t *testing.T) {
repository.TestRepositoryTypeInstances(t, NewRepository())
func TestRepositoryChartInstances(t *testing.T) {
repository.TestRepositoryChartInstances(t, NewRepository())
}
......@@ -2,8 +2,8 @@ package router
import (
"github.com/kubernetes/helm/cmd/manager/manager"
"github.com/kubernetes/helm/pkg/common"
helmhttp "github.com/kubernetes/helm/pkg/httputil"
"github.com/kubernetes/helm/pkg/repo"
)
// Config holds the global configuration parameters passed into the router.
......@@ -47,5 +47,5 @@ type Context struct {
// Manager is a helm/manager/manager.Manager
Manager manager.Manager
Encoder helmhttp.Encoder
CredentialProvider common.CredentialProvider
CredentialProvider repo.ICredentialProvider
}
......@@ -2,13 +2,13 @@ package main
import (
"net/http/httptest"
"net/url"
"regexp"
"github.com/kubernetes/helm/cmd/manager/router"
"github.com/kubernetes/helm/pkg/chart"
"github.com/kubernetes/helm/pkg/common"
"github.com/kubernetes/helm/pkg/httputil"
"github.com/kubernetes/helm/pkg/registry"
"github.com/kubernetes/helm/pkg/repo"
)
// httpHarness is a simple test server fixture.
......@@ -26,13 +26,13 @@ func httpHarness(c *router.Context, route string, fn router.HandlerFunc) *httpte
// This creates a stub context with the following properties:
// - Config is initialized to empty values
// - Encoder is initialized to httputil.DefaultEncoder
// - CredentialProvider is initialized to registry.InmemCredentialProvider
// - CredentialProvider is initialized to repo.InmemCredentialProvider
// - Manager is initialized to mockManager.
func stubContext() *router.Context {
return &router.Context{
Config: &router.Config{},
Manager: &mockManager{},
CredentialProvider: registry.NewInmemCredentialProvider(),
CredentialProvider: repo.NewInmemCredentialProvider(),
Encoder: httputil.DefaultEncoder,
}
}
......@@ -71,20 +71,24 @@ func (m *mockManager) Expand(t *common.Template) (*common.Manifest, error) {
return &common.Manifest{}, nil
}
func (m *mockManager) ListTypes() ([]string, error) {
func (m *mockManager) ListCharts() ([]string, error) {
return []string{}, nil
}
func (m *mockManager) ListInstances(typeName string) ([]*common.TypeInstance, error) {
return []*common.TypeInstance{}, nil
func (m *mockManager) ListChartInstances(chartName string) ([]*common.ChartInstance, error) {
return []*common.ChartInstance{}, nil
}
func (m *mockManager) GetRegistryForType(typeName string) (string, error) {
func (m *mockManager) GetRepoForChart(chartName string) (string, error) {
return "", nil
}
func (m *mockManager) GetMetadataForType(typeName string) (string, error) {
return "", nil
func (m *mockManager) GetMetadataForChart(chartName string) (*chart.Chartfile, error) {
return nil, nil
}
func (m *mockManager) GetChart(chartName string) (*chart.Chart, error) {
return nil, nil
}
func (m *mockManager) AddChartRepo(name string) error {
......@@ -99,32 +103,31 @@ func (m *mockManager) RemoveChartRepo(name string) error {
return nil
}
func (m *mockManager) ListRegistries() ([]*common.Registry, error) {
return []*common.Registry{}, nil
func (m *mockManager) ListRepos() ([]*repo.Repo, error) {
return []*repo.Repo{}, nil
}
func (m *mockManager) CreateRegistry(pr *common.Registry) error {
func (m *mockManager) CreateRepo(pr *repo.Repo) error {
return nil
}
func (m *mockManager) GetRegistry(name string) (*common.Registry, error) {
return &common.Registry{}, nil
func (m *mockManager) GetRepo(name string) (*repo.Repo, error) {
return &repo.Repo{}, nil
}
func (m *mockManager) DeleteRegistry(name string) error {
func (m *mockManager) DeleteRepo(name string) error {
return nil
}
func (m *mockManager) ListRegistryTypes(registryName string, regex *regexp.Regexp) ([]registry.Type, error) {
return []registry.Type{}, nil
}
func (m *mockManager) GetDownloadURLs(registryName string, t registry.Type) ([]*url.URL, error) {
return []*url.URL{}, nil
func (m *mockManager) ListRepoCharts(repoName string, regex *regexp.Regexp) ([]string, error) {
return []string{}, nil
}
func (m *mockManager) GetFile(registryName string, url string) (string, error) {
return "", nil
func (m *mockManager) GetChartForRepo(repoName, chartName string) (*chart.Chart, error) {
return nil, nil
}
func (m *mockManager) CreateCredential(name string, c *common.RegistryCredential) error {
func (m *mockManager) CreateCredential(name string, c *repo.Credential) error {
return nil
}
func (m *mockManager) GetCredential(name string) (*common.RegistryCredential, error) {
return &common.RegistryCredential{}, nil
func (m *mockManager) GetCredential(name string) (*repo.Credential, error) {
return &repo.Credential{}, nil
}
......@@ -170,9 +170,9 @@ type Resource struct {
State *ResourceState `json:"state,omitempty"`
}
// TypeInstance defines the metadata for an instantiation of a template type
// ChartInstance defines the metadata for an instantiation of a template type
// in a deployment.
type TypeInstance struct {
type ChartInstance struct {
Name string `json:"name"` // instance name
Type string `json:"type"` // instance type
Deployment string `json:"deployment"` // deployment name
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment