Repository: digitalocean/doctl
Pull request #949 (2021-01-28 07:18:51)

kubernetes: support getting kubernetes cluster details with projects command
Currently, we can `doctl projects resources assign` and `doctl projects resources list` the `Kubernetes` resource. But we can't run the `doctl projects resources get do:doks:<cluster-uuid>` command to get the details of the resource. We receive this error instead:
```go
Error: "kubernetes" is an invalid resource type, consult the documentation
```

- This PR attempts to add the `get` command so that Kubernetes cluster details are returned are returned just like when we run `doctl kubernetes cluster get <cluster-uuid>`.



**Note for reviewers:** marking this as WIP for now until I can test it locally.

MorrisLaw: rebased
ChiefMateStarbuck: The `get cluster` function uses the `list cluster` API endpoint and searches for the specific cluster by id or name. These added commits address this functionality within the `project test get` file.

Patch:
diff --git a/commands/projects.go b/commands/projects.go
index 7a3e0eee..63f8c188 100644
--- a/commands/projects.go
+++ b/commands/projects.go
@@ -268,6 +268,9 @@ func RunProjectResourcesGet(c *CmdConfig) error {
 		return RunDomainGet(c)
 	case "volume":
 		return RunVolumeGet(c)
+	case "kubernetes":
+		k8sCmdService := kubernetesCommandService()
+		return k8sCmdService.RunKubernetesClusterGet(c)
 	case "app":
 		return RunAppsGet(c)
 	default:


Test patch:
diff --git a/commands/projects_test.go b/commands/projects_test.go
index dbed5a3c..c6f2bf4d 100644
--- a/commands/projects_test.go
+++ b/commands/projects_test.go
@@ -29,6 +29,9 @@ var (
 		{
 			ProjectResource: &godo.ProjectResource{URN: "do:floatingip:1.2.3.4"},
 		},
+		{
+			ProjectResource: &godo.ProjectResource{URN: "do:kubernetes:1234"},
+		},
 		{
 			ProjectResource: &godo.ProjectResource{URN: "do:app:6f30f890-d2f7-11ec-b23c-bf05f13731ef"},
 		},
diff --git a/integration/projects_resources_get_test.go b/integration/projects_resources_get_test.go
index 4f03a18a..32b28d26 100644
--- a/integration/projects_resources_get_test.go
+++ b/integration/projects_resources_get_test.go
@@ -89,6 +89,19 @@ var _ = suite("projects/resources/get", func(t *testing.T, when spec.G, it spec.
 				}
 
 				w.Write([]byte(projectsResourcesGetVolumeResponse))
+			case "/v2/kubernetes/clusters":
+				auth := req.Header.Get("Authorization")
+				if auth != "Bearer some-magic-token" {
+					w.WriteHeader(http.StatusUnauthorized)
+					return
+				}
+
+				if req.Method != http.MethodGet {
+					w.WriteHeader(http.StatusMethodNotAllowed)
+					return
+				}
+
+				w.Write([]byte(projectsResourcesListKubernetesOutput))
 			default:
 				dump, err := httputil.DumpRequest(req, true)
 				if err != nil {
@@ -201,6 +214,24 @@ var _ = suite("projects/resources/get", func(t *testing.T, when spec.G, it spec.
 			expect.Equal(strings.TrimSpace(projectsResourcesGetVolumeOutput), strings.TrimSpace(string(output)))
 		})
 	})
+
+	when("passing a kubernetes urn", func() {
+		it("gets that resource for the project", func() {
+			cmd := exec.Command(builtBinaryPath,
+				"-t", "some-magic-token",
+				"-u", server.URL,
+				"projects",
+				"resources",
+				"get",
+				"do:kubernetes:1111",
+			)
+
+			output, err := cmd.CombinedOutput()
+			expect.NoError(err, fmt.Sprintf("received error output: %s", output))
+			expect.Equal(strings.TrimSpace(projectsResourcesGetKubernetesOutput), strings.TrimSpace(string(output)))
+		})
+	})
+
 })
 
 const (
@@ -310,5 +341,107 @@ ID                                      Name       Size      Region    Filesyste
     "tags": [ "aninterestingtag" ]
   }
 }
+`
+	projectsResourcesGetKubernetesOutput = `
+ID    Name    Region    Version    Auto Upgrade    HA Control Plane    Status          Endpoint    IPv4    Cluster Subnet    Service Subnet    Tags    Created At                       Updated At                       Node Pools
+      1111                         false           false               provisioning                                                            k8s     2021-01-29 16:02:02 +0000 UTC    0001-01-01 00:00:00 +0000 UTC    pool-test
+`
+	projectsResourcesListKubernetesOutput = `
+	{
+		"kubernetes_clusters": [
+		  {
+			"uuid": 1111,
+			"name": "1111",
+			"region_slug": "nyc1",
+			"version_slug": "1.19.3-do.3",
+			"node_pools": [
+			  {
+				"uuid": "1111",
+				"name": "pool-test",
+				"version_slug": "1.19.3-do.3",
+				"droplet_size": "s-2vcpu-4gb",
+				"count": 3,
+				"node_statuses": [
+				  "provisioning",
+				  "provisioning",
+				  "provisioning"
+				],
+				"status": {
+				  "state": "provisioning"
+				},
+				"tags": [
+					"k8s:worker",
+					"k8s",
+					"k8s:1111"
+				]
+			  }
+			],
+			"tags": [
+				"k8s"
+			],
+			"status": {
+			  "state": "provisioning",
+			  "message": "provisioning",
+			  "pending_event": true
+			},
+			"pending": true,
+			"ready": false,
+			"auto_upgrade": false,
+			"created_at": "2021-01-29T16:02:02Z"
+		  }
+		]
+	  }
+`
+	projectsResourcesGetKubernetesResponse = `
+{
+  "kubernetes_cluster": {
+    "uuid": 1111,
+    "name": "1111",
+    "region_slug": "nyc1",
+	"version_slug": "1.19.3-do.3",
+	"auto_upgrade": "false",
+	"node_pools": [
+		{
+		"uuid": "1111",
+		"name": "pool-test",
+		"version_slug": "1.19.3-do.3",
+		"droplet_size": "s-2vcpu-4gb",
+		"count": 3,
+		"node_statuses": [
+			"provisioning",
+			"provisioning",
+			"provisioning"
+		],
+		"status": {
+			"state": "provisioning"
+		},
+		"tags": [
+			{
+			"name": "k8s"
+			},
+			{
+			"name": "k8s:1111"
+			},
+			{
+			"name": "k8s:worker"
+			}
+		]
+		}
+	],
+	"tags": [
+      {
+        "name": "k8s"
+	  },
+	],
+	"status": {
+	  "state": "provisioning",
+	  "message": "provisioning",
+	  "pending_event": true
+	},
+	"pending": true,
+	"ready": false,
+	"created_at": "2021-01-29T16:02:02Z"
+  }
+}
 `
 )