alauda / captain

A Helm 3 Controller
Apache License 2.0
185 stars 46 forks source link

generate Java codes from CustomResourceDefinition error #49

Closed lin1005q closed 4 years ago

lin1005q commented 4 years ago

hello。

我们公司的开发语言是java。目前使用的是官方的sdk。https://github.com/kubernetes-client/java

官方对众多编程语言的sdk是通过openapi规范来自动生成的。昨天我找到了官方指导怎样生成crd对应的object实体类的文章。https://github.com/kubernetes-client/java/blob/e679a13248cfdf437460292cab0635c5cd54adcc/docs/generate-model-from-third-party-resources.md

然后我按照官方的指导方法进行了测试。下面是生成的类文件。

weihai@deepin:~/Desktop/java$ tree
.
├── src
│   └── main
│       └── java
│           └── io
│               └── kubernetes
│                   └── client
│                       └── models
│                           ├── ComCoreosMonitoringV1AlertmanagerList.java
│                           ├── ComCoreosMonitoringV1PodMonitorList.java
│                           ├── ComCoreosMonitoringV1PrometheusList.java
│                           ├── ComCoreosMonitoringV1PrometheusRuleList.java
│                           ├── ComCoreosMonitoringV1PrometheusRuleListMetadata.java
│                           ├── ComCoreosMonitoringV1ServiceMonitorList.java
│                           ├── IoAlaudaAppV1alpha1ChartList.java
│                           ├── IoAlaudaAppV1alpha1ChartRepoList.java
│                           ├── IoAlaudaAppV1alpha1HelmRequestList.java
│                           └── IoAlaudaAppV1alpha1ReleaseList.java
└── swagger.json

关于captain相关的只有list相关的类,没有具体的类文件。

然后我回过头读官方的说明

TL;DR: This document will be useful when you extend third-party resources into your kubernetes cluster e.g. CustomResourceDefinition and try to program java to operate the extended APIs. The generation process requires your CRD to be defined with structral-schema.

我认为可能是crd定义不是特别严格的原因。我对比了 官方示例(crontabs.stable.example.com)和HelmRequest(helmrequests.app.alauda.io)的定义的yaml文件。

很大的嫌疑应该是这里

##helmrequests

  validation:
    # openAPIV3Schema is the schema for validating custom objects.
    openAPIV3Schema:
      properties:
        spec:
          required:
            - chart
##crontabs.stable.example.com

validation:
    openAPIV3Schema:
      type: object
      properties:
        spec:
          type: object
          properties:
            cronSpec:
              type: string
            image:
              type: string
            replicas:
              type: integer

然后我按照官方的demo执行了一次。一共生成了3个文件

ComExampleStableV1CronTab.java
ComExampleStableV1CronTabList.java
ComExampleStableV1CronTabSpec.java

然后再查看ComExampleStableV1CronTabSpec.java文件。里面的三个属性就是crd定义中validation.openAPIV3Schema.properties.spec里面的内容

/*
 * Kubernetes
 * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 *
 * The version of the OpenAPI document: v1.15.5
 * 
 *
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */

package io.kubernetes.client.models;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import java.util.Objects;
import java.util.Arrays;
import com.google.gson.TypeAdapter;
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.annotations.SerializedName;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.IOException;

/**
 * ComExampleStableV1CronTabSpec
 */
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2020-02-29T02:41:11.514Z[Etc/UTC]")
public class ComExampleStableV1CronTabSpec {
  public static final String SERIALIZED_NAME_CRON_SPEC = "cronSpec";
  @SerializedName(SERIALIZED_NAME_CRON_SPEC)
  private String cronSpec;

  public static final String SERIALIZED_NAME_IMAGE = "image";
  @SerializedName(SERIALIZED_NAME_IMAGE)
  private String image;

  public static final String SERIALIZED_NAME_REPLICAS = "replicas";
  @SerializedName(SERIALIZED_NAME_REPLICAS)
  private Integer replicas;

  public ComExampleStableV1CronTabSpec cronSpec(String cronSpec) {

    this.cronSpec = cronSpec;
    return this;
  }

   /**
   * Get cronSpec
   * @return cronSpec
  **/
  @javax.annotation.Nullable
  @ApiModelProperty(value = "")

  public String getCronSpec() {
    return cronSpec;
  }

  public void setCronSpec(String cronSpec) {
    this.cronSpec = cronSpec;
  }

  public ComExampleStableV1CronTabSpec image(String image) {

    this.image = image;
    return this;
  }

   /**
   * Get image
   * @return image
  **/
  @javax.annotation.Nullable
  @ApiModelProperty(value = "")

  public String getImage() {
    return image;
  }

  public void setImage(String image) {
    this.image = image;
  }

  public ComExampleStableV1CronTabSpec replicas(Integer replicas) {

    this.replicas = replicas;
    return this;
  }

   /**
   * Get replicas
   * @return replicas
  **/
  @javax.annotation.Nullable
  @ApiModelProperty(value = "")

  public Integer getReplicas() {
    return replicas;
  }

  public void setReplicas(Integer replicas) {
    this.replicas = replicas;
  }

  @Override
  public boolean equals(java.lang.Object o) {
    return EqualsBuilder.reflectionEquals(this, o);
  }

  @Override
  public int hashCode() {
    return HashCodeBuilder.reflectionHashCode(this);
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("class ComExampleStableV1CronTabSpec {\n");
    sb.append("    cronSpec: ").append(toIndentedString(cronSpec)).append("\n");
    sb.append("    image: ").append(toIndentedString(image)).append("\n");
    sb.append("    replicas: ").append(toIndentedString(replicas)).append("\n");
    sb.append("}");
    return sb.toString();
  }

  /**
   * Convert the given object to string with each line indented by 4 spaces
   * (except the first line).
   */
  private String toIndentedString(java.lang.Object o) {
    if (o == null) {
      return "null";
    }
    return o.toString().replace("\n", "\n    ");
  }

}

所以,希望官方可以把crd的validation补充的更详细一点,然后就可以生成各种语言的sdk了。

hangyan commented 4 years ago

这个也在考虑之中,之所以目前没有完善的原因是

  1. schema的支持并不是所有k8s版本都完善的,captain考虑支持尽量多的k8s版本,所以没有再schema里放太多的逻辑
  2. 有webook来做schema校验,更灵活一些
  3. 很多field的校验依赖于一些互相关联的field,无法简单用schema表示

但是这个应该放在feautre planning里面