Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GenericKubernetesResource field type is changed from string to integer #5585

Closed
speedfl opened this issue Nov 13, 2023 · 2 comments
Closed

Comments

@speedfl
Copy link

speedfl commented Nov 13, 2023

Describe the bug

I have a simple script that Fetch a keda ScaledObject Resources in a namepace and copy them into the destination namespace:

public void test() {
        var scaledObjectCrdContext = new ResourceDefinitionContext.Builder()
                .withNamespaced(true)
                .withGroup("keda.sh")
                .withKind("ScaledObject")
                .withVersion("v1alpha1")
                .withPlural("scaledobjects")
                .build();
        kubernetesClient.genericKubernetesResources(scaledObjectCrdContext)
                        .inNamespace("source-namespace")
                        .withLabels(Map.of("my-selector", "my-app"))
                        .list()
                        .getItems()
                        .stream()
                        .peek(item -> item.getMetadata().setNamespace("destination-namespace"))
                        .forEach(item -> kubernetesClient.genericKubernetesResources(scaledObjectCrdContext).resource(item).create());
    }

When doing the create I get:

 POST at: https://localhost/apis/keda.sh/v1alpha1/namespaces/destination-namespace/scaledobjects. Message: ScaledObject.keda.sh "my-scaled-object" is invalid: spec.triggers[0].metadata.desiredReplicas: Invalid value: "integer": spec.triggers[0].metadata.desiredReplicas in body must be of type string: "integer". Received status: Status(apiVersion=v1, code=422, details=StatusDetails(causes=[StatusCause(field=spec.triggers[0].metadata.desiredReplicas, message=Invalid value: "integer": spec.triggers[0].metadata.desiredReplicas in body must be of type string: "integer", reason=FieldValueTypeInvalid, additionalProperties={})], group=keda.sh, kind=ScaledObject, name=my-scaled-object, retryAfterSeconds=null, uid=null, additionalProperties={}), kind=Status, message=ScaledObject.keda.sh "my-scaled-object" is invalid: spec.triggers[0].metadata.desiredReplicas: Invalid value: "integer": spec.triggers[0].metadata.desiredReplicas in body must be of type string: "integer", metadata=ListMeta(_continue=null, remainingItemCount=null, resourceVersion=null, selfLink=null, additionalProperties={}), reason=Invalid, status=Failure, additionalProperties={})
at io.fabric8.kubernetes.client.KubernetesClientException.copyAsCause(KubernetesClientException.java:238)
        at io.fabric8.kubernetes.client.dsl.internal.OperationSupport.waitForResult(OperationSupport.java:518)
        at io.fabric8.kubernetes.client.dsl.internal.OperationSupport.handleResponse(OperationSupport.java:535)
        at io.fabric8.kubernetes.client.dsl.internal.OperationSupport.handleCreate(OperationSupport.java:340)
        at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.handleCreate(BaseOperation.java:703)
        at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.handleCreate(BaseOperation.java:92)
        at io.fabric8.kubernetes.client.dsl.internal.CreateOnlyResourceOperation.create(CreateOnlyResourceOperation.java:42)
        at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.create(BaseOperation.java:1108)
        at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.create(BaseOperation.java:92)
        at io.fabric8.kubernetes.client.extension.ResourceAdapter.create(ResourceAdapter.java:114)

The issue is due to the desiredReplicas which must be of type string and is replaced with integer.

Fabric8 Kubernetes Client version

6.9.2

Steps to reproduce

  1. Install keda crds on your cluster
  2. Create a scaledObject
kind: ScaledObject
metadata:
  annotations:
    autoscaling.keda.sh/paused-replicas: 0
  labels:
    my-selector: my-app
  name: my-scaled-object
  namespace: source-namespace
spec:
  maxReplicaCount: 1
  scaleTargetRef:
    kind: Deployment
    name: my-deployment
  triggers:
    - metadata:
        desiredReplicas: '1'
        end: 30 */2 * * *
        start: 0 */2 * * *
        timezone: America/Montreal
      type: cron
  1. Create following code
