예제 #1
0
func (metric *Metric) Load(context *ctp.ApiContext) *ctp.HttpError {
	if !ctp.LoadResource(context, "metrics", ctp.Base64Id(context.Params[1]), metric) {
		return ctp.NewHttpError(http.StatusNotFound, "Not Found")
	}
	metric.BuildLinks(context)
	return nil
}
예제 #2
0
파일: assets.go 프로젝트: ehengzh/ctpd
func (asset *Asset) Load(context *ctp.ApiContext) *ctp.HttpError {
	if !ctp.LoadResource(context, "assets", ctp.Base64Id(context.Params[1]), asset) {
		return ctp.NewHttpError(http.StatusNotFound, "Not Found")
	}
	asset.BuildLinks(context)
	return nil
}
예제 #3
0
func (attribute *Attribute) Load(context *ctp.ApiContext) *ctp.HttpError {
	if !ctp.LoadResource(context, "attributes", ctp.Base64Id(context.Params[1]), attribute) {
		return ctp.NewHttpError(http.StatusNotFound, "Not Found")
	}
	attribute.BuildLinks(context)
	return nil
}
예제 #4
0
func (res *TaggedResource) Load(context *ctp.ApiContext) *ctp.HttpError {
	if !ctp.LoadResource(context, context.Params[0], ctp.Base64Id(context.Params[1]), res) {
		return ctp.NewHttpError(http.StatusNotFound, "Not Found")
	}
	res.BuildLinks(context)
	return nil
}
예제 #5
0
func (log *LogEntry) Load(context *ctp.ApiContext) *ctp.HttpError {
	if !ctp.LoadResource(context, "logs", ctp.Base64Id(context.Params[1]), log) {
		return ctp.NewHttpError(http.StatusNotFound, "Not Found")
	}
	log.BuildLinks(context)
	return nil
}
예제 #6
0
func (serviceview *ServiceView) Load(context *ctp.ApiContext) *ctp.HttpError {
	if !ctp.LoadResource(context, "serviceViews", ctp.Base64Id(context.Params[1]), serviceview) {
		return ctp.NewHttpError(http.StatusNotFound, "Not Found")
	}
	serviceview.BuildLinks(context)
	return nil
}
예제 #7
0
func (account *Account) Load(context *ctp.ApiContext) *ctp.HttpError {
	if !ctp.LoadResource(context, "accounts", ctp.Base64Id(context.Params[1]), account) {
		return ctp.NewHttpErrorf(http.StatusNotFound, "Account %s not found", context.Params[1])
	}
	account.BuildLinks(context)
	return nil
}
예제 #8
0
파일: access.go 프로젝트: ehengzh/ctpd
func (access *Access) Load(context *ctp.ApiContext) *ctp.HttpError {
	if !ctp.LoadResource(context, "access", ctp.Base64Id(context.Params[1]), access) {
		return ctp.NewHttpError(http.StatusNotFound, "Not Found")
	}
	access.BuildLinks(context)
	return nil
}
예제 #9
0
func (trigger *Trigger) Load(context *ctp.ApiContext) *ctp.HttpError {
	if !ctp.LoadResource(context, "triggers", ctp.Base64Id(context.Params[1]), trigger) {
		return ctp.NewHttpError(http.StatusNotFound, "Not Found")
	}
	trigger.Measurement = ctp.ExpandLink(context.CtpBase, trigger.Measurement)
	trigger.BuildLinks(context)
	return nil
}
예제 #10
0
func (measurement *Measurement) Load(context *ctp.ApiContext) *ctp.HttpError {
	if !ctp.LoadResource(context, "measurements", ctp.Base64Id(context.Params[1]), measurement) {
		return ctp.NewHttpError(http.StatusNotFound, "Not Found")
	}
	measurement.Metric = ctp.ExpandLink(context.CtpBase, measurement.Metric)
	measurement.BuildLinks(context)
	return nil
}
예제 #11
0
func measurementCheckResult(context *ctp.ApiContext, item *Measurement) *ctp.HttpError {
	var metric Metric

	if item.Metric == "" {
		return ctp.NewBadRequestError("Missing metric attribute in measurement.")
	}

	if item.Result == nil {
		return ctp.NewBadRequestError("Missing result attribute in measurement.")
	}

	metricParams, ok := ctp.ParseLink(context.CtpBase, "@/metrics/$", item.Metric)
	if !ok {
		return ctp.NewBadRequestError("Metric URL is incorrect in measurement")
	}

	if !ctp.LoadResource(context, "metrics", ctp.Base64Id(metricParams[0]), &metric) {
		return ctp.NewBadRequestErrorf("Metric %s does not exist", ctp.ExpandLink(context.CtpBase, item.Metric))
	}

	for _, row := range item.Result.Value {
		if len(row) != len(metric.ResultFormat) {
			return ctp.NewBadRequestErrorf("Metric expects %d columns, but result value provides %d", len(metric.ResultFormat), len(row))
		}
		for name, cell := range row {
			metricDetailFound := false
			for _, metricDetail := range metric.ResultFormat {
				if metricDetail.Name == name {
					metricDetailFound = true
					kind := reflect.ValueOf(cell).Kind()
					switch metricDetail.Type {
					case "number":
						if kind != reflect.Float64 {
							return ctp.NewBadRequestError("Metric expects a number, but result is of different type")
						}
					case "boolean":
						if kind != reflect.Bool {
							return ctp.NewBadRequestError("Metric expects a boolean, but result is of different type")
						}
					case "string":
						if kind != reflect.String {
							return ctp.NewBadRequestError("Metric expects a string, but result is of different type")
						}
					default:
						return ctp.NewBadRequestError("Metric type information is incorrect")
					}
					break // from for
				}
			}
			if !metricDetailFound {
				return ctp.NewBadRequestErrorf("Metric does not describe '%s', which appears in result", name)
			}
		}
	}
	return nil
}
예제 #12
0
func measurementCheckMetric(context *ctp.ApiContext, item *Measurement) *ctp.HttpError {
	var metric Metric

	if item.Metric == "" {
		return ctp.NewBadRequestError("Missing metric attribute in measurement.")
	}

	metricParams, ok := ctp.ParseLink(context.CtpBase, "@/metrics/$", item.Metric)
	if !ok {
		return ctp.NewBadRequestError("Metric URL is incorrect in measurement")
	}

	if !ctp.LoadResource(context, "metrics", ctp.Base64Id(metricParams[0]), &metric) {
		return ctp.NewBadRequestErrorf("Metric %s does not exist", ctp.ExpandLink(context.CtpBase, item.Metric))
	}
	return nil
}
예제 #13
0
func triggerCheckCondition(context *ctp.ApiContext, trigger *Trigger, measurement *Measurement) (bool, error) {

	if measurement == nil {
		measurementParams, ok := ctp.ParseLink(context.CtpBase, "@/measurements/$", trigger.Measurement)
		if !ok {
			return false, fmt.Errorf("Measurement URL is incorrect")
		}

		measurement = new(Measurement)
		if !ctp.LoadResource(context, "measurements", ctp.Base64Id(measurementParams[0]), measurement) {
			return false, fmt.Errorf("Measurement %s does not exist", ctp.ExpandLink(context.CtpBase, trigger.Measurement))
		}
	}

	machine, err := jsmm.Compile(trigger.Condition)
	if err != nil {
		return false, ctp.NewBadRequestErrorf("Error in condition specification - %s", err.Error())
	}

	if context.DebugVM {
		machine.DebugMode(true)
	}

	if measurement.State != "activated" {
		return false, nil
	}
	if measurement.Result == nil {
		ctp.Log(context, ctp.ERROR, "In /measurements/%s, the state is activated but the value is null.", measurement.Id)
		return false, nil
	}

	if err := importMeasurementResultInJSMM(machine, measurement.Result); err != nil {
		return false, err
	}

	v, exception := machine.Execute()
	if exception != nil {
		return false, fmt.Errorf("Failed to evaluate condition: %s", exception.Error())
	}
	return v.ToBoolean(), nil
}
예제 #14
0
// HandleGETBaseURI handles a request to the baseURI.
// It proceeds differently from other resources, which user the 'handler' paradigm.
func HandleGETBaseURI(w http.ResponseWriter, r *http.Request, context *ctp.ApiContext) {

	if !context.AuthenticateClient(w, r) {
		ctp.Log(context, ctp.WARNING, "Missing access tags")
		return
	}

	if !context.VerifyAccessTags(w, ctp.UserRoleTag) {
		ctp.Log(context, ctp.WARNING, "Mismatched access tags for API signature")
		return
	}

	base := new(BaseURI)

	if !ctp.LoadResource(context, "baseuri", ctp.Base64Id("0"), base) {
		base.Version = "0"
		base.Annotation = "Unconfigured ctpd prototype server"
	}
	base.BuildLinks(context)

	ctp.RenderJsonResponse(w, context, 200, base)
}
예제 #15
0
func HandleGETCollection(w http.ResponseWriter, r *http.Request, context *ctp.ApiContext) {
	var item ctp.NamedResource
	var parent ctp.Resource
	var query *mgo.Query
	var collectionType string
	var skip, page, items int
	var err error

	collection := new(Collection)
	selector := make(bson.M)

	if name, ok := r.URL.Query()["name"]; ok {
		selector["name"] = name[0]
	}

	page_query := r.URL.Query().Get("page")
	items_query := r.URL.Query().Get("items")
	if page_query != "" || items_query != "" {
		if page_query == "" || items_query == "" {
			ctp.RenderErrorResponse(w, context, ctp.NewHttpError(http.StatusBadRequest, "Must specify both 'page' and 'items' in query string."))
			return
		}
		if page, err = strconv.Atoi(page_query); err != nil || page < 0 {
			ctp.RenderErrorResponse(w, context, ctp.NewHttpError(http.StatusBadRequest, "page must be a positive number."))
			return
		}
		if items, err = strconv.Atoi(items_query); err != nil || items <= 0 {
			ctp.RenderErrorResponse(w, context, ctp.NewHttpError(http.StatusBadRequest, "items must be a non-zero positive number."))
		}
		skip = items * page
	}

	if !context.AuthenticateClient(w, r) {
		return
	}

	var mgoCollection *mgo.Collection

	if len(context.Params) == 1 {
		collectionType = context.Params[0]
		mgoCollection = context.Session.DB("ctp").C(collectionType)

		switch collectionType {
		case "serviceViews":
			if !context.VerifyAccessTags(w, ctp.UserRoleTag) {
				return
			}
			if !ctp.MatchTags(context.AccountTags, ctp.AdminRoleTag) {
				selector["accessTags"] = bson.M{"$in": context.AccountTags.WithPrefix("account:")}
			}
		case "metrics":
			if !context.VerifyAccessTags(w, ctp.UserRoleTag) {
				return
			}
		default:
			if !context.VerifyAccessTags(w, ctp.AdminRoleTag) {
				return
			}
		}
	} else {
		if !context.VerifyAccessTags(w, ctp.UserRoleTag) {
			return
		}

		if !ctp.LoadResource(context, context.Params[0], ctp.Base64Id(context.Params[1]), &parent) {
			ctp.RenderErrorResponse(w, context, ctp.NewNotFoundErrorf("Not found - /%s/%s does not exist", context.Params[0], context.Params[1]))
			return
		}

		if !context.VerifyAccessTags(w, parent.AccessTags) {
			return
		}
		collection.Scope = ctp.NewLink(context.CtpBase, "/$/$", context.Params[0], context.Params[1])

		collectionType = context.Params[2]
		if context.Params[2] == "indicators" {
			mgoCollection = context.Session.DB("ctp").C("measurements")
		} else {
			mgoCollection = context.Session.DB("ctp").C(collectionType)
		}
		selector["parent"] = context.Params[1]
	}

	query = mgoCollection.Find(selector)

	collection_length, err := query.Count()
	if err != nil {
		ctp.RenderErrorResponse(w, context, ctp.NewInternalServerError(err))
		return
	}

	query = query.Sort("$natural").Skip(skip).Limit(items)

	returned_length, err := query.Count()
	if err != nil {
		ctp.RenderErrorResponse(w, context, ctp.NewInternalServerError(err))
		return
	}

	collection.Self = ctp.Link(r.URL.RequestURI())
	collection.CollectionLength = collection_length
	collection.ReturnedLength = returned_length
	collection.CollectionType = collectionType
	collection.Items = make([]CollectionItem, 0, returned_length)

	iter := query.Iter()
	for iter.Next(&item) {
		collection.Items = append(collection.Items, CollectionItem{
			Link: ctp.NewLink(context.CtpBase, "@/$/$", collectionType, item.Id),
			Name: item.Name,
		})
	}

	if err := iter.Close(); err != nil {
		ctp.RenderErrorResponse(w, context, ctp.NewInternalServerError(err))
		return
	}

	ctp.RenderJsonResponse(w, context, 200, collection)
}