// RenderTemplate - func RenderTemplate(file string, binding Template) (*cloudinit.CloudConfig, error) { templateFile, err := ioutil.ReadFile(file) if err != nil { return nil, fmt.Errorf("failed to load template file: %s, error: %v\n", file, err) } t := string(templateFile) tpl, err := template.New("cloudconfig").Parse(t) if err != nil { return nil, fmt.Errorf("failed to parse template file: %s, error: %v\n", file, err) } var out bytes.Buffer err = tpl.Execute(&out, binding) if err != nil { return nil, fmt.Errorf("failed to execute template file: %s, error: %v\n", file, err) } ci, err := cloudinit.NewCloudConfig(out.String()) if err != nil { msg := fmt.Sprintf("failed to generate cloudinit from destination file: %s, error: %v\n", file, err) return nil, fmt.Errorf(msg) } return ci, nil }
func ParseUserData(contents string) (interface{}, error) { if len(contents) == 0 { return nil, nil } switch { case config.IsScript(contents): log.Printf("Parsing user-data as script") return config.NewScript(contents) case config.IsCloudConfig(contents): log.Printf("Parsing user-data as cloud-config") cc, err := config.NewCloudConfig(contents) if err != nil { return nil, err } if err := cc.Decode(); err != nil { return nil, err } return cc, nil case config.IsIgnitionConfig(contents): return nil, ErrIgnitionConfig default: return nil, errors.New("Unrecognized user-data format") } }
// cloudHandler returns a handler that responds with the cloud config for the // requester. func cloudHandler(srv server.Server) ContextHandler { fn := func(ctx context.Context, w http.ResponseWriter, req *http.Request) { group, err := groupFromContext(ctx) if err != nil || group.Profile == "" { http.NotFound(w, req) return } profile, err := srv.ProfileGet(ctx, &pb.ProfileGetRequest{Id: group.Profile}) if err != nil || profile.CloudId == "" { http.NotFound(w, req) return } contents, err := srv.CloudGet(ctx, profile.CloudId) if err != nil { http.NotFound(w, req) return } // collect data for rendering data := make(map[string]interface{}) if group.Metadata != nil { err = json.Unmarshal(group.Metadata, &data) if err != nil { log.Errorf("error unmarshalling metadata: %v", err) http.NotFound(w, req) return } } for key, value := range group.Selector { data[strings.ToLower(key)] = value } // render the template of a cloud config with data var buf bytes.Buffer err = renderTemplate(&buf, data, contents) if err != nil { http.NotFound(w, req) return } config := buf.String() if !cloudinit.IsCloudConfig(config) && !cloudinit.IsScript(config) { log.Error("error parsing user-data") http.NotFound(w, req) return } if cloudinit.IsCloudConfig(config) { if _, err = cloudinit.NewCloudConfig(config); err != nil { log.Errorf("error parsing cloud config: %v", err) http.NotFound(w, req) return } } http.ServeContent(w, req, "", time.Time{}, strings.NewReader(config)) } return ContextHandlerFunc(fn) }
// cloudHandler returns a handler that responds with the cloud config for the // requester. func cloudHandler(store Store) ContextHandler { fn := func(ctx context.Context, w http.ResponseWriter, req *http.Request) { group, err := groupFromContext(ctx) if err != nil || group.Spec == "" { http.NotFound(w, req) return } spec, err := store.Spec(group.Spec) if err != nil || spec.CloudConfig == "" { http.NotFound(w, req) return } contents, err := store.CloudConfig(spec.CloudConfig) if err != nil { http.NotFound(w, req) return } // collect data for rendering data := make(map[string]interface{}) for k := range group.Metadata { data[k] = group.Metadata[k] } // render the template of a cloud config with data var buf bytes.Buffer err = renderTemplate(&buf, data, contents) if err != nil { http.NotFound(w, req) return } config := buf.String() if !cloudinit.IsCloudConfig(config) && !cloudinit.IsScript(config) { log.Errorf("error parsing user-data") http.NotFound(w, req) return } if cloudinit.IsCloudConfig(config) { if _, err = cloudinit.NewCloudConfig(config); err != nil { log.Errorf("error parsing cloud config: %v", err) http.NotFound(w, req) return } } http.ServeContent(w, req, "", time.Time{}, strings.NewReader(config)) } return ContextHandlerFunc(fn) }
func ParseUserData(contents string) (interface{}, error) { if len(contents) == 0 { return nil, nil } switch { case config.IsScript(contents): log.Printf("Parsing user-data as script") return config.NewScript(contents) case config.IsCloudConfig(contents): log.Printf("Parsing user-data as cloud-config") return config.NewCloudConfig(contents) default: return nil, errors.New("Unrecognized user-data format") } }
// ReadSource - func ReadSource(file string, isTemplate bool) (*cloudinit.CloudConfig, error) { if isTemplate { binding, err := ReadProperties(file) if err != nil { return nil, err } return RenderTemplate(file, *binding) } outputFile, err := ioutil.ReadFile(file) if err != nil { msg := fmt.Sprintf("failed to load source file: %s, error: %v\n", file, err) return nil, fmt.Errorf(msg) } s := string(outputFile) ci, err := cloudinit.NewCloudConfig(s) if err != nil { msg := fmt.Sprintf("failed to generate cloudinit from source file: %s, error: %v\n", file, err) return nil, fmt.Errorf(msg) } return ci, nil }
// cloudHandler returns a handler that responds with the cloud config for the // requester. func (s *Server) cloudHandler(core server.Server) ContextHandler { fn := func(ctx context.Context, w http.ResponseWriter, req *http.Request) { group, err := groupFromContext(ctx) if err != nil { s.logger.WithFields(logrus.Fields{ "labels": labelsFromRequest(nil, req), }).Infof("No matching group") http.NotFound(w, req) return } profile, err := core.ProfileGet(ctx, &pb.ProfileGetRequest{Id: group.Profile}) if err != nil { s.logger.WithFields(logrus.Fields{ "labels": labelsFromRequest(nil, req), "group": group.Id, "group_name": group.Name, }).Infof("No profile named: %s", group.Profile) http.NotFound(w, req) return } contents, err := core.CloudGet(ctx, profile.CloudId) if err != nil { s.logger.WithFields(logrus.Fields{ "labels": labelsFromRequest(nil, req), "group": group.Id, "group_name": group.Name, "profile": group.Profile, }).Infof("No cloud-config template named: %s", profile.CloudId) http.NotFound(w, req) return } // match was successful s.logger.WithFields(logrus.Fields{ "labels": labelsFromRequest(nil, req), "group": group.Id, "profile": profile.Id, }).Debug("Matched a cloud-config template") // collect data for rendering data := make(map[string]interface{}) if group.Metadata != nil { err = json.Unmarshal(group.Metadata, &data) if err != nil { s.logger.Errorf("error unmarshalling metadata: %v", err) http.NotFound(w, req) return } } for key, value := range group.Selector { data[strings.ToLower(key)] = value } // render the template of a cloud config with data var buf bytes.Buffer err = s.renderTemplate(&buf, data, contents) if err != nil { http.NotFound(w, req) return } config := buf.String() if !cloudinit.IsCloudConfig(config) && !cloudinit.IsScript(config) { s.logger.Error("error parsing user-data") http.NotFound(w, req) return } if cloudinit.IsCloudConfig(config) { if _, err = cloudinit.NewCloudConfig(config); err != nil { s.logger.Errorf("error parsing cloud config: %v", err) http.NotFound(w, req) return } } http.ServeContent(w, req, "", time.Time{}, strings.NewReader(config)) } return ContextHandlerFunc(fn) }