public void test() {
        var scaledObjectCrdContext = new ResourceDefinitionContext.Builder()
                .withNamespaced(true)
                .withGroup("keda.sh")
                .withKind("ScaledObject")
                .withVersion("v1alpha1")
                .withPlural("scaledobjects")
                .build();
        kubernetesClient.genericKubernetesResources(scaledObjectCrdContext)
                        .inNamespace("source-namespace")
                        .withLabels(Map.of("my-selector", "my-app"))
                        .list()
                        .getItems()
                        .stream()
                        .peek(item -> item.getMetadata().setNamespace("destination-namespace"))
                        .forEach(item -> kubernetesClient.genericKubernetesResources(scaledObjectCrdContext).resource(item).create());
    }
  1. Run it

Expected behavior

Type must not be changed

Runtime

Kubernetes (vanilla)

Kubernetes API Server version

1.25.3@latest

Environment

Linux

Fabric8 Kubernetes Client Logs

 POST at: https://localhost/apis/keda.sh/v1alpha1/namespaces/destination-namespace/scaledobjects. Message: ScaledObject.keda.sh "my-scaled-object" is invalid: spec.triggers[0].metadata.desiredReplicas: Invalid value: "integer": spec.triggers[0].metadata.desiredReplicas in body must be of type string: "integer". Received status: Status(apiVersion=v1, code=422, details=StatusDetails(causes=[StatusCause(field=spec.triggers[0].metadata.desiredReplicas, message=Invalid value: "integer": spec.triggers[0].metadata.desiredReplicas in body must be of type string: "integer", reason=FieldValueTypeInvalid, additionalProperties={})], group=keda.sh, kind=ScaledObject, name=my-scaled-object, retryAfterSeconds=null, uid=null, additionalProperties={}), kind=Status, message=ScaledObject.keda.sh "my-scaled-object" is invalid: spec.triggers[0].metadata.desiredReplicas: Invalid value: "integer": spec.triggers[0].metadata.desiredReplicas in body must be of type string: "integer", metadata=ListMeta(_continue=null, remainingItemCount=null, resourceVersion=null, selfLink=null, additionalProperties={}), reason=Invalid, status=Failure, additionalProperties={})
at io.fabric8.kubernetes.client.KubernetesClientException.copyAsCause(KubernetesClientException.java:238)
        at io.fabric8.kubernetes.client.dsl.internal.OperationSupport.waitForResult(OperationSupport.java:518)
        at io.fabric8.kubernetes.client.dsl.internal.OperationSupport.handleResponse(OperationSupport.java:535)
        at io.fabric8.kubernetes.client.dsl.internal.OperationSupport.handleCreate(OperationSupport.java:340)
        at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.handleCreate(BaseOperation.java:703)
        at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.handleCreate(BaseOperation.java:92)
        at io.fabric8.kubernetes.client.dsl.internal.CreateOnlyResourceOperation.create(CreateOnlyResourceOperation.java:42)
        at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.create(BaseOperation.java:1108)
        at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.create(BaseOperation.java:92)
        at io.fabric8.kubernetes.client.extension.ResourceAdapter.create(ResourceAdapter.java:114)

Additional context

I see this issue which may be related: FasterXML/jackson-databind#796

@shawkins
Copy link
Contributor

Trying something similar locally does not exhibit the behavior you are seeing:

    String yaml = "x: '1'";
    String json = "{\"x\":\"1\"}";
    GenericKubernetesResource yamlValue = Serialization.unmarshal(yaml, GenericKubernetesResource.class);
    GenericKubernetesResource jsonValue = Serialization.unmarshal(json, GenericKubernetesResource.class);
    System.out.println(Serialization.asYaml(yamlValue));
    System.out.println(Serialization.asJson(jsonValue));

The output shows the string type is preserved.

Can you check the contents of the item retrieved from the server in your java code, and also from kubectl?

@speedfl
Copy link
Author

speedfl commented Nov 14, 2023

Thanks @shawkins. I was not able to reproduce the environment locally. I will try to investigate on my side and let you know. Have a good day

@speedfl speedfl closed this as completed Nov 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants