// 2019 Rackspace, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package notes import ( "bytes" "fmt" "net/http" "strconv" "strings" "github.com/gin-gonic/gin" "github.rackspace.com/DCM/migui/pkg/tools" "github.rackspace.com/gorax/clients/goctk" "github.rackspace.com/gorax/tools/passkey" ) // CreateNote method is the Gin handler to process and return an API response for the UpdateNote notes. func CreateNote(c *gin.Context) { // swagger:operation POST /api/customer/notes Notes createNote // // This resource will create a new note in the customer DB // // --- // parameters: // - name: payload // in: body // description: Note JSON data // required: true // schema: // $ref: '#/definitions/NotePayload' // // responses: // 204: // description: Successful action // 400: // description: Bad Request // 404: // description: 404 page not found // 503: // description: Service Unavailable // Grab the user client from the Gin Context user := c.MustGet("userID").(string) // Small function to return a response back to Gin. Intended to // nest all main interactions within the call code, err := func() (int, error) { r, err := New(c) if err != nil { return http.StatusInternalServerError, err } var payload NotePayload if err := c.BindJSON(&payload); err != nil { return http.StatusBadRequest, err } // Gather all virtual-servers on the target devices if err := r.CreateNote(payload, user); err != nil { return http.StatusInternalServerError, err } return http.StatusNoContent, nil }() // Complete the transaction and return the response back // to io.writer tools.Complete(c, nil, code, err) } // GetNotes method is the Gin handler to process and return an API response for the ReadNotes notes. func GetNotes(c *gin.Context) { // swagger:operation GET /api/customer/notes Notes getNotes // // This resource will pull a list of all notes from the // customer DB backend // // --- // // responses: // 200: // description: Successful action // schema: // $ref: '#/definitions/respGetNotes' // 400: // description: Bad Request // schema: // $ref: '#/definitions/respGetNotes' // 404: // description: 404 page not found // 500: // description: Internal Server Error // Small function to return a response back to Gin. Intended to // nest all main interactions within the call data, code, err := func() (interface{}, int, error) { r, err := New(c) if err != nil { return nil, http.StatusInternalServerError, err } // Gather all virtual-servers on the target devices notes, err := r.ReadNotes(strings.ToUpper(c.Query("data_center")), c.Param("note_id")) if err != nil { return nil, http.StatusInternalServerError, err } return notes, http.StatusOK, nil }() // Complete the transaction and return the response back // to io.writer tools.Complete(c, data, code, err) } // GetNoteID method is a mock method for swagger documentation func GetNoteID() { // swagger:operation GET /api/customer/notes/{note} Notes getNoteId // // This resource will pull a single note by note_id from the // customer DB backend // --- // parameters: // - name: note // in: path // description: Specific note-id to return // required: true // type: string // // responses: // 200: // description: Successful action // schema: // $ref: '#/definitions/respGetNotes' // 400: // description: Bad Request // schema: // $ref: '#/definitions/respGetNotes' // 404: // description: 404 page not found // 500: // description: Internal Server Error } // PutNote method is the Gin handler to process and return an API response for the UpdateNote notes. func PutNote(c *gin.Context) { // swagger:operation PUT /api/customer/notes/{note} Notes putNote // // This resource will update a notes data with information specified in the // note payload request data // // --- // parameters: // - name: note // in: path // description: Specific note-id to return // required: true // type: string // - name: payload // in: body // description: Note JSON data // required: true // schema: // $ref: '#/definitions/NotePayload' // // responses: // 204: // description: Successful action // 400: // description: Bad Request // 404: // description: 404 page not found // 503: // description: Service Unavailable // Grab the userID from the Gin Context user := c.MustGet("userID").(string) // Small function to return a response back to Gin. Intended to // nest all main interactions within the call code, err := func() (int, error) { r, err := New(c) if err != nil { return http.StatusServiceUnavailable, err } var payload NotePayload if err := c.BindJSON(&payload); err != nil { return http.StatusBadRequest, err } // Gather all virtual-servers on the target devices if err := r.UpdateNote(c.Param("note_id"), user, payload); err != nil { return http.StatusServiceUnavailable, err } return http.StatusNoContent, nil }() // Complete the transaction and return the response back // to io.writer tools.Complete(c, nil, code, err) } // PutStatus method is the Gin handler to process and return an API response for the UpdateStatus notes. func PutStatus(c *gin.Context) { // swagger:operation PUT /api/customer/notes/{note}/status/{status} Notes putStatus // // This resource will update a given status for a note. Specified // by the note_id in the url path // // --- // parameters: // - name: note // in: path // description: Specific note-id // required: true // type: string // - name: status // in: path // description: New status to set // required: true // type: string // // responses: // 204: // description: Successful action // 400: // description: Bad Request // 404: // description: 404 page not found // 503: // description: Service Unavailable // Grab the user from the Gin Context user := c.MustGet("userID").(string) // Small function to return a response back to Gin. Intended to // nest all main interactions within the call code, err := func() (int, error) { r, err := New(c) if err != nil { return http.StatusServiceUnavailable, err } // Gather all virtual-servers on the target devices if err := r.UpdateStatus(c.Param("note_id"), user, c.Param("status")); err != nil { return http.StatusServiceUnavailable, err } return http.StatusNoContent, nil }() // Complete the transaction and return the response back // to io.writer tools.Complete(c, nil, code, err) } // DeleteNote method is the Gin handler to process and return an API response for the DeleteNote notes. func DeleteNote(c *gin.Context) { // swagger:operation DELETE /api/customer/notes/{note} Notes deleteNote // // This resource will remove a note from the customer DB. // Action is not recoverable // // --- // parameters: // - name: note // in: path // description: Specific note-id to delete // required: true // type: string // // responses: // 204: // description: Successful action // 400: // description: Bad Request // 404: // description: 404 page not found // 503: // description: Service Unavailable // Small function to return a response back to Gin. Intended to // nest all main interactions within the call code, err := func() (int, error) { r, err := New(c) if err != nil { return http.StatusServiceUnavailable, err } // Gather all virtual-servers on the target devices if err := r.DeleteNote(c.Param("note")); err != nil { return http.StatusServiceUnavailable, err } return http.StatusNoContent, nil }() // Complete the transaction and return the response back // to io.writer tools.Complete(c, nil, code, err) } // CreateAttachment method is the Gin handler to process and return an API response for the CreateAttachment notes. func CreateAttachment(c *gin.Context) { // swagger:operation POST /api/customer/notes/{note}/attachment/{name} Notes createAttachment // // This resource will create a new mass comms job // // --- // parameters: // - name: note // in: path // description: Specific note-id to use // required: true // type: string // - name: name // in: path // description: Filename // required: true // type: string // - name: file // in: formData // description: File to attach to note // type: string // required: true // // consumes: // - multipart/form-data // - application/x-www-form-urlencoded // // responses: // 204: // description: Attachment uploaded successfully // 400: // description: Bad Request. Payload might have been malformed or missing required information // 404: // description: 404 page not found // 500: // description: Internal Error. A server-side error happened during processing // Grab the passkey client from the Gin Context key := c.MustGet("passkey").(*passkey.Client) user := c.MustGet("userID").(string) // Small function to return a response back to Gin. Intended to // nest all main interactions within the call code, err := func() (int, error) { file, err := c.FormFile("file") if err != nil { return http.StatusBadRequest, err } uploadedFile, err := file.Open() if err != nil { return http.StatusBadRequest, err } r, err := New(c) if err != nil { return http.StatusServiceUnavailable, err } o, err := tools.ObjectService(key.Service.RSCloud) if err != nil { return http.StatusServiceUnavailable, err } // Gather all virtual-servers on the target devices if err := r.CreateAttachment(o, c.Param("note_id"), c.Param("name"), user, uploadedFile); err != nil { return http.StatusServiceUnavailable, err } return http.StatusNoContent, nil }() // Complete the transaction and return the response back // to io.writer tools.Complete(c, nil, code, err) } // GetAttachment method is the Gin handler to process and return an API response for the GetAttachment notes. func GetAttachment(c *gin.Context) { // swagger:operation GET /api/customer/notes/{note}/attachment/{name} Notes getAttachment // // This resource will download an attachment by name/note_id from the backend files system // // --- // parameters: // - name: note // in: path // description: Specific note-id to use // required: true // type: string // - name: name // in: path // description: Filename // required: true // type: string // // consumes: // - multipart/form-data // - application/x-www-form-urlencoded // // responses: // 200: // description: Attachment downloaded and returned // 400: // description: Bad Request. Payload might have been malformed or missing required information // 404: // description: 404 page not found // 500: // description: Internal Error. A server-side error happened during processing // Grab the passkey client from the Gin Context key := c.MustGet("passkey").(*passkey.Client) user := c.MustGet("userID").(string) // Small function to return a response back to Gin. Intended to // nest all main interactions within the call r, err := New(c) if err != nil { tools.Complete(c, nil, http.StatusServiceUnavailable, err) return } o, err := tools.ObjectService(key.Service.RSCloud) if err != nil { tools.Complete(c, nil, http.StatusServiceUnavailable, err) return } // Gather all virtual-servers on the target devices byt, head, err := r.GetAttachment(o, c.Param("note_id"), c.Param("name"), user) if err != nil { tools.Complete(c, nil, http.StatusServiceUnavailable, err) return } var ( contentLength int64 contentType = fmt.Sprintf("%s; charset=utf-8", head.Get("Content-Type")) ) if head.Get("Content-Length") != "" { contentLength, err = strconv.ParseInt(head.Get("Content-Length"), 10, 64) if err != nil { tools.Complete(c, nil, http.StatusServiceUnavailable, err) return } } c.DataFromReader(http.StatusOK, contentLength, contentType, bytes.NewReader(byt), make(map[string]string)) } // DeleteAttachment method is the Gin handler to process and return an API response for the DeleteAttachment notes. func DeleteAttachment(c *gin.Context) { // swagger:operation DELETE /api/customer/notes/{note}/attachment/{name} Notes deleteAttachment // // This resource will remove the association of an attachment to a note // // --- // parameters: // - name: note // in: path // description: Specific note-id to use // required: true // type: string // - name: name // in: path // description: Filename // required: true // type: string // // responses: // 204: // description: Attachment has been unassociated with the note // 404: // description: 404 page not found // 500: // description: Internal Error. A server-side error happened during processing // Grab the passkey client from the Gin Context key := c.MustGet("passkey").(*passkey.Client) user := c.MustGet("userID").(string) // Small function to return a response back to Gin. Intended to // nest all main interactions within the call code, err := func() (int, error) { r, err := New(c) if err != nil { return http.StatusServiceUnavailable, err } o, err := tools.ObjectService(key.Service.RSCloud) if err != nil { return http.StatusServiceUnavailable, err } // Gather all virtual-servers on the target devices if err := r.DeleteAttachment(o, c.Param("note_id"), c.Param("name"), user); err != nil { return http.StatusServiceUnavailable, err } return http.StatusNoContent, nil }() // Complete the transaction and return the response back // to io.writer tools.Complete(c, nil, code, err) } // GetAccount method is the Gin handler to process and return an API response for the ReadAccount notes. func GetAccount(c *gin.Context) { // swagger:operation GET /api/customer/account/{accountId} Account getAccount // // This resource will return account information using a CTK backend // in the format of the Account model. // // --- // parameters: // - name: accountId // in: path // description: CORE Account number // required: true // type: string // // responses: // 200: // description: Successful action // schema: // $ref: '#/definitions/respGetAccount' // 400: // description: Bad Request // 404: // description: 404 page not found // 503: // description: Service Unavailable // Small function to return a response back to Gin. Intended to // nest all main interactions within the call data, code, err := func() (Account, int, error) { var a Account r, err := New(c) if err != nil { return a, http.StatusServiceUnavailable, err } // Gather all virtual-servers on the target devices acctNum, err := strconv.Atoi(c.Param("account_id")) if err != nil { return a, http.StatusBadRequest, err } a, err = r.GetAccountInfo(acctNum) if err != nil { return a, http.StatusServiceUnavailable, err } return a, http.StatusOK, nil }() // Complete the transaction and return the response back // to io.writer tools.Complete(c, data, code, err) } // FindAccount method is the Gin handler to process and return an API response // for the CTKAccountSearch notes. func FindAccount(c *gin.Context) { // swagger:operation GET /api/customer/account_search/{part} Account findAccount // // This resource is used to search the salesforce SFI backend API for partial // matches of account names. To be used by the user-interface to allow for // account searching // // --- // parameters: // - name: part // in: path // description: Partial account name search string // required: true // type: string // // responses: // 200: // description: Successful action // schema: // $ref: '#/definitions/respFindAccount' // 400: // description: Bad Request // 404: // description: 404 page not found // 503: // description: Service Unavailable // Small function to return a response back to Gin. Intended to // nest all main interactions within the call data, code, err := func() ([]goctk.AccountSFISearch, int, error) { var a = make([]goctk.AccountSFISearch, 0) r, err := New(c) if err != nil { return a, http.StatusServiceUnavailable, err } // Gather a list of accounts that match the passed in data a, err = r.CTKAccountSearch(c.Param("part")) if err != nil { return a, http.StatusServiceUnavailable, err } return a, http.StatusOK, nil }() // Complete the transaction and return the response back // to io.writer tools.Complete(c, data, code, err) } // GetAccountMoveGroups method is the Gin handler to process and return an API response for the GetMoveGroups notes. func GetAccountMoveGroups(c *gin.Context) { // swagger:operation GET /api/customer/account/move_groups/{collection} Account getAccountMoveGroups // // This resource will return a list of move-groups for a given // collection or datacenter // // --- // parameters: // - name: collection // in: path // description: Move-group collection to source from // required: true // type: string // // responses: // 200: // description: Successful action // schema: // $ref: '#/definitions/respGetMoveGroups' // 400: // description: Bad Request // 404: // description: 404 page not found // 503: // description: Service Unavailable // Small function to return a response back to Gin. Intended to // nest all main interactions within the call data, code, err := func() (map[string][]string, int, error) { var mg map[string][]string r, err := New(c) if err != nil { return mg, http.StatusServiceUnavailable, err } // Gather all virtual-servers on the target devices mg, err = r.GetAccountMoveGroups(strings.ToLower(c.Param("collection"))) if err != nil { return mg, http.StatusServiceUnavailable, err } return mg, http.StatusOK, nil }() // Complete the transaction and return the response back // to io.writer tools.Complete(c, data, code, err) } // PutSyncAccount method is the Gin handler to process and return an API response for the Sync resources. func PutSyncAccount(c *gin.Context) { // swagger:operation PUT /api/customer/sync/accounts Sync putSyncAccount // // This resource will synchronize account data from CTK into the // customer account DB // // --- // responses: // 204: // description: Successful action // 400: // description: Bad Request // 404: // description: 404 page not found // 503: // description: Service Unavailable // Grab the user from the Gin Context user := c.MustGet("userID").(string) // Small function to return a response back to Gin. Intended to // nest all main interactions within the call code, err := func() (int, error) { r, err := New(c) if err != nil { return http.StatusServiceUnavailable, err } // Gather all virtual-servers on the target devices if err := r.SyncAccountData(c.Param("account_id"), user, c.Param("collection")); err != nil { return http.StatusServiceUnavailable, err } return http.StatusNoContent, nil }() // Complete the transaction and return the response back // to io.writer tools.Complete(c, nil, code, err) } // PutSyncAccountID method is a mock method for swagger func PutSyncAccountID() { // swagger:operation PUT /api/customer/sync/account/{account_id} Sync putSyncAccountId // // This resource will synchronize account data from CTK into the // customer account DB // // --- // parameters: // - name: account_id // in: path // description: Specific account number to sync with the migration DB // required: true // type: string // // responses: // 204: // description: Successful action // 400: // description: Bad Request // 404: // description: 404 page not found // 503: // description: Service Unavailable } // PutSyncAccountDC method is a mock method for swagger func PutSyncAccountDC() { // swagger:operation PUT /api/customer/sync/accounts/{collection} Sync putSyncAccountDC // // This resource will synchronize account data from CTK into the // customer account DB // // --- // parameters: // - name: collection // in: path // description: Collection (or datacenter) to collect account info from // required: true // type: string // // responses: // 204: // description: Successful action // 400: // description: Bad Request // 404: // description: 404 page not found // 503: // description: Service Unavailable }