Jelajahi Sumber

change some endpoint logic

Mohammed Nafees 4 tahun lalu
induk
melakukan
491e8b6851

+ 69 - 1
api/server/handlers/cluster/get_incidents.go

@@ -1,12 +1,17 @@
 package cluster
 
 import (
+	"fmt"
 	"net/http"
 
 	"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/types"
+	porter_agent "github.com/porter-dev/porter/internal/kubernetes/porter_agent/v2"
+	"github.com/porter-dev/porter/internal/models"
 )
 
 type GetIncidentsHandler struct {
@@ -16,14 +21,77 @@ type GetIncidentsHandler struct {
 
 func NewGetIncidentsHandler(
 	config *config.Config,
+	decoderValidator shared.RequestDecoderValidator,
 	writer shared.ResultWriter,
 ) *GetIncidentsHandler {
 	return &GetIncidentsHandler{
-		PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, nil, writer),
+		PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, decoderValidator, writer),
 		KubernetesAgentGetter:   authz.NewOutOfClusterAgentGetter(config),
 	}
 }
 
 func (c *GetIncidentsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	cluster, _ := r.Context().Value(types.ClusterScope).(*models.Cluster)
 
+	request := &types.GetIncidentsRequest{}
+
+	if ok := c.DecodeAndValidate(w, r, request); !ok {
+		return
+	}
+
+	incidentID := request.IncidentID
+	releaseName := request.ReleaseName
+	namespace := request.Namespace
+
+	fmt.Printf("incidentID: %s\nreleaseName: %s\nnamespace: %s\n", incidentID, releaseName, namespace)
+
+	agent, err := c.GetAgent(r, cluster, "")
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	// get agent service
+	agentSvc, err := porter_agent.GetAgentService(agent.Clientset)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		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)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	c.WriteResult(w, r, incidents)
 }

+ 0 - 29
api/server/handlers/release/get_incidents.go

@@ -1,29 +0,0 @@
-package release
-
-import (
-	"net/http"
-
-	"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/config"
-)
-
-type NewGetIncidentsByReleaseName struct {
-	handlers.PorterHandlerReadWriter
-	authz.KubernetesAgentGetter
-}
-
-func NewGetIncidentsByReleaseNameHandler(
-	config *config.Config,
-	writer shared.ResultWriter,
-) *NewGetIncidentsByReleaseName {
-	return &NewGetIncidentsByReleaseName{
-		PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, nil, writer),
-		KubernetesAgentGetter:   authz.NewOutOfClusterAgentGetter(config),
-	}
-}
-
-func (c *NewGetIncidentsByReleaseName) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-
-}

+ 1 - 0
api/server/router/cluster.go

@@ -936,6 +936,7 @@ func getClusterRoutes(
 
 	getIncidentsHandler := cluster.NewGetIncidentsHandler(
 		config,
+		factory.GetDecoderValidator(),
 		factory.GetResultWriter(),
 	)
 

+ 0 - 29
api/server/router/release.go

@@ -782,34 +782,5 @@ func getReleaseRoutes(
 		Router:   r,
 	})
 
-	// GET /api/projects/{project_id}/clusters/{cluster_id}/namespaces/{namespace}/releases/{name}/incidents -> release.NewGetIncidentsByReleaseNameHandler
-	getIncidentsByReleaseNameEndpoint := factory.NewAPIEndpoint(
-		&types.APIRequestMetadata{
-			Verb:   types.APIVerbGet,
-			Method: types.HTTPVerbGet,
-			Path: &types.Path{
-				Parent:       basePath,
-				RelativePath: "/releases/{name}/incidents",
-			},
-			Scopes: []types.PermissionScope{
-				types.UserScope,
-				types.ProjectScope,
-				types.ClusterScope,
-				types.NamespaceScope,
-			},
-		},
-	)
-
-	getIncidentsByReleaseNameHandler := release.NewGetIncidentsByReleaseNameHandler(
-		config,
-		factory.GetResultWriter(),
-	)
-
-	routes = append(routes, &Route{
-		Endpoint: getIncidentsByReleaseNameEndpoint,
-		Handler:  getIncidentsByReleaseNameHandler,
-		Router:   r,
-	})
-
 	return routes, newPath
 }

