Commit 43a6876a authored by jackgr's avatar jackgr

Refactor manager/manager

parent e1afffbc
......@@ -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)
}
......@@ -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)
}
......
......@@ -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