Browse Source

Merge branch 'belanger/agent-v3-integration' into dev

Alexander Belanger 3 năm trước cách đây
mục cha
commit
76d525b413

+ 0 - 78
api/server/handlers/cluster/get_incident_event_logs.go

@@ -1,78 +0,0 @@
-package cluster
-
-import (
-	"fmt"
-	"net/http"
-	"strings"
-	"time"
-
-	"github.com/porter-dev/porter/api/server/authz"
-	"github.com/porter-dev/porter/api/server/handlers"
-	"github.com/porter-dev/porter/api/server/shared"
-	"github.com/porter-dev/porter/api/server/shared/apierrors"
-	"github.com/porter-dev/porter/api/server/shared/config"
-	"github.com/porter-dev/porter/api/server/shared/websocket"
-	"github.com/porter-dev/porter/api/types"
-	"github.com/porter-dev/porter/internal/models"
-)
-
-type GetIncidentEventLogsHandler struct {
-	handlers.PorterHandlerReadWriter
-	authz.KubernetesAgentGetter
-}
-
-func NewGetIncidentEventLogsHandler(
-	config *config.Config,
-	decoderValidator shared.RequestDecoderValidator,
-	writer shared.ResultWriter,
-) *GetIncidentEventLogsHandler {
-	return &GetIncidentEventLogsHandler{
-		PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, decoderValidator, writer),
-		KubernetesAgentGetter:   authz.NewOutOfClusterAgentGetter(config),
-	}
-}
-
-func (c *GetIncidentEventLogsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	safeRW := r.Context().Value(types.RequestCtxWebsocketKey).(*websocket.WebsocketSafeReadWriter)
-	cluster, _ := r.Context().Value(types.ClusterScope).(*models.Cluster)
-
-	request := &types.GetIncidentEventLogsRequest{}
-
-	if ok := c.DecodeAndValidate(w, r, request); !ok {
-		return
-	}
-
-	k8sAgent, err := c.GetAgent(r, cluster, "porter-agent-system")
-
-	if err != nil {
-		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-		return
-	}
-
-	if len(request.Labels) == 0 {
-		return
-	}
-
-	// validate that the labels are valid
-	for _, label := range request.Labels {
-		if key, val, found := strings.Cut(label, "="); !found || key == "" || val == "" {
-			c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(fmt.Errorf("invalid label: %s", label),
-				http.StatusBadRequest))
-			return
-		}
-	}
-
-	// validate start time
-	if _, err := time.Parse(time.RFC3339, request.StartTime); err != nil {
-		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(fmt.Errorf("invalid start time: %s", request.StartTime),
-			http.StatusBadRequest))
-		return
-	}
-
-	err = k8sAgent.StreamPorterAgentLokiLog(request.Labels, request.StartTime, request.Limit, safeRW)
-
-	if err != nil {
-		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-		return
-	}
-}

+ 7 - 37
api/server/handlers/cluster/get_incidents.go → api/server/handlers/cluster/list_incidents.go

@@ -13,35 +13,31 @@ import (
 	"github.com/porter-dev/porter/internal/models"
 )
 
