WIP
- commit
- 0b2197b7d86fe2466b2a6e683fac4482b516ded4
- author
- bnema · · 2023-09-04 16:38 UTC
- parent
- 745e6e1
- signature
- unsigned
6 files · +170 -12
M .gitignore +2 -3
| @@ -1,5 +1,4 @@ | |||
| 1 | 1 | .env | |
| 2 | 2 | node_modules/ | |
| 3 | - | tmp/ | |
| 4 | - | logs/ | |
| 5 | - | *.log⏎̸ | |
| 3 | + | tmp/* | |
| 4 | + | logs/*⏎̸ | |
| @@ -1,5 +1,4 @@ | |||||
| 1 | .env | 1 | .env | ||
| 2 | node_modules/ | 2 | node_modules/ | ||
| 3 | - | tmp/ | 3 | + | tmp/* |
| 4 | - | logs/ | 4 | + | logs/*⏎̸ |
| 5 | - | *.log⏎̸ | |||
M cmd/main.go +2 -1
| @@ -25,7 +25,7 @@ func main() { | |||
| 25 | 25 | return | |
| 26 | 26 | } | |
| 27 | 27 | ||
| 28 | - | docker.ListDocker() // List docker containers | |
| 28 | + | docker.CreateImageFromDockerfile() | |
| 29 | 29 | ||
| 30 | 30 | e := echo.New() | |
| 31 | 31 | e.HideBanner = true | |
| @@ -38,4 +38,5 @@ func main() { | |||
| 38 | 38 | return e.Start(":" + port) | |
| 39 | 39 | } | |
| 40 | 40 | utils.RunAppCatchSIGINT(startFunc, &gordon.APPLogger.Logger) | |
| 41 | + | ||
| 41 | 42 | } | |
| @@ -25,7 +25,7 @@ func main() { | |||||
| 25 | return | 25 | return | ||
| 26 | } | 26 | } | ||
| 27 | 27 | ||||
| 28 | - | docker.ListDocker() // List docker containers | 28 | + | docker.CreateImageFromDockerfile() |
| 29 | 29 | ||||
| 30 | e := echo.New() | 30 | e := echo.New() | ||
| 31 | e.HideBanner = true | 31 | e.HideBanner = true | ||
| @@ -38,4 +38,5 @@ func main() { | |||||
| 38 | return e.Start(":" + port) | 38 | return e.Start(":" + port) | ||
| 39 | } | 39 | } | ||
| 40 | utils.RunAppCatchSIGINT(startFunc, &gordon.APPLogger.Logger) | 40 | utils.RunAppCatchSIGINT(startFunc, &gordon.APPLogger.Logger) | ||
| 41 | + | ||||
| 41 | } | 42 | } | ||
M go.mod +12 -3
| @@ -11,18 +11,27 @@ require ( | |||
| 11 | 11 | require ( | |
| 12 | 12 | github.com/Microsoft/go-winio v0.6.1 // indirect | |
| 13 | 13 | github.com/andybalholm/cascadia v1.3.1 // indirect | |
| 14 | + | github.com/containerd/containerd v1.7.5 // indirect | |
| 14 | 15 | github.com/docker/distribution v2.8.2+incompatible // indirect | |
| 15 | 16 | github.com/docker/docker v24.0.5+incompatible // indirect | |
| 16 | 17 | github.com/docker/go-connections v0.4.0 // indirect | |
| 17 | 18 | github.com/docker/go-units v0.5.0 // indirect | |
| 18 | 19 | github.com/gogo/protobuf v1.3.2 // indirect | |
| 19 | 20 | github.com/golang-jwt/jwt v3.2.2+incompatible // indirect | |
| 21 | + | github.com/klauspost/compress v1.16.7 // indirect | |
| 22 | + | github.com/moby/patternmatcher v0.6.0 // indirect | |
| 23 | + | github.com/moby/sys/sequential v0.5.0 // indirect | |
| 20 | 24 | github.com/opencontainers/go-digest v1.0.0 // indirect | |
| 21 | - | github.com/opencontainers/image-spec v1.0.2 // indirect | |
| 25 | + | github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b // indirect | |
| 26 | + | github.com/opencontainers/runc v1.1.9 // indirect | |
| 22 | 27 | github.com/pkg/errors v0.9.1 // indirect | |
| 23 | - | golang.org/x/mod v0.8.0 // indirect | |
| 28 | + | github.com/sirupsen/logrus v1.9.0 // indirect | |
| 29 | + | github.com/tidwall/gjson v1.16.0 // indirect | |
| 30 | + | github.com/tidwall/match v1.1.1 // indirect | |
| 31 | + | github.com/tidwall/pretty v1.2.1 // indirect | |
| 32 | + | golang.org/x/mod v0.9.0 // indirect | |
| 24 | 33 | golang.org/x/time v0.3.0 // indirect | |
| 25 | - | golang.org/x/tools v0.6.0 // indirect | |
| 34 | + | golang.org/x/tools v0.7.0 // indirect | |
| 26 | 35 | ) | |
| 27 | 36 | ||
| 28 | 37 | require ( | |
| @@ -11,18 +11,27 @@ require ( | |||||
| 11 | require ( | 11 | require ( | ||
| 12 | github.com/Microsoft/go-winio v0.6.1 // indirect | 12 | github.com/Microsoft/go-winio v0.6.1 // indirect | ||
| 13 | github.com/andybalholm/cascadia v1.3.1 // indirect | 13 | github.com/andybalholm/cascadia v1.3.1 // indirect | ||
| 14 | + | github.com/containerd/containerd v1.7.5 // indirect | |||
| 14 | github.com/docker/distribution v2.8.2+incompatible // indirect | 15 | github.com/docker/distribution v2.8.2+incompatible // indirect | ||
| 15 | github.com/docker/docker v24.0.5+incompatible // indirect | 16 | github.com/docker/docker v24.0.5+incompatible // indirect | ||
| 16 | github.com/docker/go-connections v0.4.0 // indirect | 17 | github.com/docker/go-connections v0.4.0 // indirect | ||
| 17 | github.com/docker/go-units v0.5.0 // indirect | 18 | github.com/docker/go-units v0.5.0 // indirect | ||
| 18 | github.com/gogo/protobuf v1.3.2 // indirect | 19 | github.com/gogo/protobuf v1.3.2 // indirect | ||
| 19 | github.com/golang-jwt/jwt v3.2.2+incompatible // indirect | 20 | github.com/golang-jwt/jwt v3.2.2+incompatible // indirect | ||
| 21 | + | github.com/klauspost/compress v1.16.7 // indirect | |||
| 22 | + | github.com/moby/patternmatcher v0.6.0 // indirect | |||
| 23 | + | github.com/moby/sys/sequential v0.5.0 // indirect | |||
| 20 | github.com/opencontainers/go-digest v1.0.0 // indirect | 24 | github.com/opencontainers/go-digest v1.0.0 // indirect | ||
| 21 | - | github.com/opencontainers/image-spec v1.0.2 // indirect | 25 | + | github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b // indirect |
| 26 | + | github.com/opencontainers/runc v1.1.9 // indirect | |||
| 22 | github.com/pkg/errors v0.9.1 // indirect | 27 | github.com/pkg/errors v0.9.1 // indirect | ||
| 23 | - | golang.org/x/mod v0.8.0 // indirect | 28 | + | github.com/sirupsen/logrus v1.9.0 // indirect |
| 29 | + | github.com/tidwall/gjson v1.16.0 // indirect | |||
| 30 | + | github.com/tidwall/match v1.1.1 // indirect | |||
| 31 | + | github.com/tidwall/pretty v1.2.1 // indirect | |||
| 32 | + | golang.org/x/mod v0.9.0 // indirect | |||
| 24 | golang.org/x/time v0.3.0 // indirect | 33 | golang.org/x/time v0.3.0 // indirect | ||
| 25 | - | golang.org/x/tools v0.6.0 // indirect | 34 | + | golang.org/x/tools v0.7.0 // indirect |
| 26 | ) | 35 | ) | ||
| 27 | 36 | ||||
| 28 | require ( | 37 | require ( | ||
M go.sum +27 -0 generated file: collapsed
M pkg/docker/registry.go +106 -5
| @@ -3,24 +3,125 @@ package docker | |||
| 3 | 3 | import ( | |
| 4 | 4 | "context" | |
| 5 | 5 | "fmt" | |
| 6 | + | "io" | |
| 7 | + | "os" | |
| 6 | 8 | ||
| 7 | 9 | "github.com/docker/docker/api/types" | |
| 10 | + | "github.com/docker/docker/api/types/container" | |
| 8 | 11 | "github.com/docker/docker/client" | |
| 12 | + | "github.com/docker/docker/pkg/archive" | |
| 13 | + | "github.com/docker/docker/pkg/stdcopy" | |
| 9 | 14 | ) | |
| 10 | 15 | ||
| 11 | - | // basic list of containers and images | |
| 12 | - | func ListDocker() { | |
| 13 | - | cli, err := client.NewClientWithOpts(client.FromEnv) | |
| 16 | + | func DockertPullImageTest() { | |
| 17 | + | ctx := context.Background() | |
| 18 | + | cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) | |
| 14 | 19 | if err != nil { | |
| 15 | 20 | panic(err) | |
| 16 | 21 | } | |
| 22 | + | defer cli.Close() | |
| 17 | 23 | ||
| 18 | - | containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{}) | |
| 24 | + | reader, err := cli.ImagePull(ctx, "docker.io/library/alpine", types.ImagePullOptions{}) | |
| 19 | 25 | if err != nil { | |
| 20 | 26 | panic(err) | |
| 21 | 27 | } | |
| 28 | + | io.Copy(os.Stdout, reader) | |
| 29 | + | ||
| 30 | + | resp, err := cli.ContainerCreate(ctx, &container.Config{ | |
| 31 | + | Image: "alpine", | |
| 32 | + | Cmd: []string{"echo", "hello world"}, | |
| 33 | + | }, nil, nil, nil, "") | |
| 34 | + | if err != nil { | |
| 35 | + | panic(err) | |
| 36 | + | } | |
| 37 | + | ||
| 38 | + | if err := cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil { | |
| 39 | + | panic(err) | |
| 40 | + | } | |
| 41 | + | ||
| 42 | + | statusCh, errCh := cli.ContainerWait(ctx, resp.ID, container.WaitConditionNotRunning) | |
| 43 | + | select { | |
| 44 | + | case err := <-errCh: | |
| 45 | + | if err != nil { | |
| 46 | + | panic(err) | |
| 47 | + | } | |
| 48 | + | case <-statusCh: | |
| 49 | + | } | |
| 50 | + | ||
| 51 | + | out, err := cli.ContainerLogs(ctx, resp.ID, types.ContainerLogsOptions{ShowStdout: true}) | |
| 52 | + | if err != nil { | |
| 53 | + | panic(err) | |
| 54 | + | } | |
| 55 | + | ||
| 56 | + | stdcopy.StdCopy(os.Stdout, os.Stderr, out) | |
| 57 | + | } | |
| 58 | + | ||
| 59 | + | func DockerListContainersTest() { | |
| 60 | + | fmt.Println("Executing DockerListContainersTest()") | |
| 61 | + | ||
| 62 | + | ctx := context.Background() | |
| 63 | + | cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) | |
| 64 | + | if err != nil { | |
| 65 | + | panic(err) | |
| 66 | + | } | |
| 67 | + | defer cli.Close() | |
| 68 | + | ||
| 69 | + | fmt.Println("Initialized Docker client.") | |
| 70 | + | ||
| 71 | + | containers, err := cli.ContainerList(ctx, types.ContainerListOptions{All: true}) | |
| 72 | + | if err != nil { | |
| 73 | + | panic(err) | |
| 74 | + | } | |
| 75 | + | ||
| 76 | + | fmt.Printf("Found %d containers.\n", len(containers)) | |
| 22 | 77 | ||
| 23 | 78 | for _, container := range containers { | |
| 24 | - | fmt.Printf("%s %s\n", container.ID[:10], container.Image) | |
| 79 | + | fmt.Printf("%s %s\n", container.ID[:10], container.Status) | |
| 80 | + | } | |
| 81 | + | } | |
| 82 | + | ||
| 83 | + | // I have a Dockerfile inside tmp/docker-test/Dockerfile and i want to create an image from it and place it at the same directory. | |
| 84 | + | func CreateImageFromDockerfile() { | |
| 85 | + | fmt.Println("Executing CreateImageFromDockerfile()") | |
| 86 | + | fmt.Println("Initialized Docker client.") | |
| 87 | + | ctx := context.Background() | |
| 88 | + | cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) | |
| 89 | + | if err != nil { | |
| 90 | + | panic(err) | |
| 91 | + | } | |
| 92 | + | defer cli.Close() | |
| 93 | + | ||
| 94 | + | fmt.Println("Building image...") | |
| 95 | + | buildCtx, err := archive.TarWithOptions("tmp/docker-test/", &archive.TarOptions{}) | |
| 96 | + | if err != nil { | |
| 97 | + | panic(err) | |
| 98 | + | } | |
| 99 | + | defer buildCtx.Close() | |
| 100 | + | ||
| 101 | + | fmt.Println("Building image...") | |
| 102 | + | imageBuildResponse, err := cli.ImageBuild(ctx, buildCtx, types.ImageBuildOptions{ | |
| 103 | + | Tags: []string{"gordon-echo:latest"}, | |
| 104 | + | }) | |
| 105 | + | if err != nil { | |
| 106 | + | panic(err) | |
| 107 | + | } | |
| 108 | + | defer imageBuildResponse.Body.Close() | |
| 109 | + | ||
| 110 | + | fmt.Println("Saving image to file...") | |
| 111 | + | ||
| 112 | + | imageTar, err := cli.ImageSave(ctx, []string{"gordon-echo:latest"}) | |
| 113 | + | if err != nil { | |
| 114 | + | panic(err) | |
| 115 | + | } | |
| 116 | + | ||
| 117 | + | outputFile, err := os.Create("tmp/docker-test/gordon-echo.tar") | |
| 118 | + | if err != nil { | |
| 119 | + | panic(err) | |
| 120 | + | } | |
| 121 | + | defer outputFile.Close() | |
| 122 | + | ||
| 123 | + | _, err = io.Copy(outputFile, imageTar) | |
| 124 | + | if err != nil { | |
| 125 | + | panic(err) | |
| 25 | 126 | } | |
| 26 | 127 | } | |
| @@ -3,24 +3,125 @@ package docker | |||||
| 3 | import ( | 3 | import ( | ||
| 4 | "context" | 4 | "context" | ||
| 5 | "fmt" | 5 | "fmt" | ||
| 6 | + | "io" | |||
| 7 | + | "os" | |||
| 6 | 8 | ||||
| 7 | "github.com/docker/docker/api/types" | 9 | "github.com/docker/docker/api/types" | ||
| 10 | + | "github.com/docker/docker/api/types/container" | |||
| 8 | "github.com/docker/docker/client" | 11 | "github.com/docker/docker/client" | ||
| 12 | + | "github.com/docker/docker/pkg/archive" | |||
| 13 | + | "github.com/docker/docker/pkg/stdcopy" | |||
| 9 | ) | 14 | ) | ||
| 10 | 15 | ||||
| 11 | - | // basic list of containers and images | 16 | + | func DockertPullImageTest() { |
| 12 | - | func ListDocker() { | 17 | + | ctx := context.Background() |
| 13 | - | cli, err := client.NewClientWithOpts(client.FromEnv) | 18 | + | cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) |
| 14 | if err != nil { | 19 | if err != nil { | ||
| 15 | panic(err) | 20 | panic(err) | ||
| 16 | } | 21 | } | ||
| 22 | + | defer cli.Close() | |||
| 17 | 23 | ||||
| 18 | - | containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{}) | 24 | + | reader, err := cli.ImagePull(ctx, "docker.io/library/alpine", types.ImagePullOptions{}) |
| 19 | if err != nil { | 25 | if err != nil { | ||
| 20 | panic(err) | 26 | panic(err) | ||
| 21 | } | 27 | } | ||
| 28 | + | io.Copy(os.Stdout, reader) | |||
| 29 | + | ||||
| 30 | + | resp, err := cli.ContainerCreate(ctx, &container.Config{ | |||
| 31 | + | Image: "alpine", | |||
| 32 | + | Cmd: []string{"echo", "hello world"}, | |||
| 33 | + | }, nil, nil, nil, "") | |||
| 34 | + | if err != nil { | |||
| 35 | + | panic(err) | |||
| 36 | + | } | |||
| 37 | + | ||||
| 38 | + | if err := cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil { | |||
| 39 | + | panic(err) | |||
| 40 | + | } | |||
| 41 | + | ||||
| 42 | + | statusCh, errCh := cli.ContainerWait(ctx, resp.ID, container.WaitConditionNotRunning) | |||
| 43 | + | select { | |||
| 44 | + | case err := <-errCh: | |||
| 45 | + | if err != nil { | |||
| 46 | + | panic(err) | |||
| 47 | + | } | |||
| 48 | + | case <-statusCh: | |||
| 49 | + | } | |||
| 50 | + | ||||
| 51 | + | out, err := cli.ContainerLogs(ctx, resp.ID, types.ContainerLogsOptions{ShowStdout: true}) | |||
| 52 | + | if err != nil { | |||
| 53 | + | panic(err) | |||
| 54 | + | } | |||
| 55 | + | ||||
| 56 | + | stdcopy.StdCopy(os.Stdout, os.Stderr, out) | |||
| 57 | + | } | |||
| 58 | + | ||||
| 59 | + | func DockerListContainersTest() { | |||
| 60 | + | fmt.Println("Executing DockerListContainersTest()") | |||
| 61 | + | ||||
| 62 | + | ctx := context.Background() | |||
| 63 | + | cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) | |||
| 64 | + | if err != nil { | |||
| 65 | + | panic(err) | |||
| 66 | + | } | |||
| 67 | + | defer cli.Close() | |||
| 68 | + | ||||
| 69 | + | fmt.Println("Initialized Docker client.") | |||
| 70 | + | ||||
| 71 | + | containers, err := cli.ContainerList(ctx, types.ContainerListOptions{All: true}) | |||
| 72 | + | if err != nil { | |||
| 73 | + | panic(err) | |||
| 74 | + | } | |||
| 75 | + | ||||
| 76 | + | fmt.Printf("Found %d containers.\n", len(containers)) | |||
| 22 | 77 | ||||
| 23 | for _, container := range containers { | 78 | for _, container := range containers { | ||
| 24 | - | fmt.Printf("%s %s\n", container.ID[:10], container.Image) | 79 | + | fmt.Printf("%s %s\n", container.ID[:10], container.Status) |
| 80 | + | } | |||
| 81 | + | } | |||
| 82 | + | ||||
| 83 | + | // I have a Dockerfile inside tmp/docker-test/Dockerfile and i want to create an image from it and place it at the same directory. | |||
| 84 | + | func CreateImageFromDockerfile() { | |||
| 85 | + | fmt.Println("Executing CreateImageFromDockerfile()") | |||
| 86 | + | fmt.Println("Initialized Docker client.") | |||
| 87 | + | ctx := context.Background() | |||
| 88 | + | cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) | |||
| 89 | + | if err != nil { | |||
| 90 | + | panic(err) | |||
| 91 | + | } | |||
| 92 | + | defer cli.Close() | |||
| 93 | + | ||||
| 94 | + | fmt.Println("Building image...") | |||
| 95 | + | buildCtx, err := archive.TarWithOptions("tmp/docker-test/", &archive.TarOptions{}) | |||
| 96 | + | if err != nil { | |||
| 97 | + | panic(err) | |||
| 98 | + | } | |||
| 99 | + | defer buildCtx.Close() | |||
| 100 | + | ||||
| 101 | + | fmt.Println("Building image...") | |||
| 102 | + | imageBuildResponse, err := cli.ImageBuild(ctx, buildCtx, types.ImageBuildOptions{ | |||
| 103 | + | Tags: []string{"gordon-echo:latest"}, | |||
| 104 | + | }) | |||
| 105 | + | if err != nil { | |||
| 106 | + | panic(err) | |||
| 107 | + | } | |||
| 108 | + | defer imageBuildResponse.Body.Close() | |||
| 109 | + | ||||
| 110 | + | fmt.Println("Saving image to file...") | |||
| 111 | + | ||||
| 112 | + | imageTar, err := cli.ImageSave(ctx, []string{"gordon-echo:latest"}) | |||
| 113 | + | if err != nil { | |||
| 114 | + | panic(err) | |||
| 115 | + | } | |||
| 116 | + | ||||
| 117 | + | outputFile, err := os.Create("tmp/docker-test/gordon-echo.tar") | |||
| 118 | + | if err != nil { | |||
| 119 | + | panic(err) | |||
| 120 | + | } | |||
| 121 | + | defer outputFile.Close() | |||
| 122 | + | ||||
| 123 | + | _, err = io.Copy(outputFile, imageTar) | |||
| 124 | + | if err != nil { | |||
| 125 | + | panic(err) | |||
| 25 | } | 126 | } | ||
| 26 | } | 127 | } | ||
M pkg/utils/parser.go +21 -0
| @@ -3,7 +3,9 @@ package utils | |||
| 3 | 3 | import ( | |
| 4 | 4 | "fmt" | |
| 5 | 5 | "io" | |
| 6 | + | "os" | |
| 6 | 7 | ||
| 8 | + | "github.com/tidwall/gjson" | |
| 7 | 9 | "gogs.bnema.dev/gordon-echo/internal/ui" | |
| 8 | 10 | "gopkg.in/yaml.v3" | |
| 9 | 11 | ) | |
| @@ -59,3 +61,22 @@ func PopulateDataFromYAML(currentLang string) (YamlData, error) { | |||
| 59 | 61 | } | |
| 60 | 62 | ||
| 61 | 63 | // Json Parser | |
| 64 | + | ||
| 65 | + | // ReadDataFromJSONFile loads the data from the given JSON file | |
| 66 | + | func ReadDataFromJSONFile(filePath string) (string, error) { | |
| 67 | + | bytes, err := os.ReadFile(filePath) | |
| 68 | + | if err != nil { | |
| 69 | + | return "", err | |
| 70 | + | } | |
| 71 | + | return string(bytes), nil | |
| 72 | + | } | |
| 73 | + | ||
| 74 | + | // QueryJSON queries the provided JSON content based on the given gjson query and returns the results as a slice of strings | |
| 75 | + | func QueryJSON(jsonContent, query string) []string { | |
| 76 | + | results := gjson.GetMany(jsonContent, query) | |
| 77 | + | var values []string | |
| 78 | + | for _, result := range results { | |
| 79 | + | values = append(values, result.String()) | |
| 80 | + | } | |
| 81 | + | return values | |
| 82 | + | } | |
| @@ -3,7 +3,9 @@ package utils | |||||
| 3 | import ( | 3 | import ( | ||
| 4 | "fmt" | 4 | "fmt" | ||
| 5 | "io" | 5 | "io" | ||
| 6 | + | "os" | |||
| 6 | 7 | ||||
| 8 | + | "github.com/tidwall/gjson" | |||
| 7 | "gogs.bnema.dev/gordon-echo/internal/ui" | 9 | "gogs.bnema.dev/gordon-echo/internal/ui" | ||
| 8 | "gopkg.in/yaml.v3" | 10 | "gopkg.in/yaml.v3" | ||
| 9 | ) | 11 | ) | ||
| @@ -59,3 +61,22 @@ func PopulateDataFromYAML(currentLang string) (YamlData, error) { | |||||
| 59 | } | 61 | } | ||
| 60 | 62 | ||||
| 61 | // Json Parser | 63 | // Json Parser | ||
| 64 | + | ||||
| 65 | + | // ReadDataFromJSONFile loads the data from the given JSON file | |||
| 66 | + | func ReadDataFromJSONFile(filePath string) (string, error) { | |||
| 67 | + | bytes, err := os.ReadFile(filePath) | |||
| 68 | + | if err != nil { | |||
| 69 | + | return "", err | |||
| 70 | + | } | |||
| 71 | + | return string(bytes), nil | |||
| 72 | + | } | |||
| 73 | + | ||||
| 74 | + | // QueryJSON queries the provided JSON content based on the given gjson query and returns the results as a slice of strings | |||
| 75 | + | func QueryJSON(jsonContent, query string) []string { | |||
| 76 | + | results := gjson.GetMany(jsonContent, query) | |||
| 77 | + | var values []string | |||
| 78 | + | for _, result := range results { | |||
| 79 | + | values = append(values, result.String()) | |||
| 80 | + | } | |||
| 81 | + | return values | |||
| 82 | + | } | |||