在Go Operator Controller中动态创建Spark Operator对象求助
动态创建Spark Operator CR对象的解决方案
方法1:用Unstructured类型全动态处理
如果不需要强类型校验,直接用client-go提供的Unstructured类型处理用户提交的YAML,完全避免硬编码:
import ( "context" "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/dynamic" "sigs.k8s.io/yaml" ) // 假设userYAML是用户提供的SparkApplication YAML字符串 func createSparkAppFromYAML(userYAML string, namespace string, config interface{}) error { // 解析YAML为map[string]interface{} var obj map[string]interface{} if err := yaml.Unmarshal([]byte(userYAML), &obj); err != nil { return err } // 构造Unstructured对象 unstructuredObj := &unstructured.Unstructured{Object: obj} // 设置Spark Operator的Group/Version/Resource gvr := schema.GroupVersionResource{ Group: "sparkoperator.k8s.io", Version: "v1beta2", Resource: "sparkapplications", } // 初始化Dynamic Client并创建资源 dynamicClient, err := dynamic.NewForConfig(config.(*rest.Config)) if err != nil { return err } _, err = dynamicClient.Resource(gvr).Namespace(namespace).Create(context.TODO(), unstructuredObj, v1.CreateOptions{}) return err }
方法2:结构化类型+动态字段注入
如果需要保留Spark Application的强类型校验,同时允许用户传入动态字段,可以用mapstructure工具将用户字段注入到结构化对象:
import ( sparkv1beta2 "github.com/GoogleCloudPlatform/spark-on-k8s-operator/pkg/apis/sparkoperator.k8s.io/v1beta2" "github.com/mitchellh/mapstructure" "sigs.k8s.io/yaml" ) func createSparkAppWithDynamicFields(userYAML string) (*sparkv1beta2.SparkApplication, error) { // 解析用户YAML为map var userFields map[string]interface{} if err := yaml.Unmarshal([]byte(userYAML), &userFields); err != nil { return nil, err } // 初始化SparkApplication对象 sparkApp := &sparkv1beta2.SparkApplication{} // 配置解码器,允许注入所有用户字段 config := &mapstructure.DecoderConfig{ Result: sparkApp, // 不忽略未标记字段,保留所有用户传入的属性 IgnoreUntaggedFields: false, Squash: true, } decoder, err := mapstructure.NewDecoder(config) if err != nil { return nil, err } if err := decoder.Decode(userFields); err != nil { return nil, err } return sparkApp, nil }
之后可以用client-go的结构化Client提交这个对象,既保留类型安全,又支持动态属性。
方法3:YAML转JSON反序列化绕过硬编码
如果只需要解析用户YAML到结构化对象,且可以忽略未定义字段,直接用YAML转JSON后反序列化:
import ( sparkv1beta2 "github.com/GoogleCloudPlatform/spark-on-k8s-operator/pkg/apis/sparkoperator.k8s.io/v1beta2" "encoding/json" "sigs.k8s.io/yaml" ) func parseSparkAppFromYAML(userYAML string) (*sparkv1beta2.SparkApplication, error) { // YAML转JSON,利用Go JSON解析的字段兼容性 jsonData, err := yaml.YAMLToJSON([]byte(userYAML)) if err != nil { return nil, err } sparkApp := &sparkv1beta2.SparkApplication{} // 反序列化,自动忽略结构体未定义的字段 if err := json.Unmarshal(jsonData, sparkApp); err != nil { return nil, err } return sparkApp, nil }
内容的提问来源于stack exchange,提问作者user10437665
相关产品推荐
相关产品推荐

