示例#1
0
文件: builder.go 项目: koding/koding
func makeCreds(init bool, c ...*stack.Credential) map[string]interface{} {
	creds := make(map[string]interface{}, len(c))

	if init {
		// Using func-scope to defer unlocking in case user-provided
		// function panics.
		func() {
			providersMu.Lock()
			defer providersMu.Unlock()

			for _, c := range c {
				if c.Credential == nil {
					c.Credential = schema(c.Provider).newCredential()
				}
				if c.Bootstrap == nil {
					c.Bootstrap = schema(c.Provider).newBootstrap()
				}
			}
		}()
	}

	for _, c := range c {
		if c.Bootstrap == nil {
			creds[c.Identifier] = c.Credential
		} else {
			creds[c.Identifier] = object.Inline(c.Credential, c.Bootstrap)
		}
	}

	return creds
}
示例#2
0
func mergeIn(kfg, mixin *config.Konfig) error {
	p, err := json.Marshal(object.Inline(mixin, kfg))
	if err != nil {
		return err
	}

	return json.Unmarshal(p, kfg)
}
示例#3
0
文件: stacker.go 项目: koding/koding
func (s *Stacker) FetchCredData(bm *BaseMachine) error {
	credentials := make(map[string]interface{})

	if bm.Bootstrap != nil {
		credentials[bm.Machine.Credential] = object.Inline(bm.Credential, bm.Bootstrap)
	} else {
		credentials[bm.Machine.Credential] = object.ToAddr(bm.Credential)
	}

	return s.CredStore.Fetch(bm.Username(), credentials)
}
示例#4
0
func (bs *BaseStack) bootstrap(arg *stack.BootstrapRequest) (interface{}, error) {
	if arg.Destroy {
		bs.Log.Debug("Bootstrap destroy is called")
	} else {
		bs.Log.Debug("Bootstrap apply is called")
	}

	if err := bs.Builder.BuildCredentials(bs.Req.Method, bs.Req.Username, arg.GroupName, arg.Identifiers); err != nil {
		return nil, err
	}

	bs.Log.Debug("Connecting to terraformer kite")

	tfKite, err := terraformer.Connect(bs.Session.Terraformer)
	if err != nil {
		return nil, err
	}
	defer tfKite.Close()

	bs.Log.Debug("Iterating over credentials")

	updatedCreds := make(map[string]*stack.Credential)

	for _, cred := range bs.Builder.Credentials {
		if cred.Provider != bs.Planner.Provider {
			continue
		}

		var bootstrapMixin interface{}

		if bs.SSHKeyPairFunc != nil {
			keypair, err := stack.GenerateSSHKeyPair()
			if err != nil {
				return nil, fmt.Errorf("error generating SSH key-pair: %s", err)
			}

			if err := bs.SSHKeyPairFunc(keypair); err != nil {
				return nil, fmt.Errorf("error injecting SSH key-pair: %s", err)
			}

			bootstrapMixin = keypair
		}

		templates, err := bs.stack.BootstrapTemplates(cred)
		if err != nil {
			return nil, err
		}

		destroyUniq := make(map[string]struct{}) // protects from double-destroy
		for _, tmpl := range templates {
			if tmpl.Key == "" {
				tmpl.Key = bs.Planner.Provider + "-" + arg.GroupName + "-" + cred.Identifier
			}

			if arg.Destroy {
				if _, ok := destroyUniq[tmpl.Key]; !ok {
					bs.Log.Info("Destroying bootstrap resources belonging to identifier '%s'", cred.Identifier)

					_, err := tfKite.Destroy(&tf.TerraformRequest{
						ContentID: tmpl.Key,
						TraceID:   bs.TraceID,
					})
					if err != nil {
						return nil, err
					}

					cred.Bootstrap = bs.Provider.newBootstrap()
					destroyUniq[tmpl.Key] = struct{}{}
				}
			} else {
				bs.Log.Debug("Bootstrap template for %s: %s", cred.Identifier, tmpl)

				// TODO(rjeczalik): use []byte for templates to avoid allocations
				if err := bs.Builder.BuildTemplate(string(tmpl.Content), tmpl.Key); err != nil {
					return nil, fmt.Errorf("error building template: %s", err)
				}

				content, err := bs.Builder.Template.JsonOutput()
				if err != nil {
					return nil, err
				}

				bs.Log.Debug("Final bootstrap template: %s", content)

				state, err := tfKite.Apply(&tf.TerraformRequest{
					Content:   content,
					ContentID: tmpl.Key,
					TraceID:   bs.TraceID,
				})
				if err != nil {
					return nil, err
				}

				bs.Log.Debug("[%s] state.RootModule().Outputs = %+v\n", cred.Identifier, state.RootModule().Outputs)

				if err := bs.Builder.Object.Decode(state.RootModule().Outputs, cred.Bootstrap); err != nil {
					return nil, err
				}

				bs.Log.Debug("[%s] resp = %+v\n", cred.Identifier, cred.Bootstrap)

				if v, ok := cred.Bootstrap.(stack.Validator); ok {
					if err := v.Valid(); err != nil {
						return nil, fmt.Errorf("invalid bootstrap metadata for %q: %s", cred.Identifier, err)
					}
				}
			}

			if bootstrapMixin != nil {
				cred.Bootstrap = object.Inline(cred.Bootstrap, bootstrapMixin)
			}

			updatedCreds[cred.Identifier] = cred

			bs.Log.Debug("[%s] Bootstrap response: %+v", cred.Identifier, cred.Bootstrap)
		}
	}

	creds := make([]*stack.Credential, 0, len(updatedCreds))
	for _, cred := range updatedCreds {
		creds = append(creds, cred)
	}

	if err := bs.Builder.PutCredentials(bs.Req.Username, creds...); err != nil {
		return nil, err
	}

	return true, nil
}