Commit 5f58f640 authored by vaikas-google's avatar vaikas-google

Merge pull request #91 from bmelville/39

Implements correct Expand in API and client
parents 37cd3573 f9c0b02c
......@@ -120,14 +120,8 @@ func main() {
case "describe":
fmt.Printf("the describe feature is not yet implemented")
case "expand":
backend := expander.NewExpander(*binary)
template := loadTemplate(args)
output, err := backend.ExpandTemplate(template)
if err != nil {
log.Fatalf("cannot expand %s: %s\n", template.Name, err)
}
fmt.Println(output)
callService("expand", "POST", "expand configuration", marshalTemplate(template))
case "deploy":
template := loadTemplate(args)
action := fmt.Sprintf("deploy configuration named %s", template.Name)
......
......@@ -41,6 +41,7 @@ var deployments = []Route{
{"PutDeployment", "/deployments/{deployment}", "PUT", putDeploymentHandlerFunc, "JSON"},
{"ListManifests", "/deployments/{deployment}/manifests", "GET", listManifestsHandlerFunc, ""},
{"GetManifest", "/deployments/{deployment}/manifests/{manifest}", "GET", getManifestHandlerFunc, ""},
{"Expand", "/expand", "POST", expandHandlerFunc, ""},
{"ListTypes", "/types", "GET", listTypesHandlerFunc, ""},
{"ListTypeInstances", "/types/{type}/instances", "GET", listTypeInstancesHandlerFunc, ""},
}
......@@ -290,6 +291,23 @@ func getManifestHandlerFunc(w http.ResponseWriter, r *http.Request) {
util.LogHandlerExitWithJSON(handler, w, m, http.StatusOK)
}
func expandHandlerFunc(w http.ResponseWriter, r *http.Request) {
handler := "manager: expand config"
util.LogHandlerEntry(handler, r)
defer r.Body.Close()
t := getTemplate(w, r, handler)
if t != nil {
c, err := backend.Expand(t)
if err != nil {
util.LogAndReturnError(handler, http.StatusBadRequest, err, w)
return
}
util.LogHandlerExitWithJSON(handler, w, c, http.StatusCreated)
return
}
}
// Putting Type handlers here for now because deployments.go
// currently owns its own Manager backend and doesn't like to share.
func listTypesHandlerFunc(w http.ResponseWriter, r *http.Request) {
......
......@@ -28,6 +28,7 @@ type Manager interface {
PutDeployment(name string, t *Template) (*Deployment, error)
ListManifests(deploymentName string) (map[string]*Manifest, error)
GetManifest(deploymentName string, manifest string) (*Manifest, error)
Expand(t *Template) (*Manifest, error)
ListTypes() []string
ListInstances(typeName string) []*TypeInstance
}
......@@ -90,30 +91,27 @@ func (m *manager) GetManifest(deploymentName string, manifestName string) (*Mani
// and stores the deployment in the repository. Returns the deployment.
func (m *manager) CreateDeployment(t *Template) (*Deployment, error) {
log.Printf("Creating deployment: %s", t.Name)
et, err := m.expander.ExpandTemplate(*t)
_, err := m.repository.CreateDeployment(t.Name)
if err != nil {
log.Printf("Expansion failed %v", err)
log.Printf("CreateDeployment failed %v", err)
return nil, err
}
_, err = m.repository.CreateDeployment(t.Name)
manifest, err := m.createManifest(t)
if err != nil {
log.Printf("CreateDeployment failed %v", err)
log.Printf("Manifest creation failed: %v", err)
m.repository.SetDeploymentStatus(t.Name, FailedStatus)
return nil, err
}
manifest := NewManifest(t.Name, generateManifestName())
manifest.InputConfig = t
manifest.ExpandedConfig = et.Config
manifest.Layout = et.Layout
err = m.repository.AddManifest(t.Name, manifest)
if err != nil {
log.Printf("AddManifest failed %v", err)
m.repository.SetDeploymentStatus(t.Name, FailedStatus)
return nil, err
}
if err := m.deployer.CreateConfiguration(et.Config); err != nil {
if err := m.deployer.CreateConfiguration(manifest.ExpandedConfig); err != nil {
// Deployment failed, mark as deleted
log.Printf("CreateConfiguration failed: %v", err)
m.repository.SetDeploymentStatus(t.Name, FailedStatus)
......@@ -126,6 +124,22 @@ func (m *manager) CreateDeployment(t *Template) (*Deployment, error) {
return m.repository.GetValidDeployment(t.Name)
}
func (m *manager) createManifest(t *Template) (*Manifest, error) {
et, err := m.expander.ExpandTemplate(*t)
if err != nil {
log.Printf("Expansion failed %v", err)
return nil, err
}
return &Manifest{
Name: generateManifestName(),
Deployment: t.Name,
InputConfig: t,
ExpandedConfig: et.Config,
Layout: et.Layout,
}, nil
}
func (m *manager) addTypeInstances(deploymentName string, manifestName string, layout *Layout) {
m.repository.ClearTypeInstances(deploymentName)
......@@ -175,7 +189,7 @@ func (m *manager) DeleteDeployment(name string, forget bool) (*Deployment, error
}
// Create an empty manifest since resources have been deleted.
err = m.repository.AddManifest(name, NewManifest(name, generateManifestName()))
err = m.repository.AddManifest(name, &Manifest{Deployment: name, Name: generateManifestName()})
if err != nil {
log.Printf("Failed to add empty manifest")
return nil, err
......@@ -201,23 +215,21 @@ func (m *manager) PutDeployment(name string, t *Template) (*Deployment, error) {
return nil, err
}
// TODO(bmelville): This should just return a new manifest filled in.
et, err := m.expander.ExpandTemplate(*t)
manifest, err := m.createManifest(t)
if err != nil {
log.Printf("Manifest creation failed: %v", err)
m.repository.SetDeploymentStatus(name, FailedStatus)
return nil, err
}
if err := m.deployer.PutConfiguration(et.Config); err != nil {
err = m.repository.AddManifest(t.Name, manifest)
if err != nil {
m.repository.SetDeploymentStatus(name, FailedStatus)
return nil, err
}
manifest := NewManifest(t.Name, generateManifestName())
manifest.InputConfig = t
manifest.ExpandedConfig = et.Config
manifest.Layout = et.Layout
err = m.repository.AddManifest(t.Name, manifest)
if err != nil {
if err := m.deployer.PutConfiguration(manifest.ExpandedConfig); err != nil {
m.repository.SetDeploymentStatus(name, FailedStatus)
return nil, err
}
......@@ -227,6 +239,19 @@ func (m *manager) PutDeployment(name string, t *Template) (*Deployment, error) {
return m.repository.GetValidDeployment(t.Name)
}
func (m *manager) Expand(t *Template) (*Manifest, error) {
et, err := m.expander.ExpandTemplate(*t)
if err != nil {
log.Printf("Expansion failed %v", err)
return nil, err
}
return &Manifest{
ExpandedConfig: et.Config,
Layout: et.Layout,
}, nil
}
func (m *manager) ListTypes() []string {
return m.repository.ListTypes()
}
......
......@@ -394,6 +394,33 @@ func TestDeleteDeploymentForget(t *testing.T) {
}
}
func TestExpand(t *testing.T) {
m, err := testManager.Expand(&template)
if err != nil {
t.Error("Failed to expand template into manifest.")
}
if m.Name != "" {
t.Errorf("Name was not empty: %v", *m)
}
if m.Deployment != "" {
t.Errorf("Deployment was not empty: %v", *m)
}
if m.InputConfig != nil {
t.Errorf("Input config not nil: %v", *m)
}
if !reflect.DeepEqual(*m.ExpandedConfig, configuration) {
t.Errorf("Expanded config not correct in output manifest: %v", *m)
}
if !reflect.DeepEqual(*m.Layout, layout) {
t.Errorf("Layout not correct in output manifest: %v", *m)
}
}
func TestListTypes(t *testing.T) {
testRepository.reset()
......
......@@ -81,11 +81,6 @@ func NewDeployment(name string, id int) *Deployment {
Manifests: make(map[string]*Manifest, 0)}
}
// NewManifest creates a new manifest.
func NewManifest(deploymentName string, manifestName string) *Manifest {
return &Manifest{Deployment: deploymentName, Name: manifestName}
}
// DeploymentStatus is an enumeration type for the status of a deployment.
type DeploymentStatus string
......@@ -117,9 +112,9 @@ type Layout struct {
// expanded configuration, and the layout structure of the manifest.
//
type Manifest struct {
Deployment string `json:"deployment"`
Name string `json:"name"`
InputConfig *Template `json:"inputConfig"`
Deployment string `json:"deployment,omitempty"`
Name string `json:"name,omitempty"`
InputConfig *Template `json:"inputConfig,omitempty"`
ExpandedConfig *Configuration `json:"expandedConfig,omitempty"`
Layout *Layout `json:"layout,omitempty"`
}
......
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