diff --git a/internal/defs.go b/internal/defs.go index 5626cfd..ea508a3 100644 --- a/internal/defs.go +++ b/internal/defs.go @@ -20,3 +20,28 @@ type Facts struct { Facts []Fact `json:"facts"` Type string `json:"type"` } + +type ProblemSeverityRating string + +type Problem struct { + EnvironmentId string `json:"environment"` + Identifier string `json:"identifier"` + Version string `json:"version,omitempty"` + FixedVersion string `json:"fixedVersion,omitempty"` + Source string `json:"source,omitempty"` + Service string `json:"service,omitempty"` + Data string `json:"data"` + Severity ProblemSeverityRating `json:"severity,omitempty"` + SeverityScore float64 `json:"severityScore,omitempty"` + AssociatedPackage string `json:"associatedPackage,omitempty"` + Description string `json:"description,omitempty"` + Links string `json:"links,omitempty"` +} + +type Problems struct { + EnvironmentId int `json:"environment"` + ProjectName string `json:"projectName"` + EnvironmentName string `json:"environmentName"` + Problems []Problem `json:"problems"` + Type string `json:"type"` +} diff --git a/internal/service/service.go b/internal/service/service.go index dc000eb..73d6b03 100644 --- a/internal/service/service.go +++ b/internal/service/service.go @@ -28,9 +28,87 @@ func SetupRouter(secret string, messageQWriter func(data []byte) error, writeToQ r.MessageQWriter = messageQWriter r.WriteToQueue = writeToQueue router.POST("/facts", r.writeFacts) + router.POST("/problems", r.writeProblems) return router } +func (r *routerInstance) writeProblems(c *gin.Context) { + + h := &AuthHeader{} + if err := c.ShouldBindHeader(&h); err != nil { + c.JSON(http.StatusOK, err) + } + + namespace, err := tokens.ValidateAndExtractNamespaceDetailsFromToken(r.secret, h.Authorization) + + if err != nil { + c.JSON(http.StatusUnauthorized, gin.H{ + "status": "unauthorized", + "message": err.Error(), + }) + return + } + + fmt.Println("Going to write to namespace ", namespace) + + //TODO: drop "InsightsType" for Type of the form "direct.fact"/"direct.problem" + //details := &internal.Facts{Type: "direct.problems"} + details := &internal.Problems{Type: "direct.problems"} + + if err = c.ShouldBindJSON(details); err != nil { + c.JSON(http.StatusBadRequest, gin.H{ + "status": "Unable to parse incoming data", + "message": err.Error(), + }) + fmt.Println(err) + return + } + + //let's force our facts to get pushed to the right place + lid, err := strconv.ParseInt(namespace.EnvironmentId, 10, 32) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{ + "status": "Unable to parse environment ID", + "message": err.Error(), + }) + fmt.Println(err) + return + } + + details.EnvironmentId = int(lid) + details.ProjectName = namespace.ProjectName + details.EnvironmentName = namespace.EnvironmentName + for i := range details.Problems { + details.Problems[i].EnvironmentId = namespace.EnvironmentId + + if details.Problems[i].Source == "" { + details.Problems[i].Source = "InsightsRemoteWebService" + } + } + + // Write this to the queue + + jsonRep, err := json.Marshal(details) + if err != nil { + c.JSON(http.StatusInternalServerError, err) + return + } + + if r.WriteToQueue { + err = r.MessageQWriter(jsonRep) + if err != nil { + c.JSON(http.StatusInternalServerError, err) + return + } + } else { + fmt.Printf("Not writing to queue - would have sent these data %v\n", string(jsonRep)) + } + + c.JSON(http.StatusOK, gin.H{ + "message": "okay", + }) +} + func (r *routerInstance) writeFacts(c *gin.Context) { h := &AuthHeader{} diff --git a/internal/service/service_test.go b/internal/service/service_test.go index 544a12d..2d58f9a 100644 --- a/internal/service/service_test.go +++ b/internal/service/service_test.go @@ -29,7 +29,7 @@ func resetWriterOutput() { queueWriterOutput = "" } -func TestWriteRoute(t *testing.T) { +func TestWriteFactsRoute(t *testing.T) { defer resetWriterOutput() router := SetupRouter(secretTestTokenSecret, messageQueueWriter, true) w := httptest.NewRecorder() @@ -65,3 +65,45 @@ func TestWriteRoute(t *testing.T) { assert.Contains(t, w.Body.String(), w.Body.String()) assert.Contains(t, queueWriterOutput, testFacts.Facts[0].Name) } + +func TestWriteProblemsRoute(t *testing.T) { + defer resetWriterOutput() + router := SetupRouter(secretTestTokenSecret, messageQueueWriter, true) + w := httptest.NewRecorder() + + token, err := tokens.GenerateTokenForNamespace(secretTestTokenSecret, tokens.NamespaceDetails{ + Namespace: secretTestNamespace, + EnvironmentId: "1", + ProjectName: "Test", + EnvironmentName: "Test", + }) + + require.NoError(t, err) + + testFacts := internal.Problems{ + Problems: []internal.Problem{ + internal.Problem{ + EnvironmentId: "1", + Identifier: "123", + Version: "1", + FixedVersion: "2", + Source: "a unique sources", + Service: "test", + Data: "test", + Severity: "1", + SeverityScore: 1, + AssociatedPackage: "test", + Description: "test", + Links: "test", + }, + }} + bodyString, _ := json.Marshal(testFacts) + req, _ := http.NewRequest(http.MethodPost, "/problems", bytes.NewBuffer(bodyString)) + req.Header.Set("Authorization", token) + req.Header.Set("Content-Type", "application/json") + router.ServeHTTP(w, req) + + assert.Equal(t, http.StatusOK, w.Code) + assert.Contains(t, w.Body.String(), w.Body.String()) + assert.Contains(t, queueWriterOutput, testFacts.Problems[0].Source) +}