Ejemplo n.º 1
0
// 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
}
Ejemplo n.º 2
0
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")
	}
}
Ejemplo n.º 3
0
// 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)
}
Ejemplo n.º 4
0
// 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)
}
Ejemplo n.º 5
0
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")
	}
}
Ejemplo n.º 6
0
// 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
}
Ejemplo n.º 7
0
// 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)
}