feat: add generated parent modify resources
Introduce the modifier YAML kind for delayed parent-level modify operations and generate dedicated Terraform resources with typed parameters. Keep modifier parameters out of the ordinary instance CRUD resource, register modifiers separately, and leave delete as a no-op until an inverse API payload is confirmed. Mark vcOrg and vcNsxt modify operations during YAML generation so the contract survives regeneration.
This commit is contained in:
@@ -41,6 +41,7 @@ type OperationSpec struct {
|
|||||||
ID int `yaml:"id"`
|
ID int `yaml:"id"`
|
||||||
Kind string `yaml:"kind"`
|
Kind string `yaml:"kind"`
|
||||||
Action string `yaml:"action"`
|
Action string `yaml:"action"`
|
||||||
|
Modifier string `yaml:"modifier,omitempty"`
|
||||||
Subresource string `yaml:"subresource,omitempty"`
|
Subresource string `yaml:"subresource,omitempty"`
|
||||||
Man string `yaml:"man,omitempty"`
|
Man string `yaml:"man,omitempty"`
|
||||||
Params []ParamSpec `yaml:"params"`
|
Params []ParamSpec `yaml:"params"`
|
||||||
|
|||||||
@@ -24,11 +24,12 @@ import (
|
|||||||
"resource-generator/internal/types"
|
"resource-generator/internal/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// LoadSpecs загружает все YAML-спеки из директории и строит GenResource/GenSubresource/GenAction.
|
// LoadSpecs загружает все YAML-спеки из директории и строит модели всех ресурсов.
|
||||||
func LoadSpecs(dir string) ([]types.GenResource, []types.GenSubresource, []types.GenAction, error) {
|
func LoadSpecs(dir string) ([]types.GenResource, []types.GenSubresource, []types.GenAction, []types.GenModifier, error) {
|
||||||
var services []types.GenResource
|
var services []types.GenResource
|
||||||
var subs []types.GenSubresource
|
var subs []types.GenSubresource
|
||||||
var actions []types.GenAction
|
var actions []types.GenAction
|
||||||
|
var modifiers []types.GenModifier
|
||||||
domainServiceIDsSet := map[int]struct{}{}
|
domainServiceIDsSet := map[int]struct{}{}
|
||||||
walkErr := filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
|
walkErr := filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -56,6 +57,24 @@ func LoadSpecs(dir string) ([]types.GenResource, []types.GenSubresource, []types
|
|||||||
modifyParams := []types.Param{}
|
modifyParams := []types.Param{}
|
||||||
supportsSuspendDestroy := false
|
supportsSuspendDestroy := false
|
||||||
for _, op := range spec.Operations {
|
for _, op := range spec.Operations {
|
||||||
|
if op.Kind == "modifier" {
|
||||||
|
name := strings.TrimSpace(op.Modifier)
|
||||||
|
if name == "" {
|
||||||
|
name = strings.TrimSpace(op.Action)
|
||||||
|
}
|
||||||
|
modifier := types.GenModifier{
|
||||||
|
ServiceName: spec.Name,
|
||||||
|
ServiceID: spec.ServiceID,
|
||||||
|
ModifierName: name,
|
||||||
|
OperationName: op.Action,
|
||||||
|
Params: ConvertParams(op.Params),
|
||||||
|
}
|
||||||
|
modifier.SchemaParams = modifier.Params
|
||||||
|
params.Analyze(&modifier.UsesBool, &modifier.UsesInt64, &modifier.UsesString, &modifier.HasDefaults, &modifier.NeedsBoolDefault, &modifier.NeedsInt64Default, &modifier.NeedsStringDefault, modifier.SchemaParams)
|
||||||
|
modifier.NeedsJsonPlanMod = params.AnalyzeJsonPlanMod(modifier.SchemaParams)
|
||||||
|
modifiers = append(modifiers, modifier)
|
||||||
|
continue
|
||||||
|
}
|
||||||
if op.Kind != "instance" {
|
if op.Kind != "instance" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -192,7 +211,7 @@ func LoadSpecs(dir string) ([]types.GenResource, []types.GenSubresource, []types
|
|||||||
})
|
})
|
||||||
|
|
||||||
if walkErr != nil {
|
if walkErr != nil {
|
||||||
return nil, nil, nil, walkErr
|
return nil, nil, nil, nil, walkErr
|
||||||
}
|
}
|
||||||
|
|
||||||
domainServiceIDs := make([]int, 0, len(domainServiceIDsSet))
|
domainServiceIDs := make([]int, 0, len(domainServiceIDsSet))
|
||||||
@@ -221,8 +240,14 @@ func LoadSpecs(dir string) ([]types.GenResource, []types.GenSubresource, []types
|
|||||||
}
|
}
|
||||||
return actions[i].ServiceName < actions[j].ServiceName
|
return actions[i].ServiceName < actions[j].ServiceName
|
||||||
})
|
})
|
||||||
|
sort.Slice(modifiers, func(i, j int) bool {
|
||||||
|
if modifiers[i].ServiceName == modifiers[j].ServiceName {
|
||||||
|
return modifiers[i].ModifierName < modifiers[j].ModifierName
|
||||||
|
}
|
||||||
|
return modifiers[i].ServiceName < modifiers[j].ServiceName
|
||||||
|
})
|
||||||
|
|
||||||
return services, subs, actions, nil
|
return services, subs, actions, modifiers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConvertParams конвертирует []ParamSpec → []Param с нормализацией типов.
|
// ConvertParams конвертирует []ParamSpec → []Param с нормализацией типов.
|
||||||
@@ -313,6 +338,7 @@ var KnownKinds = map[string]bool{
|
|||||||
"instance": true,
|
"instance": true,
|
||||||
"subresource": true,
|
"subresource": true,
|
||||||
"action": true,
|
"action": true,
|
||||||
|
"modifier": true,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateSpec проверяет YAML-спек на обязательные поля и неизвестные kinds.
|
// ValidateSpec проверяет YAML-спек на обязательные поля и неизвестные kinds.
|
||||||
@@ -329,7 +355,7 @@ func ValidateSpec(path string, spec *types.ServiceSpec) error {
|
|||||||
return fmt.Errorf("operation[%d] %q: missing required field: kind", i, op.Name)
|
return fmt.Errorf("operation[%d] %q: missing required field: kind", i, op.Name)
|
||||||
}
|
}
|
||||||
if !KnownKinds[op.Kind] {
|
if !KnownKinds[op.Kind] {
|
||||||
return fmt.Errorf("operation[%d] %q: unknown kind %q (valid: instance, subresource, action)", i, op.Name, op.Kind)
|
return fmt.Errorf("operation[%d] %q: unknown kind %q (valid: instance, subresource, action, modifier)", i, op.Name, op.Kind)
|
||||||
}
|
}
|
||||||
if op.Action == "" {
|
if op.Action == "" {
|
||||||
return fmt.Errorf("operation[%d] %q (kind=%s): missing required field: action", i, op.Name, op.Kind)
|
return fmt.Errorf("operation[%d] %q (kind=%s): missing required field: action", i, op.Name, op.Kind)
|
||||||
@@ -337,6 +363,9 @@ func ValidateSpec(path string, spec *types.ServiceSpec) error {
|
|||||||
if op.Kind == "subresource" && op.Subresource == "" {
|
if op.Kind == "subresource" && op.Subresource == "" {
|
||||||
return fmt.Errorf("operation[%d] %q (kind=subresource): missing required field: subresource", i, op.Name)
|
return fmt.Errorf("operation[%d] %q (kind=subresource): missing required field: subresource", i, op.Name)
|
||||||
}
|
}
|
||||||
|
if op.Kind == "modifier" && strings.TrimSpace(op.Action) == "" {
|
||||||
|
return fmt.Errorf("operation[%d] %q (kind=modifier): missing required field: action", i, op.Name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,130 @@
|
|||||||
|
package templates
|
||||||
|
|
||||||
|
const Modifier = `package resources_gen
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"terraform-provider-nubes/internal/core"
|
||||||
|
"terraform-provider-nubes/internal/resources_core"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
||||||
|
{{- if .NeedsBoolDefault }}
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
|
||||||
|
{{- end }}
|
||||||
|
{{- if .NeedsInt64Default }}
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default"
|
||||||
|
{{- end }}
|
||||||
|
{{- if .NeedsStringDefault }}
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
|
||||||
|
{{- end }}
|
||||||
|
{{- if .NeedsJsonPlanMod }}
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
|
||||||
|
{{- end }}
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Code generated by TOOLS/resource-generator. DO NOT EDIT.
|
||||||
|
// Modifier: {{.ServiceName}}.{{.ModifierName}}
|
||||||
|
|
||||||
|
var _ resource.Resource = &{{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Resource{}
|
||||||
|
|
||||||
|
type {{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Resource struct {
|
||||||
|
client *core.UniversalClient
|
||||||
|
}
|
||||||
|
|
||||||
|
type {{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Model struct {
|
||||||
|
ID types.String ` + "`" + `tfsdk:"id"` + "`" + `
|
||||||
|
{{ToCamel .ServiceName}}ID types.String ` + "`" + `tfsdk:"{{ToSnake .ServiceName}}_id"` + "`" + `
|
||||||
|
OperationTimeout types.String ` + "`" + `tfsdk:"operation_timeout"` + "`" + `
|
||||||
|
LogLevel types.String ` + "`" + `tfsdk:"log_level"` + "`" + `
|
||||||
|
{{- range .SchemaParams }}
|
||||||
|
{{ToCamel .Code}} {{ParamType .}} ` + "`" + `tfsdk:"{{ToSnake .Code}}"` + "`" + `
|
||||||
|
{{- end }}
|
||||||
|
}
|
||||||
|
|
||||||
|
func New{{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Resource() resource.Resource {
|
||||||
|
return &{{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Resource{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *{{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Resource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
||||||
|
resp.TypeName = req.ProviderTypeName + "_{{.ServiceName}}_{{.ModifierName}}"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *{{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Resource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
|
||||||
|
attrs := map[string]schema.Attribute{
|
||||||
|
"id": schema.StringAttribute{Computed: true},
|
||||||
|
"{{ToSnake .ServiceName}}_id": schema.StringAttribute{Required: true},
|
||||||
|
"operation_timeout": schema.StringAttribute{Optional: true},
|
||||||
|
"log_level": schema.StringAttribute{Optional: true},
|
||||||
|
{{- range .SchemaParams }}
|
||||||
|
"{{ToSnake .Code}}": schema.{{if eq (ParamType .) "types.Bool"}}Bool{{else if eq (ParamType .) "types.Int64"}}Int64{{else}}String{{end}}Attribute{
|
||||||
|
{{- if and .Required (eq (ParamDefaultExpr .) "") }}Required: true,{{else}}Optional: true,{{end}}
|
||||||
|
{{- if ne (ParamDefaultExpr .) "" }}Computed: true, Default: {{ParamDefaultExpr .}},{{- end }}
|
||||||
|
{{- if ne (ParamDescription .) "" }}MarkdownDescription: {{ParamDescription .}},{{end}}
|
||||||
|
{{- if .Sensitive }}Sensitive: true,{{end}}
|
||||||
|
{{- if .IsJson }}PlanModifiers: []planmodifier.String{resources_core.JsonNormalize()},{{end}}
|
||||||
|
},
|
||||||
|
{{- end }}
|
||||||
|
}
|
||||||
|
resp.Schema = schema.Schema{Attributes: attrs}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *{{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||||
|
var plan {{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Model
|
||||||
|
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||||
|
if resp.Diagnostics.HasError() { return }
|
||||||
|
instanceUID := strings.TrimSpace(plan.{{ToCamel .ServiceName}}ID.ValueString())
|
||||||
|
if instanceUID == "" { resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра"); return }
|
||||||
|
params := resources_core.CompactParams(map[string]string{
|
||||||
|
{{- range .SchemaParams }}
|
||||||
|
"{{.Code}}": {{ParamFormat . (printf "plan.%s" (ToCamel .Code))}},
|
||||||
|
{{- end }}
|
||||||
|
})
|
||||||
|
operationTimeout := ""
|
||||||
|
if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { operationTimeout = plan.OperationTimeout.ValueString() }
|
||||||
|
if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) }
|
||||||
|
if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "{{.OperationName}}", params, operationTimeout); err != nil {
|
||||||
|
resp.Diagnostics.AddError("Ошибка клиента", err.Error()); return
|
||||||
|
}
|
||||||
|
plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "{{.OperationName}}", "{{.ModifierName}}"))
|
||||||
|
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *{{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||||
|
var state {{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Model
|
||||||
|
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
|
||||||
|
if resp.Diagnostics.HasError() { return }
|
||||||
|
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *{{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
||||||
|
var plan {{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Model
|
||||||
|
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||||
|
if resp.Diagnostics.HasError() { return }
|
||||||
|
instanceUID := strings.TrimSpace(plan.{{ToCamel .ServiceName}}ID.ValueString())
|
||||||
|
params := resources_core.CompactParams(map[string]string{
|
||||||
|
{{- range .SchemaParams }}
|
||||||
|
"{{.Code}}": {{ParamFormat . (printf "plan.%s" (ToCamel .Code))}},
|
||||||
|
{{- end }}
|
||||||
|
})
|
||||||
|
if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "{{.OperationName}}", params); err != nil {
|
||||||
|
resp.Diagnostics.AddError("Ошибка клиента", err.Error()); return
|
||||||
|
}
|
||||||
|
plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "{{.OperationName}}", "{{.ModifierName}}"))
|
||||||
|
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *{{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Resource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
||||||
|
// No-op: no confirmed inverse payload exists for this modifier.
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *{{ToCamel (printf "%s_%s" .ServiceName .ModifierName)}}Resource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
|
||||||
|
if req.ProviderData == nil { return }
|
||||||
|
client, ok := req.ProviderData.(*core.UniversalClient)
|
||||||
|
if !ok { resp.Diagnostics.AddError("Error", "Invalid client type"); return }
|
||||||
|
r.client = client
|
||||||
|
}
|
||||||
|
`
|
||||||
@@ -145,3 +145,22 @@ type GenAction struct {
|
|||||||
NeedsJsonPlanMod bool
|
NeedsJsonPlanMod bool
|
||||||
NeedsStringsImport bool
|
NeedsStringsImport bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GenModifier — отдельный ресурс для отложенной parent-level modify операции.
|
||||||
|
// Delete намеренно не содержит rollback: API-контракт обратного payload не подтверждён.
|
||||||
|
type GenModifier struct {
|
||||||
|
ServiceName string
|
||||||
|
ServiceID int
|
||||||
|
ModifierName string
|
||||||
|
OperationName string
|
||||||
|
Params []Param
|
||||||
|
SchemaParams []Param
|
||||||
|
UsesBool bool
|
||||||
|
UsesInt64 bool
|
||||||
|
UsesString bool
|
||||||
|
HasDefaults bool
|
||||||
|
NeedsBoolDefault bool
|
||||||
|
NeedsInt64Default bool
|
||||||
|
NeedsStringDefault bool
|
||||||
|
NeedsJsonPlanMod bool
|
||||||
|
}
|
||||||
|
|||||||
@@ -135,8 +135,38 @@ func WriteActionResource(outDir string, act types.GenAction) error {
|
|||||||
return os.WriteFile(filePath, formatted, 0644)
|
return os.WriteFile(filePath, formatted, 0644)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WriteModifierResource генерирует отдельный ресурс для parent-level modify.
|
||||||
|
func WriteModifierResource(outDir string, modifier types.GenModifier) error {
|
||||||
|
name := fmt.Sprintf("%s_%s", modifier.ServiceName, modifier.ModifierName)
|
||||||
|
fileName := fmt.Sprintf("%d_%s_modifier.go", modifier.ServiceID, name)
|
||||||
|
filePath := filepath.Join(outDir, fileName)
|
||||||
|
|
||||||
|
tpl, err := template.New("modifier").Funcs(template.FuncMap{
|
||||||
|
"ToCamel": helpers.ToCamel,
|
||||||
|
"ToSnake": helpers.ToSnake,
|
||||||
|
"ParamType": helpers.ParamType,
|
||||||
|
"ParamDefaultExpr": helpers.ParamDefaultExpr,
|
||||||
|
"ParamFormat": helpers.ParamFormat,
|
||||||
|
"ParamDescription": helpers.ParamDescription,
|
||||||
|
"bt": func() string { return "`" },
|
||||||
|
}).Parse(templates.Modifier)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
if err := tpl.Execute(&buf, modifier); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
formatted, err := helpers.FormatSourceOrWarn(filePath, buf.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return os.WriteFile(filePath, formatted, 0644)
|
||||||
|
}
|
||||||
|
|
||||||
// WriteRegistry генерирует registry.go со списком всех ресурсов.
|
// WriteRegistry генерирует registry.go со списком всех ресурсов.
|
||||||
func WriteRegistry(outDir string, services []types.GenResource, subs []types.GenSubresource, actions []types.GenAction) error {
|
func WriteRegistry(outDir string, services []types.GenResource, subs []types.GenSubresource, actions []types.GenAction, modifiers []types.GenModifier) error {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
buf.WriteString("package resources_gen\n\n")
|
buf.WriteString("package resources_gen\n\n")
|
||||||
buf.WriteString("import \"github.com/hashicorp/terraform-plugin-framework/resource\"\n\n")
|
buf.WriteString("import \"github.com/hashicorp/terraform-plugin-framework/resource\"\n\n")
|
||||||
@@ -152,6 +182,9 @@ func WriteRegistry(outDir string, services []types.GenResource, subs []types.Gen
|
|||||||
for _, act := range actions {
|
for _, act := range actions {
|
||||||
buf.WriteString(fmt.Sprintf("\t\tNew%[1]sResource,\n", helpers.ToCamel(act.ServiceName+"_"+act.ActionName)))
|
buf.WriteString(fmt.Sprintf("\t\tNew%[1]sResource,\n", helpers.ToCamel(act.ServiceName+"_"+act.ActionName)))
|
||||||
}
|
}
|
||||||
|
for _, modifier := range modifiers {
|
||||||
|
buf.WriteString(fmt.Sprintf("\t\tNew%[1]sResource,\n", helpers.ToCamel(modifier.ServiceName+"_"+modifier.ModifierName)))
|
||||||
|
}
|
||||||
buf.WriteString("\t}\n")
|
buf.WriteString("\t}\n")
|
||||||
buf.WriteString("}\n")
|
buf.WriteString("}\n")
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ func run() error {
|
|||||||
return fmt.Errorf("NUBES_RESOURCES_GEN_DIR is required — must point to generated/{stand}/go/")
|
return fmt.Errorf("NUBES_RESOURCES_GEN_DIR is required — must point to generated/{stand}/go/")
|
||||||
}
|
}
|
||||||
|
|
||||||
instanceResources, subresources, actions, err := loader.LoadSpecs(resourcesDir)
|
instanceResources, subresources, actions, modifiers, err := loader.LoadSpecs(resourcesDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -72,6 +72,12 @@ func run() error {
|
|||||||
writeErrs = append(writeErrs, serviceWriteErr{kind: "action", name: name, err: err})
|
writeErrs = append(writeErrs, serviceWriteErr{kind: "action", name: name, err: err})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for _, modifier := range modifiers {
|
||||||
|
if err := writers.WriteModifierResource(outDir, modifier); err != nil {
|
||||||
|
name := fmt.Sprintf("%s_%s", modifier.ServiceName, modifier.ModifierName)
|
||||||
|
writeErrs = append(writeErrs, serviceWriteErr{kind: "modifier", name: name, err: err})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(writeErrs) > 0 {
|
if len(writeErrs) > 0 {
|
||||||
var b strings.Builder
|
var b strings.Builder
|
||||||
@@ -82,7 +88,7 @@ func run() error {
|
|||||||
return errors.New(strings.TrimSpace(b.String()))
|
return errors.New(strings.TrimSpace(b.String()))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := writers.WriteRegistry(outDir, instanceResources, subresources, actions); err != nil {
|
if err := writers.WriteRegistry(outDir, instanceResources, subresources, actions, modifiers); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,16 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
for idx := range ops {
|
||||||
|
if strings.EqualFold(ops[idx].Action, "modify") && svc.ID == 19 {
|
||||||
|
ops[idx].Kind = "modifier"
|
||||||
|
ops[idx].Modifier = "ip_space"
|
||||||
|
}
|
||||||
|
if strings.EqualFold(ops[idx].Action, "modify") && svc.ID == 22 {
|
||||||
|
ops[idx].Kind = "modifier"
|
||||||
|
ops[idx].Modifier = "network"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
specYAML := types.ServiceSpec{
|
specYAML := types.ServiceSpec{
|
||||||
Name: name,
|
Name: name,
|
||||||
|
|||||||
Reference in New Issue
Block a user