Make expander use dynamic service name

pull/573/head
jackgr 9 years ago
parent 378a27e8b3
commit 2c20a3185f

@ -20,21 +20,17 @@ import (
"github.com/kubernetes/helm/pkg/common" "github.com/kubernetes/helm/pkg/common"
"github.com/kubernetes/helm/pkg/expansion" "github.com/kubernetes/helm/pkg/expansion"
"github.com/kubernetes/helm/pkg/repo" "github.com/kubernetes/helm/pkg/repo"
"github.com/kubernetes/helm/pkg/util"
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/url"
"strings"
) )
/*
const (
// TODO (iantw): Align this with a character not allowed to show up in resource names.
layoutNodeKeySeparator = "#"
)
*/
// ExpandedConfiguration is the structure returned by the expansion service. // ExpandedConfiguration is the structure returned by the expansion service.
type ExpandedConfiguration struct { type ExpandedConfiguration struct {
Config *common.Configuration `json:"config"` Config *common.Configuration `json:"config"`
@ -47,23 +43,20 @@ type Expander interface {
} }
// NewExpander returns a new initialized Expander. // NewExpander returns a new initialized Expander.
func NewExpander(URL string, rp repo.IRepoProvider) Expander { func NewExpander(port, URL string, rp repo.IRepoProvider) Expander {
if rp == nil { if rp == nil {
rp = repo.NewRepoProvider(nil, nil, nil) rp = repo.NewRepoProvider(nil, nil, nil)
} }
return &expander{expanderURL: URL, repoProvider: rp} return &expander{expanderPort: port, expanderURL: URL, repoProvider: rp}
} }
type expander struct { type expander struct {
repoProvider repo.IRepoProvider repoProvider repo.IRepoProvider
expanderPort string
expanderURL string expanderURL string
} }
func (e *expander) getBaseURL() string {
return fmt.Sprintf("%s/expand", e.expanderURL)
}
// ExpandConfiguration expands the supplied configuration and returns // ExpandConfiguration expands the supplied configuration and returns
// an expanded configuration. // an expanded configuration.
func (e *expander) ExpandConfiguration(conf *common.Configuration) (*ExpandedConfiguration, error) { func (e *expander) ExpandConfiguration(conf *common.Configuration) (*ExpandedConfiguration, error) {
@ -81,80 +74,81 @@ func (e *expander) expandConfiguration(conf *common.Configuration) (*ExpandedCon
// Iterate over all of the resources in the unexpanded configuration // Iterate over all of the resources in the unexpanded configuration
for _, resource := range conf.Resources { for _, resource := range conf.Resources {
// A primitive layout resource captures only the name and type additions := []*common.Resource{resource}
layout := &common.LayoutResource{ layout := &common.LayoutResource{
Resource: common.Resource{ Resource: common.Resource{
Name: resource.Name, Type: resource.Type, Name: resource.Name, Type: resource.Type,
}, },
} }
// If the type is not a chart reference, then it must be primitive // If the type is a chart reference
if !repo.IsChartReference(resource.Type) { if repo.IsChartReference(resource.Type) {
// Add it to the flat list of exapnded resources // Fetch, decompress and unpack
resources = append(resources, resource) cbr, _, err := e.repoProvider.GetChartByReference(resource.Type)
if err != nil {
// Add its layout to the list of layouts at this level return nil, err
layouts = append(layouts, layout) }
continue
} defer cbr.Close()
expander := cbr.Chartfile().Expander
// It is a chart, so go fetch it, decompress it and unpack it if expander != nil && expander.Name != "" {
cbr, _, err := e.repoProvider.GetChartByReference(resource.Type) // Load the charts contents into strings that we can pass to exapnsion
if err != nil { content, err := cbr.LoadContent()
return nil, err if err != nil {
} return nil, err
}
defer cbr.Close()
// Build a request to the expansion service and call it to do the expansion
// Now, load the charts contents into strings that we can pass to exapnsion svcReq := &expansion.ServiceRequest{
content, err := cbr.LoadContent() ChartInvocation: resource,
if err != nil { Chart: content,
return nil, err }
}
svcResp, err := e.callService(expander.Name, svcReq)
// Build a request to the expansion service and call it to do the expansion if err != nil {
svcReq := &expansion.ServiceRequest{ return nil, err
ChartInvocation: resource, }
Chart: content,
} // Call ourselves recursively with the list of resources returned by expansion
expConf, err := e.expandConfiguration(svcResp)
svcResp, err := e.callService(svcReq) if err != nil {
if err != nil { return nil, err
return nil, err }
// Append the reources returned by the recursion to the flat list of resources
additions = expConf.Config.Resources
// This was not a primitive resource, so add its properties to the layout
// Then add the all of the layout resources returned by the recursion to the layout
layout.Properties = resource.Properties
layout.Resources = expConf.Layout.Resources
}
} }
// Call ourselves recursively with the list of resources returned by expansion resources = append(resources, additions...)
expConf, err := e.expandConfiguration(svcResp)
if err != nil {
return nil, err
}
// Append the reources returned by the recursion to the flat list of resources
resources = append(resources, expConf.Config.Resources...)
// This was not a primitive resource, so add its properties to the layout
layout.Properties = resource.Properties
// Now add the all of the layout resources returned by the recursion to the layout
layout.Resources = expConf.Layout.Resources
layouts = append(layouts, layout) layouts = append(layouts, layout)
} }
// All done with this level, so return the espanded configuration // All done with this level, so return the expanded configuration
return &ExpandedConfiguration{ return &ExpandedConfiguration{
Config: &common.Configuration{Resources: resources}, Config: &common.Configuration{Resources: resources},
Layout: &common.Layout{Resources: layouts}, Layout: &common.Layout{Resources: layouts},
}, nil }, nil
} }
func (e *expander) callService(svcReq *expansion.ServiceRequest) (*common.Configuration, error) { func (e *expander) callService(svcName string, svcReq *expansion.ServiceRequest) (*common.Configuration, error) {
svcURL, err := e.getServiceURL(svcName)
if err != nil {
return nil, err
}
j, err := json.Marshal(svcReq) j, err := json.Marshal(svcReq)
if err != nil { if err != nil {
return nil, err return nil, err
} }
reader := ioutil.NopCloser(bytes.NewReader(j)) reader := ioutil.NopCloser(bytes.NewReader(j))
request, err := http.NewRequest("POST", e.getBaseURL(), reader) request, err := http.NewRequest("POST", svcURL, reader)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -188,3 +182,21 @@ func (e *expander) callService(svcReq *expansion.ServiceRequest) (*common.Config
return svcResp, nil return svcResp, nil
} }
func (e *expander) getServiceURL(svcName string) (string, error) {
if !strings.HasPrefix(svcName, "http:") && !strings.HasPrefix(svcName, "https:") {
var err error
svcName, err = util.GetServiceURL(svcName, e.expanderPort, e.expanderURL)
if err != nil {
return "", err
}
}
u, err := url.Parse(svcName)
if err != nil {
return "", err
}
u.Path = fmt.Sprintf("%s/expand", u.Path)
return u.String(), nil
}

@ -27,7 +27,6 @@ import (
"testing" "testing"
"github.com/ghodss/yaml" "github.com/ghodss/yaml"
"github.com/kubernetes/helm/pkg/chart"
"github.com/kubernetes/helm/pkg/common" "github.com/kubernetes/helm/pkg/common"
"github.com/kubernetes/helm/pkg/expansion" "github.com/kubernetes/helm/pkg/expansion"
"github.com/kubernetes/helm/pkg/repo" "github.com/kubernetes/helm/pkg/repo"
@ -219,21 +218,6 @@ var roundTripResponses = []*ExpandedConfiguration{
} }
*/ */
type mockRepoProvider struct {
}
func (m *mockRepoProvider) GetChartByReference(reference string) (*chart.Chart, repo.IChartRepo, error) {
return &chart.Chart{}, nil, nil
}
func (m *mockRepoProvider) GetRepoByChartURL(URL string) (repo.IChartRepo, error) {
return nil, nil
}
func (m *mockRepoProvider) GetRepoByURL(URL string) (repo.IChartRepo, error) {
return nil, nil
}
type ExpanderTestCase struct { type ExpanderTestCase struct {
Description string Description string
Error string Error string
@ -266,7 +250,7 @@ func TestExpandTemplate(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(etc.Handler)) ts := httptest.NewServer(http.HandlerFunc(etc.Handler))
defer ts.Close() defer ts.Close()
expander := NewExpander(ts.URL, getTestRepoProvider(t)) expander := NewExpander("8081", ts.URL, getTestRepoProvider(t))
resource := &common.Resource{ resource := &common.Resource{
Name: "test_invocation", Name: "test_invocation",
Type: TestResourceType, Type: TestResourceType,

Loading…
Cancel
Save