/
list.go
122 lines (102 loc) · 3.88 KB
/
list.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package manipcli
import (
"context"
"fmt"
"time"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"go.aporeto.io/elemental"
"go.aporeto.io/manipulate"
)
// generateListCommandForIdentity generates the command to list all objects based on its identity.
func generateListCommandForIdentity(identity elemental.Identity, modelManager elemental.ModelManager, manipulatorMaker ManipulatorMaker) (*cobra.Command, error) {
cmd := &cobra.Command{
Use: identity.Name,
Aliases: []string{identity.Category},
Short: "List all " + identity.Category,
// Aliases: TODO: Missing alias from the spec file -> To be stored in the identity ?,
RunE: func(cmd *cobra.Command, args []string) error {
fParam := viper.GetStringSlice("param")
fTrackingID := viper.GetString(flagTrackingID)
fRecursive := viper.GetBool(flagRecursive)
fPage := viper.GetInt(flagPage)
fPageSize := viper.GetInt(flagPageSize)
fOrder := viper.GetStringSlice(flagOrder)
fFilter := viper.GetString(flagFilter)
fOutput := viper.GetString(flagOutput)
fFormatTypeColumn := viper.GetStringSlice(formatTypeColumn)
fOutputTemplate := viper.GetString(flagOutputTemplate)
var dest elemental.Identifiables
if len(fFormatTypeColumn) == 0 {
dest = modelManager.Identifiables(identity)
} else {
dest = modelManager.SparseIdentifiables(identity)
}
if dest == nil {
return fmt.Errorf("unable to list %s. unknown identity", identity.Category)
}
manipulator, err := manipulatorMaker()
if err != nil {
return fmt.Errorf("unable to make manipulator: %w", err)
}
parameters, err := parametersToURLValues(fParam)
if err != nil {
return fmt.Errorf("unable to convert parameters to url values: %w", err)
}
options := []manipulate.ContextOption{
manipulate.ContextOptionTracking(fTrackingID, "cli"),
manipulate.ContextOptionParameters(parameters),
manipulate.ContextOptionFields(fFormatTypeColumn),
manipulate.ContextOptionRecursive(fRecursive),
manipulate.ContextOptionPage(fPage, fPageSize),
manipulate.ContextOptionOrder(fOrder...),
}
if fFilter != "" {
f, err := elemental.NewFilterFromString(fFilter)
if err != nil {
return fmt.Errorf("unable to parse filter %s: %s", fFilter, err)
}
options = append(options, manipulate.ContextOptionFilter(f))
}
if viper.IsSet(flagParent) {
parentName, parentID, err := splitParentInfo(viper.GetString(flagParent))
if err != nil {
return err
}
parent := modelManager.IdentifiableFromString(parentName)
if parent == nil {
return fmt.Errorf("unknown identity %s", parentName)
}
parent.SetIdentifier(parentID)
options = append(options, manipulate.ContextOptionParent(parent))
}
ctx, cancel := context.WithTimeout(cmd.Context(), 20*time.Second)
defer cancel()
mctx := manipulate.NewContext(ctx, options...)
if err := manipulator.RetrieveMany(mctx, dest); err != nil {
return fmt.Errorf("unable to retrieve all %s: %w", identity.Category, err)
}
outputType := fOutput
if fOutput == flagOutputDefault {
outputType = flagOutputJSON
}
result, err := formatObjects(
prepareOutputFormat(outputType, formatTypeArray, fFormatTypeColumn, fOutputTemplate),
true,
dest.List()...,
)
if err != nil {
return fmt.Errorf("unable to format output: %w", err)
}
fmt.Fprint(cmd.OutOrStdout(), result)
return nil
},
}
cmd.Flags().BoolP(flagRecursive, "r", false, "List all objects from the current namespace and all child namespaces.")
cmd.Flags().IntP(flagPageSize, "S", 0, "Page size to retrieve.")
cmd.Flags().IntP(flagPage, "P", 0, "Page number to retrieve.")
cmd.Flags().StringP(flagFilter, "f", "", "Query filter.")
cmd.Flags().StringSliceP(flagOrder, "O", nil, "Ordering of the result.")
cmd.Flags().StringP(flagParent, "", "", "Provide information about parent resource. Format `name/ID`")
return cmd, nil
}