redhat-developer / intellij-kubernetes

IntelliJ Kubernetes plugin
https://plugins.jetbrains.com/plugin/15921-kubernetes-by-red-hat
Eclipse Public License 2.0
20 stars 20 forks source link

feat: impl'd describe for pods (#553) #770

Closed adietish closed 3 months ago

adietish commented 4 months ago

partially fixes #553: it only provides "describe" for pods, no other resource kind is supported. Support for these is filed at #782

How to test this:

This implementation should provide the same output as kubectl describe pod <name>.

Steps:

  1. EXEC: copy & paste the following into an editor in IJ, naming the file "describe-test.yml": https://gist.github.com/adietish/b9bde277776f657af7d76515effa1882#file-describe-test-yml. Then push the editor to the cluster. (alternatively you can also use kubectl with the file: kubectl apply -f describe-test.yml)
  2. ASSERT: a Pod describe-test is created and show up in the resource tree
  3. EXEC: pick "Describe" in the context menu to the pod describe-test ([cluster] > Workloads > Pods > describe-test)
  4. ASSERT: An editor is opened describing the pod. The title of the editor is "Describe Pod describe-test".
  5. EXEC: run kubectl describe pod describe-test and compare the output with the content of the editor

Comparing the outputs: You can use a diff or https://www.diffchecker.com/text-compare/ which helps a lot. There are limitations that were not implemented yet (ex. the list of events that kubectl is printing in the end of the output):

The following examples show equivalence in intellij-kubernetes and kubectl. The differences are mainly in formatting, cause by the fact the intellij-kubernetes is producing YAML whereas kubectl is simply printing text.

Examples:

adietish commented 4 months ago

@sbouchet, @olkornii: please test/review this. Instructions are in the 1st comment to this issue. The content in the (read-only) editor should be equivalent (not identical) to kubectl describe pod <name>. Some differences are caused by limitations (filed to issues, to be implemented later). Other differences, that are basically in formatting only, should not matter (see examples pasted in comment) Thanks!

sbouchet commented 4 months ago

issue discovered when describing a simple pod :

---
apiVersion: "v1"
kind: "Pod"
metadata:
  labels:
    jedi: "luke"
  name: "alpine1"
spec:
  containers:
    - image: "alpine"
      name: "alpine"
      ports:
        - containerPort: 8080

the kubectl describe returns
Node: minikube/192.168.39.85

while intellij-kubes returns Node: minikube/10.244.3.78

sbouchet commented 4 months ago

issues discovered while describing a pod created with helm chart ( kuberos ): kubectl

Name:             kube-kuberos-659f864687-hd889
Namespace:        myproj
Priority:         0
Service Account:  default
Node:             minikube/192.168.39.85
Start Time:       Mon, 15 Jul 2024 17:48:18 +0200
Labels:           app=kuberos
                  checksum/config=2c10ca940734118cab9c36c72a4b8e7c49570b8d5022d8636e780df38d43a74
                  pod-template-hash=659f864687
                  release=kube
Annotations:      checksum/config: 2c10ca940734118cab9c36c72a4b8e7c49570b8d5022d8636e780df38d43a74
Status:           Running
IP:               10.244.3.87
IPs:
  IP:           10.244.3.87
