From 9bd056c7eb35f1cf0f67a3d34fc50830d7aa399b Mon Sep 17 00:00:00 2001 From: GitLab CI/CD <> Date: Tue, 30 Mar 2021 23:30:14 +0200 Subject: [PATCH 1/3] allow generation for many namespace --- .gitignore | 4 +++ Dockerfile | 14 ++++++++- Makefile | 13 ++++++++ README.md | 15 ++++----- cmd/k8sviz/main.go | 61 +++++++++++++++++++------------------ development.m4 | 6 ++++ go.sum | 18 ----------- icons/cj-128.png | Bin 0 -> 7611 bytes k8sviz.sh | 50 ++++++++++++++++++++++-------- monitoring.m4 | 7 +++++ operators.m4 | 6 ++++ pkg/graph/graph.go | 32 ++++++++++++++----- pkg/resources/resources.go | 15 ++++++++- production.m4 | 10 ++++++ staging.m4 | 9 ++++++ 15 files changed, 183 insertions(+), 77 deletions(-) create mode 100644 development.m4 create mode 100644 icons/cj-128.png create mode 100644 monitoring.m4 create mode 100644 operators.m4 create mode 100644 production.m4 create mode 100644 staging.m4 diff --git a/.gitignore b/.gitignore index 85d0bbc..d60951e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ bin/ lib/ +/out/* +/k8sviz.iml +service-account-key.json +config-k8sviz diff --git a/Dockerfile b/Dockerfile index d0374a0..0d36080 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,8 +5,20 @@ COPY . . RUN make build FROM alpine:3.11 -RUN apk add --no-cache bash graphviz ttf-linux-libertine +RUN apk add --no-cache bash graphviz ttf-linux-libertine curl python +# Downloading gcloud package +RUN curl https://dl.google.com/dl/cloudsdk/release/google-cloud-sdk.tar.gz > /tmp/google-cloud-sdk.tar.gz +# Installing the package +RUN mkdir -p /usr/local/share \ + && tar -C /usr/local/share -xvf /tmp/google-cloud-sdk.tar.gz \ + && /usr/local/share/google-cloud-sdk/install.sh + +# Adding the package path to local +ENV PATH $PATH:/usr/local/gcloud/google-cloud-sdk/bin +ENV GOOGLE_APPLICATION_CREDENTIALS /service-account-key.json + +RUN if [ -f /service-account-key.json ]; then rm /service-account-key.json; fi COPY icons /icons COPY --from=build /src/bin/k8sviz / diff --git a/Makefile b/Makefile index 38f3b4d..2599d2c 100644 --- a/Makefile +++ b/Makefile @@ -47,3 +47,16 @@ image-push: image-build docker push $(IMAGE):$(TAG) .PHONY: test test-lint test-fmt test-vet test-unit test-e2e build release image-build image-push + +generate-graph: + mkdir -p out + ./k8sviz.sh -t dot -k config-k8sviz -o out -n "ns1,ns2" -f k8s-diagram.png + +merge-graph: + m4 merge.m4 > merged.gv + sed -i -e "s/\/icons/icons/" merged.gv + dot -n -Tpng merged.gv -o diagram_staging.png + m4 production.m4 > merged.gv + sed -i -e "s/\/icons/icons/" merged.gv + dot -n -Tpng merged.gv -o diagram_production.png + rm merged.gv diff --git a/README.md b/README.md index ac7e59a..28a0900 100644 --- a/README.md +++ b/README.md @@ -55,11 +55,12 @@ $ cp -r icons ${PATH_TO_INSTALL} $ ./k8sviz.sh --help USAGE: ./k8sviz.sh [flags] args flags: - -n,--namespace: The namespace to visualize. (default: 'default') - -o,--outfile: The filename to output. (default: 'k8sviz.out') + -n,--namespace: The namespace to visualize. It is possible to specify many coma separated namespaces (default: 'default') + -o,--outdir: The directory to generate files. filename use namespace name (default: 'out') -t,--type: The type of output. (default: 'dot') -k,--kubeconfig: Path to kubeconfig file. (default: '/home/user1/kubeconfig') -i,--image: Image name of the container. (default: 'mkimuram/k8sviz:0.3') + -f,--filename: concatenated diagram filename (default: "global.dot") -h,--help: show this help (default: false) ``` @@ -91,13 +92,13 @@ Usage of ./k8sviz: -kubeconfig string absolute path to the kubeconfig file (default "/home/user1/.kube/config") -n string - namespace to visualize (shorthand) (default "namespace") + namespace to visualize. It is possible to specify many coma separated namespaces (shorthand) (default "namespace") -namespace string - namespace to visualize (default "namespace") + namespace to visualize. It is possible to specify many coma separated namespaces (default "namespace") -o string - output filename (shorthand) (default "k8sviz.out") - -outfile string - output filename (default "k8sviz.out") + output directory (shorthand) (default "out") + -outdir string + output directory. filename is based on each namespace name (default "k8sviz.out") -t string type of output (shorthand) (default "dot") -type string diff --git a/cmd/k8sviz/main.go b/cmd/k8sviz/main.go index ff28b9b..0475623 100644 --- a/cmd/k8sviz/main.go +++ b/cmd/k8sviz/main.go @@ -6,24 +6,23 @@ package main import ( "flag" "fmt" - "os" - "path/filepath" - "github.com/mkimuram/k8sviz/pkg/graph" "github.com/mkimuram/k8sviz/pkg/resources" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" + "os" + "path/filepath" + "strings" _ "k8s.io/client-go/plugin/pkg/client/auth" ) const ( defaultNamespace = "namespace" - defaultOutFile = "k8sviz.out" + defaultOutDir = "out" defaultOutType = "dot" descNamespaceOpt = "namespace to visualize" - descOutFileOpt = "output filename" + descOutDirOpt = "output dir" descOutTypeOpt = "type of output" descShortOptSuffix = " (shorthand)" ) @@ -33,7 +32,7 @@ var ( dir string // Flags namespace string - outFile string + outDir string outType string ) @@ -49,8 +48,8 @@ func init() { } flag.StringVar(&namespace, "namespace", defaultNamespace, descNamespaceOpt) flag.StringVar(&namespace, "n", defaultNamespace, descNamespaceOpt+descShortOptSuffix) - flag.StringVar(&outFile, "outfile", defaultOutFile, descOutFileOpt) - flag.StringVar(&outFile, "o", defaultOutFile, descOutFileOpt+descShortOptSuffix) + flag.StringVar(&outDir, "outDir", defaultOutDir, descOutDirOpt) + flag.StringVar(&outDir, "o", defaultOutDir, descOutDirOpt+descShortOptSuffix) flag.StringVar(&outType, "type", defaultOutType, descOutTypeOpt) flag.StringVar(&outType, "t", defaultOutType, descOutTypeOpt+descShortOptSuffix) flag.Parse() @@ -70,11 +69,13 @@ func init() { } // test connectivity for k8s cluster and the namespace - _, err = clientset.CoreV1().Namespaces().Get(namespace, metav1.GetOptions{}) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to get namespace %q: %v\n", namespace, err) - os.Exit(1) - } + //if !strings.Contains(namespace,",") { + // _, err = clientset.CoreV1().Namespaces().Get(namespace, metav1.GetOptions{}) + // if err != nil { + // fmt.Fprintf(os.Stderr, "Failed to get namespace %q: %v\n", namespace, err) + // os.Exit(1) + // } + //} dir, err = getBinDir() if err != nil { @@ -85,23 +86,25 @@ func init() { func main() { // Get all resources in the namespace - res, err := resources.NewResources(clientset, namespace) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to get k8s resources: %v\n", err) - os.Exit(1) - } - - g := graph.NewGraph(res, dir) - - if outType == "dot" { - if err := g.WriteDotFile(outFile); err != nil { - fmt.Fprintf(os.Stderr, "Failed to output %q file with format %q for namespace %q: %v\n", outFile, outType, namespace, err) + words := strings.Split(namespace, ",") + for _, ns := range words { + res, err := resources.NewResources(clientset, ns) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to get k8s resources: %v\n", err) os.Exit(1) } - } else { - if err := g.PlotDotFile(outFile, outType); err != nil { - fmt.Fprintf(os.Stderr, "Failed to output %q file with format %q for namespace %q: %v\n", outFile, outType, namespace, err) - os.Exit(1) + + g := graph.NewGraph(res, dir) + if outType == "dot" { + if err := g.WriteDotFile(outDir + "/" + ns + "." + outType); err != nil { + fmt.Fprintf(os.Stderr, "Failed to output %q file with format %q for namespace %q: %v\n", outDir, outType, namespace, err) + os.Exit(1) + } + } else { + if err := g.PlotDotFile(outDir+"/"+ns+"."+outType, outType); err != nil { + fmt.Fprintf(os.Stderr, "Failed to output %q file with format %q for namespace %q: %v\n", outDir, outType, namespace, err) + os.Exit(1) + } } } } diff --git a/development.m4 b/development.m4 new file mode 100644 index 0000000..cc7c6f7 --- /dev/null +++ b/development.m4 @@ -0,0 +1,6 @@ +### merge dot files +digraph k8s_diagram { +define(`digraph',`subgraph') +include(out/gitlab-managed-apps.dot)dnl +include(out/jmeter.dot)dnl +} diff --git a/go.sum b/go.sum index e2aa1ad..842fb73 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,4 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -36,7 +35,6 @@ github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkg github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -54,7 +52,6 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -66,7 +63,6 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= @@ -86,7 +82,6 @@ github.com/gophercloud/gophercloud v0.9.0/go.mod h1:gmC5oQqMDOMO1t1gq5DquX/yAU80 github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ= @@ -117,13 +112,11 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.15.2 h1:l77YT15o814C2qVL47NOyjV/6RbaP7kKdrvZnxQ3Org= github.com/onsi/ginkgo v1.15.2/go.mod h1:Dd6YFfwBW84ETqqtL0CPyPXillHgY6XhQH3uuCCTr/o= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= @@ -146,11 +139,9 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191202143827-86a70503ff7e h1:egKlR8l7Nu9vHGWbcUV8lqR4987UfUbBd7GbhqGzNYU= golang.org/x/crypto v0.0.0-20191202143827-86a70503ff7e/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -168,9 +159,7 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933 h1:e6HwijUxhDe+hPNjZQQn9bA5PW3vNmnN64U2ZW759Lk= golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= @@ -193,12 +182,10 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456 h1:ng0gs1AKnRRuEMZoTLLlbOd+C17zUDepwGQBb/n+JVg= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 h1:ZBzSG/7F4eNKz2L3GE9o300RX0Az1Bw5HF7PDraD+qU= golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -208,7 +195,6 @@ golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -224,7 +210,6 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191203134012-c197fd4bf371/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e h1:4nW4NLDYnU28ojHaHO8OVxFHk/aQ33U01a9cjED+pzE= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -233,7 +218,6 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1N golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -252,7 +236,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= @@ -262,7 +245,6 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/icons/cj-128.png b/icons/cj-128.png new file mode 100644 index 0000000000000000000000000000000000000000..f3f4c423aa2b280c8f0f0d3f58cb8c86965fe51a GIT binary patch literal 7611 zcmV;s9Yo@ZP)DXT00006VoOIv0RI60 z0RN!9r;`8x9dJoRK~#90?Ok_#Q|0>qz9*|~Mt2Jo*#+5KHi!$a3OE1((d)*acu^4) zsC(Xf^$K1^#eslcFACRz3Mx|&0TE~^8_FuQ6uM}dot)?QM{?4WG-;DGCuwTGpHDxZ zzT=$tN!};#cqZ^C0ueDHx|)bSA)>=XWF(>zBHBkpuMttNXw%pX2|z>~5sf9HT~t4Q zC8Dv>rnwnm01+vO=q@5U6u`uLV>b~^BqA2=&mkq6LZIL#Q;Q<2w(<)M*(Db zv;pPo_L%bj@nu!-N`oWG*Yj;NWrZ(HOF7lEo#F}rDzE0F0R92sGsc)z0`jARCcywi zlm_4t05bt3i`#fY>4sd>ftUY#sc*H3*9G#vR2^43XF}qEYx>0ZWencWoCmNFz}t*5 zV>sxKCSsZah$s`l;{g5!AVJ*b;Bj`<*6I^)eXAd6u~B>|?@v^7`X?tQ?i)!!ceY5mO96L_Gn_0WbydoLsY&j(ohXx^(H!`oTO8 znH1wIpHBi)Ou%&wuml zD)VP35f}674xQp2e1af^Ng|GQ6MiMG&%-w30`gj zFdx8RuV(&yrDONA%PKUxk6XJ&o;v>++BGgeXKJFkMUrfwkLL9No@I<}k2GENq0uk^ z5pe)+1n@k7eqPPCf@1scIm;?q9y@325OLyyz>u!0{HLcTnOh{u2B7x$yA8lU7-Qc> zfi$0pIs*`q62N2tIRH9)HCv9Jv+tezNqO7TCH9t)r!I8#Xs0~-?9`--9b3u=1GNsN zxd0ZxDO8H8bTMiSKtyWPh-+JWw!yIbxMlY<%PTLxQ0d6<`GOchn+#cD&g7(%1F}_v zP+PjVAHeGXK4*;CBTrov7=Va$0PX=W7x27O^F-wva?Sa#t*GjK$>>{L8>`4ll@&dE zN7C^D*{T8X5?TQ`1*ddzF=NaeNxCA&07R6I8achkdDs4ak5a4z@W;@ZMhTdPklT&=&t zYNa@zFKD7rt624nvD!ToM`|wT7`(SRLCpMb##p(ObV$YkMAQ*Z<;-+=?R^$29sg)u zb;+`y^@GACu8mbBs5rwTV>P=cj?iRt9J~*@)c}^jd2=X|V*Ic(fXl3EHh`({I{lih zboj%y)m6(k=m+u|UA@ETOGwgaF=2!n^Co$3(}82!KQH1?p)IIq1nJ_O z35l8n74sH$*#N8n@ET+6P{@Rd(BS2_E^+O}OZL3yKD{L0dBoDQq2v5nz!SLDJB$Or z+i9e+gA#VlxIUFF03*Gc9EGL!Z8=LT z(+-@r_HGDqe`XMYt=?fAxO#^XqkG5ipL=^EpQhymt7Q((AKZ;Z^dA6EFvc!~GEPVg zKt$u<+>^wIJL}=Iw(U9vVHIq-vHyE~zd%k3FQJK9}Fz;$c=*T-^ zz5L2K#a;7HS+G@@(u#`VK|bG%FoFo|zJ;Zo2@p#Qrv~$mfEmE0wsrs77p>M; zNo9N2jKEQ@=Tmncw&aVdt_kM(U{-*B00i@D<2Tz4eS#UN8Peh7AFIW>guX7%sDKa* z1Gty_ifaBysJ8aa2tRU9Sh^5F&>kuP1T1k4h5?4U2Q08&3gWqDNDQ99l~wV_L{-BA zeKr^d7$W?$A=ji0;<;u-0DB6o)uLi}8Gwj7p~iZL|Mie1yRQDth&& zh=f5+8Q<2!H_sJp;H8fSdQ3n(zLN6o(3}VvS%x z=YV<{fQW?U1OTux&(tP((wY$oY}#j0h>GE1062gB902fy3ui7kyhE-uqmf`^u1V}Q z)scw2UD<0P5C(8_(z#OmiBJe@Mr3fl!jb9VNvsYY;@gf$~_D7@%6 zB`Vgt4b*uHAR-U3;<{W*TF8_E=+asNE<`ibDie=$r4FBMS!pup;)7LeI>8fgT(=+jZ@vn>#8%rm31I+0APky~KJ3~<}RpF3?&2T0>Gy$SzQd^ zJ^&UJ+lv7-IR>aU@p$VS|8Dr2cnI}tmZCz$-v`WnFFUv z?8rN5#jYb3oW2m1U>|N6t(0K0(2;l*>*A^!h7cIQy#j2`H#d4u-eB?DK?`19QHhcY z&%K>vz_9Ld7&kZp!@H}Xl-K>y6V)6N)f~FDQQ(Gw&Sm$+c{_gi-H30u8&MJAYoLI` zh1Qb3om2t?429F5qZWKJfGdoP+rE5buBl1M|5yBCz`y=?3A|_pXAHQmUp(#`qeaJ- z4fC1p&_a&Cjnm$Ui5n-NQX)<>KXHt(~@`*w1B?)g0k`n$jkfy=j_CzPH%Z*Lo3 z@}dKt2mb!$CA_}MbMo7_kYn-8G`xCua)T#dj5sC3)X{2u^-KnC8BrIAW0$%=aC01@Vc+}r?MFKvZlaBtKq?2*!5;)ACoP-4r zrXW!r8KJ?sQhN)YhoBf@@S_;2mjQl1Y%_(Kwy5B}AM_s9Jsbn(PD;cJcP1fT8JVBv zh#qnHbWS?jW<(|`PGPD2w5aHF8>qzqL?i=ng-~9%*VrHhP-DOkznk#!PkMJ*#sRO~ zos5YiA}`y@N|oWG$I{THwW9vc4a9E;EMg%>UsmF(Hf`};iu7HA&uEeVqu=g zHsE&!*t)-ID1c-fFn)0KPyO{FMayAyZ)xIXA3bLkpT38R+uUaWBGLeGNA%pV*OY}Y zf-yiFqCqI&+<*NUSR|+z1$CS>H@8A;AnptQ z(uFn3OqSta52Rq>^b`-7gRm{!{KAExwgsu_1%PrrFFv)lliRY|J%DVru1$I3>g1#_90o{B#WJQgf5;+fj+D0@U-b*(JRSCL@Uxn~E37 z0qg{DD*&|1ly{9&GNaiV{uJ(&1|H*HC<*y_z0v<9<}9m((u;LXR%d^sg|H#lgt3Dn zV-(UhLyko=Qt{nRBi{X9kDSR#0r>=4Y=ob7OY4NytDW+QQs#CU2Y_5gM0WuAOsM&G zyJ_=_pI2NdDJ2m``xbJ1IX@%h5Otx#<{*z)0(IewEe8B^rL=iCRzIJyGb>d-NK}>0 z!I_Nsh)^?baNNM`)`}+K5Gvs0dAsDlE?)?A@=aF4vUSziyIzXF&ov?^t+!>XK&;~a-3aVr3TvML^Led|9QOtf&Q(1!nPG}PZQM5yDK ze(9_;AK3D3%y>FIcL#|n}F%lDG zmCNU3$QW~r_-z0tF~)pqdh5KX647D+4+`a9_nUutbaDBpIv$BhjOibb*|#MkMJtU7 z84>Wq??$}wzbcPl72yWQz^{2Jb5DArY=EfxA;#EZf6vs%015yb0E`f-7JOB;{j*Kg zL+f}fCZUbzF#QHCZXK2oRwvE;Q&zn7O;y-U$9&iwjy z#6!CPw02dQ?q67XYHxwHYaNfpEK+qGri{|yhAZNcnG~9K+~y!`J7B?=TMP{{4haU6 zM`^asnV=hvnmOGLU^HW_P67gAbs`!JU^ATN#BlI*?)s-o;+jhQ0AJu3(6^HcLoQcg zKxZX7wp94F*yRZ*E_Wcez=~Z*E!eW(j7x^dNgaE%QyyLRL|PUAA;`da00S6f^}6^6 zyw(xXT>zE|<%(*4&zPL^y&QbN*+*j@naMJwXgFvSI50S6_y#kN!ix^cEs*^oQO#BS z^h##6LdJy1E;ayHxum=GBH&XGV{AEqMM61Q!}WXT|5CQq@koak{>uszLy_FvfzuYld`yV~p)3 zqUiuW1ptmitN-O>+#ADJ3HL|l5kaIv`sRL{OFycQO z4IcZm_(Hm85(*i^!810zzebPU0ayg5>9~s@KbEFLO+H66fZGK1ZmWS!o#ABMyHYvtsGGYW$LKMxvU-#NoAV_gbdNuxxf3I<`j5)1 z?K8vf5=uXQiw>{+H5skbw8)CXOd4QFckF#yoFlWOGu-K5?6-uLyr)iwi` zK9P=RrY7OW=SpDp;~@IsqsiNo)Z9o>)dI%Yl6r})0}T>>yUfX^0&u$<-9JVS?ZY3dJp?Zf-f03x1dR6)7`nLJ zfyHZUCLeIh>Wvoi@cXL^p^mLL@wJ%Z;2CGixfCsj5#4<|XWx6Bc3ZFZD)HoR1n^`) z#MXfZYd;uc<#3vn3wBM4g%72)XptiG85z1~JLeJ`j4u4hIUCH@+P?}R=Dx4J^W=Fu zN~;{mN|n_LPj}?3%_EQ$;FRWFyySo`A+WEcA!GaUQ`l2r@p!KoS9FQnKVz&`tl&8f zU@~K@!6(zOsJ|Fvc>wMLKmfooWUP29y;LQyEr-^+zTgW%7(x146#%#sQTubvE_Kyw z;yw3bf5xG92LcWz9qQQr`j@%;dlHbIB)hQa;gnRk#P9%2a31UJ zH-xe_f$On!c3Q2&iQee^pc%m^TKovwgo*SQ2r|u8FOC}&E`&O^zy7K2{xu9DmvOc) z=BA(LIJ6XXy^k@rJ5;*85pD(eTmWl@Lgy^S@R{RuTf`lNjG9BbHarlC;7Kb4i4>!4 zh8$@+8P1hCB+`z0Mf>Zy3mTBdiSI%1?U- zfa5~lU$4~+8QCK)Pbjb4Y6Q;%)BmFN84@iR6|9g1>VfMu9@)5L95Cxv9T)??-7byA zPpD&S<2l?n#xrR}w>Aol=^u}BJ&&yioV(`Cn{`{dw^N93Q|kfD5BKK?yC#n@RzXDL z0PFyu1EBcVgDI`XJ$IqFxWeA@c##eNSak_cO-#g!x#{>N-;Bai2a?nry0=xJ+Qj3* ze+L$)YR_>iKHFH0X;*2mDklT$_nKg_5r%b-Lx&b}>@Bcj`Fd$QZbBV?mcTwg4^=ggSi{})8Dd9Nuc|#IaE@SKv5&adwR{$8t zkiIe}{qWWE&L>%H6u)Y#0mshSaM#ru4Ct)F=-v#K1|G-G*@L#xTkv%i4j0-maikhI z4N8Dq1{7X&V9|F~_-vCwGMoEQ$39nT$EzzUF>|~QlSiqckUJ%T@BQGE1ZF16OWuAs zB?C2wzG?vD7-N!%+9h?DB%+rAf$M*HA6@Dip!O9+;AW}OM%C4(c$SSi68H~OtWN+^}g{NH&Q zm7>Wf0QW>{@_`64fD11GSS1uXw3H8>cYES55vHNhVCk&1Kh!GLO;q(FV{Db*2P8m5 z8NijW@E!ne4xcbwJ^U{N6aI)K9gP9=Cns<2lBF0fs#*=;#Yoc;@p$Ttv1&LEg_W)< z*-LjNb!e9%KND$MqJ?Yv#qYUoSiE@h4+FT*>O};Y7o(U0I#^qK>3Gj^#?y#s~;AtSw00hHB9!|gg@9TI}Qbd~p7=SMTOcd8Ucq-a`)Ou{!F{}J+nLUo@W0M); zl+4jSLuMY*J&tv5rRd3+J1>)fXBcBIM};^SqW;AakrKd40OO)fON8++#@OuoyGe_v zC)IH|GfV>TDqOJ&n>fk=JkS^>A7}(CfEYy72~OL>8v(QjkQ`l#!UBTRUHd4U>haH| dQtgI<{|CB~Y merged.gv + sed -i -e "s/\/icons/icons/" merged.gv + if [ "dot" != "${FLAGS_type}" ]; then + dot -n -T${FLAGS_type} merged.gv -o $GLOBAL_FILENAME.${FLAGS_type} + rm merged.gv + else + mv merged.gv $GLOBAL_FILENAME.${FLAGS_type} + fi +fi diff --git a/monitoring.m4 b/monitoring.m4 new file mode 100644 index 0000000..0b84943 --- /dev/null +++ b/monitoring.m4 @@ -0,0 +1,7 @@ +### merge dot files +digraph k8s_diagram { +define(`digraph',`subgraph') +include(out/elasticsearch.dot)dnl +include(out/grafana-ds-api-plugin-25435752-production.dot)dnl +include(out/prometheus.dot)dnl +} diff --git a/operators.m4 b/operators.m4 new file mode 100644 index 0000000..e33fa63 --- /dev/null +++ b/operators.m4 @@ -0,0 +1,6 @@ +### merge dot files +digraph k8s_diagram { +define(`digraph',`subgraph') +include(out/mongodb.dot)dnl +include(out/postgresql.dot)dnl +} diff --git a/pkg/graph/graph.go b/pkg/graph/graph.go index 42a07e0..fb98115 100644 --- a/pkg/graph/graph.go +++ b/pkg/graph/graph.go @@ -6,13 +6,12 @@ package graph import ( "bytes" "fmt" - "os" - "os/exec" - "strings" - "github.com/awalterschulze/gographviz" "github.com/mkimuram/k8sviz/pkg/resources" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "os" + "os/exec" + "strings" ) // Graph represents a graph of k8s resources @@ -36,7 +35,6 @@ func (g *Graph) WriteDotFile(outFile string) error { if err != nil { return err } - if _, err := f.WriteString(g.toDot()); err != nil { if closeErr := f.Close(); closeErr != nil { return fmt.Errorf("failed to close file after write failure: %v, %v", closeErr, err) @@ -125,15 +123,15 @@ func (g *Graph) generateCommon() { if err != nil { fmt.Fprintf(os.Stderr, "Failed to set to digraph: %v\n", err) } - err = g.gviz.SetName("G") + err = g.gviz.SetName("G_" + g.escapeName(g.res.Namespace)) if err != nil { fmt.Fprintf(os.Stderr, "Failed to set to graph name to G: %v\n", err) } - err = g.gviz.AddAttr("G", "rankdir", "TD") + err = g.gviz.AddAttr("G_"+g.escapeName(g.res.Namespace), "rankdir", "TD") if err != nil { fmt.Fprintf(os.Stderr, "Failed to set rankdir to TD: %v\n", err) } - err = g.gviz.AddSubGraph("G", g.clusterName(), + err = g.gviz.AddSubGraph("G_"+g.escapeName(g.res.Namespace), g.clusterName(), map[string]string{"label": g.clusterLabel(), "labeljust": "l", "style": "dotted"}) if err != nil { fmt.Fprintf(os.Stderr, "Failed to add subgraph %s to digraph G: %v\n", g.clusterName(), err) @@ -217,6 +215,9 @@ func (g *Graph) generateEdges() { // Owner reference for rs g.genRsOwnerRef() + // Owner reference for job + g.genJobOwnerRef() + // hpa to scale target g.genHpaScaleTargetRef() @@ -260,6 +261,21 @@ func (g *Graph) genRsOwnerRef() { } } +// genJobOwnerRef generates the edges of OwnerReferences from RS +func (g *Graph) genJobOwnerRef() { + // Add edge if below matches: + // - apps/v1.ReplicaSet.metadata.ownerReferences. + // - kind + // - name + // - {kind}.metadata.{name} + // ``` + // deploy_my_deployment->rs_my_replicaset[ style=dashed ]; + // ``` + for _, job := range g.res.Jobs.Items { + g.genOwnerRef("job", &job) + } +} + // genOwnerRef generates the edges of OwnerReferences for specified obj func (g *Graph) genOwnerRef(kind string, obj metav1.Object) { for _, ref := range obj.GetOwnerReferences() { diff --git a/pkg/resources/resources.go b/pkg/resources/resources.go index 85b811c..5d72afc 100644 --- a/pkg/resources/resources.go +++ b/pkg/resources/resources.go @@ -10,6 +10,7 @@ import ( appsv1 "k8s.io/api/apps/v1" autov1 "k8s.io/api/autoscaling/v1" batchv1 "k8s.io/api/batch/v1" + batchv1beta1 "k8s.io/api/batch/v1beta1" corev1 "k8s.io/api/core/v1" v1beta1 "k8s.io/api/extensions/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -19,7 +20,7 @@ import ( var ( // ResourceTypes represents the set of resource types. // Resouces are grouped by the same level of abstraction. - ResourceTypes = []string{"hpa", "deploy job", "sts ds rs", "pod", "pvc", "svc", "ing"} + ResourceTypes = []string{"hpa cj", "deploy job", "sts ds rs", "pod", "pvc", "svc", "ing"} normalizedNames = map[string]string{ "ns": "namespace", "svc": "service", @@ -30,6 +31,7 @@ var ( "rs": "replicaset", "deploy": "deployment", "job": "job", + "cj": "cronjob", "ing": "ingress", "hpa": "horizontalpodautoscaler", } @@ -48,6 +50,7 @@ type Resources struct { Rss *appsv1.ReplicaSetList Deploys *appsv1.DeploymentList Jobs *batchv1.JobList + CronJobs *batchv1beta1.CronJobList Ingresses *v1beta1.IngressList Hpas *autov1.HorizontalPodAutoscalerList } @@ -99,6 +102,12 @@ func NewResources(clientset kubernetes.Interface, namespace string) (*Resources, return nil, fmt.Errorf("failed to get deployments in namespace %q: %v", namespace, err) } + // CronJobs + res.CronJobs, err = clientset.BatchV1beta1().CronJobs(namespace).List(metav1.ListOptions{}) + if err != nil { + return nil, fmt.Errorf("failed to get cronjobs in namespace %q: %v", namespace, err) + } + // job res.Jobs, err = clientset.BatchV1().Jobs(namespace).List(metav1.ListOptions{}) if err != nil { @@ -153,6 +162,10 @@ func (r *Resources) GetResourceNames(kind string) []string { for _, n := range r.Deploys.Items { names = append(names, n.Name) } + case "cj": + for _, n := range r.CronJobs.Items { + names = append(names, n.Name) + } case "job": for _, n := range r.Jobs.Items { names = append(names, n.Name) diff --git a/production.m4 b/production.m4 new file mode 100644 index 0000000..d89fad6 --- /dev/null +++ b/production.m4 @@ -0,0 +1,10 @@ +### merge dot files +digraph k8s_diagram { +define(`digraph',`subgraph') +include(out/postgresql-prod.dot)dnl +include(out/keycloak.dot)dnl +include(out/mongodb-production.dot)dnl +include(out/feamzy-web-production.dot)dnl +include(out/feamzy-api-production.dot)dnl +include(out/haproxy.dot)dnl +} diff --git a/staging.m4 b/staging.m4 new file mode 100644 index 0000000..153b740 --- /dev/null +++ b/staging.m4 @@ -0,0 +1,9 @@ +### merge dot files +digraph k8s_diagram { +define(`digraph',`subgraph') +include(out/postgresql-staging.dot)dnl +include(out/keycloak-staging.dot)dnl +include(out/mongodb-staging.dot)dnl +include(out/feamzy-web-staging.dot)dnl +include(out/feamzy-api-staging.dot)dnl +} From d794af9c1cd78407e71703e41059148d42e6817b Mon Sep 17 00:00:00 2001 From: GitLab CI/CD <> Date: Fri, 2 Apr 2021 12:20:43 +0200 Subject: [PATCH 2/3] add m4 package in docker image --- .gitignore | 5 +++++ Dockerfile | 4 +--- Makefile | 3 --- development.m4 | 6 ------ k8sviz.sh | 4 ++-- operators.m4 => merge.m4 | 4 ++-- monitoring.m4 | 7 ------- production.m4 | 10 ---------- staging.m4 | 9 --------- 9 files changed, 10 insertions(+), 42 deletions(-) delete mode 100644 development.m4 rename operators.m4 => merge.m4 (55%) delete mode 100644 monitoring.m4 delete mode 100644 production.m4 delete mode 100644 staging.m4 diff --git a/.gitignore b/.gitignore index d60951e..3d21600 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,8 @@ lib/ /k8sviz.iml service-account-key.json config-k8sviz +/*.png +/merged.gv-e +/global.dot +/config-k8sviz.json +/service-account-key2.json diff --git a/Dockerfile b/Dockerfile index 0d36080..4031094 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ COPY . . RUN make build FROM alpine:3.11 -RUN apk add --no-cache bash graphviz ttf-linux-libertine curl python +RUN apk add --no-cache bash graphviz ttf-linux-libertine curl python m4 # Downloading gcloud package RUN curl https://dl.google.com/dl/cloudsdk/release/google-cloud-sdk.tar.gz > /tmp/google-cloud-sdk.tar.gz @@ -16,9 +16,7 @@ RUN mkdir -p /usr/local/share \ # Adding the package path to local ENV PATH $PATH:/usr/local/gcloud/google-cloud-sdk/bin -ENV GOOGLE_APPLICATION_CREDENTIALS /service-account-key.json -RUN if [ -f /service-account-key.json ]; then rm /service-account-key.json; fi COPY icons /icons COPY --from=build /src/bin/k8sviz / diff --git a/Makefile b/Makefile index 2599d2c..1a14794 100644 --- a/Makefile +++ b/Makefile @@ -56,7 +56,4 @@ merge-graph: m4 merge.m4 > merged.gv sed -i -e "s/\/icons/icons/" merged.gv dot -n -Tpng merged.gv -o diagram_staging.png - m4 production.m4 > merged.gv - sed -i -e "s/\/icons/icons/" merged.gv - dot -n -Tpng merged.gv -o diagram_production.png rm merged.gv diff --git a/development.m4 b/development.m4 deleted file mode 100644 index cc7c6f7..0000000 --- a/development.m4 +++ /dev/null @@ -1,6 +0,0 @@ -### merge dot files -digraph k8s_diagram { -define(`digraph',`subgraph') -include(out/gitlab-managed-apps.dot)dnl -include(out/jmeter.dot)dnl -} diff --git a/k8sviz.sh b/k8sviz.sh index ff2bd7f..5c36ee4 100755 --- a/k8sviz.sh +++ b/k8sviz.sh @@ -4,7 +4,7 @@ NAMESPACE="default" OUTDIR="out" TYPE="dot" -GLOBAL_FILENAME="global" +GLOBAL_FILENAME="" KUBECONFIG=~/kubeconfig #CONTAINER_IMG=mkimuram/k8sviz:0.3 CONTAINER_IMG=docker.io/library/k8sviz:devel @@ -75,7 +75,7 @@ if [ -z $GLOBAL_FILENAME ]; then -e GOOGLE_APPLICATION_CREDENTIALS=/work/service-account-key.json \ -it --rm ${FLAGS_image} \ /k8sviz -kubeconfig /config \ - -n ${FLAGS_namespace} -t ${FLAGS_type} -o /work/${FILENAME} + -t ${FLAGS_type} -n ${FLAGS_namespace} -o /work/${FILENAME} else docker run --network host \ diff --git a/operators.m4 b/merge.m4 similarity index 55% rename from operators.m4 rename to merge.m4 index e33fa63..7db6c99 100644 --- a/operators.m4 +++ b/merge.m4 @@ -1,6 +1,6 @@ ### merge dot files digraph k8s_diagram { define(`digraph',`subgraph') -include(out/mongodb.dot)dnl -include(out/postgresql.dot)dnl +include(out/ns1.dot)dnl +include(out/ns2.dot)dnl } diff --git a/monitoring.m4 b/monitoring.m4 deleted file mode 100644 index 0b84943..0000000 --- a/monitoring.m4 +++ /dev/null @@ -1,7 +0,0 @@ -### merge dot files -digraph k8s_diagram { -define(`digraph',`subgraph') -include(out/elasticsearch.dot)dnl -include(out/grafana-ds-api-plugin-25435752-production.dot)dnl -include(out/prometheus.dot)dnl -} diff --git a/production.m4 b/production.m4 deleted file mode 100644 index d89fad6..0000000 --- a/production.m4 +++ /dev/null @@ -1,10 +0,0 @@ -### merge dot files -digraph k8s_diagram { -define(`digraph',`subgraph') -include(out/postgresql-prod.dot)dnl -include(out/keycloak.dot)dnl -include(out/mongodb-production.dot)dnl -include(out/feamzy-web-production.dot)dnl -include(out/feamzy-api-production.dot)dnl -include(out/haproxy.dot)dnl -} diff --git a/staging.m4 b/staging.m4 deleted file mode 100644 index 153b740..0000000 --- a/staging.m4 +++ /dev/null @@ -1,9 +0,0 @@ -### merge dot files -digraph k8s_diagram { -define(`digraph',`subgraph') -include(out/postgresql-staging.dot)dnl -include(out/keycloak-staging.dot)dnl -include(out/mongodb-staging.dot)dnl -include(out/feamzy-web-staging.dot)dnl -include(out/feamzy-api-staging.dot)dnl -} From d45b87a7192ce4efbfde1a3a53b409cbb8b0b85d Mon Sep 17 00:00:00 2001 From: GitLab CI/CD <> Date: Fri, 2 Apr 2021 14:13:51 +0200 Subject: [PATCH 3/3] correction tests --- Makefile | 2 +- pkg/graph/testdata/common.golden | 2 +- pkg/graph/testdata/generate_res1.golden | 2 +- pkg/graph/testdata/generate_res2.golden | 2 +- pkg/graph/testdata/generate_res3.golden | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 1a14794..497c49b 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -IMAGE ?= mkimuram/k8sviz +IMAGE ?= sguerard/k8sviz TAG ?= 0.3 DEVEL_IMAGE ?= k8sviz DEVEL_TAG ?= devel diff --git a/pkg/graph/testdata/common.golden b/pkg/graph/testdata/common.golden index 52109d3..5c80e71 100644 --- a/pkg/graph/testdata/common.golden +++ b/pkg/graph/testdata/common.golden @@ -1,4 +1,4 @@ -digraph G { +digraph G_testns { rankdir=TD; 0->1[ style=invis ]; 1->2[ style=invis ]; diff --git a/pkg/graph/testdata/generate_res1.golden b/pkg/graph/testdata/generate_res1.golden index bc1fed5..a0fd989 100644 --- a/pkg/graph/testdata/generate_res1.golden +++ b/pkg/graph/testdata/generate_res1.golden @@ -1,4 +1,4 @@ -digraph G { +digraph G_testns { rankdir=TD; 0->1[ style=invis ]; 1->2[ style=invis ]; diff --git a/pkg/graph/testdata/generate_res2.golden b/pkg/graph/testdata/generate_res2.golden index e28c52c..49db7e8 100644 --- a/pkg/graph/testdata/generate_res2.golden +++ b/pkg/graph/testdata/generate_res2.golden @@ -1,4 +1,4 @@ -digraph G { +digraph G_testns { rankdir=TD; 0->1[ style=invis ]; 1->2[ style=invis ]; diff --git a/pkg/graph/testdata/generate_res3.golden b/pkg/graph/testdata/generate_res3.golden index 800b720..625ab3e 100644 --- a/pkg/graph/testdata/generate_res3.golden +++ b/pkg/graph/testdata/generate_res3.golden @@ -1,4 +1,4 @@ -digraph G { +digraph G_testns { rankdir=TD; 0->1[ style=invis ]; 1->2[ style=invis ];