manusa / yakc

Yet another Kubernetes Client - Lower level Java REST client for Kubernetes API
https://blog.marcnuri.com/tag/yakc/
Apache License 2.0
45 stars 11 forks source link

get deployment resource #30

Closed cforce closed 3 years ago

cforce commented 3 years ago

Is there a feature planned tp get deployment resource definitions? I would like to ask for the replicas coont.

manusa commented 3 years ago

Do you mean something like the following:

final Deployment deployment = new KubernetesClient().create(AppsV1Api.class)
  .readNamespacedDeployment("$deploymentName", "$namespace").get();
deployment.getSpec().getReplicas();
deployment.getStatus().getAvailableReplicas();
deployment.getStatus().getReadyReplicas();
deployment.getStatus().getReplicas();

This is already possible. There are type definitions and API definitions for all vanilla Kubernetes types up to 1.19. You can also find a set of extensions for additional non-standard kubernetes types too see https://github.com/manusa/yakc/tree/master/apis or details in Javadoc.

manusa commented 3 years ago

I added a test suite for reference: https://github.com/manusa/yakc/blob/6e6dded0e573b228aef0c0d322063e551279fa7c/tests/src/test/java/com/marcnuri/yakc/DeploymentIT.java

Please, confirm if this is what you were looking for.

cforce commented 3 years ago

@manusa Is there any kind of callback feature that allow me to implement a method in case replicas are changed? I want to allow my application to dynamically adopt on scale.

manusa commented 3 years ago

Yes, if you are familiar with RxJava or any other reactive library this should be easy and straightforward with the watch() method implemented by "listable" APIs.

For example, the following code in the PodIT test blocks the current thread until a pod with a given name is created or a timeout occurs: https://github.com/manusa/yakc/blob/f89668ba34a11aeca9575b130f99c59a263f2740/tests/src/test/java/com/marcnuri/yakc/PodIT.java#L95-L100

The following code might be useful as a starting-point/scaffold

new KubernetesClient().create(AppsV1Api.class).listNamespacedDeployment("$namespace").watch()
  .filter(we -> {
    // Perform client side filtering
    return we.getObject().getMetadata().getName().equals("$myWatchedDeployment");
  })
  .timeout(
    // Add a timeout if you want (Check RxJava operations)
    20, TimeUnit.SECONDS)
  .subscribe(
    // Perform actions for any event produced on the watched resources
    deploymentWatchEvent -> {
      switch (deploymentWatchEvent.getType()) {
        case ADDED:
        case MODIFIED: {
          if (deploymentWatchEvent.getObject().getStatus().getAvailableReplicas().equals(desiredNumber)) {
            // Do something
          }
          break;
        }
        case DELETED: {
          break;
        }
      }
    },
    error -> {
      // Do something when the watch connection breaks due to an exception
    }
  );

The following recording shows how I'm doing something similar to what you need in the YAKC - Kubernetes Dashboard example (however things here are more complicated since stuff is happening in the front-end too).

TJZ5k0Rp5I

What you can see here is the user scaling up and down a deployment. There is an active subscription to Deployment changes, the UI reflects whenever the number of ready replicas matches those requested by the user by setting the ReplicaSet and Deployment green or red.