@@ -8,11 +8,14 @@ import (
88 "github.com/OctopusDeploy/cli/pkg/factory"
99 "github.com/OctopusDeploy/cli/pkg/output"
1010 "github.com/OctopusDeploy/cli/pkg/question/selectors"
11+ "github.com/OctopusDeploy/cli/pkg/util/featuretoggle"
1112 "github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/actiontemplates"
1213 "github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/client"
1314 "github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/core"
15+ "github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/tenants"
1416 "github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/variables"
1517 "github.com/spf13/cobra"
18+ "sort"
1619)
1720
1821const (
@@ -99,67 +102,169 @@ func listRun(cmd *cobra.Command, f factory.Factory, id string) error {
99102 return err
100103 }
101104
102- vars , err := client .Tenants .GetVariables (tenant )
103- if err != nil {
104- return err
105- }
105+ toggleValue , err := featuretoggle .IsToggleEnabled (client , "CommonVariableScopingFeatureToggle" )
106106
107- missingVariablesResponse , err := client .Tenants .GetMissingVariables (variables.MissingVariablesQuery {TenantID : vars .TenantID })
108- var missingVariables []variables.MissingVariable
109- if len (* missingVariablesResponse ) > 0 {
110- missingVariables = (* missingVariablesResponse )[0 ].MissingVariables
111- }
112- var allVariableValues []* VariableValue
113- for _ , element := range vars .LibraryVariables {
107+ if toggleValue {
108+ projectVariablesQuery := variables.GetTenantProjectVariablesQuery {
109+ TenantID : tenant .ID ,
110+ SpaceID : tenant .SpaceID ,
111+ IncludeMissingVariables : true ,
112+ }
114113
115- variableValues := unwrapCommonVariables ( element , missingVariables )
116- for _ , v := range variableValues {
117- allVariableValues = append ( allVariableValues , v )
114+ projectVariables , err := tenants . GetProjectVariables ( client , projectVariablesQuery )
115+ if err != nil {
116+ return err
118117 }
119- }
120118
121- if err != nil {
122- return err
123- }
124- environmentMap , err := getEnvironmentMap (client )
125- if err != nil {
126- return err
127- }
128- for _ , element := range vars .ProjectVariables {
129- variableValues := unwrapProjectVariables (element , environmentMap , missingVariables )
130- for _ , v := range variableValues {
131- allVariableValues = append (allVariableValues , v )
119+ commonVariablesQuery := variables.GetTenantCommonVariablesQuery {
120+ TenantID : tenant .ID ,
121+ SpaceID : tenant .SpaceID ,
122+ IncludeMissingVariables : true ,
132123 }
133- }
134124
135- return output .PrintArray (allVariableValues , cmd , output.Mappers [* VariableValue ]{
136- Json : func (item * VariableValue ) any {
137- if item .Type == LibraryVariableSetType {
138- return NewVariableValueAsJson (item )
139- } else {
140- return NewVariableValueProjectAsJson (item )
125+ commonVariables , err := tenants .GetCommonVariables (client , commonVariablesQuery )
126+ if err != nil {
127+ return err
128+ }
129+
130+ environmentMap , err := getEnvironmentMap (client )
131+ if err != nil {
132+ return err
133+ }
134+
135+ var allVariableValues []* VariableValue
136+
137+ for _ , element := range commonVariables .MissingCommonVariables {
138+ variableValue := unwrapCommonVariables (element , environmentMap )
139+ allVariableValues = append (allVariableValues , variableValue ... )
140+ }
141+
142+ for _ , element := range commonVariables .CommonVariables {
143+ variableValue := unwrapCommonVariables (element , environmentMap )
144+ allVariableValues = append (allVariableValues , variableValue ... )
145+ }
146+
147+ for _ , element := range projectVariables .MissingProjectVariables {
148+ variableValue := unwrapProjectVariables (element , environmentMap )
149+ allVariableValues = append (allVariableValues , variableValue ... )
150+ }
151+
152+ for _ , element := range projectVariables .ProjectVariables {
153+ variableValue := unwrapProjectVariables (element , environmentMap )
154+ allVariableValues = append (allVariableValues , variableValue ... )
155+ }
156+
157+ sortVariableOutput (allVariableValues )
158+
159+ return output .PrintArray (allVariableValues , cmd , output.Mappers [* VariableValue ]{
160+ Json : func (item * VariableValue ) any {
161+ if item .Type == LibraryVariableSetType {
162+ return NewVariableValueAsJson (item )
163+ } else {
164+ return NewVariableValueProjectAsJson (item )
165+ }
166+ },
167+ Table : output.TableDefinition [* VariableValue ]{
168+ Header : []string {"NAME" , "LABEL" , "TYPE" , "OWNER" , "ENVIRONMENT" , "VALUE" , "SENSITIVE" , "DEFAULT VALUE" },
169+ Row : func (item * VariableValue ) []string {
170+ value := item .Value
171+ if item .HasMissingValue {
172+ value = output .Red ("<missing>" )
173+ }
174+
175+ return []string {output .Bold (item .Name ), item .Label , item .Type , item .OwnerName , item .ScopeName , value , fmt .Sprint (item .IsSensitive ), fmt .Sprint (item .IsDefaultValue )}
176+ },
177+ },
178+ Basic : func (item * VariableValue ) string {
179+ return item .Name
180+ },
181+ })
182+
183+ return nil
184+ } else {
185+ vars , err := client .Tenants .GetVariables (tenant )
186+ if err != nil {
187+ return err
188+ }
189+
190+ missingVariablesResponse , err := client .Tenants .GetMissingVariables (variables.MissingVariablesQuery {TenantID : vars .TenantID })
191+ var missingVariables []variables.MissingVariable
192+ if len (* missingVariablesResponse ) > 0 {
193+ missingVariables = (* missingVariablesResponse )[0 ].MissingVariables
194+ }
195+ var allVariableValues []* VariableValue
196+ for _ , element := range vars .LibraryVariables {
197+
198+ variableValues := unwrapCommonVariablesV1 (element , missingVariables )
199+ for _ , v := range variableValues {
200+ allVariableValues = append (allVariableValues , v )
141201 }
142- },
143- Table : output.TableDefinition [* VariableValue ]{
144- Header : []string {"NAME" , "LABEL" , "TYPE" , "OWNER" , "ENVIRONMENT" , "VALUE" , "SENSITIVE" , "DEFAULT VALUE" },
145- Row : func (item * VariableValue ) []string {
146- value := item .Value
147- if item .HasMissingValue {
148- value = output .Red ("<missing>" )
202+ }
203+
204+ if err != nil {
205+ return err
206+ }
207+ environmentMap , err := getEnvironmentMap (client )
208+ if err != nil {
209+ return err
210+ }
211+ for _ , element := range vars .ProjectVariables {
212+ variableValues := unwrapProjectVariablesV1 (element , environmentMap , missingVariables )
213+ for _ , v := range variableValues {
214+ allVariableValues = append (allVariableValues , v )
215+ }
216+ }
217+
218+ return output .PrintArray (allVariableValues , cmd , output.Mappers [* VariableValue ]{
219+ Json : func (item * VariableValue ) any {
220+ if item .Type == LibraryVariableSetType {
221+ return NewVariableValueAsJson (item )
222+ } else {
223+ return NewVariableValueProjectAsJson (item )
149224 }
225+ },
226+ Table : output.TableDefinition [* VariableValue ]{
227+ Header : []string {"NAME" , "LABEL" , "TYPE" , "OWNER" , "ENVIRONMENT" , "VALUE" , "SENSITIVE" , "DEFAULT VALUE" },
228+ Row : func (item * VariableValue ) []string {
229+ value := item .Value
230+ if item .HasMissingValue {
231+ value = output .Red ("<missing>" )
232+ }
150233
151- return []string {output .Bold (item .Name ), item .Label , item .Type , item .OwnerName , item .ScopeName , value , fmt .Sprint (item .IsSensitive ), fmt .Sprint (item .IsDefaultValue )}
234+ return []string {output .Bold (item .Name ), item .Label , item .Type , item .OwnerName , item .ScopeName , value , fmt .Sprint (item .IsSensitive ), fmt .Sprint (item .IsDefaultValue )}
235+ },
152236 },
153- },
154- Basic : func (item * VariableValue ) string {
155- return item .Name
156- },
157- })
237+ Basic : func (item * VariableValue ) string {
238+ return item .Name
239+ },
240+ })
158241
159- return nil
242+ return nil
243+ }
160244}
161245
162- func unwrapCommonVariables (variables variables.LibraryVariable , missingVariables []variables.MissingVariable ) []* VariableValue {
246+ func sortVariableOutput (allVariableValues []* VariableValue ) {
247+ sort .SliceStable (allVariableValues , func (i , j int ) bool {
248+ if allVariableValues [i ].Type != allVariableValues [j ].Type {
249+ return allVariableValues [i ].Type < allVariableValues [j ].Type
250+ }
251+ if allVariableValues [i ].OwnerName != allVariableValues [j ].OwnerName {
252+ return allVariableValues [i ].OwnerName < allVariableValues [j ].OwnerName
253+ }
254+ if allVariableValues [i ].Name != allVariableValues [j ].Name {
255+ return allVariableValues [i ].Name < allVariableValues [j ].Name
256+ }
257+ if allVariableValues [i ].Value == "" && allVariableValues [j ].Value != "" {
258+ return true
259+ }
260+ if allVariableValues [i ].Value != "" && allVariableValues [j ].Value == "" {
261+ return false
262+ }
263+ return allVariableValues [i ].Value < allVariableValues [j ].Value
264+ })
265+ }
266+
267+ func unwrapCommonVariablesV1 (variables variables.LibraryVariable , missingVariables []variables.MissingVariable ) []* VariableValue {
163268 var results []* VariableValue = nil
164269 for _ , template := range variables .Templates {
165270 value , isDefault := getVariableValue (template , variables .Variables )
@@ -182,7 +287,7 @@ func unwrapCommonVariables(variables variables.LibraryVariable, missingVariables
182287 return results
183288}
184289
185- func unwrapProjectVariables (variables variables.ProjectVariable , environmentMap map [string ]string , missingVariables []variables.MissingVariable ) []* VariableValue {
290+ func unwrapProjectVariablesV1 (variables variables.ProjectVariable , environmentMap map [string ]string , missingVariables []variables.MissingVariable ) []* VariableValue {
186291 var results []* VariableValue = nil
187292 for _ , template := range variables .Templates {
188293 for environmentId , environmentVariables := range variables .Variables {
@@ -207,6 +312,62 @@ func unwrapProjectVariables(variables variables.ProjectVariable, environmentMap
207312 return results
208313}
209314
315+ func unwrapCommonVariables (variable variables.TenantCommonVariable , environmentMap map [string ]string ) []* VariableValue {
316+ var results []* VariableValue = nil
317+ var isDefault = variable .ID == ""
318+ var displayValue string
319+
320+ if isDefault {
321+ displayValue = getDisplayValue (variable .Template .DefaultValue )
322+ } else {
323+ displayValue = getDisplayValue (& variable .Value )
324+ }
325+
326+ for _ , environmentId := range variable .Scope .EnvironmentIds {
327+
328+ results = append (results , & VariableValue {
329+ Type : LibraryVariableSetType ,
330+ OwnerName : variable .LibraryVariableSetName ,
331+ Name : variable .Template .Name ,
332+ Value : displayValue ,
333+ IsSensitive : variable .Value .IsSensitive ,
334+ IsDefaultValue : isDefault , // Variables without an ID are sourced from the MissingVariables list. For consistency with V1, IsDefault applies to both default and missing variables
335+ ScopeName : environmentMap [environmentId ],
336+ HasMissingValue : isDefault && displayValue == "" ,
337+ })
338+ }
339+
340+ return results
341+ }
342+
343+ func unwrapProjectVariables (variable variables.TenantProjectVariable , environmentMap map [string ]string ) []* VariableValue {
344+ var results []* VariableValue = nil
345+ var isDefault = variable .ID == ""
346+ var displayValue string
347+
348+ if isDefault {
349+ displayValue = getDisplayValue (variable .Template .DefaultValue )
350+ } else {
351+ displayValue = getDisplayValue (& variable .Value )
352+ }
353+
354+ for _ , environmentId := range variable .Scope .EnvironmentIds {
355+
356+ results = append (results , & VariableValue {
357+ Type : ProjectType ,
358+ OwnerName : variable .ProjectName ,
359+ Name : variable .Template .Name ,
360+ Value : displayValue ,
361+ IsSensitive : variable .Value .IsSensitive ,
362+ IsDefaultValue : isDefault , // Variables without an ID are sourced from the MissingVariables list. For consistency with V1, IsDefault applies to both default and missing variables
363+ ScopeName : environmentMap [environmentId ],
364+ HasMissingValue : isDefault && displayValue == "" ,
365+ })
366+ }
367+
368+ return results
369+ }
370+
210371func hasMissingProjectValue (missingVariables []variables.MissingVariable , projectID string , environmentID string , templateID string ) bool {
211372 for _ , v := range missingVariables {
212373 if v .ProjectID == projectID && v .EnvironmentID == environmentID && v .VariableTemplateID == templateID {
0 commit comments