diff --git a/cmd/manager/manager/manager.go b/cmd/manager/manager/manager.go index 515396bf9..d1f67de3d 100644 --- a/cmd/manager/manager/manager.go +++ b/cmd/manager/manager/manager.go @@ -19,15 +19,13 @@ package manager import ( "fmt" "log" - "net/url" "regexp" - "strings" "time" "github.com/kubernetes/helm/cmd/manager/repository" + "github.com/kubernetes/helm/pkg/chart" "github.com/kubernetes/helm/pkg/common" - "github.com/kubernetes/helm/pkg/registry" - "github.com/kubernetes/helm/pkg/util" + "github.com/kubernetes/helm/pkg/repo" ) // Manager manages a persistent set of Deployments. @@ -44,26 +42,20 @@ type Manager interface { GetManifest(deploymentName string, manifest string) (*common.Manifest, error) Expand(t *common.Template) (*common.Manifest, error) - // Types - ListTypes() ([]string, error) - ListInstances(typeName string) ([]*common.TypeInstance, error) - GetRegistryForType(typeName string) (string, error) - GetMetadataForType(typeName string) (string, error) + // Charts + ListCharts() ([]string, error) + ListChartInstances(chartName string) ([]*common.ChartInstance, error) + GetRepoForChart(chartName string) (string, error) + GetMetadataForChart(chartName string) (*chart.Chartfile, error) + GetChart(chartName string) (*chart.Chart, error) - // Registries - ListRegistries() ([]*common.Registry, error) - CreateRegistry(pr *common.Registry) error - GetRegistry(name string) (*common.Registry, error) - DeleteRegistry(name string) error - - // Registry Types - ListRegistryTypes(registryName string, regex *regexp.Regexp) ([]registry.Type, error) - GetDownloadURLs(registryName string, t registry.Type) ([]*url.URL, error) - GetFile(registryName string, url string) (string, error) + // Repo Charts + ListRepoCharts(repoName string, regex *regexp.Regexp) ([]string, error) + GetChartForRepo(repoName, chartName string) (*chart.Chart, error) // Credentials - CreateCredential(name string, c *common.RegistryCredential) error - GetCredential(name string) (*common.RegistryCredential, error) + CreateCredential(name string, c *repo.Credential) error + GetCredential(name string) (*repo.Credential, error) // Chart Repositories ListChartRepos() ([]string, error) @@ -72,24 +64,23 @@ type Manager interface { } type manager struct { - expander Expander - deployer Deployer - repository repository.Repository - registryProvider registry.RegistryProvider - service common.RegistryService + expander Expander + deployer Deployer + repository repository.Repository + repoProvider repo.IRepoProvider + service repo.IRepoService //TODO: add chart repo service - credentialProvider common.CredentialProvider + credentialProvider repo.ICredentialProvider } // NewManager returns a new initialized Manager. func NewManager(expander Expander, deployer Deployer, repository repository.Repository, - registryProvider registry.RegistryProvider, - service common.RegistryService, - //TODO: add chart repo service - credentialProvider common.CredentialProvider) Manager { - return &manager{expander, deployer, repository, registryProvider, service, credentialProvider} + repoProvider repo.IRepoProvider, + service repo.IRepoService, + credentialProvider repo.ICredentialProvider) Manager { + return &manager{expander, deployer, repository, repoProvider, service, credentialProvider} } // ListDeployments returns the list of deployments @@ -190,7 +181,7 @@ func (m *manager) CreateDeployment(t *common.Template) (*common.Deployment, erro } // Finally update the type instances for this deployment. - m.setTypeInstances(t.Name, manifest.Name, manifest.Layout) + m.setChartInstances(t.Name, manifest.Name, manifest.Layout) return m.repository.GetValidDeployment(t.Name) } @@ -210,20 +201,20 @@ func (m *manager) createManifest(t *common.Template) (*common.Manifest, error) { }, nil } -func (m *manager) setTypeInstances(deploymentName string, manifestName string, layout *common.Layout) { - m.repository.ClearTypeInstancesForDeployment(deploymentName) +func (m *manager) setChartInstances(deploymentName string, manifestName string, layout *common.Layout) { + m.repository.ClearChartInstancesForDeployment(deploymentName) - instances := make(map[string][]*common.TypeInstance) + instances := make(map[string][]*common.ChartInstance) for i, r := range layout.Resources { - addTypeInstances(&instances, r, deploymentName, manifestName, fmt.Sprintf("$.resources[%d]", i)) + addChartInstances(&instances, r, deploymentName, manifestName, fmt.Sprintf("$.resources[%d]", i)) } - m.repository.AddTypeInstances(instances) + m.repository.AddChartInstances(instances) } -func addTypeInstances(instances *map[string][]*common.TypeInstance, r *common.LayoutResource, deploymentName string, manifestName string, jsonPath string) { +func addChartInstances(instances *map[string][]*common.ChartInstance, r *common.LayoutResource, deploymentName string, manifestName string, jsonPath string) { // Add this resource. - inst := &common.TypeInstance{ + inst := &common.ChartInstance{ Name: r.Name, Type: r.Type, Deployment: deploymentName, @@ -235,7 +226,7 @@ func addTypeInstances(instances *map[string][]*common.TypeInstance, r *common.La // Add all sub resources if they exist. for i, sr := range r.Resources { - addTypeInstances(instances, sr, deploymentName, manifestName, fmt.Sprintf("%s.resources[%d]", jsonPath, i)) + addChartInstances(instances, sr, deploymentName, manifestName, fmt.Sprintf("%s.resources[%d]", jsonPath, i)) } } @@ -286,7 +277,7 @@ func (m *manager) DeleteDeployment(name string, forget bool) (*common.Deployment } // Finally remove the type instances for this deployment. - m.repository.ClearTypeInstancesForDeployment(name) + m.repository.ClearChartInstancesForDeployment(name) return d, nil } @@ -319,7 +310,7 @@ func (m *manager) PutDeployment(name string, t *common.Template) (*common.Deploy } // Finally update the type instances for this deployment. - m.setTypeInstances(t.Name, manifest.Name, manifest.Layout) + m.setChartInstances(t.Name, manifest.Name, manifest.Layout) return m.repository.GetValidDeployment(t.Name) } @@ -336,59 +327,47 @@ func (m *manager) Expand(t *common.Template) (*common.Manifest, error) { }, nil } -func (m *manager) ListTypes() ([]string, error) { - return m.repository.ListTypes() +func (m *manager) ListCharts() ([]string, error) { + return m.repository.ListCharts() } -func (m *manager) ListInstances(typeName string) ([]*common.TypeInstance, error) { - return m.repository.GetTypeInstances(typeName) +func (m *manager) ListChartInstances(chartName string) ([]*common.ChartInstance, error) { + return m.repository.GetChartInstances(chartName) } -// GetRegistryForType returns the registry where a type resides. -func (m *manager) GetRegistryForType(typeName string) (string, error) { - _, r, err := registry.GetDownloadURLs(m.registryProvider, typeName) +// GetRepoForChart returns the repository where a chart resides. +func (m *manager) GetRepoForChart(chartName string) (string, error) { + _, r, err := m.repoProvider.GetChartByReference(chartName) if err != nil { return "", err } - return r.GetRegistryName(), nil + return r.GetName(), nil } -// GetMetadataForType returns the metadata for type. -func (m *manager) GetMetadataForType(typeName string) (string, error) { - URLs, r, err := registry.GetDownloadURLs(m.registryProvider, typeName) +// GetMetadataForChart returns the metadata for a chart. +func (m *manager) GetMetadataForChart(chartName string) (*chart.Chartfile, error) { + c, _, err := m.repoProvider.GetChartByReference(chartName) if err != nil { - return "", err - } - - if len(URLs) < 1 { - return "", nil + return nil, err } - // If it's a chart, we want the provenance file - fPath := URLs[0] - if !strings.Contains(fPath, ".prov") { - // It's not a chart, so we want the schema - fPath += ".schema" - } + return c.Chartfile(), nil +} - metadata, err := getFileFromRegistry(fPath, r) +// GetChart returns a chart. +func (m *manager) GetChart(chartName string) (*chart.Chart, error) { + c, _, err := m.repoProvider.GetChartByReference(chartName) if err != nil { - return "", fmt.Errorf("cannot get metadata for type (%s): %s", typeName, err) + return nil, err } - return metadata, nil -} - -// ListRegistries returns the list of registries -func (m *manager) ListRegistries() ([]*common.Registry, error) { - return m.service.List() + return c, nil } // ListChartRepos returns the list of chart repositories func (m *manager) ListChartRepos() ([]string, error) { - //TODO: implement - return nil, nil + return m.service.List() } // AddChartRepo adds a chart repository to list of available chart repositories @@ -399,22 +378,17 @@ func (m *manager) AddChartRepo(name string) error { // RemoveChartRepo removes a chart repository to list of available chart repositories func (m *manager) RemoveChartRepo(name string) error { - //TODO: implement - return nil + return m.service.Delete(name) } -func (m *manager) CreateRegistry(pr *common.Registry) error { +func (m *manager) CreateRepo(pr repo.IRepo) error { return m.service.Create(pr) } -func (m *manager) GetRegistry(name string) (*common.Registry, error) { +func (m *manager) GetRepo(name string) (repo.IRepo, error) { return m.service.Get(name) } -func (m *manager) DeleteRegistry(name string) error { - return m.service.Delete(name) -} - func generateManifestName() string { return fmt.Sprintf("manifest-%d", time.Now().UTC().UnixNano()) } @@ -437,54 +411,33 @@ func getResourceErrors(c *common.Configuration) []string { return errs } -// ListRegistryTypes lists types in a given registry whose string values -// conform to the supplied regular expression, or all types, if the regular +// ListRepoCharts lists charts in a given repository whose names +// conform to the supplied regular expression, or all charts, if the regular // expression is nil. -func (m *manager) ListRegistryTypes(registryName string, regex *regexp.Regexp) ([]registry.Type, error) { - r, err := m.registryProvider.GetRegistryByName(registryName) +func (m *manager) ListRepoCharts(repoName string, regex *regexp.Regexp) ([]string, error) { + r, err := m.repoProvider.GetRepoByName(repoName) if err != nil { return nil, err } - return r.ListTypes(regex) + return r.ListCharts(regex) } -// GetDownloadURLs returns the URLs required to download the contents -// of a given type in a given registry. -func (m *manager) GetDownloadURLs(registryName string, t registry.Type) ([]*url.URL, error) { - r, err := m.registryProvider.GetRegistryByName(registryName) +// GetChartForRepo returns a chart from a given repository. +func (m *manager) GetChartForRepo(repoName, chartName string) (*chart.Chart, error) { + r, err := m.repoProvider.GetRepoByName(repoName) if err != nil { return nil, err } - return r.GetDownloadURLs(t) -} - -// GetFile returns a file from the backing registry -func (m *manager) GetFile(registryName string, url string) (string, error) { - r, err := m.registryProvider.GetRegistryByName(registryName) - if err != nil { - return "", err - } - - return getFileFromRegistry(url, r) -} - -func getFileFromRegistry(url string, r registry.Registry) (string, error) { - getter := util.NewHTTPClient(3, r, util.NewSleeper()) - body, _, err := getter.Get(url) - if err != nil { - return "", err - } - - return body, nil + return r.GetChart(chartName) } -// CreateCredential creates a credential that can be used to authenticate to registry -func (m *manager) CreateCredential(name string, c *common.RegistryCredential) error { +// CreateCredential creates a credential that can be used to authenticate to repository +func (m *manager) CreateCredential(name string, c *repo.Credential) error { return m.credentialProvider.SetCredential(name, c) } -func (m *manager) GetCredential(name string) (*common.RegistryCredential, error) { +func (m *manager) GetCredential(name string) (*repo.Credential, error) { return m.credentialProvider.GetCredential(name) } diff --git a/cmd/manager/manager/manager_test.go b/cmd/manager/manager/manager_test.go index 86428372a..64bcc1901 100644 --- a/cmd/manager/manager/manager_test.go +++ b/cmd/manager/manager/manager_test.go @@ -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) } diff --git a/pkg/common/types.go b/pkg/common/types.go index b9d923b30..0d17cc092 100644 --- a/pkg/common/types.go +++ b/pkg/common/types.go @@ -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