Bläddra i källkod

add get history handler

Alexander Belanger 4 år sedan
förälder
incheckning
d4520c744f

+ 1 - 1
api/server/handlers/release/get.go

@@ -33,7 +33,7 @@ func (c *ReleaseGetHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	helmRelease, _ := r.Context().Value(types.ReleaseScope).(*release.Release)
 
 	res := &types.Release{
-		HelmRelease: helmRelease,
+		Release: helmRelease,
 	}
 
 	// look up the release in the database; if not found, do not populate Porter fields

+ 52 - 0
api/server/handlers/release/get_history.go

@@ -0,0 +1,52 @@
+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/apierrors"
+	"github.com/porter-dev/porter/api/server/shared/config"
+	"github.com/porter-dev/porter/api/server/shared/requestutils"
+	"github.com/porter-dev/porter/api/types"
+	"github.com/porter-dev/porter/internal/models"
+)
+
+type GetReleaseHistoryHandler struct {
+	handlers.PorterHandlerReadWriter
+	authz.KubernetesAgentGetter
+}
+
+func NewGetReleaseHistoryHandler(
+	config *config.Config,
+	decoderValidator shared.RequestDecoderValidator,
+	writer shared.ResultWriter,
+) *GetReleaseHistoryHandler {
+	return &GetReleaseHistoryHandler{
+		PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, decoderValidator, writer),
+		KubernetesAgentGetter:   authz.NewOutOfClusterAgentGetter(config),
+	}
+}
+
+func (c *GetReleaseHistoryHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	cluster, _ := r.Context().Value(types.ClusterScope).(*models.Cluster)
+
+	helmAgent, err := c.GetHelmAgent(r, cluster)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	// get the name of the application
+	name, _ := requestutils.GetURLParamString(r, types.URLParamReleaseName)
+	history, err := helmAgent.GetReleaseHistory(name)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	c.WriteResult(w, r, history)
+}

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

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

+ 1 - 1
api/types/release.go

