Plumb deployment request through manager

pull/462/head
jackgr 9 years ago
parent 4573939f8c
commit 212dece6aa

@ -22,7 +22,6 @@ import (
"regexp"
"time"
"github.com/ghodss/yaml"
"github.com/kubernetes/helm/cmd/manager/repository"
"github.com/kubernetes/helm/pkg/chart"
"github.com/kubernetes/helm/pkg/common"
@ -34,14 +33,14 @@ type Manager interface {
// Deployments
ListDeployments() ([]common.Deployment, error)
GetDeployment(name string) (*common.Deployment, error)
CreateDeployment(t *common.Template) (*common.Deployment, error)
CreateDeployment(depReq *common.DeploymentRequest) (*common.Deployment, error)
DeleteDeployment(name string, forget bool) (*common.Deployment, error)
PutDeployment(name string, t *common.Template) (*common.Deployment, error)
PutDeployment(name string, depReq *common.DeploymentRequest) (*common.Deployment, error)
// Manifests
ListManifests(deploymentName string) (map[string]*common.Manifest, error)
GetManifest(deploymentName string, manifest string) (*common.Manifest, error)
Expand(t *common.Template) (*common.Manifest, error)
Expand(t *common.DeploymentRequest) (*common.Manifest, error)
// Charts
ListCharts() ([]string, error)
@ -126,27 +125,27 @@ func (m *manager) GetManifest(deploymentName string, manifestName string) (*comm
return d, nil
}
// CreateDeployment expands the supplied template, creates the resulting
// configuration in the cluster, creates a new deployment that tracks it,
// and stores the deployment in the repository. Returns the deployment.
func (m *manager) CreateDeployment(t *common.Template) (*common.Deployment, error) {
log.Printf("Creating deployment: %s", t.Name)
_, err := m.repository.CreateDeployment(t.Name)
// CreateDeployment expands the supplied configuration, creates the resulting
// resources in the cluster, creates a new deployment that tracks it, stores the
// deployment in the repository and returns the deployment.
func (m *manager) CreateDeployment(depReq *common.DeploymentRequest) (*common.Deployment, error) {
log.Printf("Creating deployment: %s", depReq.Name)
_, err := m.repository.CreateDeployment(depReq.Name)
if err != nil {
log.Printf("CreateDeployment failed %v", err)
return nil, err
}
manifest, err := m.Expand(t)
manifest, err := m.Expand(depReq)
if err != nil {
log.Printf("Manifest creation failed: %v", err)
m.repository.SetDeploymentState(t.Name, failState(err))
m.repository.SetDeploymentState(depReq.Name, failState(err))
return nil, err
}
if err := m.repository.AddManifest(manifest); err != nil {
log.Printf("AddManifest failed %v", err)
m.repository.SetDeploymentState(t.Name, failState(err))
m.repository.SetDeploymentState(depReq.Name, failState(err))
return nil, err
}
@ -154,7 +153,7 @@ func (m *manager) CreateDeployment(t *common.Template) (*common.Deployment, erro
if err != nil {
// Deployment failed, mark as failed
log.Printf("CreateConfiguration failed: %v", err)
m.repository.SetDeploymentState(t.Name, failState(err))
m.repository.SetDeploymentState(depReq.Name, failState(err))
// If we failed before being able to create some of the resources, then
// return the failure as such. Otherwise, we're going to add the manifest
@ -167,24 +166,24 @@ func (m *manager) CreateDeployment(t *common.Template) (*common.Deployment, erro
errs := getResourceErrors(actualConfig)
if len(errs) > 0 {
e := fmt.Errorf("Found resource errors during deployment: %v", errs)
m.repository.SetDeploymentState(t.Name, failState(e))
m.repository.SetDeploymentState(depReq.Name, failState(e))
return nil, e
}
m.repository.SetDeploymentState(t.Name, &common.DeploymentState{Status: common.DeployedStatus})
m.repository.SetDeploymentState(depReq.Name, &common.DeploymentState{Status: common.DeployedStatus})
}
// Update the manifest with the actual state of the reified resources
manifest.ExpandedConfig = actualConfig
if err := m.repository.SetManifest(manifest); err != nil {
log.Printf("SetManifest failed %v", err)
m.repository.SetDeploymentState(t.Name, failState(err))
m.repository.SetDeploymentState(depReq.Name, failState(err))
return nil, err
}
// Finally update the type instances for this deployment.
m.setChartInstances(t.Name, manifest.Name, manifest.Layout)
return m.repository.GetValidDeployment(t.Name)
m.setChartInstances(depReq.Name, manifest.Name, manifest.Layout)
return m.repository.GetValidDeployment(depReq.Name)
}
func (m *manager) setChartInstances(deploymentName string, manifestName string, layout *common.Layout) {
@ -269,13 +268,13 @@ func (m *manager) DeleteDeployment(name string, forget bool) (*common.Deployment
// PutDeployment replaces the configuration of the deployment with
// the supplied identifier in the cluster, and returns the deployment.
func (m *manager) PutDeployment(name string, t *common.Template) (*common.Deployment, error) {
func (m *manager) PutDeployment(name string, depReq *common.DeploymentRequest) (*common.Deployment, error) {
_, err := m.repository.GetValidDeployment(name)
if err != nil {
return nil, err
}
manifest, err := m.Expand(t)
manifest, err := m.Expand(depReq)
if err != nil {
log.Printf("Manifest creation failed: %v", err)
m.repository.SetDeploymentState(name, failState(err))
@ -296,17 +295,12 @@ func (m *manager) PutDeployment(name string, t *common.Template) (*common.Deploy
}
// Finally update the type instances for this deployment.
m.setChartInstances(t.Name, manifest.Name, manifest.Layout)
return m.repository.GetValidDeployment(t.Name)
m.setChartInstances(depReq.Name, manifest.Name, manifest.Layout)
return m.repository.GetValidDeployment(depReq.Name)
}
func (m *manager) Expand(t *common.Template) (*common.Manifest, error) {
conf := &common.Configuration{}
if err := yaml.Unmarshal([]byte(t.Content), conf); err != nil {
return nil, fmt.Errorf("Unable to unmarshal configuration: %s\n%s\n", err, t.Content)
}
expConf, err := m.expander.ExpandConfiguration(conf)
func (m *manager) Expand(depReq *common.DeploymentRequest) (*common.Manifest, error) {
expConf, err := m.expander.ExpandConfiguration(&depReq.Configuration)
if err != nil {
log.Printf("Expansion failed %v", err)
return nil, err
@ -314,8 +308,8 @@ func (m *manager) Expand(t *common.Template) (*common.Manifest, error) {
return &common.Manifest{
Name: generateManifestName(),
Deployment: t.Name,
InputConfig: t,
Deployment: depReq.Name,
InputConfig: &depReq.Configuration,
ExpandedConfig: expConf.Config,
Layout: expConf.Layout,
}, nil

@ -19,7 +19,6 @@ package manager
import (
"github.com/kubernetes/helm/pkg/common"
"github.com/kubernetes/helm/pkg/repo"
"github.com/kubernetes/helm/pkg/util"
"errors"
"reflect"
@ -46,7 +45,7 @@ var resourcesWithFailureState = common.Configuration{
},
}},
}
var template = common.Template{Name: "test", Content: util.ToYAMLOrError(&configuration)}
var deploymentRequest = common.DeploymentRequest{Name: "test", Configuration: configuration}
var expandedConfig = ExpandedConfiguration{
Config: &configuration,
@ -334,25 +333,25 @@ func TestGetManifest(t *testing.T) {
func TestCreateDeployment(t *testing.T) {
testRepository.reset()
testDeployer.reset()
d, err := testManager.CreateDeployment(&template)
d, err := testManager.CreateDeployment(&deploymentRequest)
if !reflect.DeepEqual(d, &deployment) || err != nil {
t.Fatalf("Expected a different set of response values from invoking CreateDeployment."+
"Received: %v, %s. Expected: %#v, %s.", d, err, &deployment, "nil")
}
if testRepository.Created[0] != template.Name {
if testRepository.Created[0] != deploymentRequest.Name {
t.Fatalf("Repository CreateDeployment was called with %s but expected %s.",
testRepository.Created[0], template.Name)
testRepository.Created[0], deploymentRequest.Name)
}
if !strings.HasPrefix(testRepository.ManifestAdd[template.Name].Name, "manifest-") {
if !strings.HasPrefix(testRepository.ManifestAdd[deploymentRequest.Name].Name, "manifest-") {
t.Fatalf("Repository AddManifest was called with %s but expected manifest name"+
"to begin with manifest-.", testRepository.ManifestAdd[template.Name].Name)
"to begin with manifest-.", testRepository.ManifestAdd[deploymentRequest.Name].Name)
}
if !strings.HasPrefix(testRepository.ManifestSet[template.Name].Name, "manifest-") {
if !strings.HasPrefix(testRepository.ManifestSet[deploymentRequest.Name].Name, "manifest-") {
t.Fatalf("Repository SetManifest was called with %s but expected manifest name"+
"to begin with manifest-.", testRepository.ManifestSet[template.Name].Name)
"to begin with manifest-.", testRepository.ManifestSet[deploymentRequest.Name].Name)
}
if !reflect.DeepEqual(*testDeployer.Created[0], configuration) || err != nil {
@ -377,11 +376,11 @@ func TestCreateDeploymentCreationFailure(t *testing.T) {
testRepository.reset()
testDeployer.reset()
testDeployer.FailCreate = true
d, err := testManager.CreateDeployment(&template)
d, err := testManager.CreateDeployment(&deploymentRequest)
if testRepository.Created[0] != template.Name {
if testRepository.Created[0] != deploymentRequest.Name {
t.Fatalf("Repository CreateDeployment was called with %s but expected %s.",
testRepository.Created[0], template.Name)
testRepository.Created[0], deploymentRequest.Name)
}
if len(testRepository.Deleted) != 0 {
@ -407,11 +406,11 @@ func TestCreateDeploymentCreationResourceFailure(t *testing.T) {
testRepository.reset()
testDeployer.reset()
testDeployer.FailCreateResource = true
d, err := testManager.CreateDeployment(&template)
d, err := testManager.CreateDeployment(&deploymentRequest)
if testRepository.Created[0] != template.Name {
if testRepository.Created[0] != deploymentRequest.Name {
t.Fatalf("Repository CreateDeployment was called with %s but expected %s.",
testRepository.Created[0], template.Name)
testRepository.Created[0], deploymentRequest.Name)
}
if len(testRepository.Deleted) != 0 {
@ -423,14 +422,14 @@ func TestCreateDeploymentCreationResourceFailure(t *testing.T) {
t.Fatal("CreateDeployment failure did not mark deployment as failed")
}
if manifest, ok := testRepository.ManifestAdd[template.Name]; ok {
if manifest, ok := testRepository.ManifestAdd[deploymentRequest.Name]; ok {
if !strings.HasPrefix(manifest.Name, "manifest-") {
t.Fatalf("Repository AddManifest was called with %s but expected manifest name"+
"to begin with manifest-.", manifest.Name)
}
}
if manifest, ok := testRepository.ManifestSet[template.Name]; ok {
if manifest, ok := testRepository.ManifestSet[deploymentRequest.Name]; ok {
if !strings.HasPrefix(manifest.Name, "manifest-") {
t.Fatalf("Repository AddManifest was called with %s but expected manifest name"+
"to begin with manifest-.", manifest.Name)
@ -450,25 +449,25 @@ func TestCreateDeploymentCreationResourceFailure(t *testing.T) {
func TestDeleteDeploymentForget(t *testing.T) {
testRepository.reset()
testDeployer.reset()
d, err := testManager.CreateDeployment(&template)
d, err := testManager.CreateDeployment(&deploymentRequest)
if !reflect.DeepEqual(d, &deployment) || err != nil {
t.Fatalf("Expected a different set of response values from invoking CreateDeployment."+
"Received: %v, %s. Expected: %#v, %s.", d, err, &deployment, "nil")
}
if testRepository.Created[0] != template.Name {
if testRepository.Created[0] != deploymentRequest.Name {
t.Fatalf("Repository CreateDeployment was called with %s but expected %s.",
testRepository.Created[0], template.Name)
testRepository.Created[0], deploymentRequest.Name)
}
if !strings.HasPrefix(testRepository.ManifestAdd[template.Name].Name, "manifest-") {
if !strings.HasPrefix(testRepository.ManifestAdd[deploymentRequest.Name].Name, "manifest-") {
t.Fatalf("Repository AddManifest was called with %s but expected manifest name"+
"to begin with manifest-.", testRepository.ManifestAdd[template.Name].Name)
"to begin with manifest-.", testRepository.ManifestAdd[deploymentRequest.Name].Name)
}
if !strings.HasPrefix(testRepository.ManifestSet[template.Name].Name, "manifest-") {
if !strings.HasPrefix(testRepository.ManifestSet[deploymentRequest.Name].Name, "manifest-") {
t.Fatalf("Repository SetManifest was called with %s but expected manifest name"+
"to begin with manifest-.", testRepository.ManifestSet[template.Name].Name)
"to begin with manifest-.", testRepository.ManifestSet[deploymentRequest.Name].Name)
}
if !reflect.DeepEqual(*testDeployer.Created[0], configuration) || err != nil {
@ -497,9 +496,9 @@ func TestDeleteDeploymentForget(t *testing.T) {
}
func TestExpand(t *testing.T) {
m, err := testManager.Expand(&template)
m, err := testManager.Expand(&deploymentRequest)
if err != nil {
t.Fatal("Failed to expand template into manifest.")
t.Fatal("Failed to expand deployment request into manifest.")
}
if !reflect.DeepEqual(*m.ExpandedConfig, configuration) {

@ -83,7 +83,7 @@ func (m *mockManager) GetDeployment(name string) (*common.Deployment, error) {
return nil, errors.New("mock error: No such deployment")
}
func (m *mockManager) CreateDeployment(t *common.Template) (*common.Deployment, error) {
func (m *mockManager) CreateDeployment(depReq *common.DeploymentRequest) (*common.Deployment, error) {
return &common.Deployment{}, nil
}
@ -91,7 +91,7 @@ func (m *mockManager) DeleteDeployment(name string, forget bool) (*common.Deploy
return &common.Deployment{}, nil
}
func (m *mockManager) PutDeployment(name string, t *common.Template) (*common.Deployment, error) {
func (m *mockManager) PutDeployment(name string, depReq *common.DeploymentRequest) (*common.Deployment, error) {
return &common.Deployment{}, nil
}
@ -103,7 +103,7 @@ func (m *mockManager) GetManifest(deploymentName string, manifest string) (*comm
return &common.Manifest{}, nil
}
func (m *mockManager) Expand(t *common.Template) (*common.Manifest, error) {
func (m *mockManager) Expand(depReq *common.DeploymentRequest) (*common.Manifest, error) {
return &common.Manifest{}, nil
}

@ -70,14 +70,15 @@ func (s DeploymentStatus) String() string {
type Manifest struct {
Deployment string `json:"deployment,omitempty"`
Name string `json:"name,omitempty"`
InputConfig *Template `json:"inputConfig,omitempty"`
InputConfig *Configuration `json:"inputConfig,omitempty"`
ExpandedConfig *Configuration `json:"expandedConfig,omitempty"`
Layout *Layout `json:"layout,omitempty"`
}
// CreateDeploymentRequest defines the manager API to create deployments.
type CreateDeploymentRequest struct {
ChartInvocation *Resource `json:"chart_invocation"`
// DeploymentRequest defines the manager API to create deployments.
type DeploymentRequest struct {
Configuration
Name string `json:"name"`
}
// ChartInstance defines the metadata for an instantiation of a chart.

Loading…
Cancel
Save