diff --git a/agent/container/pkg/clients/mock_nats_client.go b/agent/container/pkg/clients/mock_nats_client.go new file mode 100644 index 00000000..5f26bbd1 --- /dev/null +++ b/agent/container/pkg/clients/mock_nats_client.go @@ -0,0 +1,76 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: /Users/vijeshdeepan/Desktop/kubviz/agent/container/pkg/clients/nats_client.go + +// Package clients is a generated GoMock package. +package clients + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + nats "github.com/nats-io/nats.go" +) + +// MockNATSClientInterface is a mock of NATSClientInterface interface. +type MockNATSClientInterface struct { + ctrl *gomock.Controller + recorder *MockNATSClientInterfaceMockRecorder +} + +// MockNATSClientInterfaceMockRecorder is the mock recorder for MockNATSClientInterface. +type MockNATSClientInterfaceMockRecorder struct { + mock *MockNATSClientInterface +} + +// NewMockNATSClientInterface creates a new mock instance. +func NewMockNATSClientInterface(ctrl *gomock.Controller) *MockNATSClientInterface { + mock := &MockNATSClientInterface{ctrl: ctrl} + mock.recorder = &MockNATSClientInterfaceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockNATSClientInterface) EXPECT() *MockNATSClientInterfaceMockRecorder { + return m.recorder +} + +// Close mocks base method. +func (m *MockNATSClientInterface) Close() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Close") +} + +// Close indicates an expected call of Close. +func (mr *MockNATSClientInterfaceMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockNATSClientInterface)(nil).Close)) +} + +// CreateStream mocks base method. +func (m *MockNATSClientInterface) CreateStream() (nats.JetStreamContext, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateStream") + ret0, _ := ret[0].(nats.JetStreamContext) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateStream indicates an expected call of CreateStream. +func (mr *MockNATSClientInterfaceMockRecorder) CreateStream() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateStream", reflect.TypeOf((*MockNATSClientInterface)(nil).CreateStream)) +} + +// Publish mocks base method. +func (m *MockNATSClientInterface) Publish(event []byte, repo string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Publish", event, repo) + ret0, _ := ret[0].(error) + return ret0 +} + +// Publish indicates an expected call of Publish. +func (mr *MockNATSClientInterfaceMockRecorder) Publish(event, repo interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Publish", reflect.TypeOf((*MockNATSClientInterface)(nil).Publish), event, repo) +} diff --git a/agent/container/pkg/clients/nats_client.go b/agent/container/pkg/clients/nats_client.go index d087bb6c..cef9d0ba 100755 --- a/agent/container/pkg/clients/nats_client.go +++ b/agent/container/pkg/clients/nats_client.go @@ -15,6 +15,12 @@ import ( "github.com/nats-io/nats.go" ) +type NATSClientInterface interface { + Close() + CreateStream() (nats.JetStreamContext, error) + Publish(event []byte, repo string) error +} + // constant variables to use with nats stream and // nats publishing const ( diff --git a/agent/container/pkg/handler/api_handler.go b/agent/container/pkg/handler/api_handler.go index 6efee78d..7df98def 100755 --- a/agent/container/pkg/handler/api_handler.go +++ b/agent/container/pkg/handler/api_handler.go @@ -1,18 +1,26 @@ package handler import ( + "encoding/json" + "errors" + "fmt" + "io" "log" "net/http" + "strings" "github.com/gin-gonic/gin" "github.com/intelops/kubviz/agent/container/api" "github.com/intelops/kubviz/agent/container/pkg/clients" + "github.com/intelops/kubviz/model" "github.com/intelops/kubviz/pkg/opentelemetry" "go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" ) type APIHandler struct { - conn *clients.NATSContext + conn clients.NATSClientInterface } const ( @@ -56,6 +64,7 @@ func (ah *APIHandler) BindRequest(r *gin.Engine) { // This endpoint can be used by tools like Swagger UI to provide interactive documentation for the API. func (ah *APIHandler) GetApiDocs(c *gin.Context) { swagger, err := api.GetSwagger() + fmt.Println(swagger) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -73,3 +82,157 @@ func (ah *APIHandler) GetStatus(c *gin.Context) { c.Header(contentType, appJSONContentType) c.Status(http.StatusOK) } + +var ErrInvalidPayload = errors.New("invalid or malformed Azure Container Registry webhook payload") + +// PostEventAzureContainer listens for Azure Container Registry image push events. +// When a new image is pushed, this endpoint receives the event payload, validates it, +// and then publishes it to a NATS messaging system. This allows client of the +// application to subscribe to these events and respond to changes in the container registry. +// If the payload is invalid or the publishing process fails, an error response is returned. +func (ah *APIHandler) PostEventAzureContainer(c *gin.Context) { + + tracer := otel.Tracer("azure-container") + _, span := tracer.Start(c.Request.Context(), "PostEventAzureContainer") + span.SetAttributes(attribute.String("http.method", "POST")) + defer span.End() + + defer func() { + _, _ = io.Copy(io.Discard, c.Request.Body) + _ = c.Request.Body.Close() + }() + payload, err := io.ReadAll(c.Request.Body) + if err != nil || len(payload) == 0 { + log.Printf("%v: %v", ErrReadingBody, err) + c.Status(http.StatusBadRequest) + return + } + + var pushEvent model.AzureContainerPushEventPayload + err = json.Unmarshal(payload, &pushEvent) + if err != nil { + log.Printf("%v: %v", ErrInvalidPayload, err) + c.JSON(http.StatusBadRequest, gin.H{"error": "Bad Request"}) + return + } + + log.Printf("Received event from Azure Container Registry: %v", pushEvent) + + err = ah.conn.Publish(payload, "Azure_Container_Registry") + if err != nil { + log.Printf("%v: %v", ErrPublishToNats, err) + c.Status(http.StatusInternalServerError) + return + } + c.Status(http.StatusOK) +} + +// parse errors +var ( + ErrReadingBody = errors.New("error reading the request body") + ErrPublishToNats = errors.New("error while publishing to nats") +) + +func (ah *APIHandler) PostEventDockerHub(c *gin.Context) { + + tracer := otel.Tracer("dockerhub-container") + _, span := tracer.Start(c.Request.Context(), "PostEventDockerHub") + span.SetAttributes(attribute.String("http.method", "POST")) + defer span.End() + + payload, err := io.ReadAll(c.Request.Body) + if err != nil { + log.Printf("%v: %v", ErrReadingBody, err) + c.Status(http.StatusBadRequest) + return + } + if len(payload) == 0 || strings.TrimSpace(string(payload)) == "" { + log.Printf("%v: %v", ErrReadingBody, "empty body") + c.Status(http.StatusBadRequest) + return + } + log.Printf("Received event from docker artifactory: %v", string(payload)) + err = ah.conn.Publish(payload, "Dockerhub_Registry") + if err != nil { + log.Printf("%v: %v", ErrPublishToNats, err) + c.AbortWithStatus(http.StatusInternalServerError) // Use AbortWithStatus + return + } + c.Status(http.StatusOK) +} + +var ErrInvalidPayloads = errors.New("invalid or malformed jfrog Container Registry webhook payload") + +func (ah *APIHandler) PostEventJfrogContainer(c *gin.Context) { + + tracer := otel.Tracer("jfrog-container") + _, span := tracer.Start(c.Request.Context(), "PostEventJfrogContainer") + span.SetAttributes(attribute.String("http.method", "POST")) + defer span.End() + + payload, err := io.ReadAll(c.Request.Body) + if err != nil { + log.Printf("%v: %v", ErrReadingBody, err) + c.Status(http.StatusBadRequest) + return + } + if len(payload) == 0 || strings.TrimSpace(string(payload)) == "" { + log.Printf("%v: %v", ErrReadingBody, "empty body") + c.Status(http.StatusBadRequest) + return + } + + var pushEvent model.JfrogContainerPushEventPayload + err = json.Unmarshal(payload, &pushEvent) + if err != nil { + log.Printf("%v: %v", ErrInvalidPayloads, err) + c.JSON(http.StatusBadRequest, gin.H{"error": "Bad Request"}) + return + } + + log.Printf("Received event from jfrog Container Registry: %v", pushEvent) + + err = ah.conn.Publish(payload, "Jfrog_Container_Registry") + if err != nil { + log.Printf("%v: %v", ErrPublishToNats, err) + c.AbortWithStatus(http.StatusInternalServerError) // Use AbortWithStatus + return + } + c.Status(http.StatusOK) +} + +func (ah *APIHandler) PostEventQuayContainer(c *gin.Context) { + + tracer := otel.Tracer("quay-container") + _, span := tracer.Start(c.Request.Context(), "PostEventQuayContainer") + span.SetAttributes(attribute.String("http.method", "POST")) + defer span.End() + + payload, err := io.ReadAll(c.Request.Body) + if err != nil { + log.Printf("%v: %v", ErrReadingBody, err) + c.Status(http.StatusBadRequest) + return + } + if len(payload) == 0 || strings.TrimSpace(string(payload)) == "" { + log.Printf("%v: %v", ErrReadingBody, "empty body") + c.Status(http.StatusBadRequest) + return + } + var pushEvent model.QuayImagePushPayload + err = json.Unmarshal(payload, &pushEvent) + if err != nil { + log.Printf("%v: %v", "invalid or malformed Quay Container Registry webhook payload", err) + c.JSON(http.StatusBadRequest, gin.H{"error": "Bad Request"}) + return + } + log.Printf("Received event from Quay Container Registry: %v", pushEvent) + + err = ah.conn.Publish(payload, "Quay_Container_Registry") + if err != nil { + log.Printf("%v: %v", ErrPublishToNats, err) + c.AbortWithStatus(http.StatusInternalServerError) // Use AbortWithStatus + return + } + c.Status(http.StatusOK) +} diff --git a/agent/container/pkg/handler/api_handler_test.go b/agent/container/pkg/handler/api_handler_test.go new file mode 100644 index 00000000..88aa7948 --- /dev/null +++ b/agent/container/pkg/handler/api_handler_test.go @@ -0,0 +1,323 @@ +package handler + +import ( + "bytes" + "errors" + "log" + "net/http" + "net/http/httptest" + "os" + "testing" + + "github.com/gin-gonic/gin" + "github.com/golang/mock/gomock" + mock_main "github.com/intelops/kubviz/agent/container/pkg/clients" + "github.com/stretchr/testify/assert" +) + +func TestGetLiveness(t *testing.T) { + gin.SetMode(gin.TestMode) + app := &APIHandler{} + w := httptest.NewRecorder() + c, _ := gin.CreateTestContext(w) + app.GetStatus(c) + assert.Equal(t, http.StatusOK, w.Code) +} + +func TestPostEventAzureContainer(t *testing.T) { + gin.SetMode(gin.TestMode) + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + mockNatsClient := mock_main.NewMockNATSClientInterface(mockCtrl) + app := &APIHandler{ + conn: mockNatsClient, + } + + tests := []struct { + name string + headerEvent string + bodyData []byte + expectedLog string + expectedStatus int + mockPublishErr error + }{ + { + name: "Valid request", + headerEvent: "event", + bodyData: []byte(`{"id":"123","timestamp":"2024-06-10T10:00:00Z","action":"push","target":{"mediaType":"application/vnd.docker.distribution.manifest.v2+json","size":123,"digest":"sha256:1234567890abcdef","length":123,"repository":"repo","tag":"latest"},"request":{"id":"456","host":"localhost","method":"GET","useragent":"curl"}}`), + expectedLog: "Received event from Azure Container Registry", + expectedStatus: http.StatusOK, + mockPublishErr: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Reset the recorder for each test case + w := httptest.NewRecorder() + c, _ := gin.CreateTestContext(w) + + // Set the request body and header + req, _ := http.NewRequest(http.MethodPost, "/", bytes.NewBuffer(tt.bodyData)) + req.Header.Set("X-Event", tt.headerEvent) + c.Request = req + + // Set the expectation on the mock + if tt.mockPublishErr != nil { + mockNatsClient.EXPECT().Publish(gomock.Any(), gomock.Any()).Return(tt.mockPublishErr) + } else { + mockNatsClient.EXPECT().Publish(gomock.Any(), gomock.Any()).Return(nil) + } + var logOutput bytes.Buffer + log.SetOutput(&logOutput) + defer log.SetOutput(os.Stderr) + // Perform the request + app.PostEventAzureContainer(c) + // Verify the log output using strings.Contains + logStr := logOutput.String() + assert.Contains(t, logStr, tt.expectedLog, "log output should contain the expected log") + + // Check the response status code + assert.Equal(t, tt.expectedStatus, w.Code) + }) + } +} + +func TestPostEventDockerHub(t *testing.T) { + gin.SetMode(gin.TestMode) + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + mockNatsClient := mock_main.NewMockNATSClientInterface(mockCtrl) + app := &APIHandler{ + conn: mockNatsClient, + } + + // Define test cases + tests := []struct { + name string + headerEvent string + bodyData []byte + expectedLog string + expectedStatus int + mockPublishErr error + }{ + { + name: "Valid request", + headerEvent: "event", + bodyData: []byte(`{"key": "value"}`), + expectedLog: "Received event from docker artifactory:", + expectedStatus: http.StatusOK, + mockPublishErr: nil, + }, + { + name: "Empty body", + headerEvent: "event", + bodyData: []byte{}, + expectedLog: "error reading the request body", + expectedStatus: http.StatusOK, + mockPublishErr: nil, + }, + { + name: "Error publishing to NATS", + headerEvent: "event", + bodyData: []byte(`{"key": "value"}`), + expectedLog: "error while publishing to nats", + expectedStatus: http.StatusInternalServerError, + mockPublishErr: errors.New("some error"), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Reset the recorder for each test case + w := httptest.NewRecorder() + c, _ := gin.CreateTestContext(w) + + // Set the request body and header + req, _ := http.NewRequest(http.MethodPost, "/", bytes.NewBuffer(tt.bodyData)) + req.Header.Set("X-Event", tt.headerEvent) + c.Request = req + + // Set the mock expectation only if the body is not empty + if len(tt.bodyData) > 0 { + mockNatsClient.EXPECT().Publish(gomock.Any(), gomock.Any()).Return(tt.mockPublishErr) + } + + var logOutput bytes.Buffer + log.SetOutput(&logOutput) + defer log.SetOutput(os.Stderr) + + // Perform the request + app.PostEventDockerHub(c) + + // Verify the log output using strings.Contains + logStr := logOutput.String() + assert.Contains(t, logStr, tt.expectedLog, "log output should contain the expected log") + + // Check the response status code + assert.Equal(t, tt.expectedStatus, w.Code) + + // Log the error message and request body for debugging + if w.Code != tt.expectedStatus { + t.Log("Response body:", w.Body.String()) + t.Log("Request body:", string(tt.bodyData)) + } + + }) + } +} + +func TestPostEventJfrogContainer(t *testing.T) { + gin.SetMode(gin.TestMode) + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + mockNatsClient := mock_main.NewMockNATSClientInterface(mockCtrl) + app := &APIHandler{ + conn: mockNatsClient, + } + + tests := []struct { + name string + headerEvent string + bodyData []byte + expectedLog string + expectedStatus int + mockPublishErr error + }{ + { + name: "Valid request", + headerEvent: "event", + bodyData: []byte(`{"domain":"domain","event_type":"event","data":{"repo_key":"key","path":"path","name":"name","sha256":"sha","size":123,"image_name":"image","tag":"tag"},"subscription_key":"sub","jpd_origin":"origin","source":"source"}`), + expectedLog: "Received event from jfrog Container Registry", + expectedStatus: http.StatusOK, + mockPublishErr: nil, + }, + { + name: "Empty body", + headerEvent: "event", + bodyData: []byte{}, + expectedLog: "error reading the request body", + expectedStatus: http.StatusOK, + mockPublishErr: nil, + }, + { + name: "Error publishing to NATS", + headerEvent: "event", + bodyData: []byte(`{"domain":"domain","event_type":"event","data":{"repo_key":"key","path":"path","name":"name","sha256":"sha","size":123,"image_name":"image","tag":"tag"},"subscription_key":"sub","jpd_origin":"origin","source":"source"}`), + expectedLog: "Received event from jfrog Container", + expectedStatus: http.StatusInternalServerError, + mockPublishErr: errors.New("some error"), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + w := httptest.NewRecorder() + c, _ := gin.CreateTestContext(w) + + req, _ := http.NewRequest(http.MethodPost, "/", bytes.NewBuffer(tt.bodyData)) + req.Header.Set("X-Event", tt.headerEvent) + c.Request = req + + // Set the mock expectation only if the body is not empty + if len(tt.bodyData) > 0 { + mockNatsClient.EXPECT().Publish(gomock.Any(), gomock.Any()).Return(tt.mockPublishErr) + } + var logOutput bytes.Buffer + log.SetOutput(&logOutput) + defer log.SetOutput(os.Stderr) + + app.PostEventJfrogContainer(c) + + logStr := logOutput.String() + assert.Contains(t, logStr, tt.expectedLog, "log output should contain the expected log") + + assert.Equal(t, tt.expectedStatus, w.Code) + + if w.Code != tt.expectedStatus { + t.Log("Response body:", w.Body.String()) + t.Log("Request body:", string(tt.bodyData)) + } + }) + } +} + +func TestPostEventQuayContainer(t *testing.T) { + gin.SetMode(gin.TestMode) + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + mockNatsClient := mock_main.NewMockNATSClientInterface(mockCtrl) + app := &APIHandler{ + conn: mockNatsClient, + } + + tests := []struct { + name string + headerEvent string + bodyData []byte + expectedLog string + expectedStatus int + mockPublishErr error + }{ + { + name: "Valid request", + headerEvent: "event", + bodyData: []byte(`{"name":"name","repository":"repo","namespace":"namespace","docker_url":"url","homepage":"home","updated_tags":["tag1","tag2"]}`), + expectedLog: "Received event from Quay Container Registry", + expectedStatus: http.StatusOK, + mockPublishErr: nil, + }, + { + name: "Empty body", + headerEvent: "event", + bodyData: []byte{}, + expectedLog: "error reading the request body", + expectedStatus: http.StatusOK, + mockPublishErr: nil, + }, + { + name: "Error publishing to NATS", + headerEvent: "event", + bodyData: []byte(`{"name":"name","repository":"repo","namespace":"namespace","docker_url":"url","homepage":"home","updated_tags":["tag1","tag2"]}`), + expectedLog: "Received event from Quay Container", + expectedStatus: http.StatusInternalServerError, + mockPublishErr: errors.New("some error"), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + w := httptest.NewRecorder() + c, _ := gin.CreateTestContext(w) + + req, _ := http.NewRequest(http.MethodPost, "/", bytes.NewBuffer(tt.bodyData)) + req.Header.Set("X-Event", tt.headerEvent) + c.Request = req + + // Set the mock expectation only if the body is not empty + if len(tt.bodyData) > 0 { + mockNatsClient.EXPECT().Publish(gomock.Any(), gomock.Any()).Return(tt.mockPublishErr) + } + + var logOutput bytes.Buffer + log.SetOutput(&logOutput) + defer log.SetOutput(os.Stderr) + + app.PostEventQuayContainer(c) + + logStr := logOutput.String() + assert.Contains(t, logStr, tt.expectedLog, "log output should contain the expected log") + + assert.Equal(t, tt.expectedStatus, w.Code) + + if w.Code != tt.expectedStatus { + t.Log("Response body:", w.Body.String()) + t.Log("Request body:", string(tt.bodyData)) + } + }) + } +} diff --git a/agent/container/pkg/handler/azure_container.go b/agent/container/pkg/handler/azure_container.go deleted file mode 100644 index 35a72f3f..00000000 --- a/agent/container/pkg/handler/azure_container.go +++ /dev/null @@ -1,58 +0,0 @@ -package handler - -import ( - "encoding/json" - "errors" - "io" - "log" - "net/http" - - "github.com/gin-gonic/gin" - "github.com/intelops/kubviz/model" - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/attribute" -) - -var ErrInvalidPayload = errors.New("invalid or malformed Azure Container Registry webhook payload") - -// PostEventAzureContainer listens for Azure Container Registry image push events. -// When a new image is pushed, this endpoint receives the event payload, validates it, -// and then publishes it to a NATS messaging system. This allows client of the -// application to subscribe to these events and respond to changes in the container registry. -// If the payload is invalid or the publishing process fails, an error response is returned. -func (ah *APIHandler) PostEventAzureContainer(c *gin.Context) { - - tracer := otel.Tracer("azure-container") - _, span := tracer.Start(c.Request.Context(), "PostEventAzureContainer") - span.SetAttributes(attribute.String("http.method", "POST")) - defer span.End() - - defer func() { - _, _ = io.Copy(io.Discard, c.Request.Body) - _ = c.Request.Body.Close() - }() - payload, err := io.ReadAll(c.Request.Body) - if err != nil || len(payload) == 0 { - log.Printf("%v: %v", ErrReadingBody, err) - c.Status(http.StatusBadRequest) - return - } - - var pushEvent model.AzureContainerPushEventPayload - err = json.Unmarshal(payload, &pushEvent) - if err != nil { - log.Printf("%v: %v", ErrInvalidPayload, err) - c.JSON(http.StatusBadRequest, gin.H{"error": "Bad Request"}) - return - } - - log.Printf("Received event from Azure Container Registry: %v", pushEvent) - - err = ah.conn.Publish(payload, "Azure_Container_Registry") - if err != nil { - log.Printf("%v: %v", ErrPublishToNats, err) - c.Status(http.StatusInternalServerError) - return - } - c.Status(http.StatusOK) -} diff --git a/agent/container/pkg/handler/docker_event_dockerhub.go b/agent/container/pkg/handler/docker_event_dockerhub.go deleted file mode 100644 index f74bd8ae..00000000 --- a/agent/container/pkg/handler/docker_event_dockerhub.go +++ /dev/null @@ -1,45 +0,0 @@ -package handler - -import ( - "errors" - "io" - "log" - "net/http" - - "github.com/gin-gonic/gin" - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/attribute" -) - -// parse errors -var ( - ErrReadingBody = errors.New("error reading the request body") - ErrPublishToNats = errors.New("error while publishing to nats") -) - -func (ah *APIHandler) PostEventDockerHub(c *gin.Context) { - - tracer := otel.Tracer("dockerhub-container") - _, span := tracer.Start(c.Request.Context(), "PostEventDockerHub") - span.SetAttributes(attribute.String("http.method", "POST")) - defer span.End() - - defer func() { - _, _ = io.Copy(io.Discard, c.Request.Body) - _ = c.Request.Body.Close() - }() - payload, err := io.ReadAll(c.Request.Body) - if err != nil || len(payload) == 0 { - log.Printf("%v: %v", ErrReadingBody, err) - c.Status(http.StatusBadRequest) - return - } - log.Printf("Received event from docker artifactory: %v", string(payload)) - err = ah.conn.Publish(payload, "Dockerhub_Registry") - if err != nil { - log.Printf("%v: %v", ErrPublishToNats, err) - c.Status(http.StatusInternalServerError) - return - } - c.Status(http.StatusOK) -} diff --git a/agent/container/pkg/handler/jfrog_container.go b/agent/container/pkg/handler/jfrog_container.go deleted file mode 100644 index 8d57f272..00000000 --- a/agent/container/pkg/handler/jfrog_container.go +++ /dev/null @@ -1,53 +0,0 @@ -package handler - -import ( - "encoding/json" - "errors" - "io" - "log" - "net/http" - - "github.com/gin-gonic/gin" - "github.com/intelops/kubviz/model" - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/attribute" -) - -var ErrInvalidPayloads = errors.New("invalid or malformed jfrog Container Registry webhook payload") - -func (ah *APIHandler) PostEventJfrogContainer(c *gin.Context) { - - tracer := otel.Tracer("jfrog-container") - _, span := tracer.Start(c.Request.Context(), "PostEventJfrogContainer") - span.SetAttributes(attribute.String("http.method", "POST")) - defer span.End() - - defer func() { - _, _ = io.Copy(io.Discard, c.Request.Body) - _ = c.Request.Body.Close() - }() - payload, err := io.ReadAll(c.Request.Body) - if err != nil || len(payload) == 0 { - log.Printf("%v: %v", ErrReadingBody, err) - c.Status(http.StatusBadRequest) - return - } - - var pushEvent model.JfrogContainerPushEventPayload - err = json.Unmarshal(payload, &pushEvent) - if err != nil { - log.Printf("%v: %v", ErrInvalidPayloads, err) - c.JSON(http.StatusBadRequest, gin.H{"error": "Bad Request"}) - return - } - - log.Printf("Received event from jfrog Container Registry: %v", pushEvent) - - err = ah.conn.Publish(payload, "Jfrog_Container_Registry") - if err != nil { - log.Printf("%v: %v", ErrPublishToNats, err) - c.Status(http.StatusInternalServerError) - return - } - c.Status(http.StatusOK) -} diff --git a/agent/container/pkg/handler/quay_handler.go b/agent/container/pkg/handler/quay_handler.go deleted file mode 100644 index b1a2be84..00000000 --- a/agent/container/pkg/handler/quay_handler.go +++ /dev/null @@ -1,48 +0,0 @@ -package handler - -import ( - "encoding/json" - "io" - "log" - "net/http" - - "github.com/gin-gonic/gin" - "github.com/intelops/kubviz/model" - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/attribute" -) - -func (ah *APIHandler) PostEventQuayContainer(c *gin.Context) { - - tracer := otel.Tracer("quay-container") - _, span := tracer.Start(c.Request.Context(), "PostEventQuayContainer") - span.SetAttributes(attribute.String("http.method", "POST")) - defer span.End() - - defer func() { - _, _ = io.Copy(io.Discard, c.Request.Body) - _ = c.Request.Body.Close() - }() - payload, err := io.ReadAll(c.Request.Body) - if err != nil || len(payload) == 0 { - log.Printf("%v: %v", ErrReadingBody, err) - c.Status(http.StatusBadRequest) - return - } - var pushEvent model.QuayImagePushPayload - err = json.Unmarshal(payload, &pushEvent) - if err != nil { - log.Printf("%v: %v", ErrInvalidPayload, err) - c.JSON(http.StatusBadRequest, gin.H{"error": "Bad Request"}) - return - } - log.Printf("Received event from Quay Container Registry: %v", pushEvent) - - err = ah.conn.Publish(payload, "Quay_Container_Registry") - if err != nil { - log.Printf("%v: %v", ErrPublishToNats, err) - c.Status(http.StatusInternalServerError) - return - } - c.Status(http.StatusOK) -} \ No newline at end of file