@@ -14,61 +14,131 @@ import (
1414 "github.com/charmbracelet/log"
1515)
1616
17- // Node Filter for config.
18- var configFilter []string
19-
20- // configCmd represents the config command.
21- var configCmd = & cobra.Command {
22- Use : "config" ,
23- Short : "configure a lab" ,
24- Long : "configure a lab based on templates and variables from the topology definition file\n reference: https://containerlab.dev/cmd/config/" ,
25- Aliases : []string {"conf" },
26- ValidArgs : []string {"commit" , "send" , "compare" , "template" },
27- SilenceUsage : true ,
28- RunE : configRun ,
29- }
17+ func configCmd (o * Options ) (* cobra.Command , error ) {
18+ c := & cobra.Command {
19+ Use : "config" ,
20+ Short : "configure a lab" ,
21+ Long : "configure a lab based on templates and variables from the topology definition file\n reference: https://containerlab.dev/cmd/config/" ,
22+ Aliases : []string {"conf" },
23+ ValidArgs : []string {"commit" , "send" , "compare" , "template" },
24+ SilenceUsage : true ,
25+ RunE : func (cobraCmd * cobra.Command , args []string ) error {
26+ return configRun (cobraCmd , args , o )
27+ },
28+ }
3029
31- var configSendCmd = & cobra.Command {
32- Use : "send" ,
33- Short : "send raw configuration to a lab" ,
34- SilenceUsage : true ,
35- RunE : func (cmd * cobra.Command , args []string ) error {
36- if len (args ) > 0 {
37- return fmt .Errorf ("unexpected arguments: %s" , args )
38- }
39- return configRun (cmd , []string {"send" })
40- },
30+ c .Flags ().StringSliceVarP (
31+ & clabcoreconfig .TemplatePaths ,
32+ "template-path" ,
33+ "p" ,
34+ []string {},
35+ "comma separated list of paths to search for templates" ,
36+ )
37+
38+ c .Flags ().StringSliceVarP (
39+ & clabcoreconfig .TemplateNames ,
40+ "template-list" ,
41+ "l" ,
42+ []string {},
43+ "comma separated list of template names to render" ,
44+ )
45+
46+ c .Flags ().StringSliceVarP (
47+ & o .Filter .LabelFilter ,
48+ "filter" ,
49+ "f" ,
50+ o .Filter .LabelFilter ,
51+ "comma separated list of nodes (by labels) to include" ,
52+ )
53+
54+ c .Flags ().StringSliceVarP (
55+ & o .Filter .NodeFilter ,
56+ "node-filter" ,
57+ "" ,
58+ o .Filter .NodeFilter ,
59+ "comma separated list of nodes to include" ,
60+ )
61+
62+ c .Flags ().SortFlags = false
63+
64+ err := c .MarkFlagDirname ("template-path" )
65+ if err != nil {
66+ return nil , err
67+ }
68+
69+ configSubCmds (c , o )
70+
71+ return c , nil
4172}
4273
43- var configCompareCmd = & cobra.Command {
44- Use : "compare" ,
45- Short : "compare configuration to a running lab" ,
46- SilenceUsage : true ,
47- RunE : func (cmd * cobra.Command , args []string ) error {
48- if len (args ) > 0 {
49- return fmt .Errorf ("unexpected arguments: %s" , args )
50- }
51- return configRun (cmd , []string {"compare" })
52- },
74+ func configSubCmds (c * cobra.Command , o * Options ) {
75+ sendC := & cobra.Command {
76+ Use : "send" ,
77+ Short : "send raw configuration to a lab" ,
78+ SilenceUsage : true ,
79+ RunE : func (cobraCmd * cobra.Command , args []string ) error {
80+ if len (args ) > 0 {
81+ return fmt .Errorf ("unexpected arguments: %s" , args )
82+ }
83+
84+ return configRun (cobraCmd , []string {"send" }, o )
85+ },
86+ }
87+
88+ c .AddCommand (sendC )
89+ sendC .Flags ().AddFlagSet (c .Flags ())
90+
91+ compareC := & cobra.Command {
92+ Use : "compare" ,
93+ Short : "compare configuration to a running lab" ,
94+ SilenceUsage : true ,
95+ RunE : func (cobraCmd * cobra.Command , args []string ) error {
96+ if len (args ) > 0 {
97+ return fmt .Errorf ("unexpected arguments: %s" , args )
98+ }
99+
100+ return configRun (cobraCmd , []string {"compare" }, o )
101+ },
102+ }
103+
104+ c .AddCommand (compareC )
105+ compareC .Flags ().AddFlagSet (c .Flags ())
106+
107+ templateC := & cobra.Command {
108+ Use : "template" ,
109+ Short : "render a template" ,
110+ Long : "render a template based on variables from the topology definition file\n reference: https://containerlab.dev/cmd/config/template" ,
111+ Aliases : []string {"conf" },
112+ SilenceUsage : true ,
113+ RunE : func (_ * cobra.Command , _ []string ) error {
114+ return configTemplate (o )
115+ },
116+ }
117+
118+ c .AddCommand (templateC )
119+ templateC .Flags ().AddFlagSet (c .Flags ())
120+ templateC .Flags ().BoolVarP (& o .Config .TemplateVarOnly , "vars" , "v" , o .Config .TemplateVarOnly ,
121+ "show variable used for template rendering" )
122+ templateC .Flags ().SortFlags = false
53123}
54124
55- func configRun (_ * cobra.Command , args []string ) error {
125+ func configRun (_ * cobra.Command , args []string , o * Options ) error {
56126 var err error
57127
58- transport .DebugCount = debugCount
59- clabcoreconfig .DebugCount = debugCount
128+ transport .DebugCount = o . Global . DebugCount
129+ clabcoreconfig .DebugCount = o . Global . DebugCount
60130
61131 c , err := clabcore .NewContainerLab (
62- clabcore .WithTimeout (timeout ),
63- clabcore .WithTopoPath (topoFile , varsFile ),
64- clabcore .WithNodeFilter (nodeFilter ),
65- clabcore .WithDebug (debug ),
132+ clabcore .WithTimeout (o . Global . Timeout ),
133+ clabcore .WithTopoPath (o . Global . TopologyFile , o . Global . VarsFile ),
134+ clabcore .WithNodeFilter (o . Filter . NodeFilter ),
135+ clabcore .WithDebug (o . Global . DebugCount > 0 ),
66136 )
67137 if err != nil {
68138 return err
69139 }
70140
71- err = validateFilter (c .Nodes )
141+ err = validateFilter (c .Nodes , o )
72142 if err != nil {
73143 return err
74144 }
@@ -112,8 +182,8 @@ func configRun(_ *cobra.Command, args []string) error {
112182 log .Warnf ("%s: %s" , cs .TargetNode .ShortName , err )
113183 }
114184 }
115- wg .Add (len (configFilter ))
116- for _ , node := range configFilter {
185+ wg .Add (len (o . Filter . LabelFilter ))
186+ for _ , node := range o . Filter . LabelFilter {
117187 // On debug this will not be executed concurrently
118188 if log .GetLevel () == (log .DebugLevel ) {
119189 deploy (node )
@@ -126,16 +196,56 @@ func configRun(_ *cobra.Command, args []string) error {
126196 return nil
127197}
128198
129- func validateFilter (nodes map [string ]clabnodes.Node ) error {
130- if len (configFilter ) == 0 {
199+ func configTemplate (o * Options ) error {
200+ var err error
201+
202+ clabcoreconfig .DebugCount = o .Global .DebugCount
203+
204+ c , err := clabcore .NewContainerLab (
205+ clabcore .WithTimeout (o .Global .Timeout ),
206+ clabcore .WithTopoPath (o .Global .TopologyFile , o .Global .VarsFile ),
207+ clabcore .WithDebug (o .Global .DebugCount > 0 ),
208+ )
209+ if err != nil {
210+ return err
211+ }
212+
213+ err = validateFilter (c .Nodes , o )
214+ if err != nil {
215+ return err
216+ }
217+
218+ allConfig := clabcoreconfig .PrepareVars (c )
219+ if o .Config .TemplateVarOnly {
220+ for _ , n := range o .Filter .LabelFilter {
221+ conf := allConfig [n ]
222+ conf .Print (true , false )
223+ }
224+ return nil
225+ }
226+
227+ err = clabcoreconfig .RenderAll (allConfig )
228+ if err != nil {
229+ return err
230+ }
231+
232+ for _ , n := range o .Filter .LabelFilter {
233+ allConfig [n ].Print (false , true )
234+ }
235+
236+ return nil
237+ }
238+
239+ func validateFilter (nodes map [string ]clabnodes.Node , o * Options ) error {
240+ if len (o .Filter .LabelFilter ) == 0 {
131241 for n := range nodes {
132- configFilter = append (configFilter , n )
242+ o . Filter . LabelFilter = append (o . Filter . LabelFilter , n )
133243 }
134244 return nil
135245 }
136246
137247 var mis []string
138- for _ , nn := range configFilter {
248+ for _ , nn := range o . Filter . LabelFilter {
139249 if _ , ok := nodes [nn ]; ! ok {
140250 mis = append (mis , nn )
141251 }
@@ -145,24 +255,3 @@ func validateFilter(nodes map[string]clabnodes.Node) error {
145255 }
146256 return nil
147257}
148-
149- func init () {
150- RootCmd .AddCommand (configCmd )
151- configCmd .Flags ().StringSliceVarP (& clabcoreconfig .TemplatePaths , "template-path" , "p" , []string {},
152- "comma separated list of paths to search for templates" )
153- _ = configCmd .MarkFlagDirname ("template-path" )
154- configCmd .Flags ().StringSliceVarP (& clabcoreconfig .TemplateNames , "template-list" , "l" , []string {},
155- "comma separated list of template names to render" )
156- configCmd .Flags ().StringSliceVarP (& configFilter , "filter" , "f" , []string {},
157- "comma separated list of nodes to include" )
158- configCmd .Flags ().SortFlags = false
159-
160- configCmd .Flags ().StringSliceVarP (& nodeFilter , "node-filter" , "" , []string {},
161- "comma separated list of nodes to include" )
162-
163- configCmd .AddCommand (configSendCmd )
164- configSendCmd .Flags ().AddFlagSet (configCmd .Flags ())
165-
166- configCmd .AddCommand (configCompareCmd )
167- configCompareCmd .Flags ().AddFlagSet (configCmd .Flags ())
168- }
0 commit comments