Add a custom Args type that accepts both a key-value map and a flat
CLI-style list, normalizing internally to []string so downstream code
requires no changes.
- Args: new []string alias with UnmarshalJSON (map + list) and
MarshalJSON (map) — keys are sorted for deterministic ordering
- CRD schema: switch args from typed array to
x-kubernetes-preserve-unknown-fields to accept either shape
- Bump go-flink-client to v0.2.2 (fix: programArgsList → programArg
query parameter name for Flink REST API)
Args can now be written as:
args:
kafka-host: broker:9092
kafka-group-id: my-group
Or the existing list format:
args:
- "--kafka-host"
- broker:9092
143 lines
5.3 KiB
Go
143 lines
5.3 KiB
Go
package v1alpha1
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
|
|
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
)
|
|
|
|
//go:generate go run sigs.k8s.io/controller-tools/cmd/controller-gen object paths=$GOFILE
|
|
|
|
// Args is a list of program arguments passed to the Flink job.
|
|
// It accepts two formats in JSON/YAML:
|
|
//
|
|
// List: ["--kafka-host", "broker:9092", "--kafka-group-id", "my-group"]
|
|
// Map: {kafka-host: "broker:9092", kafka-group-id: "my-group"}
|
|
//
|
|
// Map keys are automatically prefixed with "--" and expanded into alternating
|
|
// key/value pairs. The internal representation is always a flat []string.
|
|
type Args []string
|
|
|
|
// UnmarshalJSON implements dual-format deserialization.
|
|
func (a *Args) UnmarshalJSON(data []byte) error {
|
|
// Try map format first: {"key": "value", ...}
|
|
var m map[string]string
|
|
if err := json.Unmarshal(data, &m); err == nil {
|
|
*a = make(Args, 0, len(m)*2)
|
|
// Sort keys for deterministic ordering.
|
|
keys := make([]string, 0, len(m))
|
|
for k := range m {
|
|
keys = append(keys, k)
|
|
}
|
|
sort.Strings(keys)
|
|
for _, k := range keys {
|
|
*a = append(*a, "--"+k, m[k])
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Fall back to list format: ["--key", "value", ...]
|
|
var s []string
|
|
if err := json.Unmarshal(data, &s); err != nil {
|
|
return err
|
|
}
|
|
*a = Args(s)
|
|
return nil
|
|
}
|
|
|
|
// MarshalJSON serializes Args in the compact map format.
|
|
func (a Args) MarshalJSON() ([]byte, error) {
|
|
m := make(map[string]string, len(a)/2)
|
|
for i := 0; i < len(a)-1; i += 2 {
|
|
key := strings.TrimPrefix(a[i], "--")
|
|
m[key] = a[i+1]
|
|
}
|
|
return json.Marshal(m)
|
|
}
|
|
|
|
type FlinkJobSpec struct {
|
|
Key string `json:"key"`
|
|
Name string `json:"name"`
|
|
FlinkCluster string `json:"flinkCluster"`
|
|
Parallelism int `json:"parallelism"`
|
|
JarURI string `json:"jarUri"`
|
|
JarURIBasicAuthUsername *string `json:"jarURIBasicAuthUsername"`
|
|
JarURIBasicAuthPassword *string `json:"jarURIBasicAuthPassword"`
|
|
SavepointInterval metaV1.Duration `json:"savepointInterval"`
|
|
EntryClass string `json:"entryClass"`
|
|
Args Args `json:"args,omitempty"`
|
|
}
|
|
|
|
type FlinkJobStatus struct {
|
|
JobStatus JobStatus `json:"jobStatus,omitempty"`
|
|
LifeCycleStatus LifeCycleStatus `json:"lifeCycleStatus,omitempty"`
|
|
LastSavepointPath *string `json:"lastSavepointPath,omitempty"`
|
|
JarId *string `json:"jarId,omitempty"`
|
|
JobId *string `json:"jobId,omitempty"`
|
|
Error *string `json:"error,omitempty"`
|
|
SavepointTriggerId *string `json:"savepointTriggerId,omitempty"`
|
|
PauseSavepointTriggerId *string `json:"pauseSavepointTriggerId,omitempty"`
|
|
LastSavepointDate *time.Time `json:"lastSavepointDate,omitempty"`
|
|
LastRestoredSavepointDate *time.Time `json:"lastRestoredSavepointDate,omitempty"`
|
|
LastRestoredSavepointRestoredDate *time.Time `json:"lastRestoredSavepointRestoredDate,omitempty"`
|
|
RestoredCount int `json:"restoredCount,omitempty"`
|
|
RunningJarURI *string `json:"runningJarURI"`
|
|
}
|
|
|
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
|
type FlinkJob struct {
|
|
metaV1.TypeMeta `json:",inline"`
|
|
metaV1.ObjectMeta `json:"metadata,omitempty"`
|
|
Spec FlinkJobSpec `json:"spec"`
|
|
Status FlinkJobStatus `json:"status"`
|
|
}
|
|
|
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
|
type FlinkJobList struct {
|
|
metaV1.TypeMeta `json:",inline"`
|
|
metaV1.ListMeta `json:"metadata,omitempty"`
|
|
Items []FlinkJob `json:"items"`
|
|
}
|
|
|
|
var (
|
|
ErrNoJobId = errors.New("[managed-job] no job id")
|
|
ErrNoJarId = errors.New("[managed-job] no jar id")
|
|
ErrNoSavepointTriggerId = errors.New("[managed-job] no savepoint trigger id")
|
|
ErrNoSavepointPath = errors.New("[managed-job] no savepoint path")
|
|
ErrOnStartingJob = errors.New("[managed-job] error on starting job")
|
|
)
|
|
|
|
type JobStatus string
|
|
|
|
var (
|
|
JobStatusInitializing JobStatus = "INITIALIZING"
|
|
JobStatusRunning JobStatus = "RUNNING"
|
|
JobStatusCreating JobStatus = "CREATING"
|
|
JobStatusError JobStatus = "ERROR"
|
|
JobStatusReconciling JobStatus = "RECONCILING"
|
|
JobStatusFailed JobStatus = "FAILED"
|
|
JobStatusFailing JobStatus = "FAILING"
|
|
JobStatusRestarting JobStatus = "RESTARTING"
|
|
JobStatusFinished JobStatus = "FINISHED"
|
|
JobStatusCanceled JobStatus = "CANCELED"
|
|
JobStatusCancelling JobStatus = "CANCELLING"
|
|
JobStatusSuspended JobStatus = "SUSPENDED"
|
|
)
|
|
|
|
type LifeCycleStatus string
|
|
|
|
const (
|
|
LifeCycleStatusInitializing LifeCycleStatus = "INITIALIZING"
|
|
LifeCycleStatusRestoring LifeCycleStatus = "RESTORING"
|
|
LifeCycleStatusGracefulStopFailed LifeCycleStatus = "GRACEFUL_STOP_FAILED"
|
|
LifeCycleStatusUpgradeFailed LifeCycleStatus = "UPGRADE_FAILED"
|
|
LifeCycleStatusGracefullyPaused LifeCycleStatus = "GRACEFULLY_PAUSED"
|
|
LifeCycleStatusUnhealthyJobManager LifeCycleStatus = "UNHEALTHY_JOB_MANAGER"
|
|
LifeCycleStatusHealthy LifeCycleStatus = "HEALTHY"
|
|
LifeCycleStatusFailed LifeCycleStatus = "FAILED"
|
|
)
|