Skip to content

Commit

Permalink
Merge pull request meshery#11190 from boku13/master
Browse files Browse the repository at this point in the history
[Server] Adding POST Capability to /api/events/
  • Loading branch information
MUzairS15 authored Jul 30, 2024
2 parents d6f6f82 + 884f5c9 commit fec178a
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 4 deletions.
12 changes: 11 additions & 1 deletion docs/_data/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1946,6 +1946,16 @@ paths:
- EventsAPI
summary: Handle GET request for events.
operationId: idGetEventStreamer
post:
responses:
"200":
description: ""
description: |-
Receives client-generated events bound for the Notification Center.
tags:
- EventsAPI
summary: Handle POST request for client generated events.
operationId: idClientEventHandler
/api/integrations/connections/{connectionKind}:
get:
description: |-
Expand Down Expand Up @@ -2859,4 +2869,4 @@ securityDefinitions:
in: cookie
security:
- token:
- '[]'
- '[]'
58 changes: 57 additions & 1 deletion server/handlers/events_streamer.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Package handlers :collection of handlers (aka "HTTP middleware")

package handlers

import (
Expand Down Expand Up @@ -473,3 +473,59 @@ func closeAdapterConnections(localMeshAdaptersLock *sync.Mutex, localMeshAdapter

return map[string]*meshes.MeshClient{}
}

// swagger:route POST /api/events EventsAPI idClientEventHandler
// Receives client-generated events bound for the Notification Center.
// responses:
// 200:

func (h *Handler) ClientEventHandler(w http.ResponseWriter, req *http.Request, prefObj *models.Preference, user *models.User, provider models.Provider) {
userID := uuid.FromStringOrNil(user.ID)

defer func() {
_ = req.Body.Close()
}()

var evt events.Event
body, err := io.ReadAll(req.Body)
if err != nil {
h.log.Error(ErrRequestBody(err))
http.Error(w, ErrRequestBody(err).Error(), http.StatusInternalServerError)
return
}

err = json.Unmarshal(body, &evt)
if err != nil {
h.log.Error(models.ErrUnmarshal(err, "event"))
http.Error(w, models.ErrUnmarshal(err, "event").Error(), http.StatusInternalServerError)
return
}

if(evt.ActedUpon.IsNil() || evt.Action == "" || evt.Category == "" || evt.Severity == ""){
h.log.Error(models.ErrInvalidEventData())
http.Error(w, models.ErrInvalidEventData().Error(), http.StatusBadRequest)
return
}

eventBuilder := events.NewEvent().FromUser(userID).FromSystem(*h.SystemID).
WithCategory(evt.Category).WithAction(evt.Action).WithSeverity(events.EventSeverity(evt.Severity)).
WithDescription(evt.Description).WithMetadata(evt.Metadata).ActedUpon(evt.ActedUpon)

event := eventBuilder.Build()
err = provider.PersistEvent(event)
if err != nil {
h.log.Error(models.ErrPersistEvent(err))
http.Error(w, models.ErrPersistEvent(err).Error(), http.StatusInternalServerError)
return

}
go h.config.EventBroadcaster.Publish(userID, event)

w.WriteHeader(http.StatusCreated)
err = json.NewEncoder(w).Encode(event)
if err != nil {
h.log.Error(models.ErrMarshal(err, "event response"))
http.Error(w, models.ErrMarshal(err, "event response").Error(), http.StatusInternalServerError)
return
}
}
12 changes: 11 additions & 1 deletion server/helpers/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,16 @@ paths:
summary: Handle GET request for events.
tags:
- EventsAPI
post:
description: |-
Receives client-generated events bound for the Notification Center.
operationId: idClientEventHandler
responses:
"200":
$ref: '#/responses/eventResponseWrapper'
summary: Handle POST request for client-generated events.
tags:
- EventsAPI
/api/events/{id}:
delete:
description: Deletes event associated with the id.
Expand Down Expand Up @@ -2805,4 +2815,4 @@ securityDefinitions:
in: cookie
name: token
type: apiKey
swagger: "2.0"
swagger: "2.0"
7 changes: 6 additions & 1 deletion server/models/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ const (
ErrUnreachableRemoteProviderCode = "meshery-server-1301"
ErrShareFilterCode = "meshery-server-1302"
ErrPersistEventCode = "meshery-server-1303"
ErrInvalidEventDataCode = "replace-me"
ErrUnreachableKubeAPICode = "meshery-server-1304"
ErrFlushMeshSyncDataCode = "meshery-server-1305"
ErrUpdateConnectionStatusCode = "meshery-server-1306"
Expand Down Expand Up @@ -463,6 +464,10 @@ func ErrPersistEvent(err error) error {
return errors.New(ErrPersistEventCode, errors.Alert, []string{"Could not persist event"}, []string{err.Error()}, []string{"Database could be down or not reachable", "Meshery Database handler is not accessible to perform operations"}, []string{"Restart Meshery Server or Perform Hard Reset"})
}

func ErrInvalidEventData() error {
return errors.New(ErrInvalidEventDataCode, errors.Alert, []string{"The event provided is not valid"}, []string{"ActedUpon, Action, Category and Severity are required fields of an event"}, []string{}, []string{"Ensure that ActedUpon, Action, Category and Severity are present in the event"})
}

func ErrUnreachableKubeAPI(err error, server string) error {
return errors.New(ErrUnreachableKubeAPICode, errors.Alert, []string{fmt.Sprintf("Error communicating with KubeAPI at %s.", server)}, []string{err.Error()}, []string{"The Kubernetes API server is not reachable.", "Credentials are invalid."}, []string{"Verify network connectivity and Kubernetes API responsiveness between Meshery Server and your cluster.", "Ensure client credential is not expired and is properly formed.", "Remove the cluster credential and enable 'insecure-skip-tls-verify'."})
}
Expand Down Expand Up @@ -556,4 +561,4 @@ func ErrUpdateResource(name, namespace string) error {
[]string{},
[]string{"Possible causes include invalid resource configuration, insufficient permissions, or network issues."},
[]string{"Verify the resource configuration and ensure it is correct. Ensure you have the necessary permissions to update the resource. Check network connectivity to the Kubernetes cluster."})
}
}
1 change: 1 addition & 0 deletions server/models/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ type HandlerInterface interface {
AdaptersHandler(w http.ResponseWriter, req *http.Request, prefObj *Preference, user *User, provider Provider)
AvailableAdaptersHandler(w http.ResponseWriter, req *http.Request)
EventStreamHandler(w http.ResponseWriter, req *http.Request, prefObj *Preference, user *User, provider Provider)
ClientEventHandler(w http.ResponseWriter, req *http.Request, prefObj *Preference, user *User, provider Provider)
AdapterPingHandler(w http.ResponseWriter, req *http.Request, prefObj *Preference, user *User, provider Provider)

DownloadHandler(w http.ResponseWriter, req *http.Request)
Expand Down
2 changes: 2 additions & 0 deletions server/router/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ func NewRouter(_ context.Context, h models.HandlerInterface, port int, g http.Ha

gMux.Handle("/api/events", h.ProviderMiddleware(h.AuthMiddleware(h.SessionInjectorMiddleware(h.EventStreamHandler), models.ProviderAuth))).
Methods("GET")
gMux.Handle("/api/v2/events", h.ProviderMiddleware(h.AuthMiddleware(h.SessionInjectorMiddleware(h.ClientEventHandler), models.ProviderAuth))).
Methods("POST")
// This will be changed to /api/events once the UI is compeltely updated to use new events and SSE is tunred off, otherwise existing events will break.
gMux.Handle("/api/v2/events", h.ProviderMiddleware(h.AuthMiddleware(h.SessionInjectorMiddleware(h.GetAllEvents), models.ProviderAuth))).
Methods("GET")
Expand Down

0 comments on commit fec178a

Please sign in to comment.