// 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 }
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 }
// 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 }
// List existing recomputations 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 := "application/json" charset := "utf-8" //STANDARD DECLARATIONS END urlValues := r.URL.Query() contentType := r.Header.Get("Accept") 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 } filter := IncomingRecomputation{ StartTime: urlValues.Get("start_time"), EndTime: urlValues.Get("end_time"), Reason: urlValues.Get("reason"), Report: urlValues.Get("report"), } session, err := mongo.OpenSession(tenantDbConfig) if err != nil { code = http.StatusInternalServerError return code, h, output, err } results := []MongoInterface{} err = mongo.Find(session, tenantDbConfig.Db, recomputationsColl, filter, "timestamp", &results) if err != nil { code = http.StatusInternalServerError return code, h, output, err } output, err = createListView(results, contentType) return code, h, output, err }
// ListOne function implement an http GET request that accepts // a name parameter urlvar and retrieves information only for the // specific tenant 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 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)) // Try to open the mongo session session, err := mongo.OpenSession(cfg.MongoDB) defer session.Close() if err != nil { code = http.StatusInternalServerError return code, h, output, err } // Create structure to hold query results results := []Tenant{} // Create a simple query object to query by id query := bson.M{"id": vars["ID"]} // Query collection tenants for the specific tenant id err = mongo.Find(session, cfg.MongoDB.Db, "tenants", query, "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 = http.StatusNotFound return code, h, output, err } // After successfully retrieving the db results // call the createView function to render them into idented xml output, err = createListView(results, "Success", code) 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 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 function that implements the http GET request that retrieves // all avaiable report information 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 urlValues := r.URL.Query() // 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) // Try to open the mongo session session, err := mongo.OpenSession(cfg.MongoDB) defer session.Close() if err != nil { code = http.StatusInternalServerError return code, h, output, err } query := bson.M{} if urlValues.Get("name") != "" { query["info.name"] = urlValues["name"] } // Create structure for storing query results results := []MongoInterface{} // Query tenant collection for all available documents. // nil query param == match everything err = mongo.Find(session, tenantDbConfig.Db, reportsColl, nil, "id", &results) if err != nil { code = http.StatusInternalServerError return code, h, output, err } // After successfully retrieving the db results // call the createView function to render them into idented xml output, err = createView(results, contentType) 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 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 }
// 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 }
// validateID validates the metric profile id func (mp *MetricProfile) validateID(session *mgo.Session, db string, col string) error { var results []MetricProfile filter := bson.M{"id": mp.ID} err := mongo.Find(session, db, "metric_profiles", filter, "name", &results) if err != nil { return err } if len(results) > 0 { mp.Name = results[0].Name return nil } err = errors.New("Cannot validate") return err }
// List function that implements the http GET request that retrieves // all avaiable tenant information 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)) // Try to open the mongo session session, err := mongo.OpenSession(cfg.MongoDB) defer session.Close() if err != nil { code = http.StatusInternalServerError return code, h, output, err } // Create structure for storing query results results := []Tenant{} // Query tenant collection for all available documents. // nil query param == match everything err = mongo.Find(session, cfg.MongoDB.Db, "tenants", nil, "name", &results) if err != nil { code = http.StatusInternalServerError return code, h, output, err } // After successfully retrieving the db results // call the createView function to render them into idented xml output, err = createListView(results, "Success", code) 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 existing recomputations 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) filter := IncomingRecomputation{ StartTime: urlValues.Get("start_time"), EndTime: urlValues.Get("end_time"), Reason: urlValues.Get("reason"), Report: urlValues.Get("report"), } session, err := mongo.OpenSession(tenantDbConfig) if err != nil { code = http.StatusInternalServerError return code, h, output, err } results := []MongoInterface{} err = mongo.Find(session, tenantDbConfig.Db, recomputationsColl, filter, "timestamp", &results) if err != nil { code = http.StatusInternalServerError return code, h, output, err } output, err = createListView(results, contentType) 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 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 }
// 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 }
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") }
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) contentType := "text/xml" charset := "utf-8" //STANDARD DECLARATIONS END message := "" //Authentication procedure if authentication.Authenticate(r.Header, cfg) { session, err := mongo.OpenSession(cfg) if err != nil { code = http.StatusInternalServerError return code, h, output, err } name := []string{} namespace := []string{} //Reading the json input reqBody, err := ioutil.ReadAll(r.Body) input := AvailabilityProfileInput{} results := []AvailabilityProfileOutput{} //Unmarshalling the json input into byte form err = json.Unmarshal(reqBody, &input) if err != nil { if err != nil { message = "Malformated json input data" // User provided malformed json input data output, err := messageXML(message) if err != nil { code = http.StatusInternalServerError return code, h, output, err } code = http.StatusBadRequest h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) return code, h, output, err } } //Making sure that no profile with the requested name and namespace combination already exists in the DB name = append(name, input.Name) namespace = append(namespace, input.Namespace) search := AvailabilityProfileSearch{ name, namespace, } query := readOne(search) err = mongo.Find(session, cfg.MongoDB.Db, "aps", query, "name", &results) if err != nil { code = http.StatusInternalServerError return code, h, output, err } if len(results) <= 0 { //If name-namespace combination is unique we insert the new record into mongo query := createOne(input) err = mongo.Insert(session, cfg.MongoDB.Db, "aps", query) if err != nil { code = http.StatusInternalServerError return code, h, output, err } mongo.CloseSession(session) //Providing with the appropriate user response message = "Availability Profile record successfully created" output, err := messageXML(message) //Render the response into XML 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 } else { message = "An availability profile with that name already exists" output, err := messageXML(message) //Render the response into XML if err != nil { code = http.StatusInternalServerError return code, h, output, err } code = http.StatusBadRequest h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) return code, h, output, err } } else { 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 } }
// 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) 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)) if err != nil { code = http.StatusNotAcceptable output, _ = respond.MarshalContent(respond.NotAcceptableContentType, contentType, "", " ") return code, h, output, err } urlValues := r.URL.Query() // 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 } // 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 }
// Create function is used to implement the create report request. // The request is an http POST request with the report description // provided as json structure in the request body func Create(r *http.Request, cfg config.Config) (int, http.Header, []byte, error) { //STANDARD DECLARATIONS START code := http.StatusCreated 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) //Reading the json input from the request body reqBody, err := ioutil.ReadAll(io.LimitReader(r.Body, cfg.Server.ReqSizeLimit)) if err != nil { return code, h, output, err } input := MongoInterface{} //Unmarshalling the json input into byte form err = json.Unmarshal(reqBody, &input) // Check if json body is malformed if err != nil { output, _ := respond.MarshalContent(respond.MalformedJSONInput, contentType, "", " ") code = http.StatusBadRequest h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) return code, h, output, err } // Try to open the mongo session session, err := mongo.OpenSession(tenantDbConfig) defer session.Close() if err != nil { code = http.StatusInternalServerError return code, h, output, err } // Validate profiles given in report validationErrors := input.ValidateProfiles(session.DB(tenantDbConfig.Db)) if len(validationErrors) > 0 { code = 422 out := respond.UnprocessableEntity out.Errors = validationErrors output = out.MarshalTo(contentType) return code, h, output, err } // Prepare structure for storing query results results := []MongoInterface{} // Check if report with the same name exists in datastore query := searchName(input.Info.Name) err = mongo.Find(session, tenantDbConfig.Db, reportsColl, query, "name", &results) if err != nil { code = http.StatusInternalServerError return code, h, output, err } // If results are returned for the specific name // then we already have an existing report and we must // abort creation notifing the user if len(results) > 0 { // Name was found so print the error message in xml out := respond.ResponseMessage{ Status: respond.StatusResponse{ Message: "Report with the same name already exists", Code: strconv.Itoa(http.StatusConflict), }} output, _ = respond.MarshalContent(out, contentType, "", " ") code = http.StatusConflict h.Set("Content-Type", fmt.Sprintf("%s; charset=%s", contentType, charset)) return code, h, output, err } input.Info.Created = time.Now().Format("2006-01-02 15:04:05") input.Info.Updated = input.Info.Created input.ID = mongo.NewUUID() // If no report exists with this name create a new one err = mongo.Insert(session, tenantDbConfig.Db, reportsColl, input) if err != nil { code = http.StatusInternalServerError return code, h, output, err } // Notify user that the report has been created. In xml style selfLink := "https://" + r.Host + r.URL.Path + "/" + input.ID output, err = SubmitSuccesful(input, contentType, selfLink) 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 }
//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 }
//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 }
// Delete function used to implement remove tenant request func Delete(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 authentication procedure fails then // return unauthorized if authentication.AuthenticateAdmin(r.Header, cfg) == false { 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 } // Try to open the mongo session session, err := mongo.OpenSession(cfg.MongoDB) defer session.Close() if err != nil { code = http.StatusInternalServerError return code, h, output, err } filter := bson.M{"id": vars["ID"]} // Retrieve Results from database results := []Tenant{} err = mongo.Find(session, cfg.MongoDB.Db, "tenants", 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 = http.StatusNotFound return code, h, output, err } mongo.Remove(session, cfg.MongoDB.Db, "tenants", filter) if err != nil { code = http.StatusInternalServerError return code, h, output, err } // Create view of the results output, err = createMsgView("Tenant Successfully Deleted", 200) //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 function that implements the http GET request that retrieves // all avaiable report information 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 urlValues := r.URL.Query() 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 } // Try to open the mongo session session, err := mongo.OpenSession(cfg.MongoDB) defer session.Close() if err != nil { code = http.StatusInternalServerError return code, h, output, err } query := bson.M{} if urlValues.Get("name") != "" { query["info.name"] = urlValues["name"] } // Create structure for storing query results results := []MongoInterface{} // Query tenant collection for all available documents. // nil query param == match everything err = mongo.Find(session, tenantDbConfig.Db, reportsColl, nil, "id", &results) if err != nil { code = http.StatusInternalServerError return code, h, output, err } // After successfully retrieving the db results // call the createView function to render them into idented xml output, err = createView(results, contentType) 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 }
// Delete function used to implement remove tenant request func Delete(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) // Try to open the mongo session session, err := mongo.OpenSession(cfg.MongoDB) defer session.Close() if err != nil { code = http.StatusInternalServerError return code, h, output, err } filter := bson.M{"id": vars["ID"]} // Retrieve Results from database results := []Tenant{} err = mongo.Find(session, cfg.MongoDB.Db, "tenants", 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 = http.StatusNotFound return code, h, output, err } mongo.Remove(session, cfg.MongoDB.Db, "tenants", filter) if err != nil { code = http.StatusInternalServerError return code, h, output, err } // Create view of the results output, err = createMsgView("Tenant Successfully Deleted", 200) //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 }
// Update function used to implement update tenant request. // This is an http PUT request that gets a specific tenant's name // as a urlvar parameter input and a json structure in the request // body in order to update the datastore document for the specific // tenant 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 // 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) incoming := Tenant{} // 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 = http.StatusBadRequest return code, h, output, err } // Try to open the mongo session session, err := mongo.OpenSession(cfg.MongoDB) defer session.Close() 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 := []Tenant{} err = mongo.Find(session, cfg.MongoDB.Db, "tenants", 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 = http.StatusNotFound return code, h, output, err } // If user chose to change name - check if name already exists if results[0].Info.Name != incoming.Info.Name { sameName := []Tenant{} filter = bson.M{"info.name": incoming.Info.Name} err = mongo.Find(session, cfg.MongoDB.Db, "tenants", filter, "name", &sameName) if len(sameName) > 1 { code = http.StatusConflict output, err = createMsgView("Tenant with same name already exists", code) return code, h, output, err } } // run the update query incoming.Info.Created = results[0].Info.Created incoming.Info.Updated = time.Now().Format("2006-01-02 15:04:05") filter = bson.M{"id": vars["ID"]} err = mongo.Update(session, cfg.MongoDB.Db, "tenants", filter, incoming) if err != nil { code = http.StatusInternalServerError return code, h, output, err } // Create view for response message output, err = createMsgView("Tenant successfully updated", 200) //Render the results into JSON code = http.StatusOK return code, h, output, err }
// List function that implements the http GET request that retrieves // all avaiable tenant information 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 // Content Negotiation 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 } // if authentication procedure fails then // return unauthorized http status if authentication.AuthenticateAdmin(r.Header, cfg) == false { 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 } // Try to open the mongo session session, err := mongo.OpenSession(cfg.MongoDB) defer session.Close() if err != nil { code = http.StatusInternalServerError return code, h, output, err } // Create structure for storing query results results := []Tenant{} // Query tenant collection for all available documents. // nil query param == match everything err = mongo.Find(session, cfg.MongoDB.Db, "tenants", nil, "name", &results) if err != nil { code = http.StatusInternalServerError return code, h, output, err } // After successfully retrieving the db results // call the createView function to render them into idented xml output, err = createListView(results, "Success", code) 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 function is used to implement the create tenant request. // The request is an http POST request with the tenant description // provided as json structure in the request body 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)) // 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) } incoming := Tenant{} // Parse body json if err := json.Unmarshal(body, &incoming); err != nil { output, _ = respond.MarshalContent(respond.BadRequestBadJSON, contentType, "", " ") code = http.StatusBadRequest return code, h, output, err } // Try to open the mongo session session, err := mongo.OpenSession(cfg.MongoDB) defer session.Close() if err != nil { code = http.StatusInternalServerError return code, h, output, err } // Check if name exists sameName := []Tenant{} filter := bson.M{"info.name": incoming.Info.Name} err = mongo.Find(session, cfg.MongoDB.Db, "tenants", filter, "name", &sameName) if len(sameName) > 0 { code = http.StatusConflict output, err = createMsgView("Tenant with same name already exists", code) return code, h, output, err } // Generate new id incoming.ID = mongo.NewUUID() incoming.Info.Created = time.Now().Format("2006-01-02 15:04:05") incoming.Info.Updated = incoming.Info.Created err = mongo.Insert(session, cfg.MongoDB.Db, "tenants", incoming) if err != nil { panic(err) } // Create view of the results output, err = createRefView(incoming, "Tenant was succesfully created", 201, r) //Render the results into JSON code = http.StatusCreated return code, h, output, err }
// ListOne function implement an http GET request that accepts // a name parameter urlvar and retrieves information only for the // specific tenant 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 vars := mux.Vars(r) // Content Negotiation 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 } // if authentication procedure fails then // return unauthorized http status if authentication.AuthenticateAdmin(r.Header, cfg) == false { 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 } // Try to open the mongo session session, err := mongo.OpenSession(cfg.MongoDB) defer session.Close() if err != nil { code = http.StatusInternalServerError return code, h, output, err } // Create structure to hold query results results := []Tenant{} // Create a simple query object to query by id query := bson.M{"id": vars["ID"]} // Query collection tenants for the specific tenant id err = mongo.Find(session, cfg.MongoDB.Db, "tenants", query, "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 = http.StatusNotFound return code, h, output, err } // After successfully retrieving the db results // call the createView function to render them into idented xml output, err = createListView(results, "Success", code) 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 }