-type GetIncidentsHandler struct {
+type ListIncidentsHandler struct {
 	handlers.PorterHandlerReadWriter
 	authz.KubernetesAgentGetter
 }
 
-func NewGetIncidentsHandler(
+func NewListIncidentsHandler(
 	config *config.Config,
 	decoderValidator shared.RequestDecoderValidator,
 	writer shared.ResultWriter,
-) *GetIncidentsHandler {
-	return &GetIncidentsHandler{
+) *ListIncidentsHandler {
+	return &ListIncidentsHandler{
 		PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, decoderValidator, writer),
 		KubernetesAgentGetter:   authz.NewOutOfClusterAgentGetter(config),
 	}
 }
 
-func (c *GetIncidentsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+func (c *ListIncidentsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	cluster, _ := r.Context().Value(types.ClusterScope).(*models.Cluster)
 
-	request := &types.GetIncidentsRequest{}
+	request := &types.ListIncidentsRequest{}
 
 	if ok := c.DecodeAndValidate(w, r, request); !ok {
 		return
 	}
 
-	// incidentID := request.IncidentID
-	// releaseName := request.ReleaseName
-	// namespace := request.Namespace
-
 	agent, err := c.GetAgent(r, cluster, "")
 
 	if err != nil {
@@ -57,33 +53,7 @@ func (c *GetIncidentsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
 		return
 	}
 
-	// if incidentID != "" {
-	// 	events, err := porter_agent.GetIncidentEventsByID(agent.Clientset, agentSvc, incidentID)
-
-	// 	if err != nil {
-	// 		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-	// 		return
-	// 	}
-
-	// 	c.WriteResult(w, r, events)
-	// 	return
-	// } else if releaseName != "" {
-	// 	if namespace == "" {
-	// 		namespace = "default"
-	// 	}
-
-	// 	incidents, err := porter_agent.GetIncidentsByReleaseNamespace(agent.Clientset, agentSvc, releaseName, namespace)
-
-	// 	if err != nil {
-	// 		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-	// 		return
-	// 	}
-
-	// 	c.WriteResult(w, r, incidents)
-	// 	return
-	// }
-
-	incidents, err := porter_agent.GetAllIncidents(agent.Clientset, agentSvc)
+	incidents, err := porter_agent.ListIncidents(agent.Clientset, agentSvc, request)
 
 	if err != nil {
 		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))

+ 1 - 2
api/server/handlers/cluster/notify_new_incident.go

@@ -11,7 +11,6 @@ import (
 	"github.com/porter-dev/porter/api/server/shared/config"
 	"github.com/porter-dev/porter/api/types"
 	"github.com/porter-dev/porter/internal/integrations/slack"
-	porter_agent "github.com/porter-dev/porter/internal/kubernetes/porter_agent/v2"
 	"github.com/porter-dev/porter/internal/models"
 )
 
@@ -34,7 +33,7 @@ func NewNotifyNewIncidentHandler(
 func (c *NotifyNewIncidentHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	cluster, _ := r.Context().Value(types.ClusterScope).(*models.Cluster)
 
-	request := &porter_agent.Incident{}
+	request := &types.Incident{}
 
 	if ok := c.DecodeAndValidate(w, r, request); !ok {
 		return

+ 1 - 2
api/server/handlers/cluster/notify_resolved_incident.go

@@ -11,7 +11,6 @@ import (
 	"github.com/porter-dev/porter/api/server/shared/config"
 	"github.com/porter-dev/porter/api/types"
 	"github.com/porter-dev/porter/internal/integrations/slack"
-	porter_agent "github.com/porter-dev/porter/internal/kubernetes/porter_agent/v2"
 	"github.com/porter-dev/porter/internal/models"
 )
 
@@ -34,7 +33,7 @@ func NewNotifyResolvedIncidentHandler(
 func (c *NotifyResolvedIncidentHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	cluster, _ := r.Context().Value(types.ClusterScope).(*models.Cluster)
 
-	request := &porter_agent.Incident{}
+	request := &types.Incident{}
 
 	if ok := c.DecodeAndValidate(w, r, request); !ok {
 		return

+ 3 - 33
api/server/router/cluster.go

@@ -1156,7 +1156,7 @@ func getClusterRoutes(
 	})
 
 	// GET /api/projects/{project_id}/clusters/{cluster_id}/incidents -> cluster.NewGetIncidentsHandler
-	getIncidentsEndpoint := factory.NewAPIEndpoint(
+	listIncidentsEndpoint := factory.NewAPIEndpoint(
 		&types.APIRequestMetadata{
 			Verb:   types.APIVerbGet,
 			Method: types.HTTPVerbGet,
@@ -1172,48 +1172,18 @@ func getClusterRoutes(
 		},
 	)
 
-	getIncidentsHandler := cluster.NewGetIncidentsHandler(
+	getIncidentsHandler := cluster.NewListIncidentsHandler(
 		config,
 		factory.GetDecoderValidator(),
 		factory.GetResultWriter(),
 	)
 
 	routes = append(routes, &router.Route{
-		Endpoint: getIncidentsEndpoint,
+		Endpoint: listIncidentsEndpoint,
 		Handler:  getIncidentsHandler,
 		Router:   r,
 	})
 
-	// GET /api/projects/{project_id}/clusters/{cluster_id}/incidents/logs -> cluster.NewGetIncidentsHandler
-	getIncidentEventLogsEndpoint := factory.NewAPIEndpoint(
-		&types.APIRequestMetadata{
-			Verb:   types.APIVerbGet,
-			Method: types.HTTPVerbGet,
-			Path: &types.Path{
-				Parent:       basePath,
-				RelativePath: relPath + "/incidents/logs",
-			},
-			Scopes: []types.PermissionScope{
-				types.UserScope,
-				types.ProjectScope,
-				types.ClusterScope,
-			},
-			IsWebsocket: true,
-		},
-	)
-
-	getIncidentEventLogsHandler := cluster.NewGetIncidentEventLogsHandler(
-		config,
-		factory.GetDecoderValidator(),
-		factory.GetResultWriter(),
-	)
-
-	routes = append(routes, &router.Route{
-		Endpoint: getIncidentEventLogsEndpoint,
-		Handler:  getIncidentEventLogsHandler,
-		Router:   r,
-	})
-
 	// POST /api/projects/{project_id}/clusters/{cluster_id}/incidents/notify_new -> cluster.NewNotifyNewIncidentHandler
 	notifyNewIncidentEndpoint := factory.NewAPIEndpoint(
 		&types.APIRequestMetadata{

+ 100 - 10
api/types/cluster.go

@@ -1,6 +1,8 @@
 package types
 
 import (
+	"time"
+
 	"github.com/porter-dev/porter/internal/kubernetes/prometheus"
 )
 
@@ -273,18 +275,106 @@ type CreateClusterCandidateResponse []*ClusterCandidate
 
 type ListClusterCandidateResponse []*ClusterCandidate
 
-type GetIncidentsRequest struct {
-	IncidentID  string `schema:"incident_id"`
-	ReleaseName string `schema:"release_name"`
-	Namespace   string `schema:"namespace"`
+type SeverityType string
+
+const (
+	SeverityCritical SeverityType = "critical"
+	SeverityNormal   SeverityType = "normal"
+)
+
+type InvolvedObjectKind string
+
+const (
+	InvolvedObjectDeployment InvolvedObjectKind = "deployment"
+	InvolvedObjectJob        InvolvedObjectKind = "job"
+	InvolvedObjectPod        InvolvedObjectKind = "pod"
+)
+
+type IncidentStatus string
+
+const (
+	IncidentStatusResolved IncidentStatus = "resolved"
+	IncidentStatusActive   IncidentStatus = "active"
+)
+
+type IncidentMeta struct {
+	ID                      string             `json:"id" form:"required"`
+	ReleaseName             string             `json:"release_name" form:"required"`
+	ReleaseNamespace        string             `json:"release_namespace" form:"required"`
+	ChartName               string             `json:"chart_name" form:"required"`
+	CreatedAt               time.Time          `json:"created_at" form:"required"`
+	UpdatedAt               time.Time          `json:"updated_at" form:"required"`
+	LastSeen                *time.Time         `json:"last_seen" form:"required"`
+	Status                  IncidentStatus     `json:"status" form:"required"`
+	Summary                 string             `json:"summary" form:"required"`
+	Severity                SeverityType       `json:"severity" form:"required"`
+	InvolvedObjectKind      InvolvedObjectKind `json:"involved_object_kind" form:"required"`
+	InvolvedObjectName      string             `json:"involved_object_name" form:"required"`
+	InvolvedObjectNamespace string             `json:"involved_object_namespace" form:"required"`
+}
+
+type PaginationRequest struct {
+	Page int64 `schema:"page"`
+}
+
+type PaginationResponse struct {
+	NumPages    int64 `json:"num_pages" form:"required"`
+	CurrentPage int64 `json:"current_page" form:"required"`
+	NextPage    int64 `json:"next_page" form:"required"`
+}
+
+type ListIncidentsRequest struct {
+	*PaginationRequest
+	Status           *IncidentStatus `schema:"status"`
+	ReleaseName      *string         `schema:"release_name"`
+	ReleaseNamespace *string         `schema:"release_namespace"`
+}
+
+type ListIncidentsResponse struct {
+	Incidents  []*IncidentMeta     `json:"incidents" form:"required"`
+	Pagination *PaginationResponse `json:"pagination"`
+}
+
+type Incident struct {
+	*IncidentMeta
+	Pods   []string `json:"pods" form:"required"`
+	Detail string   `json:"detail" form:"required"`
+}
+
+type IncidentEvent struct {
+	ID           string     `json:"id" form:"required"`
+	LastSeen     *time.Time `json:"last_seen" form:"required"`
+	PodName      string     `json:"pod_name" form:"required"`
+	PodNamespace string     `json:"pod_namespace" form:"required"`
+	Summary      string     `json:"summary" form:"required"`
+	Detail       string     `json:"detail" form:"required"`
+}
+
+type ListIncidentEventsRequest struct {
+	*PaginationRequest
+	PodName      *string `schema:"pod_name"`
+	PodNamespace *string `schema:"pod_namespace"`
+	Summary      *string `schema:"summary"`
+}
+
+type ListIncidentEventsResponse struct {
+	Events     []*IncidentEvent    `json:"events" form:"required"`
+	Pagination *PaginationResponse `json:"pagination"`
+}
+
+type GetLogRequest struct {
+	Limit      uint       `json:"limit"`
+	StartRange *time.Time `json:"start_range"`
+	EndRange   *time.Time `json:"end_range"`
+	Pods       []string   `json:"pods"`
 }
 
-type GetIncidentEventLogsRequest struct {
-	Labels    []string `schema:"labels" form:"required"`
-	StartTime string   `schema:"start_time" form:"required"`
-	Limit     uint32   `schema:"limit"`
+type LogLine struct {
+	Timestamp *time.Time `json:"timestamp"`
+	Line      string     `json:"line"`
 }
 
-type IncidentNotifyRequest struct {
-	IncidentID string `json:"incident_id" form:"required"`
+type GetLogResponse struct {
+	ContinueTime *time.Time `json:"continue_time"`
+	Logs         []LogLine  `json:"logs"`
 }

+ 2 - 3
internal/integrations/slack/incidents_notifier.go

@@ -8,7 +8,6 @@ import (
 	"time"
 
 	"github.com/porter-dev/porter/api/types"
-	porter_agent "github.com/porter-dev/porter/internal/kubernetes/porter_agent/v2"
 	"github.com/porter-dev/porter/internal/models/integrations"
 )
 
@@ -24,7 +23,7 @@ func NewIncidentsNotifier(conf *types.NotificationConfig, slackInts ...*integrat
 	}
 }
 
-func (s *IncidentsNotifier) NotifyNew(incident *porter_agent.Incident, url string) error {
+func (s *IncidentsNotifier) NotifyNew(incident *types.Incident, url string) error {
 	res := []*SlackBlock{}
 
 	topSectionMarkdwn := fmt.Sprintf(
@@ -75,7 +74,7 @@ func (s *IncidentsNotifier) NotifyNew(incident *porter_agent.Incident, url strin
 	return nil
 }
 
-func (s *IncidentsNotifier) NotifyResolved(incident *porter_agent.Incident, url string) error {
+func (s *IncidentsNotifier) NotifyResolved(incident *types.Incident, url string) error {
 	res := []*SlackBlock{}
 
 	createdAt := incident.CreatedAt

+ 29 - 56
internal/kubernetes/porter_agent/v2/agent_server.go

@@ -5,6 +5,7 @@ import (
 	"encoding/json"
 	"fmt"
 
+	"github.com/porter-dev/porter/api/types"
 	v1 "k8s.io/api/core/v1"
 	"k8s.io/client-go/kubernetes"
 
@@ -20,10 +21,11 @@ func GetAgentService(clientset kubernetes.Interface) (*v1.Service, error) {
 	)
 }
 
-func GetAllIncidents(
+func ListIncidents(
 	clientset kubernetes.Interface,
 	service *v1.Service,
-) (*ListIncidentsResponse, error) {
+	req *types.ListIncidentsRequest,
+) (*types.ListIncidentsResponse, error) {
 	resp := clientset.CoreV1().Services(service.Namespace).ProxyGet(
 		"http",
 		service.Name,
@@ -37,7 +39,7 @@ func GetAllIncidents(
 		return nil, err
 	}
 
-	incidentsResp := &ListIncidentsResponse{}
+	incidentsResp := &types.ListIncidentsResponse{}
 
 	err = json.Unmarshal(rawQuery, incidentsResp)
 	if err != nil {
@@ -47,66 +49,37 @@ func GetAllIncidents(
 	return incidentsResp, nil
 }
 
-// func GetIncidentEventsByID(
-// 	clientset kubernetes.Interface,
-// 	service *v1.Service,
-// 	incidentID string,
-// ) (*EventsResponse, error) {
-// 	resp := clientset.CoreV1().Services(service.Namespace).ProxyGet(
-// 		"http",
-// 		service.Name,
-// 		fmt.Sprintf("%d", service.Spec.Ports[0].Port),
-// 		fmt.Sprintf("/incidents/%s", incidentID),
-// 		nil,
-// 	)
-
-// 	rawQuery, err := resp.DoRaw(context.Background())
-// 	if err != nil {
-// 		return nil, err
-// 	}
-
-// 	eventsResp := &EventsResponse{}
-
-// 	err = json.Unmarshal(rawQuery, eventsResp)
-// 	if err != nil {
-// 		return nil, err
-// 	}
-
-// 	return eventsResp, nil
-// }
-
-// func GetIncidentsByReleaseNamespace(
-// 	clientset kubernetes.Interface,
-// 	service *v1.Service,
-// 	releaseName, namespace string,
-// ) (*IncidentsResponse, error) {
-// 	resp := clientset.CoreV1().Services(service.Namespace).ProxyGet(
-// 		"http",
-// 		service.Name,
-// 		fmt.Sprintf("%d", service.Spec.Ports[0].Port),
-// 		fmt.Sprintf("/incidents/namespaces/%s/releases/%s", namespace, releaseName),
-// 		nil,
-// 	)
+func GetIncidentByID(
+	clientset kubernetes.Interface,
+	service *v1.Service,
+	incidentID string,
+) (*types.Incident, error) {
+	resp := clientset.CoreV1().Services(service.Namespace).ProxyGet(
+		"http",
+		service.Name,
+		fmt.Sprintf("%d", service.Spec.Ports[0].Port),
+		fmt.Sprintf("/incidents/%s", incidentID),
+		nil,
+	)
 
-// 	rawQuery, err := resp.DoRaw(context.Background())
-// 	if err != nil {
-// 		return nil, err
-// 	}
+	rawQuery, err := resp.DoRaw(context.Background())
+	if err != nil {
+		return nil, err
+	}
 
-// 	incidentsResp := &IncidentsResponse{}
+	incident := &types.Incident{}
 
-// 	err = json.Unmarshal(rawQuery, incidentsResp)
-// 	if err != nil {
-// 		return nil, err
-// 	}
+	if err := json.Unmarshal(rawQuery, incident); err != nil {
+		return nil, err
+	}
 
-// 	return incidentsResp, nil
-// }
+	return incident, nil
+}
 
-// func GetLogs(
+// func GetHistoricalLogs(
 // 	clientset kubernetes.Interface,
 // 	service *v1.Service,
-// 	logID string,
+// 	req *GetLogRequest,
 // ) (*LogsResponse, error) {
 // 	resp := clientset.CoreV1().Services(service.Namespace).ProxyGet(
 // 		"http",

+ 0 - 107
internal/kubernetes/porter_agent/v2/models.go

@@ -1,107 +0,0 @@
-package v2
-
-import "time"
-
-type SeverityType string
-
-const (
-	SeverityCritical SeverityType = "critical"
-	SeverityNormal   SeverityType = "normal"
-)
-
-type InvolvedObjectKind string
-
-const (
-	InvolvedObjectDeployment InvolvedObjectKind = "deployment"
-	InvolvedObjectJob        InvolvedObjectKind = "job"
-	InvolvedObjectPod        InvolvedObjectKind = "pod"
-)
-
-type IncidentStatus string
-
-const (
-	IncidentStatusResolved IncidentStatus = "resolved"
-	IncidentStatusActive   IncidentStatus = "active"
-)
-
-type IncidentMeta struct {
-	ID                      string             `json:"id" form:"required"`
-	ReleaseName             string             `json:"release_name" form:"required"`
-	ReleaseNamespace        string             `json:"release_namespace" form:"required"`
-	ChartName               string             `json:"chart_name" form:"required"`
-	CreatedAt               time.Time          `json:"created_at" form:"required"`
-	UpdatedAt               time.Time          `json:"updated_at" form:"required"`
-	LastSeen                *time.Time         `json:"last_seen" form:"required"`
-	Status                  IncidentStatus     `json:"status" form:"required"`
-	Summary                 string             `json:"summary" form:"required"`
-	Severity                SeverityType       `json:"severity" form:"required"`
-	InvolvedObjectKind      InvolvedObjectKind `json:"involved_object_kind" form:"required"`
-	InvolvedObjectName      string             `json:"involved_object_name" form:"required"`
-	InvolvedObjectNamespace string             `json:"involved_object_namespace" form:"required"`
-}
-
-type PaginationRequest struct {
-	Page int64 `schema:"page"`
-}
-
-type PaginationResponse struct {
-	NumPages    int64 `json:"num_pages" form:"required"`
-	CurrentPage int64 `json:"current_page" form:"required"`
-	NextPage    int64 `json:"next_page" form:"required"`
-}
-
-type ListIncidentsRequest struct {
-	*PaginationRequest
-	Status           *IncidentStatus `schema:"status"`
-	ReleaseName      *string         `schema:"release_name"`
-	ReleaseNamespace *string         `schema:"release_namespace"`
-}
-
-type ListIncidentsResponse struct {
-	Incidents  []*IncidentMeta     `json:"incidents" form:"required"`
-	Pagination *PaginationResponse `json:"pagination"`
-}
-
-type Incident struct {
-	*IncidentMeta
-	Pods   []string `json:"pods" form:"required"`
-	Detail string   `json:"detail" form:"required"`
-}
-
-type IncidentEvent struct {
-	ID           string     `json:"id" form:"required"`
-	LastSeen     *time.Time `json:"last_seen" form:"required"`
-	PodName      string     `json:"pod_name" form:"required"`
-	PodNamespace string     `json:"pod_namespace" form:"required"`
-	Summary      string     `json:"summary" form:"required"`
-	Detail       string     `json:"detail" form:"required"`
-}
-
-type ListIncidentEventsRequest struct {
-	*PaginationRequest
-	PodName      *string `schema:"pod_name"`
-	PodNamespace *string `schema:"pod_namespace"`
-	Summary      *string `schema:"summary"`
-}
-
-type ListIncidentEventsResponse struct {
-	Events     []*IncidentEvent    `json:"events" form:"required"`
-	Pagination *PaginationResponse `json:"pagination"`
-}
-
-type GetLogRequest struct {
-	Limit      uint       `json:"limit"`
-	StartRange *time.Time `json:"start_range"`
-	EndRange   *time.Time `json:"end_range"`
-	Pods       []string   `json:"pods"`
-}
-
-type LogLine struct {
-	Timestamp *time.Time `json:"timestamp"`
-	Line      string     `json:"line"`
-}
-
-type GetLogResponse struct {
-	ContinueTime *time.Time `json:"continue_time"`
-	Logs         []LogLine  `json:"logs"`
-}