Controlled By:  ReplicaSet/kube-kuberos-659f864687
Containers:
  kuberos:
    Container ID:  docker://2be868e2f251764998e133426963e2ae866c806d85d183f40925b2297a3a51b5
    Image:         negz/kuberos:ede4085
    Image ID:      docker-pullable://negz/kuberos@sha256:5fce210b3a813083da0ef60ac10b7cdf81f274c866b92598f3d07d6aa4ff4d2e
    Port:          10003/TCP
    Host Port:     0/TCP
    Command:
      /kuberos
      https://accounts.google.com
      REDACTED.apps.googleusercontent.com
      /cfg/secret
      /cfg/template
    State:          Running
      Started:      Tue, 30 Jul 2024 10:08:55 +0200
    Last State:     Terminated
      Reason:       Error
      Exit Code:    2
      Started:      Tue, 30 Jul 2024 10:08:25 +0200
      Finished:     Tue, 30 Jul 2024 10:08:54 +0200
    Ready:          True
    Restart Count:  11
    Liveness:       http-get http://:kuberos-port/healthz delay=0s timeout=1s period=10s #success=1 #failure=3
    Readiness:      http-get http://:kuberos-port/healthz delay=0s timeout=1s period=10s #success=1 #failure=3
    Environment:    <none>
    Mounts:
      /cfg/secret from secret (rw,path="oidcSecret")
      /cfg/template from template (rw,path="template")
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-mlnjq (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True 
  Initialized                 True 
  Ready                       True 
  ContainersReady             True 
  PodScheduled                True 
Volumes:
  template:
    Type:      ConfigMap (a volume populated by a ConfigMap)
    Name:      kube-kuberos-config
    Optional:  false
  secret:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  kuberos-secret
    Optional:    false
  kube-api-access-mlnjq:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:                      <none>

intellij-kubernetes

Name: kube-kuberos-659f864687-hd889
Namespace: myproj
Priority: 0
Service Account: default
Node: minikube/10.244.3.87
Start Time: Mon, 15 Jul 2024 15:48:18 +0200
Labels:
  app: kuberos
  checksum/config: 2c10ca940734118cab9c36c72a4b8e7c49570b8d5022d8636e780df38d43a74
  pod-template-hash: 659f864687
  release: kube
Annotations:
  checksum/config: 2c10ca940734118cab9c36c72a4b8e7c49570b8d5022d8636e780df38d43a74
Status: Running
IP: 10.244.3.87
IPs:
  IP: 10.244.3.87
Controlled By: ReplicaSet/kube-kuberos-659f864687
Init Containers: <none>
Containers:
  kuberos:
    Container ID: docker://2be868e2f251764998e133426963e2ae866c806d85d183f40925b2297a3a51b5
    Image: negz/kuberos:ede4085
    Image ID: docker-pullable://negz/kuberos@sha256:5fce210b3a813083da0ef60ac10b7cdf81f274c866b92598f3d07d6aa4ff4d2e
    Port: 10003/TCP
    Host Port: 0/TCP
    Command:
    - /kuberos
    - https://accounts.google.com
    - REDACTED.apps.googleusercontent.com
    - /cfg/secret
    - /cfg/template
    State: Running
    Started: Tue, 30 Jul 2024 08:08:55 +0200
    Last State: Terminated
    Reason: Error
    Exit Code: 2
    Finished: Tue, 30 Jul 2024 08:08:54 +0200
    Ready: true
    Restart Count: 11
    Liveness: 'http-get http:/healthz delay=nulls timeout=1s period=10s #success=1
      #failure=3'
    Readiness: 'http-get http:/healthz delay=nulls timeout=1s period=10s #success=1
      #failure=3'
    Environment: <none>
    Mounts:
    - /cfg/template from template (rw, path = "template")
    - /cfg/secret from secret (rw, path = "oidcSecret")
    - /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-mlnjq (ro)
Conditions:
  PodReadyToStartContainers: true
  Initialized: true
  Ready: true
  ContainersReady: true
  PodScheduled: true
Volumes:
  template:
    Type: ConfigMap (a volume populated by a ConfigMap)
    Name: kube-kuberos-config
    Optional: <none>
  secret:
    Type: Secret (a volume populated by a Secret)
    SecretName: kuberos-secret
    Optional: <none>
  kube-api-access-mlnjq:
    Type: Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds: '3607'
    ConfigMapName: kube-root-ca.crt
    ConfigMapOptional: <none>
    DownwardAPI: 'true'
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations:
- node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
- node.kubernetes.io/unreachable:NoExecute op=Exists for 300s

note the Node: issue same as above then on the Containers part, there is missing spaces for State / Started and Last State / Reason... on the same place, there is a missing Started value later on the liveness/readiness seems delay is returning null ( should be 0 )

On Volumes, the Optional value should be False ( returns none )

adietish commented 3 months ago

@sbouchet thx for the review. On top of your issues I saw the following:

Then I imho ConfigMapOptional printed as <nil> is imho a "bug" in kubectl. nil in golang represents a zero value (similar - but not equal to null in java). It is printed by golang/sprintf when there's no ConfigMapOptional:

w.Write(LEVEL_2, "ConfigMapName:\t%v\n"+
                "    ConfigMapOptional:\t%v\n",
                source.ConfigMap.Name, source.ConfigMap.Optional)

This is in constrast to Optional, which is a boolean too, but is printed as false if there's no optional (notice that they print a variable optional who's value is it's not null && its value):

optional := configMap.Optional != nil && *configMap.Optional
w.Write(LEVEL_2, "Type:\tConfigMap (a volume populated by a ConfigMap)\n"+
    "    Name:\t%v\n"+
    "    Optional:\t%v\n",
    configMap.Name, optional)

I therefore use false (instead of <none> previously) if there's no ConfigMapOptional like I do for Optional.

adietish commented 3 months ago

@sbouchet please re-review, I have fixed the issues that you have found. Thanks!

adietish commented 3 months ago

@sbouchet I also changed Command to better match kubectl:

adietish commented 3 months ago

@sbouchet please re-review, thanks!

sonarcloud[bot] commented 3 months ago

Quality Gate Passed Quality Gate passed

Issues
0 New issues
2 Accepted issues

Measures
0 Security Hotspots
0.0% Coverage on New Code
0.0% Duplication on New Code

See analysis details on SonarCloud