Example #1
0
// BuildStack fetches stack details from MongoDB.
//
// When nil error is returned, the b.Stack field is non-nil.
func (b *Builder) BuildStack(stackID string, credentials map[string][]string) error {
	var overallErr error

	computeStack, err := modelhelper.GetComputeStack(stackID)
	if err != nil {
		return models.ResError(err, "jComputeStack")
	}

	b.Stack = &stack.Stack{
		ID:          computeStack.Id,
		Stack:       computeStack,
		Machines:    make([]string, len(computeStack.Machines)),
		Credentials: make(map[string][]string),
	}

	for i, m := range b.Stack.Stack.Machines {
		b.Stack.Machines[i] = m.Hex()
	}

	baseStackID := b.Stack.Stack.BaseStackId.Hex()

	// If fetching jStackTemplate fails, it might got deleted outside.
	// Continue building stack and let the caller decide, whether missing
	// jStackTemplate is fatal or not (e.g. for apply operations it's fatal,
	// for destroy ones - not).
	if stackTemplate, err := modelhelper.GetStackTemplate(baseStackID); err == nil {
		// first copy admin/group based credentials
		for k, v := range stackTemplate.Credentials {
			b.Stack.Credentials[k] = v
		}

		b.Stack.Template = stackTemplate.Template.Content
	} else {
		overallErr = models.ResError(err, "jStackTemplate")
	}

	// copy user based credentials
	for k, v := range computeStack.Credentials {
		// however don't override anything the admin already added
		if _, ok := b.Stack.Credentials[k]; !ok {
			b.Stack.Credentials[k] = v
		}
	}

	// Set or override credentials when passed in apply request.
	for k, v := range credentials {
		if len(v) != 0 {
			b.Stack.Credentials[k] = v
		}
	}

	b.Log.Debug("Stack built: len(machines)=%d, len(credentials)=%d, overallErr=%v",
		len(b.Stack.Machines), len(b.Stack.Credentials), overallErr)

	return overallErr
}
Example #2
0
// Status
//
// Status method is provider-agnostic.
func (k *Kloud) Status(r *kite.Request) (interface{}, error) {
	if r.Args == nil {
		return nil, NewError(ErrNoArguments)
	}

	var arg StatusRequest
	if err := r.Args.One().Unmarshal(&arg); err != nil {
		return nil, err
	}
	if err := arg.Valid(); err != nil {
		return nil, err
	}

	var resp *StatusResponse
	switch v, err := k.statusCache.Get(arg.StackID); {
	case err == cache.ErrNotFound:
		// TODO(rjeczalik): fetch only status
		computeStack, err := modelhelper.GetComputeStack(arg.StackID)
		if err != nil {
			return nil, err
		}

		resp = &StatusResponse{
			StackID:    arg.StackID,
			Status:     computeStack.Status.State,
			ModifiedAt: computeStack.Status.ModifiedAt,
		}

		k.statusCache.Set(arg.StackID, resp)
	case err != nil:
		return nil, err
	default:
		resp = v.(*StatusResponse)
	}

	return resp, nil
}