Monitord Acces Change
This commit is contained in:
+146
-29
@@ -4,12 +4,12 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"cloud.o-forge.io/core/oc-lib/config"
|
||||
"cloud.o-forge.io/core/oc-lib/models/common/models"
|
||||
"cloud.o-forge.io/core/oc-lib/models/resources"
|
||||
"cloud.o-forge.io/core/oc-lib/models/resources/native_tools"
|
||||
"cloud.o-forge.io/core/oc-lib/models/workflow"
|
||||
"cloud.o-forge.io/core/oc-lib/models/workflow_execution"
|
||||
"cloud.o-forge.io/core/oc-lib/tools"
|
||||
)
|
||||
@@ -48,6 +48,7 @@ func (c *Container) AddVolumeMount(volumeMount VolumeMount, volumes []VolumeMoun
|
||||
type VolumeMount struct {
|
||||
Name string `yaml:"name"`
|
||||
MountPath string `yaml:"mountPath"`
|
||||
ReadOnly bool `yaml:"readOnly,omitempty"`
|
||||
Storage *resources.StorageResource `yaml:"-"`
|
||||
IsReparted bool `yaml:"-"`
|
||||
}
|
||||
@@ -90,8 +91,8 @@ type Artifact struct {
|
||||
}
|
||||
|
||||
type ArtifactRepositoryRef struct {
|
||||
ConfigMap string `yaml:"configMap"`
|
||||
Key string `yaml:"key"`
|
||||
ConfigMap string `yaml:"configMap,omitempty"`
|
||||
Key string `yaml:"key,omitempty"`
|
||||
}
|
||||
|
||||
type InOut struct {
|
||||
@@ -110,7 +111,7 @@ type Template struct {
|
||||
NodeSelector map[string]string `yaml:"nodeSelector,omitempty"`
|
||||
}
|
||||
|
||||
func (template *Template) CreateEventContainer(execution *workflow_execution.WorkflowExecution, nt *resources.NativeTool, dag *Dag) {
|
||||
func (template *Template) CreateEventContainer(execution *workflow_execution.WorkflowExecution, id string, wf *workflow.Workflow, nt *resources.NativeTool, dag *Dag, natsURL string) {
|
||||
container := Container{Image: "natsio/nats-box", ImagePullPolicy: "IfNotPresent"}
|
||||
container.Command = []string{"sh", "-c"} // all is bash
|
||||
|
||||
@@ -139,12 +140,21 @@ func (template *Template) CreateEventContainer(execution *workflow_execution.Wor
|
||||
cmd := exec.Command(
|
||||
"nats",
|
||||
"pub",
|
||||
"--server", config.GetConfig().NATSUrl+":4222",
|
||||
"--server", natsURL,
|
||||
tools.WORKFLOW_EVENT.GenerateKey(),
|
||||
string(payload),
|
||||
)
|
||||
for _, args := range cmd.Args {
|
||||
container.Args = append(container.Args, args)
|
||||
if len(wf.Args[id]) > 0 {
|
||||
for _, args := range wf.Args[id] {
|
||||
container.Args = append(container.Args, args)
|
||||
}
|
||||
} else {
|
||||
for _, args := range cmd.Args {
|
||||
container.Args = append(container.Args, args)
|
||||
}
|
||||
}
|
||||
container.Args = []string{
|
||||
strings.Join(container.Args, " "),
|
||||
}
|
||||
template.Container = container
|
||||
}
|
||||
@@ -152,7 +162,7 @@ func (template *Template) CreateEventContainer(execution *workflow_execution.Wor
|
||||
}
|
||||
}
|
||||
|
||||
func (template *Template) CreateContainer(exec *workflow_execution.WorkflowExecution, processing *resources.ProcessingResource, dag *Dag) {
|
||||
func (template *Template) CreateContainer(exec *workflow_execution.WorkflowExecution, wf *workflow.Workflow, itemID string, processing *resources.ProcessingResource, dag *Dag) {
|
||||
index := 0
|
||||
if d, ok := exec.SelectedInstances[processing.GetID()]; ok {
|
||||
index = d
|
||||
@@ -162,40 +172,147 @@ func (template *Template) CreateContainer(exec *workflow_execution.WorkflowExecu
|
||||
return
|
||||
}
|
||||
inst := instance.(*resources.ProcessingInstance)
|
||||
container := Container{Image: inst.Access.Container.Image, ImagePullPolicy: "IfNotPresent"}
|
||||
container := Container{
|
||||
Image: inst.Access.Container.Image,
|
||||
ImagePullPolicy: "IfNotPresent",
|
||||
}
|
||||
if container.Image == "" {
|
||||
return
|
||||
}
|
||||
container.Command = []string{"sh", "-c"} // all is bash
|
||||
for _, v := range inst.Env {
|
||||
template.Inputs.Parameters = append(template.Inputs.Parameters, Parameter{Name: v.Name})
|
||||
for _, v := range processing.Env {
|
||||
template.Inputs.Parameters = AppendParamIfAbsent(template.Inputs.Parameters, Parameter{Name: v.Name})
|
||||
}
|
||||
for _, v := range inst.Inputs {
|
||||
template.Inputs.Parameters = append(template.Inputs.Parameters, Parameter{Name: v.Name})
|
||||
for _, v := range wf.Env[itemID] {
|
||||
template.Inputs.Parameters = AppendParamIfAbsent(template.Inputs.Parameters, Parameter{Name: v.Name})
|
||||
}
|
||||
for _, v := range inst.Inputs {
|
||||
template.Outputs.Parameters = append(template.Inputs.Parameters, Parameter{Name: v.Name})
|
||||
for _, v := range processing.Inputs {
|
||||
template.Inputs.Parameters = AppendParamIfAbsent(template.Inputs.Parameters, Parameter{Name: v.Name})
|
||||
}
|
||||
for _, v := range wf.Inputs[itemID] {
|
||||
template.Inputs.Parameters = AppendParamIfAbsent(template.Inputs.Parameters, Parameter{Name: v.Name})
|
||||
}
|
||||
for _, v := range processing.Outputs {
|
||||
template.Outputs.Parameters = AppendParamIfAbsent(template.Outputs.Parameters, Parameter{
|
||||
Name: v.Name,
|
||||
Value: v.Value,
|
||||
})
|
||||
}
|
||||
for _, v := range wf.Outputs[itemID] {
|
||||
template.Outputs.Parameters = AppendParamIfAbsent(template.Outputs.Parameters, Parameter{
|
||||
Name: v.Name,
|
||||
Value: v.Value,
|
||||
})
|
||||
}
|
||||
cmd := strings.ReplaceAll(inst.Access.Container.Command, container.Image, "")
|
||||
|
||||
for _, a := range strings.Split(cmd, " ") {
|
||||
container.Args = append(container.Args, template.ReplacePerEnv(a, inst.Env))
|
||||
container.Args = append(container.Args, template.ReplacePerEnv(a, template.Inputs.Parameters))
|
||||
}
|
||||
for _, a := range strings.Split(inst.Access.Container.Args, " ") {
|
||||
container.Args = append(container.Args, template.ReplacePerEnv(a, inst.Env))
|
||||
if len(wf.Args[itemID]) > 0 {
|
||||
for _, a := range wf.Args[itemID] {
|
||||
container.Args = append(container.Args, template.ReplacePerEnv(a, template.Inputs.Parameters))
|
||||
}
|
||||
} else {
|
||||
for _, a := range strings.Split(inst.Access.Container.Args, " ") {
|
||||
container.Args = append(container.Args, template.ReplacePerEnv(a, template.Inputs.Parameters))
|
||||
}
|
||||
}
|
||||
|
||||
container.Args = []string{strings.Join(container.Args, " ")}
|
||||
|
||||
template.Container = container
|
||||
}
|
||||
|
||||
func (template *Template) ReplacePerEnv(arg string, envs []models.Param) string {
|
||||
for _, v := range envs {
|
||||
if v.Name != "" && strings.Contains(arg, v.Name) {
|
||||
// CreateServiceContainer crée le container Argo pour un ServiceResource.
|
||||
// Pour HOSTED, le container appelle le service distant (endpoint connu) ;
|
||||
// pour DEPLOYMENT, le container EST le service à déployer.
|
||||
// La logique de paramètres est identique à CreateContainer.
|
||||
func (template *Template) CreateServiceContainer(exec *workflow_execution.WorkflowExecution, wf *workflow.Workflow, itemID string, service *resources.ServiceResource, dag *Dag) {
|
||||
index := 0
|
||||
if d, ok := exec.SelectedInstances[service.GetID()]; ok {
|
||||
index = d
|
||||
}
|
||||
instance := service.GetSelectedInstance(&index)
|
||||
if instance == nil {
|
||||
return
|
||||
}
|
||||
inst := instance.(*resources.ServiceInstance)
|
||||
if inst.Access == nil || inst.Access.Container == nil || inst.Access.Container.Image == "" {
|
||||
return
|
||||
}
|
||||
container := Container{
|
||||
Image: inst.Access.Container.Image,
|
||||
ImagePullPolicy: "IfNotPresent",
|
||||
}
|
||||
container.Command = []string{"sh", "-c"}
|
||||
for _, v := range service.Env {
|
||||
template.Inputs.Parameters = AppendParamIfAbsent(template.Inputs.Parameters, Parameter{Name: v.Name})
|
||||
}
|
||||
for _, v := range wf.Env[itemID] {
|
||||
template.Inputs.Parameters = AppendParamIfAbsent(template.Inputs.Parameters, Parameter{Name: v.Name})
|
||||
}
|
||||
for _, v := range service.Inputs {
|
||||
template.Inputs.Parameters = AppendParamIfAbsent(template.Inputs.Parameters, Parameter{Name: v.Name})
|
||||
}
|
||||
for _, v := range wf.Inputs[itemID] {
|
||||
template.Inputs.Parameters = AppendParamIfAbsent(template.Inputs.Parameters, Parameter{Name: v.Name})
|
||||
}
|
||||
for _, v := range service.Outputs {
|
||||
template.Outputs.Parameters = AppendParamIfAbsent(template.Outputs.Parameters, Parameter{
|
||||
Name: v.Name,
|
||||
Value: v.Value,
|
||||
})
|
||||
}
|
||||
for _, v := range wf.Outputs[itemID] {
|
||||
template.Outputs.Parameters = AppendParamIfAbsent(template.Outputs.Parameters, Parameter{
|
||||
Name: v.Name,
|
||||
Value: v.Value,
|
||||
})
|
||||
}
|
||||
cmd := strings.ReplaceAll(inst.Access.Container.Command, container.Image, "")
|
||||
for _, a := range strings.Split(cmd, " ") {
|
||||
container.Args = append(container.Args, template.ReplacePerEnv(a, template.Inputs.Parameters))
|
||||
}
|
||||
if len(wf.Args[itemID]) > 0 {
|
||||
for _, a := range wf.Args[itemID] {
|
||||
container.Args = append(container.Args, template.ReplacePerEnv(a, template.Inputs.Parameters))
|
||||
}
|
||||
} else {
|
||||
for _, a := range strings.Split(inst.Access.Container.Args, " ") {
|
||||
container.Args = append(container.Args, template.ReplacePerEnv(a, template.Inputs.Parameters))
|
||||
}
|
||||
}
|
||||
container.Args = []string{strings.Join(container.Args, " ")}
|
||||
template.Container = container
|
||||
}
|
||||
|
||||
// AppendParamIfAbsent ajoute p à params uniquement si aucun paramètre
|
||||
// portant le même nom n'est déjà présent. Évite les doublons quand les
|
||||
// variables sont définies à la fois sur le ProcessingResource et sur le
|
||||
// Workflow (overrides).
|
||||
func AppendParamIfAbsent(params []Parameter, p Parameter) []Parameter {
|
||||
for _, existing := range params {
|
||||
if existing.Name == p.Name {
|
||||
return params
|
||||
}
|
||||
}
|
||||
return append(params, p)
|
||||
}
|
||||
|
||||
func (template *Template) ReplacePerEnv(arg string, envs []Parameter) string {
|
||||
// Tri par longueur décroissante : les noms longs sont remplacés en premier
|
||||
// pour éviter que $FOO matche à l'intérieur de $FOOBAR.
|
||||
sorted := make([]Parameter, len(envs))
|
||||
copy(sorted, envs)
|
||||
sort.Slice(sorted, func(i, j int) bool {
|
||||
return len(sorted[i].Name) > len(sorted[j].Name)
|
||||
})
|
||||
for _, v := range sorted {
|
||||
needle := "$" + v.Name
|
||||
if v.Name != "" && strings.Contains(arg, needle) {
|
||||
value := "{{ inputs.parameters." + v.Name + " }}"
|
||||
arg = strings.ReplaceAll(arg, v.Name, value)
|
||||
arg = strings.ReplaceAll(arg, "$"+v.Name, value)
|
||||
arg = strings.ReplaceAll(arg, "$", "")
|
||||
arg = strings.ReplaceAll(arg, needle, value)
|
||||
}
|
||||
}
|
||||
return arg
|
||||
@@ -204,10 +321,10 @@ func (template *Template) ReplacePerEnv(arg string, envs []models.Param) string
|
||||
// AddAdmiraltyAnnotations marque le template pour qu'Admiralty route le pod
|
||||
// vers le cluster virtuel correspondant au peerId.
|
||||
//
|
||||
// - elect: "" déclenche le webhook Admiralty sur le pod créé par Argo.
|
||||
// - nodeSelector cible le virtual node Admiralty dont le label
|
||||
// multicluster.admiralty.io/cluster-name vaut peerId,
|
||||
// ce qui contraint le scheduling au cluster distant.
|
||||
// - elect: "" déclenche le webhook Admiralty sur le pod créé par Argo.
|
||||
// - nodeSelector cible le virtual node Admiralty dont le label
|
||||
// multicluster.admiralty.io/cluster-name vaut peerId,
|
||||
// ce qui contraint le scheduling au cluster distant.
|
||||
func (t *Template) AddAdmiraltyAnnotations(peerId string) {
|
||||
if t.Metadata.Annotations == nil {
|
||||
t.Metadata.Annotations = make(map[string]string)
|
||||
|
||||
+22
-7
@@ -17,11 +17,26 @@ type VolumeSpec struct {
|
||||
} `yaml:"resources"`
|
||||
}
|
||||
|
||||
// ExistingVolume references a pre-provisioned PVC (created by oc-datacenter).
|
||||
// Used in Workflow.Spec.ExistingVolumes (yaml: "volumes") instead of volumeClaimTemplates.
|
||||
type ExistingVolume struct {
|
||||
Name string `yaml:"name"`
|
||||
PersistentVolumeClaim struct {
|
||||
ClaimName string `yaml:"claimName"`
|
||||
} `yaml:"persistentVolumeClaim"`
|
||||
// PVCRef references a pre-provisioned PersistentVolumeClaim by name.
|
||||
type PVCRef struct {
|
||||
ClaimName string `yaml:"claimName"`
|
||||
}
|
||||
|
||||
// SecretRef references a K8s Secret to mount as a volume.
|
||||
type SecretRef struct {
|
||||
SecretName string `yaml:"secretName"`
|
||||
}
|
||||
|
||||
// EmptyDirRef declares an emptyDir volume. Set Medium to "Memory" for /dev/shm-style RAM backing.
|
||||
type EmptyDirRef struct {
|
||||
Medium string `yaml:"medium,omitempty"`
|
||||
}
|
||||
|
||||
// ExistingVolume represents any volume mounted into an Argo workflow spec.
|
||||
// Exactly one of PersistentVolumeClaim, Secret, or EmptyDir should be non-nil.
|
||||
type ExistingVolume struct {
|
||||
Name string `yaml:"name"`
|
||||
PersistentVolumeClaim *PVCRef `yaml:"persistentVolumeClaim,omitempty"`
|
||||
Secret *SecretRef `yaml:"secret,omitempty"`
|
||||
EmptyDir *EmptyDirRef `yaml:"emptyDir,omitempty"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user