Skip to content

Commit

Permalink
Merge pull request #14 from uselagoon/feature/problems_service
Browse files Browse the repository at this point in the history
Extend service to include directly written problems
  • Loading branch information
bomoko authored Nov 21, 2023
2 parents 843696d + a29fdd6 commit 0e52d0c
Show file tree
Hide file tree
Showing 3 changed files with 196 additions and 7 deletions.
25 changes: 25 additions & 0 deletions internal/defs.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,28 @@ type Facts struct {
Facts []Fact `json:"facts"`
Type string `json:"type"`
}

type ProblemSeverityRating string

type Problem struct {
EnvironmentId int `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"`
}
95 changes: 91 additions & 4 deletions internal/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package service

import (
"fmt"
"io/ioutil"
"net/http"
"strconv"

Expand All @@ -28,10 +29,11 @@ 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) writeFacts(c *gin.Context) {
func (r *routerInstance) writeProblems(c *gin.Context) {

h := &AuthHeader{}
if err := c.ShouldBindHeader(&h); err != nil {
Expand All @@ -50,10 +52,10 @@ func (r *routerInstance) writeFacts(c *gin.Context) {

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.facts"}
details := &internal.Problems{Type: "direct.problems"}
problemList := *new([]internal.Problem)

if err = c.ShouldBindJSON(details); err != nil {
if err = c.ShouldBindJSON(&problemList); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"status": "Unable to parse incoming data",
"message": err.Error(),
Expand All @@ -73,6 +75,91 @@ func (r *routerInstance) writeFacts(c *gin.Context) {
return
}

details.EnvironmentId = int(lid)
details.ProjectName = namespace.ProjectName
details.EnvironmentName = namespace.EnvironmentName
details.Problems = problemList
for i := range details.Problems {
details.Problems[i].EnvironmentId = int(lid)

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{}
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.facts"}

// we try two different ways of parsing incoming facts - first as a simple list of facts
ByteBody, _ := ioutil.ReadAll(c.Request.Body)

factList := *new([]internal.Fact)
if err = json.Unmarshal(ByteBody, &factList); err != nil { // it might just be they're passing the "big" version with all details
if err = json.Unmarshal(ByteBody, details); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"status": "Unable to parse incoming data",
"message": err.Error(),
})
fmt.Println(err)
return
}
} else {
details.Facts = factList
}

//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
Expand Down
83 changes: 80 additions & 3 deletions internal/service/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ import (

const secretTestTokenSecret = "secret"
const secretTestNamespace = "testNS"
const testEnvironmentId = "777"

var queueWriterOutput string

func messageQueueWriter(data []byte) error {
//fmt.Println(string(data))
queueWriterOutput = string(data)
return nil
}
Expand All @@ -29,14 +29,14 @@ func resetWriterOutput() {
queueWriterOutput = ""
}

func TestWriteRoute(t *testing.T) {
func TestWriteFactsRoute(t *testing.T) {
defer resetWriterOutput()
router := SetupRouter(secretTestTokenSecret, messageQueueWriter, true)
w := httptest.NewRecorder()

token, err := tokens.GenerateTokenForNamespace(secretTestTokenSecret, tokens.NamespaceDetails{
Namespace: secretTestNamespace,
EnvironmentId: "1",
EnvironmentId: testEnvironmentId,
ProjectName: "Test",
EnvironmentName: "Test",
})
Expand Down Expand Up @@ -65,3 +65,80 @@ func TestWriteRoute(t *testing.T) {
assert.Contains(t, w.Body.String(), w.Body.String())
assert.Contains(t, queueWriterOutput, testFacts.Facts[0].Name)
}

func TestWriteFactsRouteNoProjectData(t *testing.T) {
defer resetWriterOutput()
router := SetupRouter(secretTestTokenSecret, messageQueueWriter, true)
w := httptest.NewRecorder()

token, err := tokens.GenerateTokenForNamespace(secretTestTokenSecret, tokens.NamespaceDetails{
Namespace: secretTestNamespace,
EnvironmentId: testEnvironmentId,
ProjectName: "Test",
EnvironmentName: "Test",
})

require.NoError(t, err)

testFacts := []internal.Fact{
{
Name: "testfact1",
Value: "testvalue1",
Source: "testsource1",
Description: "testdescription1",
Type: "testtype1",
Category: "testcategory1",
Service: "testservice1",
},
}
bodyString, _ := json.Marshal(testFacts)
req, _ := http.NewRequest(http.MethodPost, "/facts", 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[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: testEnvironmentId,
ProjectName: "Test",
EnvironmentName: "Test",
})

require.NoError(t, err)

testProblems := []internal.Problem{
{
EnvironmentId: 4,
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(testProblems)
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, queueWriterOutput, testProblems[0].Source)
}

0 comments on commit 0e52d0c

Please sign in to comment.