+ 6 - 0
api/types/cluster.go

@@ -247,3 +247,9 @@ type ListClusterResponse []*Cluster
 type CreateClusterCandidateResponse []*ClusterCandidate
 
 type ListClusterCandidateResponse []*ClusterCandidate
+
+type GetIncidentsRequest struct {
+	IncidentID  string `schema:"incident_id"`
+	ReleaseName string `schema:"release_name"`
+	Namespace   string `schema:"namespace"`
+}

+ 80 - 3
internal/kubernetes/porter_agent/v2/agent_server.go

@@ -1,7 +1,84 @@
 package v2
 
-func GetAllIncidents() {}
+import (
+	"context"
+	"encoding/json"
+	"fmt"
 
-func GetIncidentEventsByID() {}
+	v1 "k8s.io/api/core/v1"
+	"k8s.io/client-go/kubernetes"
 
-func GetIncidentsByReleaseName() {}
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+// returns the agent service
+func GetAgentService(clientset kubernetes.Interface) (*v1.Service, error) {
+	return clientset.CoreV1().Services("porter-agent-system").Get(
+		context.TODO(),
+		"porter-agent-controller-manager",
+		metav1.GetOptions{},
+	)
+}
+
+func GetAllIncidents(
+	clientset kubernetes.Interface,
+	service *v1.Service,
+) (*IncidentsResponse, error) {
+	resp := clientset.CoreV1().Services(service.Namespace).ProxyGet(
+		"http",
+		service.Name,
+		fmt.Sprintf("%d", service.Spec.Ports[0].Port),
+		"/incidents",
+		nil,
+	)
+
+	rawQuery, err := resp.DoRaw(context.Background())
+	if err != nil {
+		return nil, err
+	}
+
+	incidentsResp := &IncidentsResponse{}
+
+	err = json.Unmarshal(rawQuery, incidentsResp)
+	if err != nil {
+		return nil, err
+	}
+
+	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) {
+	return nil, nil
+}

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

@@ -0,0 +1,41 @@
+package v2
+
+type ContainerEvent struct {
+	Name     string `json:"container_name"`
+	Reason   string `json:"reason"`
+	Message  string `json:"message"`
+	LogID    string `json:"log_id"`
+	ExitCode int32  `json:"exit_code"`
+}
+
+type PodEvent struct {
+	EventID         string                     `json:"event_id"`
+	PodName         string                     `json:"pod_name"`
+	Namespace       string                     `json:"namespace"`
+	Cluster         string                     `json:"cluster"`
+	OwnerName       string                     `json:"release_name"`
+	OwnerType       string                     `json:"release_type"`
+	Timestamp       int64                      `json:"timestamp"`
+	Phase           string                     `json:"pod_phase"`
+	Status          string                     `json:"pod_status"`
+	Reason          string                     `json:"reason"`
+	Message         string                     `json:"message"`
+	ContainerEvents map[string]*ContainerEvent `json:"container_events"`
+}
+
+type Incident struct {
+	ID            string `json:"id" form:"required"`
+	ReleaseName   string `json:"release_name" form:"required"`
+	LatestState   string `json:"latest_state" form:"required"`
+	LatestReason  string `json:"latest_reason" form:"required"`
+	LatestMessage string `json:"latest_message" form:"required"`
+}
+
+type IncidentsResponse struct {
+	Incidents []*Incident `json:"incidents" form:"required"`
+}
+
+type EventsResponse struct {
+	IncidentID string      `json:"incident_id" form:"required"`
+	Events     []*PodEvent `json:"events" form:"required"`
+}