// TestListFactors will run unit tests against the List function func (suite *FactorsTestSuite) TestListFactors() { suite.respFactorsList = `<root> <Factor site="CETA-GRID" weight="5406"></Factor> <Factor site="CFP-IST" weight="1019"></Factor> <Factor site="CIEMAT-LCG2" weight="14595"></Factor> </root>` // Prepare the request object request, _ := http.NewRequest("GET", "/api/v2/factors", strings.NewReader("")) // add the authentication token which is seeded in testdb request.Header.Set("x-api-key", "secret") request.Header.Set("Accept", "application/xml") // Execute the request in the controller response := httptest.NewRecorder() suite.router.ServeHTTP(response, request) code := response.Code output := response.Body.String() suite.Equal(200, code, "Something went wrong") suite.Equal(suite.respFactorsList, string(output), "Response body mismatch") // Prepare new request object request, _ = http.NewRequest("GET", "/api/v2/factors", strings.NewReader("")) // add the authentication token which is seeded in testdb request.Header.Set("x-api-key", "wrongkey") request.Header.Set("Accept", "application/xml") // Execute the request in the controller response = httptest.NewRecorder() suite.router.ServeHTTP(response, request) code = response.Code output = response.Body.String() suite.Equal(401, code, "Should have gotten return code 401 (Unauthorized)") suite.Equal(suite.respUnauthorized, string(output), "Should have gotten reply Unauthorized") // Remove the test data from core db not to contaminate other tests // Open session to core mongo session, err := mongo.OpenSession(suite.cfg.MongoDB) if err != nil { panic(err) } defer mongo.CloseSession(session) // Open collection authentication c := session.DB(suite.cfg.MongoDB.Db).C("authentication") // Remove the specific entries inserted during this test c.Remove(bson.M{"name": "John Doe"}) // Remove the test data from tenant db not to contaminate other tests // Open session to tenant mongo session, err = mgo.Dial(suite.tenantcfg.Host) if err != nil { panic(err) } defer mongo.CloseSession(session) // Open collection authentication c = session.DB(suite.tenantcfg.Db).C("weights") // Remove the specific entries inserted during this test c.Remove(bson.M{"name": "CIEMAT-LCG2"}) c.Remove(bson.M{"name": "CFP-IST"}) c.Remove(bson.M{"name": "CETA-GRID"}) }
// List returns a list of factors (weights) per endpoint group (i.e. site) func List(r *http.Request, cfg config.Config) (int, http.Header, []byte, error) { //STANDARD DECLARATIONS START code := http.StatusOK h := http.Header{} output := []byte("") err := error(nil) contentType := "text/xml" charset := "utf-8" //STANDARD DECLARATIONS END contentType, err = respond.ParseAcceptHeader(r) h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) if err != nil { code = http.StatusNotAcceptable output, _ = respond.MarshalContent(respond.NotAcceptableContentType, contentType, "", " ") return code, h, output, err } tenantDbConfig, err := authentication.AuthenticateTenant(r.Header, cfg) if err != nil { output = []byte(http.StatusText(http.StatusUnauthorized)) code = http.StatusUnauthorized //If wrong api key is passed we return UNAUTHORIZED http status h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) return code, h, output, err } session, err := mongo.OpenSession(tenantDbConfig) if err != nil { code = http.StatusInternalServerError return code, h, output, err } defer mongo.CloseSession(session) results := []FactorsOutput{} err = mongo.Find(session, tenantDbConfig.Db, "weights", nil, "name", &results) if err != nil { code = http.StatusInternalServerError return code, h, output, err } output, err = createView(results, contentType) //Render the results into XML format if err != nil { code = http.StatusInternalServerError return code, h, output, err } mongo.CloseSession(session) return code, h, output, err }
// List returns a list of factors (weights) per endpoint group (i.e. site) func List(r *http.Request, cfg config.Config) (int, http.Header, []byte, error) { //STANDARD DECLARATIONS START code := http.StatusOK h := http.Header{} output := []byte("") err := error(nil) contentType := "text/xml" charset := "utf-8" //STANDARD DECLARATIONS END contentType, err = respond.ParseAcceptHeader(r) h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) if err != nil { code = http.StatusNotAcceptable output, _ = respond.MarshalContent(respond.NotAcceptableContentType, contentType, "", " ") return code, h, output, err } // Grab Tenant DB configuration from context tenantDbConfig := context.Get(r, "tenant_conf").(config.MongoConfig) session, err := mongo.OpenSession(tenantDbConfig) if err != nil { code = http.StatusInternalServerError return code, h, output, err } defer mongo.CloseSession(session) results := []FactorsOutput{} err = mongo.Find(session, tenantDbConfig.Db, "weights", nil, "name", &results) if err != nil { code = http.StatusInternalServerError return code, h, output, err } output, err = createView(results, contentType) //Render the results into XML format if err != nil { code = http.StatusInternalServerError return code, h, output, err } mongo.CloseSession(session) return code, h, output, err }
func Authenticate(h http.Header, cfg config.Config) bool { session, err := mongo.OpenSession(cfg.MongoDB) defer mongo.CloseSession(session) if err != nil { panic(err) } query := bson.M{ "apiKey": h.Get("x-api-key"), } results := []Auth{} err = mongo.Find(session, cfg.MongoDB.Db, "authentication", query, "apiKey", &results) if err != nil { return false } if len(results) > 0 { return true } return false }
// AuthenticateTenant is used to find which tenant the user making the requests // belongs to and return the database configuration for that specific tenant. // If the api-key in the request is not found in any tenant an empty configuration is // returned along with an error func AuthenticateTenant(h http.Header, cfg config.Config) (config.MongoConfig, error) { session, err := mongo.OpenSession(cfg.MongoDB) if err != nil { return config.MongoConfig{}, err } defer mongo.CloseSession(session) apiKey := h.Get("x-api-key") query := bson.M{"users.api_key": apiKey} projection := bson.M{"_id": 0, "name": 1, "db_conf": 1, "users": 1} var results []map[string][]config.MongoConfig mongo.FindAndProject(session, cfg.MongoDB.Db, "tenants", query, projection, "server", &results) if len(results) == 0 { return config.MongoConfig{}, errors.New("Unauthorized") } mongoConf := results[0]["db_conf"][0] // mongoConf := config.MongoConfig{ // Host: conf["server"].(string), // Port: conf["port"].(int), // Db: conf["database"].(string), // Username: conf["username"].(string), // Password: conf["password"].(string), // Store: conf["store"].(string), // } for _, user := range results[0]["users"] { if user.ApiKey == apiKey { mongoConf.User = user.User mongoConf.Email = user.Email } } return mongoConf, nil }
// HasResourceRoles returns if a resource has the roles given func HasResourceRoles(cfg config.Config, resource string, roles []string) bool { session, err := mongo.OpenSession(cfg.MongoDB) defer mongo.CloseSession(session) if err != nil { panic(err) } var results []QRole query := bson.M{"resource": resource, "roles": bson.M{"$in": roles}} err = mongo.Find(session, cfg.MongoDB.Db, "roles", query, "resource", &results) if err != nil { log.Fatal(err) } if len(results) > 0 { return true } return false }
// SetupTest will bootstrap and provide the testing environment func (suite *FactorsTestSuite) SetupTest() { // Connect to mongo coredb session, err := mongo.OpenSession(suite.cfg.MongoDB) defer mongo.CloseSession(session) if err != nil { panic(err) } // Add authentication token to mongo coredb seedAuth := bson.M{"name": "TEST", "db_conf": []bson.M{bson.M{"server": "127.0.0.1", "port": 27017, "database": "AR_test"}}, "users": []bson.M{bson.M{"name": "Jack Doe", "email": "*****@*****.**", "api_key": "secret", "roles": []string{"viewer"}}}} _ = mongo.Insert(session, suite.cfg.MongoDB.Db, "tenants", seedAuth) // Add a few factors in collection c := session.DB(suite.tenantcfg.Db).C("weights") c.Insert(bson.M{"hepspec": 14595, "name": "CIEMAT-LCG2"}) c.Insert(bson.M{"hepspec": 1019, "name": "CFP-IST"}) c.Insert(bson.M{"hepspec": 5406, "name": "CETA-GRID"}) c = session.DB(suite.cfg.MongoDB.Db).C("roles") c.Insert( bson.M{ "resource": "factors.list", "roles": []string{"editor", "viewer"}, }) }
// ListOne handles the listing of one specific profile based on its given id func ListOne(r *http.Request, cfg config.Config) (int, http.Header, []byte, error) { //STANDARD DECLARATIONS START code := http.StatusOK h := http.Header{} output := []byte("") err := error(nil) charset := "utf-8" //STANDARD DECLARATIONS END // Set Content-Type response Header value contentType := r.Header.Get("Accept") h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) vars := mux.Vars(r) // Grab Tenant DB configuration from context tenantDbConfig := context.Get(r, "tenant_conf").(config.MongoConfig) // Open session to tenant database session, err := mongo.OpenSession(tenantDbConfig) defer mongo.CloseSession(session) if err != nil { code = http.StatusInternalServerError return code, h, output, err } filter := bson.M{"id": vars["ID"]} // Retrieve Results from database results := []MongoInterface{} err = mongo.Find(session, tenantDbConfig.Db, "metric_profiles", filter, "name", &results) if err != nil { code = http.StatusInternalServerError return code, h, output, err } // Check if nothing found if len(results) < 1 { output, _ = respond.MarshalContent(respond.NotFound, contentType, "", " ") code = 404 return code, h, output, err } // Create view of the results output, err = createListView(results, "Success", code) //Render the results into JSON if err != nil { code = http.StatusInternalServerError return code, h, output, err } h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) return code, h, output, err }
// List the existing metric profiles for the tenant making the request // Also there is an optional url param "name" to filter results by func List(r *http.Request, cfg config.Config) (int, http.Header, []byte, error) { //STANDARD DECLARATIONS START code := http.StatusOK h := http.Header{} output := []byte("") err := error(nil) charset := "utf-8" //STANDARD DECLARATIONS END // Set Content-Type response Header value contentType := r.Header.Get("Accept") h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) urlValues := r.URL.Query() // Grab Tenant DB configuration from context tenantDbConfig := context.Get(r, "tenant_conf").(config.MongoConfig) // Open session to tenant database session, err := mongo.OpenSession(tenantDbConfig) defer mongo.CloseSession(session) if err != nil { code = http.StatusInternalServerError return code, h, output, err } // Retrieve Results from database var filter interface{} if len(urlValues["name"]) > 0 { filter = bson.M{"name": urlValues["name"][0]} } else { filter = nil } results := []MongoInterface{} err = mongo.Find(session, tenantDbConfig.Db, "metric_profiles", filter, "name", &results) if err != nil { code = http.StatusInternalServerError return code, h, output, err } // Create view of the results output, err = createListView(results, "Success", code) //Render the results into JSON if err != nil { code = http.StatusInternalServerError return code, h, output, err } h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) return code, h, output, err }
func routeGroup(r *http.Request, cfg config.Config) (int, http.Header, []byte, error) { //STANDARD DECLARATIONS START code := http.StatusOK h := http.Header{} output := []byte("") err := error(nil) charset := "utf-8" //STANDARD DECLARATIONS END // Handle response format based on Accept Header contentType := r.Header.Get("Accept") vars := mux.Vars(r) // Grab Tenant DB configuration from context tenantcfg := context.Get(r, "tenant_conf").(config.MongoConfig) session, err := mongo.OpenSession(tenantcfg) defer mongo.CloseSession(session) if err != nil { return code, h, output, err } requestedReport := reports.MongoInterface{} err = mongo.FindOne(session, tenantcfg.Db, "reports", bson.M{"info.name": vars["report_name"]}, &requestedReport) if err != nil { code = http.StatusNotFound message := "The report with the name " + vars["report_name"] + " does not exist" output, err := createErrorMessage(message, code, contentType) //Render the response into XML or JSON h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) return code, h, output, err } selectedGroupType := requestedReport.DetermineGroupType(vars["group_type"]) if selectedGroupType == "endpoint" { if vars["lgroup_type"] == "" { vars["lgroup_type"] = vars["group_type"] vars["lgroup_name"] = vars["group_name"] vars["group_type"] = "" vars["group_name"] = "" } return ListEndpointGroupResults(r, cfg) } else if selectedGroupType == "group" { return ListSuperGroupResults(r, cfg) } code = http.StatusNotFound message := "The report " + vars["report_name"] + " does not define any group type: " + vars["group_type"] output, err = createErrorMessage(message, code, contentType) //Render the response into XML or JSON h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) return code, h, output, err }
func List(r *http.Request, cfg config.Config) (int, http.Header, []byte, error) { //STANDARD DECLARATIONS START code := http.StatusOK h := http.Header{} output := []byte("") err := error(nil) contentType := "text/xml" charset := "utf-8" //STANDARD DECLARATIONS END //Read the search values urlValues := r.URL.Query() //Searchig is based on name and namespace input := AvailabilityProfileSearch{ urlValues["name"], urlValues["namespace"], } results := []AvailabilityProfileOutput{} session, err := mongo.OpenSession(cfg) if err != nil { code = http.StatusInternalServerError return code, h, output, err } query := readOne(input) if len(input.Name) == 0 { query = nil //If no name and namespace is provided then we have to retrieve all profiles thus we send nil into db query } err = mongo.Find(session, cfg.MongoDB.Db, "aps", query, "_id", &results) if err != nil { code = http.StatusInternalServerError return code, h, output, err } mongo.CloseSession(session) output, err = createView(results) //Render the results into XML format if err != nil { code = http.StatusInternalServerError return code, h, output, err } h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) return code, h, output, err }
//Create a new metric profile func Create(r *http.Request, cfg config.Config) (int, http.Header, []byte, error) { //STANDARD DECLARATIONS START code := http.StatusOK h := http.Header{} output := []byte("") err := error(nil) charset := "utf-8" //STANDARD DECLARATIONS END // Set Content-Type response Header value contentType := r.Header.Get("Accept") h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) // Grab Tenant DB configuration from context tenantDbConfig := context.Get(r, "tenant_conf").(config.MongoConfig) session, err := mongo.OpenSession(tenantDbConfig) defer mongo.CloseSession(session) if err != nil { code = http.StatusInternalServerError return code, h, output, err } incoming := MongoInterface{} // Try ingest request body body, err := ioutil.ReadAll(io.LimitReader(r.Body, cfg.Server.ReqSizeLimit)) if err != nil { panic(err) } if err := r.Body.Close(); err != nil { panic(err) } // Parse body json if err := json.Unmarshal(body, &incoming); err != nil { output, _ = respond.MarshalContent(respond.BadRequestBadJSON, contentType, "", " ") code = 400 return code, h, output, err } // Generate new id incoming.ID = mongo.NewUUID() err = mongo.Insert(session, tenantDbConfig.Db, "metric_profiles", incoming) if err != nil { panic(err) } // Create view of the results output, err = createRefView(incoming, "Metric Profile successfully created", 201, r) //Render the results into JSON code = 201 return code, h, output, err }
// GetMetricResult returns the detailed message from a probe func GetMetricResult(r *http.Request, cfg config.Config) (int, http.Header, []byte, error) { //STANDARD DECLARATIONS START code := http.StatusOK h := http.Header{} output := []byte("") err := error(nil) charset := "utf-8" //STANDARD DECLARATIONS END // Set Content-Type response Header value contentType := r.Header.Get("Accept") h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) // Grab Tenant DB configuration from context tenantDbConfig := context.Get(r, "tenant_conf").(config.MongoConfig) // Parse the request into the input urlValues := r.URL.Query() vars := mux.Vars(r) input := metricResultQuery{ EndpointName: vars["endpoint_name"], MetricName: vars["metric_name"], ExecTime: urlValues.Get("exec_time"), } session, err := mongo.OpenSession(tenantDbConfig) defer mongo.CloseSession(session) if err != nil { code = http.StatusInternalServerError return code, h, output, err } result := metricResultOutput{} metricCol := session.DB(tenantDbConfig.Db).C("status_metrics") // Query the detailed metric results err = metricCol.Find(prepQuery(input)).One(&result) output, err = createMetricResultView(result, contentType) if err != nil { code = http.StatusInternalServerError return code, h, output, err } return code, h, output, err }
func routeCheckGroup(r *http.Request, cfg config.Config) (int, http.Header, []byte, error) { //STANDARD DECLARATIONS START code := http.StatusOK h := http.Header{} output := []byte("group check") err := error(nil) contentType := "application/xml" charset := "utf-8" //STANDARD DECLARATIONS END // Handle response format based on Accept Header // Default is application/xml format := r.Header.Get("Accept") if strings.EqualFold(format, "application/json") { contentType = "application/json" } vars := mux.Vars(r) tenantcfg, err := authentication.AuthenticateTenant(r.Header, cfg) if err != nil { return code, h, output, err } session, err := mongo.OpenSession(tenantcfg) defer mongo.CloseSession(session) if err != nil { return code, h, output, err } result := reports.MongoInterface{} err = mongo.FindOne(session, tenantcfg.Db, "reports", bson.M{"info.name": vars["report_name"]}, &result) if err != nil { message := "The report with the name " + vars["report_name"] + " does not exist" output, err := createMessageOUT(message, format) //Render the response into XML or JSON h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) return code, h, output, err } if vars["group_type"] != result.GetEndpointGroupType() { message := "The report " + vars["report_name"] + " does not define endpoint group type: " + vars["group_type"] output, err := createMessageOUT(message, format) //Render the response into XML or JSON h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) return code, h, output, err } return ListEndpointTimelines(r, cfg) }
func routeCheckGroup(r *http.Request, cfg config.Config) (int, http.Header, []byte, error) { //STANDARD DECLARATIONS START code := http.StatusOK h := http.Header{} output := []byte("group check") err := error(nil) charset := "utf-8" //STANDARD DECLARATIONS END // Handle response format based on Accept Header contentType := r.Header.Get("Accept") vars := mux.Vars(r) // Grab Tenant DB configuration from context tenantcfg := context.Get(r, "tenant_conf").(config.MongoConfig) session, err := mongo.OpenSession(tenantcfg) defer mongo.CloseSession(session) if err != nil { code = http.StatusInternalServerError output, _ = respond.MarshalContent(respond.InternalServerErrorMessage, contentType, "", " ") return code, h, output, err } result := reports.MongoInterface{} err = mongo.FindOne(session, tenantcfg.Db, "reports", bson.M{"info.name": vars["report_name"]}, &result) if err != nil { code = http.StatusNotFound message := "The report with the name " + vars["report_name"] + " does not exist" output, err := createMessageOUT(message, code, contentType) //Render the response into XML or JSON h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) return code, h, output, err } if vars["group_type"] != result.GetEndpointGroupType() { code = http.StatusNotFound message := "The report " + vars["report_name"] + " does not define endpoint group type: " + vars["group_type"] output, err := createMessageOUT(message, code, contentType) //Render the response into XML or JSON h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) return code, h, output, err } return ListMetricTimelines(r, cfg) }
func List(r *http.Request, cfg config.Config) (int, http.Header, []byte, error) { //STANDARD DECLARATIONS START code := http.StatusOK h := http.Header{} output := []byte("") err := error(nil) contentType := "text/xml" charset := "utf-8" //STANDARD DECLARATIONS END session, err := mongo.OpenSession(cfg) if err != nil { code = http.StatusInternalServerError return code, h, output, err } results := []FactorsOutput{} err = mongo.Find(session, "AR", "hepspec", nil, "p", &results) if err != nil { code = http.StatusInternalServerError return code, h, output, err } output, err = createView(results) //Render the results into XML format if err != nil { code = http.StatusInternalServerError return code, h, output, err } mongo.CloseSession(session) h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) return code, h, output, err }
// AuthenticateAdmin is used to authenticate and administrator of ARGO // and allow further CRUD ops wrt the argo_core database (i.e. add a new // tenant, modify another tenant's configuration etc) func AuthenticateAdmin(h http.Header, cfg config.Config) bool { session, err := mongo.OpenSession(cfg.MongoDB) defer mongo.CloseSession(session) if err != nil { panic(err) } query := bson.M{"api_key": h.Get("x-api-key")} projection := bson.M{"_id": 0, "name": 0, "email": 0} results := []Auth{} err = mongo.FindAndProject(session, cfg.MongoDB.Db, "authentication", query, projection, "api_key", &results) if err != nil { return false } if len(results) > 0 { return true } return false }
//Create a new metric profile func Create(r *http.Request, cfg config.Config) (int, http.Header, []byte, error) { //STANDARD DECLARATIONS START code := http.StatusOK h := http.Header{} output := []byte("") err := error(nil) charset := "utf-8" //STANDARD DECLARATIONS END contentType, err := respond.ParseAcceptHeader(r) h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) if err != nil { code = http.StatusNotAcceptable output, _ = respond.MarshalContent(respond.NotAcceptableContentType, contentType, "", " ") return code, h, output, err } tenantDbConfig, err := authentication.AuthenticateTenant(r.Header, cfg) if err != nil { output, _ = respond.MarshalContent(respond.UnauthorizedMessage, contentType, "", " ") code = http.StatusUnauthorized //If wrong api key is passed we return UNAUTHORIZED http status return code, h, output, err } session, err := mongo.OpenSession(tenantDbConfig) defer mongo.CloseSession(session) if err != nil { code = http.StatusInternalServerError return code, h, output, err } incoming := OpsProfile{} // Try ingest request body body, err := ioutil.ReadAll(io.LimitReader(r.Body, cfg.Server.ReqSizeLimit)) if err != nil { panic(err) } if err := r.Body.Close(); err != nil { panic(err) } // Parse body json if err := json.Unmarshal(body, &incoming); err != nil { output, _ = respond.MarshalContent(respond.BadRequestBadJSON, contentType, "", " ") code = 400 return code, h, output, err } // Validate States var errList []string errList = append(errList, incoming.validateDuplicates()...) errList = append(errList, incoming.validateStates()...) errList = append(errList, incoming.validateMentions()...) if len(errList) > 0 { output, err = createErrView("Validation Error", 422, errList) code = 422 return code, h, output, err } // Generate new id incoming.ID = mongo.NewUUID() err = mongo.Insert(session, tenantDbConfig.Db, "operations_profiles", incoming) if err != nil { panic(err) } // Create view of the results output, err = createRefView(incoming, "Operations Profile successfully created", 201, r) //Render the results into JSON code = 201 return code, h, output, err }
// ListServiceFlavorResults is responsible for handling request to list service flavor results func ListServiceFlavorResults(r *http.Request, cfg config.Config) (int, http.Header, []byte, error) { //STANDARD DECLARATIONS START code := http.StatusOK h := http.Header{} output := []byte("") err := error(nil) contentType := "application/xml" charset := "utf-8" //STANDARD DECLARATIONS END contentType, err = respond.ParseAcceptHeader(r) h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) if err != nil { code = http.StatusNotAcceptable output, _ = respond.MarshalContent(respond.NotAcceptableContentType, contentType, "", " ") return code, h, output, err } // Parse the request into the input urlValues := r.URL.Query() vars := mux.Vars(r) tenantDbConfig, err := authentication.AuthenticateTenant(r.Header, cfg) if err != nil { if err.Error() == "Unauthorized" { code = http.StatusUnauthorized out := respond.UnauthorizedMessage output = out.MarshalTo(contentType) return code, h, output, err } code = http.StatusInternalServerError return code, h, output, err } session, err := mongo.OpenSession(tenantDbConfig) defer mongo.CloseSession(session) if err != nil { code = http.StatusInternalServerError return code, h, output, err } report := reports.MongoInterface{} err = mongo.FindOne(session, tenantDbConfig.Db, "reports", bson.M{"info.name": vars["report_name"]}, &report) if err != nil { code = http.StatusBadRequest message := "The report with the name " + vars["report_name"] + " does not exist" output, err := createErrorMessage(message, contentType) //Render the response into XML or JSON h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) return code, h, output, err } input := serviceFlavorResultQuery{ basicQuery: basicQuery{ Name: vars["service_type"], Granularity: urlValues.Get("granularity"), Format: contentType, StartTime: urlValues.Get("start_time"), EndTime: urlValues.Get("end_time"), Report: report, Vars: vars, }, EndpointGroup: vars["lgroup_name"], } tenantDB := session.DB(tenantDbConfig.Db) errs := input.Validate(tenantDB) if len(errs) > 0 { out := respond.BadRequestSimple out.Errors = errs output = out.MarshalTo(contentType) code = 400 return code, h, output, err } if vars["lgroup_type"] != report.GetEndpointGroupType() { code = http.StatusBadRequest message := "The report " + vars["report_name"] + " does not define endpoint group type: " + vars["lgroup_type"] + ". Try using " + report.GetEndpointGroupType() + " instead." output, err := createErrorMessage(message, contentType) //Render the response into XML or JSON h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) return code, h, output, err } results := []ServiceFlavorInterface{} if err != nil { code = http.StatusInternalServerError return code, h, output, err } // Construct the query to mongodb based on the input filter := bson.M{ "date": bson.M{"$gte": input.StartTimeInt, "$lte": input.EndTimeInt}, "report": report.ID, } if input.Name != "" { filter["name"] = input.Name } if input.EndpointGroup != "" { filter["supergroup"] = input.EndpointGroup } // Select the granularity of the search daily/monthly if input.Granularity == "daily" { customForm[0] = "20060102" customForm[1] = "2006-01-02" query := DailyServiceFlavor(filter) err = mongo.Pipe(session, tenantDbConfig.Db, "service_ar", query, &results) } else if input.Granularity == "monthly" { customForm[0] = "200601" customForm[1] = "2006-01" query := MonthlyServiceFlavor(filter) err = mongo.Pipe(session, tenantDbConfig.Db, "service_ar", query, &results) } // mongo.Find(session, tenantDbConfig.Db, "endpoint_group_ar", bson.M{}, "_id", &results) if err != nil { code = http.StatusInternalServerError return code, h, output, err } output, err = createServiceFlavorResultView(results, report, input.Format) if err != nil { code = http.StatusInternalServerError return code, h, output, err } return code, h, output, err }
// ListSuperGroupResults supergroup availabilities according to the http request func ListSuperGroupResults(r *http.Request, cfg config.Config) (int, http.Header, []byte, error) { //STANDARD DECLARATIONS START code := http.StatusOK h := http.Header{} output := []byte("") err := error(nil) charset := "utf-8" //STANDARD DECLARATIONS END // Set Content-Type response Header value contentType := r.Header.Get("Accept") h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) // Parse the request into the input urlValues := r.URL.Query() vars := mux.Vars(r) // Grab Tenant DB configuration from context tenantDbConfig := context.Get(r, "tenant_conf").(config.MongoConfig) session, err := mongo.OpenSession(tenantDbConfig) defer mongo.CloseSession(session) if err != nil { code = http.StatusInternalServerError return code, h, output, err } report := reports.MongoInterface{} err = mongo.FindOne(session, tenantDbConfig.Db, "reports", bson.M{"info.name": vars["report_name"]}, &report) if err != nil { code = http.StatusInternalServerError return code, h, output, err } input := endpointGroupResultQuery{ basicQuery{ Name: vars["group_name"], Granularity: urlValues.Get("granularity"), Format: contentType, StartTime: urlValues.Get("start_time"), EndTime: urlValues.Get("end_time"), Report: report, Vars: vars, }, "", } tenantDB := session.DB(tenantDbConfig.Db) errs := input.Validate(tenantDB) if len(errs) > 0 { out := respond.BadRequestSimple out.Errors = errs output = out.MarshalTo(contentType) code = 400 return code, h, output, err } results := []SuperGroupInterface{} if err != nil { code = http.StatusInternalServerError return code, h, output, err } // Construct the query to mongodb based on the input filter := bson.M{ "date": bson.M{"$gte": input.StartTimeInt, "$lte": input.EndTimeInt}, "report": report.ID, } if input.Name != "" { filter["supergroup"] = input.Name } // Select the granularity of the search daily/monthly if input.Granularity == "daily" { customForm[0] = "20060102" customForm[1] = "2006-01-02" query := DailySuperGroup(filter) err = mongo.Pipe(session, tenantDbConfig.Db, "endpoint_group_ar", query, &results) } else if input.Granularity == "monthly" { customForm[0] = "200601" customForm[1] = "2006-01" query := MonthlySuperGroup(filter) err = mongo.Pipe(session, tenantDbConfig.Db, "endpoint_group_ar", query, &results) } // mongo.Find(session, tenantDbConfig.Db, "endpoint_group_ar", bson.M{}, "_id", &results) if err != nil { code = http.StatusInternalServerError return code, h, output, err } if len(results) == 0 { code = http.StatusNotFound message := "No results found for given query" output, err = createErrorMessage(message, code, contentType) return code, h, output, err } output, err = createSuperGroupView(results, report, input.Format) if err != nil { code = http.StatusInternalServerError return code, h, output, err } return code, h, output, err }
//Update function to update contents of an existing metric profile func Update(r *http.Request, cfg config.Config) (int, http.Header, []byte, error) { //STANDARD DECLARATIONS START code := http.StatusOK h := http.Header{} output := []byte("") err := error(nil) charset := "utf-8" //STANDARD DECLARATIONS END vars := mux.Vars(r) contentType, err := respond.ParseAcceptHeader(r) h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) if err != nil { code = http.StatusNotAcceptable output, _ = respond.MarshalContent(respond.NotAcceptableContentType, contentType, "", " ") return code, h, output, err } tenantDbConfig, err := authentication.AuthenticateTenant(r.Header, cfg) if err != nil { output, _ = respond.MarshalContent(respond.UnauthorizedMessage, contentType, "", " ") code = http.StatusUnauthorized //If wrong api key is passed we return UNAUTHORIZED http status return code, h, output, err } incoming := OpsProfile{} // ingest body data body, err := ioutil.ReadAll(io.LimitReader(r.Body, cfg.Server.ReqSizeLimit)) if err != nil { panic(err) } if err := r.Body.Close(); err != nil { panic(err) } // parse body json if err := json.Unmarshal(body, &incoming); err != nil { output, _ = respond.MarshalContent(respond.BadRequestBadJSON, contentType, "", " ") code = 400 return code, h, output, err } session, err := mongo.OpenSession(tenantDbConfig) defer mongo.CloseSession(session) if err != nil { code = http.StatusInternalServerError return code, h, output, err } // create filter to retrieve specific profile with id filter := bson.M{"id": vars["ID"]} incoming.ID = vars["ID"] // Retrieve Results from database results := []OpsProfile{} err = mongo.Find(session, tenantDbConfig.Db, "operations_profiles", filter, "name", &results) if err != nil { panic(err) } // Check if nothing found if len(results) < 1 { output, _ = respond.MarshalContent(respond.NotFound, contentType, "", " ") code = 404 return code, h, output, err } // Validate States var errList []string errList = append(errList, incoming.validateDuplicates()...) errList = append(errList, incoming.validateStates()...) errList = append(errList, incoming.validateMentions()...) if len(errList) > 0 { output, err = createErrView("Validation Error", 422, errList) code = 422 return code, h, output, err } // run the update query err = mongo.Update(session, tenantDbConfig.Db, "operations_profiles", filter, incoming) if err != nil { code = http.StatusInternalServerError return code, h, output, err } // Create view for response message output, err = createMsgView("Operations Profile successfully updated", 200) //Render the results into JSON code = 200 return code, h, output, err }
func List(r *http.Request, cfg config.Config) (int, http.Header, []byte, error) { //STANDARD DECLARATIONS START code := http.StatusOK h := http.Header{} output := []byte("Hello there!") err := error(nil) contentType := "text/xml" charset := "utf-8" //var buffer bytes.Buffer //STANDARD DECLARATIONS END // URL PATH_VALUES urlPath := r.URL.Path group := strings.Split(urlPath, "/")[6] urlValues := r.URL.Query() input := StatusSitesInput{ urlValues.Get("start_time"), urlValues.Get("end_time"), urlValues.Get("vo"), urlValues.Get("profile"), urlValues.Get("group_type"), group, } // Set default values if len(input.profile) == 0 { input.profile = "ch.cern.sam.ROC_CRITICAL" } if len(input.group_type) == 0 { input.group_type = "site" } if len(input.vo) == 0 { input.vo = "ops" } // Mongo Session results := []StatusSitesOutput{} session, err := mongo.OpenSession(cfg) c := session.DB("AR").C("status_sites") err = c.Find(prepQuery(input)).All(&results) mongo.CloseSession(session) output, err = createView(results, input) //Render the results into XML format //if strings.ToLower(input.format) == "json" { // contentType = "application/json" //} //buffer.WriteString(strconv.Itoa(len(results))) //output = []byte(buffer.String()) h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) return code, h, output, err }
func routeGroup(r *http.Request, cfg config.Config) (int, http.Header, []byte, error) { //STANDARD DECLARATIONS START code := http.StatusOK h := http.Header{} output := []byte("") err := error(nil) contentType := "application/xml" charset := "utf-8" //STANDARD DECLARATIONS END // Handle response format based on Accept Header // Default is application/xml format := r.Header.Get("Accept") if strings.EqualFold(format, "application/json") { contentType = "application/json" } vars := mux.Vars(r) tenantcfg, err := authentication.AuthenticateTenant(r.Header, cfg) if err != nil { if err.Error() == "Unauthorized" { code = http.StatusUnauthorized message := err.Error() output, err = createErrorMessage(message, contentType) h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) return code, h, output, err } code = http.StatusInternalServerError return code, h, output, err } session, err := mongo.OpenSession(tenantcfg) defer mongo.CloseSession(session) if err != nil { return code, h, output, err } requestedReport := reports.MongoInterface{} err = mongo.FindOne(session, tenantcfg.Db, "reports", bson.M{"info.name": vars["report_name"]}, &requestedReport) if err != nil { code = http.StatusBadRequest message := "The report with the name " + vars["report_name"] + " does not exist" output, err := createErrorMessage(message, contentType) //Render the response into XML or JSON h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) return code, h, output, err } selectedGroupType := requestedReport.DetermineGroupType(vars["group_type"]) if selectedGroupType == "endpoint" { if vars["lgroup_type"] == "" { vars["lgroup_type"] = vars["group_type"] vars["lgroup_name"] = vars["group_name"] vars["group_type"] = "" vars["group_name"] = "" } return ListEndpointGroupResults(r, cfg) } else if selectedGroupType == "group" { return ListSuperGroupResults(r, cfg) } code = http.StatusBadRequest message := "The report " + vars["report_name"] + " does not define any group type: " + vars["group_type"] output, err = createErrorMessage(message, format) //Render the response into XML or JSON h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", format, charset)) return code, h, output, err }
// ListOne handles the listing of one specific profile based on its given id func ListOne(r *http.Request, cfg config.Config) (int, http.Header, []byte, error) { //STANDARD DECLARATIONS START code := http.StatusOK h := http.Header{} output := []byte("") err := error(nil) contentType := "text/xml" charset := "utf-8" //STANDARD DECLARATIONS END // Content Negotiation contentType, err = respond.ParseAcceptHeader(r) h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) vars := mux.Vars(r) if err != nil { code = http.StatusNotAcceptable output, _ = respond.MarshalContent(respond.NotAcceptableContentType, contentType, "", " ") return code, h, output, err } // Tenant Authentication tenantDbConfig, err := authentication.AuthenticateTenant(r.Header, cfg) if err != nil { output, _ = respond.MarshalContent(respond.UnauthorizedMessage, contentType, "", " ") code = http.StatusUnauthorized //If wrong api key is passed we return UNAUTHORIZED http status return code, h, output, err } // Open session to tenant database session, err := mongo.OpenSession(tenantDbConfig) defer mongo.CloseSession(session) if err != nil { code = http.StatusInternalServerError return code, h, output, err } filter := bson.M{"id": vars["ID"]} // Retrieve Results from database results := []OpsProfile{} err = mongo.Find(session, tenantDbConfig.Db, "operations_profiles", filter, "name", &results) if err != nil { code = http.StatusInternalServerError return code, h, output, err } // Check if nothing found if len(results) < 1 { output, _ = respond.MarshalContent(respond.NotFound, contentType, "", " ") code = 404 return code, h, output, err } // Create view of the results output, err = createListView(results, "Success", code) //Render the results into JSON if err != nil { code = http.StatusInternalServerError return code, h, output, err } h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) return code, h, output, err }
// SetupTest will bootstrap and provide the testing environment func (suite *AuthenticationProfileTestSuite) SetupTest() { const testConfig = ` [server] bindip = "" port = 8080 maxprocs = 4 cache = false lrucache = 700000000 gzip = true [mongodb] host = "127.0.0.1" port = 27017 db = "argo_core_test_authenticate" ` _ = gcfg.ReadStringInto(&suite.cfg, testConfig) suite.respUnauthorized = "Unauthorized" suite.tenantdb = "argo_egi_AR_data" suite.clientkey = "mysecretcombination" suite.tenantpassword = "******" suite.tenantusername = "******" suite.tenantstorename = "ar" // seed mongo session, err := mongo.OpenSession(suite.cfg.MongoDB) if err != nil { panic(err) } defer mongo.CloseSession(session) // Seed database with tenants //TODO: move tests to c := session.DB(suite.cfg.MongoDB.Db).C("tenants") c.Insert( bson.M{"name": "Westeros", "db_conf": []bson.M{ bson.M{ "server": "localhost", "port": 27017, "database": "argo_Westeros1", }, bson.M{ "server": "localhost", "port": 27017, "database": "argo_Westeros2", }, }, "users": []bson.M{ bson.M{ "name": "John Snow", "email": "*****@*****.**", "api_key": "wh1t3_w@lk3rs", }, bson.M{ "name": "King Joffrey", "email": "*****@*****.**", "api_key": "sansa <3", }, }}) c.Insert( bson.M{"name": "EGI", "db_conf": []bson.M{ bson.M{ "store": suite.tenantstorename, "server": "localhost", "port": 27017, "database": suite.tenantdb, "username": suite.tenantusername, "password": suite.tenantpassword, }, bson.M{ "server": "localhost", "port": 27017, "database": "argo_egi_metric_data", }, }, "users": []bson.M{ bson.M{ "name": "Joe Complex", "email": "*****@*****.**", "api_key": suite.clientkey, }, bson.M{ "name": "Josh Plain", "email": "*****@*****.**", "api_key": "itsamysterytoyou", }, }}) c = session.DB(suite.cfg.MongoDB.Db).C("authentication") c.Insert( bson.M{ "name": "Igano Kabamaru", "email": "*****@*****.**", "api_key": "makaronada", }, ) c.Insert( bson.M{ "name": "Optimus Prime", "email": "*****@*****.**", "api_key": "megatron_sucks", }, ) }
func (suite *RecomputationsProfileTestSuite) TestSubmitRecomputations() { submission := IncomingRecomputation{ StartTime: "2015-01-10T12:00:00Z", EndTime: "2015-01-30T23:00:00Z", Reason: "Ups failure", Report: "EGI_Critical", Exclude: []string{"SITE5", "SITE8"}, } jsonsubmission, _ := json.Marshal(submission) request, _ := http.NewRequest("POST", "https://argo-web-api.grnet.gr:443/api/v2/recomputations", bytes.NewBuffer(jsonsubmission)) request.Header.Set("x-api-key", suite.clientkey) request.Header.Set("Accept", "application/json") response := httptest.NewRecorder() suite.router.ServeHTTP(response, request) code := response.Code output := response.Body.String() recomputationRequestsJSON := `{ "status": { "message": "Recomputations successfully created", "code": "201" }, "data": { "id": ".+", "links": { "self": "https://argo-web-api.grnet.gr:443/api/v2/recomputations/.+" } } }` // Check that we must have a 200 ok code suite.Equal(202, code, "Internal Server Error") // Compare the expected and actual xml response suite.Regexp(recomputationRequestsJSON, output, "Response body mismatch") dbDumpJson := `\[ \{ "id": "6ac7d684-1f8e-4a02-a502-720e8f11e50a", "requester_name": "Arya Stark", "requester_email": "*****@*****.**", "reason": "power cuts", "start_time": "2015-01-10T12:00:00Z", "end_time": "2015-01-30T23:00:00Z", "report": "EGI_Critical", "exclude": \[ "SITE2", "SITE4" \], "status": "running", "timestamp": "2015-02-01 14:58:40" \}, \{ "id": "6ac7d684-1f8e-4a02-a502-720e8f11e50b", "requester_name": "John Snow", "requester_email": "*****@*****.**", "reason": "reasons", "start_time": "2015-03-10T12:00:00Z", "end_time": "2015-03-30T23:00:00Z", "report": "EGI_Critical", "exclude": \[ "SITE1", "SITE3" \], "status": "pending", "timestamp": "2015-04-01 14:58:40" \}, \{ "id": ".+-.+-.+-.+-.+", "requester_name": "Joe Complex", "requester_email": "*****@*****.**", "reason": "Ups failure", "start_time": "2015-01-10T12:00:00Z", "end_time": "2015-01-30T23:00:00Z", "report": "EGI_Critical", "exclude": \[ "SITE5", "SITE8" \], "status": "pending", "timestamp": ".*" \} \]` session, _ := mongo.OpenSession(suite.tenantDbConf) defer mongo.CloseSession(session) var results []MongoInterface mongo.Find(session, suite.tenantDbConf.Db, recomputationsColl, nil, "timestamp", &results) json, _ := json.MarshalIndent(results, "", " ") suite.Regexp(dbDumpJson, string(json), "Database contents were not expected") }
// ListMetricTimelines returns a list of metric timelines func ListMetricTimelines(r *http.Request, cfg config.Config) (int, http.Header, []byte, error) { //STANDARD DECLARATIONS START code := http.StatusOK h := http.Header{} output := []byte("List Metric Timelines") err := error(nil) contentType := "application/xml" charset := "utf-8" //STANDARD DECLARATIONS END contentType, err = respond.ParseAcceptHeader(r) h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) if err != nil { code = http.StatusNotAcceptable output, _ = respond.MarshalContent(respond.NotAcceptableContentType, contentType, "", " ") return code, h, output, err } // Parse the request into the input urlValues := r.URL.Query() vars := mux.Vars(r) parsedStart, parsedEnd, errs := respond.ValidateDateRange(urlValues.Get("start_time"), urlValues.Get("end_time")) if len(errs) > 0 { code = http.StatusBadRequest output = respond.CreateFailureResponseMessage("Bad Request", "400", errs).MarshalTo(contentType) } input := InputParams{ parsedStart, parsedEnd, vars["report_name"], vars["group_type"], vars["group_name"], vars["service_name"], vars["endpoint_name"], vars["metric_name"], contentType, } // Call authenticateTenant to check the api key and retrieve // the correct tenant db conf tenantDbConfig, err := authentication.AuthenticateTenant(r.Header, cfg) if err != nil { output = []byte(http.StatusText(http.StatusUnauthorized)) code = http.StatusUnauthorized //If wrong api key is passed we return UNAUTHORIZED http status h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) return code, h, output, err } // Mongo Session results := []DataOutput{} session, err := mongo.OpenSession(tenantDbConfig) defer mongo.CloseSession(session) metricCollection := session.DB(tenantDbConfig.Db).C("status_metrics") // Query the detailed metric results reportID, err := mongo.GetReportID(session, tenantDbConfig.Db, input.report) if err != nil { code = http.StatusInternalServerError return code, h, output, err } err = metricCollection.Find(prepareQuery(input, reportID)).All(&results) if err != nil { code = http.StatusInternalServerError return code, h, output, err } output, err = createView(results, input) //Render the results into XML format h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) return code, h, output, err }
// ListMetricTimelines returns a list of metric timelines func ListServiceTimelines(r *http.Request, cfg config.Config) (int, http.Header, []byte, error) { //STANDARD DECLARATIONS START code := http.StatusOK h := http.Header{} output := []byte("List Service Timelines") err := error(nil) charset := "utf-8" //STANDARD DECLARATIONS END // Set Content-Type response Header value contentType := r.Header.Get("Accept") h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) // Parse the request into the input urlValues := r.URL.Query() vars := mux.Vars(r) parsedStart, _ := parseZuluDate(urlValues.Get("start_time")) parsedEnd, _ := parseZuluDate(urlValues.Get("end_time")) input := InputParams{ parsedStart, parsedEnd, vars["report_name"], vars["group_type"], vars["group_name"], vars["service_name"], contentType, } // Grab Tenant DB configuration from context tenantDbConfig := context.Get(r, "tenant_conf").(config.MongoConfig) // Mongo Session results := []DataOutput{} session, err := mongo.OpenSession(tenantDbConfig) defer mongo.CloseSession(session) metricCollection := session.DB(tenantDbConfig.Db).C("status_services") // Query the detailed metric results reportID, err := mongo.GetReportID(session, tenantDbConfig.Db, input.report) if err != nil { code = http.StatusInternalServerError return code, h, output, err } err = metricCollection.Find(prepareQuery(input, reportID)).All(&results) if err != nil { code = http.StatusInternalServerError return code, h, output, err } output, err = createView(results, input) //Render the results into XML format h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) return code, h, output, err }
func List(r *http.Request, cfg config.Config) (int, http.Header, []byte, error) { //STANDARD DECLARATIONS START code := http.StatusOK h := http.Header{} output := []byte("") err := error(nil) contentType := "text/xml" charset := "utf-8" //STANDARD DECLARATIONS END // This is the input we will receive from the API urlValues := r.URL.Query() input := ApiNgiAvailabilityInProfileInput{ urlValues.Get("start_time"), urlValues.Get("end_time"), urlValues.Get("availability_profile"), urlValues.Get("granularity"), urlValues.Get("infrastructure"), urlValues.Get("production"), urlValues.Get("monitored"), urlValues.Get("certification"), urlValues.Get("format"), urlValues["group_name"], } if len(input.Infrastructure) == 0 { input.Infrastructure = "Production" } if len(input.Production) == 0 || input.Production == "true" { input.Production = "Y" } else { input.Production = "N" } if len(input.Monitored) == 0 || input.Monitored == "true" { input.Monitored = "Y" } else { input.Monitored = "N" } if len(input.Certification) == 0 { input.Certification = "Certified" } if strings.ToLower(input.format) == "json" { contentType = "application/json" } found, output := caches.HitCache("ngis", input, cfg) h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) if found { return code, h, output, err } session, err := mongo.OpenSession(cfg) if err != nil { code = http.StatusInternalServerError return code, h, output, err } results := []ApiNgiAvailabilityInProfileOutput{} // Select the granularity of the search daily/monthly if len(input.Granularity) == 0 || strings.ToLower(input.Granularity) == "daily" { CustomForm[0] = "20060102" CustomForm[1] = "2006-01-02" query := Daily(input) err = mongo.Pipe(session, "AR", "sites", query, &results) } else if strings.ToLower(input.Granularity) == "monthly" { CustomForm[0] = "200601" CustomForm[1] = "2006-01" query := Monthly(input) err = mongo.Pipe(session, "AR", "sites", query, &results) } if err != nil { code = http.StatusInternalServerError return code, h, output, err } output, err = createView(results, input.format) if err != nil { code = http.StatusInternalServerError return code, h, output, err } if len(results) > 0 { caches.WriteCache("ngis", input, output, cfg) } mongo.CloseSession(session) return code, h, output, err }
//Update function to update contents of an existing metric profile func Update(r *http.Request, cfg config.Config) (int, http.Header, []byte, error) { //STANDARD DECLARATIONS START code := http.StatusOK h := http.Header{} output := []byte("") err := error(nil) charset := "utf-8" //STANDARD DECLARATIONS END vars := mux.Vars(r) // Set Content-Type response Header value contentType := r.Header.Get("Accept") h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) // Grab Tenant DB configuration from context tenantDbConfig := context.Get(r, "tenant_conf").(config.MongoConfig) incoming := MongoInterface{} // ingest body data body, err := ioutil.ReadAll(io.LimitReader(r.Body, cfg.Server.ReqSizeLimit)) if err != nil { panic(err) } if err := r.Body.Close(); err != nil { panic(err) } // parse body json if err := json.Unmarshal(body, &incoming); err != nil { output, _ = respond.MarshalContent(respond.BadRequestBadJSON, contentType, "", " ") code = 400 return code, h, output, err } session, err := mongo.OpenSession(tenantDbConfig) defer mongo.CloseSession(session) if err != nil { code = http.StatusInternalServerError return code, h, output, err } // create filter to retrieve specific profile with id filter := bson.M{"id": vars["ID"]} incoming.ID = vars["ID"] // Retrieve Results from database results := []MongoInterface{} err = mongo.Find(session, tenantDbConfig.Db, "metric_profiles", filter, "name", &results) if err != nil { panic(err) } // Check if nothing found if len(results) < 1 { output, _ = respond.MarshalContent(respond.NotFound, contentType, "", " ") code = 404 return code, h, output, err } // run the update query err = mongo.Update(session, tenantDbConfig.Db, "metric_profiles", filter, incoming) if err != nil { code = http.StatusInternalServerError return code, h, output, err } // Create view for response message output, err = createMsgView("Metric Profile successfully updated", 200) //Render the results into JSON code = 200 return code, h, output, err }