@@ -4,7 +4,7 @@ import "helm.sh/helm/v3/pkg/release"
 
 // Release is a helm release with a form attached
 type Release struct {
-	HelmRelease *release.Release `json:"helm_release"`
+	*release.Release
 
 	ID              uint             `json:"id"`
 	WebhookToken    string           `json:"webhook_token"`

+ 3 - 7
dashboard/src/main/home/cluster-dashboard/expanded-chart/ExpandedChartWrapper.tsx

@@ -38,11 +38,8 @@ class ExpandedChartWrapper extends Component<PropsType, StateType> {
         .getRevisions(
           "<token>",
           {
-            namespace: namespace,
-            cluster_id: currentCluster.id,
-            storage: StorageType.Secret,
           },
-          { id: currentProject.id, name: chartName }
+          { id: currentProject.id, namespace: namespace, cluster_id: currentCluster.id ,name: chartName }
         )
         .then((res) => {
           res.data.sort((a: ChartType, b: ChartType) => {
@@ -53,13 +50,12 @@ class ExpandedChartWrapper extends Component<PropsType, StateType> {
             .getChart(
               "<token>",
               {
-                namespace: namespace,
-                cluster_id: currentCluster.id,
-                storage: StorageType.Secret,
               },
               {
                 name: chartName,
                 revision: maxVersion,
+                namespace: namespace,
+                cluster_id: currentCluster.id,
                 id: currentProject.id,
               }
             )

+ 2 - 3
dashboard/src/main/home/cluster-dashboard/expanded-chart/ExpandedJobChart.tsx

@@ -71,13 +71,12 @@ class ExpandedJobChart extends Component<PropsType, StateType> {
       .getChart(
         "<token>",
         {
-          namespace: currentChart.namespace,
-          cluster_id: currentCluster.id,
-          storage: StorageType.Secret,
         },
         {
           name: chart.name,
           revision: revision,
+          namespace: currentChart.namespace,
+          cluster_id: currentCluster.id,
           id: currentProject.id,
         }
       )

+ 2 - 4
dashboard/src/main/home/cluster-dashboard/expanded-chart/RevisionSection.tsx

@@ -47,15 +47,13 @@ class RevisionSection extends Component<PropsType, StateType> {
   refreshHistory = () => {
     let { chart } = this.props;
     let { currentCluster, currentProject } = this.context;
+    
     return api
       .getRevisions(
         "<token>",
         {
-          namespace: chart.namespace,
-          cluster_id: currentCluster.id,
-          storage: StorageType.Secret,
         },
-        { id: currentProject.id, name: chart.name }
+        { id: currentProject.id, namespace: chart.namespace, cluster_id: currentCluster.id, name: chart.name }
       )
       .then((res) => {
         res.data.sort((a: ChartType, b: ChartType) => {

+ 2 - 3
dashboard/src/main/home/cluster-dashboard/expanded-chart/metrics/MetricsSection.tsx

@@ -137,13 +137,12 @@ const MetricsSection: React.FunctionComponent<PropsType> = ({
       .getChartControllers(
         "<token>",
         {
-          namespace: currentChart.namespace,
-          cluster_id: currentCluster.id,
-          storage: StorageType.Secret,
         },
         {
           id: currentProject.id,
           name: currentChart.name,
+          namespace: currentChart.namespace,
+          cluster_id: currentCluster.id,
           revision: currentChart.version,
         }
       )

+ 2 - 3
dashboard/src/main/home/cluster-dashboard/expanded-chart/status/StatusSection.tsx

@@ -33,11 +33,10 @@ const StatusSectionFC: React.FunctionComponent<Props> = ({
       .getChartControllers(
         "<token>",
         {
-          namespace: currentChart.namespace,
-          cluster_id: currentCluster.id,
-          storage: StorageType.Secret,
         },
         {
+          namespace: currentChart.namespace,
+          cluster_id: currentCluster.id,
           id: currentProject.id,
           name: currentChart.name,
           revision: currentChart.version,

+ 7 - 6
dashboard/src/shared/api.tsx

@@ -445,7 +445,7 @@ const getChartControllers = baseApi<
 { id: number; cluster_id: number; namespace: string; name: string; revision: number }
 >("GET", (pathParams) => {
   let { id, cluster_id, namespace, name, revision } = pathParams
-  
+
   return `/api/projects/${id}/clusters/${cluster_id}/namespaces/${namespace}/releases/${name}/${revision}/controllers`
 });
 
@@ -729,13 +729,14 @@ const getSlackIntegrations = baseApi<{}, { id: number }>(
 
 const getRevisions = baseApi<
   {
-    namespace: string;
-    cluster_id: number;
-    storage: StorageType;
   },
-  { id: number; name: string }
+  { id: number; cluster_id: number; namespace: string; name: string }
 >("GET", (pathParams) => {
-  return `/api/projects/${pathParams.id}/releases/${pathParams.name}/history`;
+  console.log("PATH PARAMS", pathParams)
+  
+  let { id, cluster_id, namespace, name } = pathParams
+
+  return `/api/projects/${id}/clusters/${cluster_id}/namespaces/${namespace}/releases/${name}/history`
 });
 
 const getTemplateInfo = baseApi<

+ 54 - 6
internal/kubernetes/agent.go

@@ -331,56 +331,104 @@ func (a *Agent) GetIngress(namespace string, name string) (*v1beta1.Ingress, err
 
 // GetDeployment gets the deployment given the name and namespace
 func (a *Agent) GetDeployment(c grapher.Object) (*appsv1.Deployment, error) {
-	return a.Clientset.AppsV1().Deployments(c.Namespace).Get(
+	res, err := a.Clientset.AppsV1().Deployments(c.Namespace).Get(
 		context.TODO(),
 		c.Name,
 		metav1.GetOptions{},
 	)
+
+	if err != nil {
+		return nil, err
+	}
+
+	res.Kind = c.Kind
+
+	return res, nil
 }
 
 // GetStatefulSet gets the statefulset given the name and namespace
 func (a *Agent) GetStatefulSet(c grapher.Object) (*appsv1.StatefulSet, error) {
-	return a.Clientset.AppsV1().StatefulSets(c.Namespace).Get(
+	res, err := a.Clientset.AppsV1().StatefulSets(c.Namespace).Get(
 		context.TODO(),
 		c.Name,
 		metav1.GetOptions{},
 	)
+
+	if err != nil {
+		return nil, err
+	}
+
+	res.Kind = c.Kind
+
+	return res, nil
 }
 
 // GetReplicaSet gets the replicaset given the name and namespace
 func (a *Agent) GetReplicaSet(c grapher.Object) (*appsv1.ReplicaSet, error) {
-	return a.Clientset.AppsV1().ReplicaSets(c.Namespace).Get(
+	res, err := a.Clientset.AppsV1().ReplicaSets(c.Namespace).Get(
 		context.TODO(),
 		c.Name,
 		metav1.GetOptions{},
 	)
+
+	if err != nil {
+		return nil, err
+	}
+
+	res.Kind = c.Kind
+
+	return res, nil
 }
 
 // GetDaemonSet gets the daemonset by name and namespace
 func (a *Agent) GetDaemonSet(c grapher.Object) (*appsv1.DaemonSet, error) {
-	return a.Clientset.AppsV1().DaemonSets(c.Namespace).Get(
+	res, err := a.Clientset.AppsV1().DaemonSets(c.Namespace).Get(
 		context.TODO(),
 		c.Name,
 		metav1.GetOptions{},
 	)
+
+	if err != nil {
+		return nil, err
+	}
+
+	res.Kind = c.Kind
+
+	return res, nil
 }
 
 // GetJob gets the job by name and namespace
 func (a *Agent) GetJob(c grapher.Object) (*batchv1.Job, error) {
-	return a.Clientset.BatchV1().Jobs(c.Namespace).Get(
+	res, err := a.Clientset.BatchV1().Jobs(c.Namespace).Get(
 		context.TODO(),
 		c.Name,
 		metav1.GetOptions{},
 	)
+
+	if err != nil {
+		return nil, err
+	}
+
+	res.Kind = c.Kind
+
+	return res, nil
 }
 
 // GetCronJob gets the CronJob by name and namespace
 func (a *Agent) GetCronJob(c grapher.Object) (*batchv1beta1.CronJob, error) {
-	return a.Clientset.BatchV1beta1().CronJobs(c.Namespace).Get(
+	res, err := a.Clientset.BatchV1beta1().CronJobs(c.Namespace).Get(
 		context.TODO(),
 		c.Name,
 		metav1.GetOptions{},
 	)
+
+	if err != nil {
+		return nil, err
+	}
+
+	res.Kind = c.Kind
+
+	return res, nil
 }
 
 // GetPodsByLabel retrieves pods with matching labels