@@ -2,6 +2,7 @@ package main
22
33import (
44 "fmt"
5+ "slices"
56 "strings"
67
78 "github.com/ObolNetwork/obol-stack/internal/config"
@@ -36,22 +37,27 @@ func networkCommand(cfg *config.Config) *cli.Command {
3637 },
3738 },
3839 {
39- Name : "delete " ,
40- Usage : "Remove network and clean up cluster resources " ,
41- ArgsUsage : "<network>" ,
42- Flags : [] cli.Flag {
43- & cli. BoolFlag {
44- Name : "force" ,
45- Aliases : [] string { "f" },
46- Usage : "Skip confirmation prompt" ,
47- },
40+ Name : "sync " ,
41+ Usage : "Deploy or update network configuration to cluster " ,
42+ ArgsUsage : "<network>/<id> or <network>-<id> " ,
43+ Action : func ( c * cli.Context ) error {
44+ if c . NArg () == 0 {
45+ return fmt . Errorf ( "deployment identifier required (e.g., ethereum/knowing-wahoo or ethereum-knowing-wahoo)" )
46+ }
47+ deploymentIdentifier := c . Args (). First ()
48+ return network . Sync ( cfg , deploymentIdentifier )
4849 },
50+ },
51+ {
52+ Name : "delete" ,
53+ Usage : "Remove network deployment and clean up cluster resources" ,
54+ ArgsUsage : "<network>/<id> or <network>-<id>" ,
4955 Action : func (c * cli.Context ) error {
5056 if c .NArg () == 0 {
51- return fmt .Errorf ("network name required (e.g., ethereum, helios )" )
57+ return fmt .Errorf ("deployment identifier required (e.g., ethereum/test-deploy or ethereum-test-deploy )" )
5258 }
53- networkName := c .Args ().First ()
54- return network .Delete (cfg , networkName , c . Bool ( "force" ) )
59+ deploymentIdentifier := c .Args ().First ()
60+ return network .Delete (cfg , deploymentIdentifier )
5561 },
5662 },
5763 },
@@ -68,76 +74,95 @@ func buildNetworkInstallCommands(cfg *config.Config) []*cli.Command {
6874
6975 var commands []* cli.Command
7076 for _ , networkName := range networks {
71- // Parse the embedded helmfile to get env vars
72- envVars , err := network .ParseEmbeddedNetworkEnvVars (networkName )
77+ // Parse the embedded values template to get fields
78+ fields , err := network .ParseTemplateFields (networkName )
7379 if err != nil {
7480 // Skip networks we can't parse
7581 continue
7682 }
7783
78- // Build flags from env vars
79- flags := []cli.Flag {}
80- for _ , envVar := range envVars {
84+ // Build flags from template fields
85+ flags := []cli.Flag {
86+ // id flag is always present (special case - not parsed from template)
87+ & cli.StringFlag {
88+ Name : "id" ,
89+ Usage : fmt .Sprintf ("Deployment identifier for namespace (e.g., 'my-node' becomes '%s-my-node', defaults to generated petname)" , networkName ),
90+ Required : false ,
91+ },
92+ // force flag to allow overwriting existing deployments
93+ & cli.BoolFlag {
94+ Name : "force" ,
95+ Aliases : []string {"f" },
96+ Usage : "Overwrite existing deployment configuration if it already exists" ,
97+ },
98+ }
99+
100+ // Add flags from parsed template fields
101+ for _ , field := range fields {
81102 // Build usage string
82- usage := envVar .Description
103+ usage := field .Description
83104 if usage == "" {
84- usage = fmt .Sprintf ("Override %s" , envVar .Name )
105+ usage = fmt .Sprintf ("Override %s" , field .Name )
85106 }
86107
87108 // Mark as required if no default value
88- if envVar .Required {
109+ if field .Required {
89110 usage = "[REQUIRED] " + usage
90111 }
91112
92113 // Add enum options if available
93- if len (envVar .EnumValues ) > 0 {
94- usage += fmt .Sprintf (" [options: %s]" , strings .Join (envVar .EnumValues , ", " ))
114+ if len (field .EnumValues ) > 0 {
115+ usage += fmt .Sprintf (" [options: %s]" , strings .Join (field .EnumValues , ", " ))
95116 }
96117
97118 // Add default value
98- if envVar .DefaultValue != "" {
99- usage += fmt .Sprintf (" (default: %s)" , envVar .DefaultValue )
119+ if field .DefaultValue != "" {
120+ usage += fmt .Sprintf (" (default: %s)" , field .DefaultValue )
100121 }
101122
102123 flags = append (flags , & cli.StringFlag {
103- Name : envVar .FlagName ,
124+ Name : field .FlagName ,
104125 Usage : usage ,
105- Required : envVar .Required ,
126+ Required : field .Required ,
106127 })
107128 }
108129
109130 // Create the network-specific install command
110131 netName := networkName // Capture for closure
111- netEnvVars := envVars // Capture for validation
132+ netFields := fields // Capture for validation
112133 commands = append (commands , & cli.Command {
113134 Name : netName ,
114135 Usage : fmt .Sprintf ("Install %s network" , netName ),
115136 Flags : flags ,
116137 Action : func (c * cli.Context ) error {
117138 // Collect and validate flag values
118139 overrides := make (map [string ]string )
119- for _ , envVar := range netEnvVars {
120- value := c .String (envVar .FlagName )
140+
141+ // Collect id flag (special case - not in parsed fields)
142+ if idValue := c .String ("id" ); idValue != "" {
143+ overrides ["id" ] = idValue
144+ }
145+
146+ // Collect parsed template fields
147+ for _ , field := range netFields {
148+ value := c .String (field .FlagName )
121149 if value != "" {
122150 // Validate enum constraint if defined
123- if len (envVar .EnumValues ) > 0 {
124- valid := false
125- for _ , enumVal := range envVar .EnumValues {
126- if value == enumVal {
127- valid = true
128- break
129- }
130- }
151+ if len (field .EnumValues ) > 0 {
152+ valid := slices .Contains (field .EnumValues , value )
131153 if ! valid {
132154 return fmt .Errorf ("invalid value '%s' for --%s. Valid options: %s" ,
133- value , envVar .FlagName , strings .Join (envVar .EnumValues , ", " ))
155+ value , field .FlagName , strings .Join (field .EnumValues , ", " ))
134156 }
135157 }
136- overrides [envVar .FlagName ] = value
158+ overrides [field .FlagName ] = value
137159 }
138160 }
139161
140- return network .Install (cfg , netName , overrides )
162+ // Get force flag
163+ force := c .Bool ("force" )
164+
165+ return network .Install (cfg , netName , overrides , force )
141166 },
142167 })
143168 }
0 commit comments