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 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
|
package cmd
import (
"net/http"
"strings"
"github.com/kong/deck/dump"
"github.com/kong/deck/file"
"github.com/kong/deck/state"
"github.com/kong/deck/utils"
"github.com/kong/go-kong/kong"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
var (
dumpCmdKongStateFile string
dumpCmdStateFormat string
dumpWorkspace string
dumpAllWorkspaces bool
dumpWithID bool
)
func listWorkspaces(client *kong.Client, baseURL string) ([]string, error) {
type Workspace struct {
Name string
}
type Response struct {
Data []Workspace
}
var response Response
// TODO handle pagination
req, err := http.NewRequest("GET", baseURL+"/workspaces?size=1000", nil)
if err != nil {
return nil, errors.Wrap(err, "building request for fetching workspaces")
}
_, err = client.Do(nil, req, &response)
if err != nil {
return nil, errors.Wrap(err, "fetching workspaces from Kong")
}
var res []string
for _, workspace := range response.Data {
res = append(res, workspace.Name)
}
return res, nil
}
// dumpCmd represents the dump command
var dumpCmd = &cobra.Command{
Use: "dump",
Short: "Export Kong configuration to a file",
Long: `Dump command reads all the entities present in Kong
and writes them to a file on disk.
The file can then be read using the Sync o Diff command to again
configure Kong.`,
Args: validateNoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
wsClient, err := utils.GetKongClient(rootConfig)
if err != nil {
return err
}
format := file.Format(strings.ToUpper(dumpCmdStateFormat))
// Kong Enterprise dump all workspace
if dumpAllWorkspaces {
if dumpWorkspace != "" {
return errors.New("workspace cannot be specified with --all-workspace flag")
}
if dumpCmdKongStateFile != "kong" {
return errors.New("output-file cannot be specified with --all-workspace flag")
}
workspaces, err := listWorkspaces(wsClient, rootConfig.Address)
if err != nil {
return err
}
for _, workspace := range workspaces {
wsClient, err := utils.GetKongClient(rootConfig.ForWorkspace(workspace))
if err != nil {
return err
}
rawState, err := dump.Get(wsClient, dumpConfig)
if err != nil {
return errors.Wrap(err, "reading configuration from Kong")
}
ks, err := state.Get(rawState)
if err != nil {
return errors.Wrap(err, "building state")
}
if err := file.KongStateToFile(ks, file.WriteConfig{
SelectTags: dumpConfig.SelectorTags,
Workspace: workspace,
Filename: workspace,
FileFormat: format,
WithID: dumpWithID,
}); err != nil {
return err
}
}
return nil
}
// Kong OSS
// or Kong Enterprise single workspace
if dumpWorkspace != "" {
wsConfig := rootConfig.ForWorkspace(dumpWorkspace)
exists, err := workspaceExists(wsConfig)
if err != nil {
return err
}
if !exists {
return errors.Errorf("workspace '%v' does not exist in Kong", dumpWorkspace)
}
wsClient, err = utils.GetKongClient(wsConfig)
if err != nil {
return err
}
}
rawState, err := dump.Get(wsClient, dumpConfig)
if err != nil {
return errors.Wrap(err, "reading configuration from Kong")
}
ks, err := state.Get(rawState)
if err != nil {
return errors.Wrap(err, "building state")
}
if err := file.KongStateToFile(ks, file.WriteConfig{
SelectTags: dumpConfig.SelectorTags,
Workspace: dumpWorkspace,
Filename: dumpCmdKongStateFile,
FileFormat: format,
WithID: dumpWithID,
}); err != nil {
return err
}
return nil
},
}
func init() {
rootCmd.AddCommand(dumpCmd)
dumpCmd.Flags().StringVarP(&dumpCmdKongStateFile, "output-file", "o",
"kong", "file to which to write Kong's configuration."+
"Use '-' to write to stdout.")
dumpCmd.Flags().StringVar(&dumpCmdStateFormat, "format",
"yaml", "output file format: json or yaml")
dumpCmd.Flags().BoolVar(&dumpWithID, "with-id",
false, "write ID of all entities in the output")
dumpCmd.Flags().StringVarP(&dumpWorkspace, "workspace", "w",
"", "dump configuration of a specific workspace"+
"(Kong Enterprise only).")
dumpCmd.Flags().BoolVar(&dumpAllWorkspaces, "all-workspaces",
false, "dump configuration of all workspaces (Kong Enterprise only).")
dumpCmd.Flags().BoolVar(&dumpConfig.SkipConsumers, "skip-consumers",
false, "skip exporting consumers and any plugins associated "+
"with consumers")
dumpCmd.Flags().StringSliceVar(&dumpConfig.SelectorTags,
"select-tag", []string{},
"only entities matching tags specified via this flag are exported.\n"+
"Multiple tags are ANDed together.")
}
|