├── .circleci └── config.yml ├── .gitignore ├── .goreleaser.yml ├── LICENSE ├── README.adoc ├── client ├── kubernetes_client.go ├── network_policy_access.go └── pod_access.go ├── cmd ├── network_policy.go ├── network_policy_list.go └── version.go ├── collector └── collector.go ├── go.mod ├── go.sum ├── main.go └── renderer └── renderer.go /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | jobs: 3 | build: 4 | docker: 5 | - image: circleci/golang:1.12.6 6 | steps: 7 | - checkout 8 | - restore_cache: 9 | keys: 10 | - go-mod-v1-{{ checksum "go.sum" }} 11 | - run: 12 | name: Download Dependencies 13 | command: go mod download 14 | - save_cache: 15 | key: go-mod-v1-{{ checksum "go.sum" }} 16 | paths: 17 | - "/go/pkg/mod" 18 | - run: 19 | name: Compile Packages and Dependencies 20 | command: go build 21 | - run: 22 | name: Unit Tests 23 | command: go test ./... -coverprofile=coverage.txt -covermode=count || bash <(curl -s https://codecov.io/bash) 24 | - run: 25 | name: Code Quality Analysis 26 | command: | 27 | curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b /go/bin v1.12.5 28 | golangci-lint run 29 | - run: 30 | name: Release Binaries 31 | command: | 32 | if [ "$CIRCLE_TAG" ]; then 33 | curl -sL https://git.io/goreleaser | bash 34 | fi -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea 3 | dist 4 | kubectl-swiftnp -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | builds: 2 | - env: 3 | - CGO_ENABLED=0 4 | goos: 5 | - linux 6 | - darwin 7 | - windows 8 | - netbsd 9 | - openbsd 10 | - freebsd 11 | goarch: 12 | - 386 13 | - amd64 14 | - arm 15 | - arm64 16 | ldflags: -s -w -X main.version={{.Version}} 17 | archive: 18 | name_template: '{{ .ProjectName }}-{{ .Version }}-{{ .Os }}-{{ .Arch }}{{ if .Arm}}v{{ .Arm }}{{ end }}' 19 | format_overrides: 20 | - goos: windows 21 | format: zip 22 | replacements: 23 | darwin: Darwin 24 | linux: Linux 25 | windows: Windows 26 | 386: i386 27 | amd64: x86_64 28 | checksum: 29 | name_template: 'checksums.txt' 30 | snapshot: 31 | name_template: "{{ .Tag }}-next" 32 | changelog: 33 | sort: asc 34 | filters: 35 | exclude: 36 | - '^docs:' 37 | - '^test:' 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | = kubectl swiftnp image:https://circleci.com/gh/bmuschko/kubectl-swiftnp.svg?style=svg["CircleCI", link="https://circleci.com/gh/bmuschko/kubectl-swiftnp"] image:https://goreportcard.com/badge/github.com/bmuschko/kubectl-swiftnp["Go Report Card", link="https://goreportcard.com/report/github.com/bmuschko/kubectl-swiftnp"] 2 | 3 | kubectl plugin for rendering details of Network Policies 4 | 5 | == Intro 6 | 7 | Listing all Network Policies in a Namespace provides little information about the Pods they apply to and the rules they specify. 8 | The following command list all Network Policies describes as examples in the https://kubernetes.io/docs/concepts/services-networking/network-policies/[Kubernetes documentation]. 9 | 10 | [source,bash] 11 | ---- 12 | $ kubectl get networkpolicy 13 | NAME POD-SELECTOR AGE 14 | allow-all-egress 17h 15 | allow-all-ingress 17h 16 | deny-all-egress 17h 17 | deny-all-ingress 17h 18 | deny-all-ingress-egress 17h 19 | test-network-policy role=db 17h 20 | ---- 21 | 22 | As you can see, it's extremely hard to grasp the effect of the Network Policies. 23 | You'd usually have to have a look at the details of each Network Policy to understand their inner workings. 24 | This is where this plugin comes in. 25 | 26 | == Usage 27 | 28 | Run the command `swiftnp` with the subcommand `list` to render detailed information about Network Policies. 29 | You can render Network Policies in other Namespaces by providing the `--namespace` option. 30 | 31 | [source,bash] 32 | ---- 33 | $ kubectl swiftnp list 34 | NAME SELECTED-PODS INGRESS-POLICY EGRESS-POLICY INGRESS-RULE EGRESS-RULE FROM-COUNT TO-COUNT 35 | allow-all-egress frontend, mypod ✖ ✔ ✖ ✔ 0 0 36 | allow-all-ingress frontend, mypod ✔ ✖ ✔ ✖ 0 0 37 | deny-all-egress frontend, mypod ✖ ✔ ✖ ✖ 0 0 38 | deny-all-ingress frontend, mypod ✔ ✖ ✖ ✖ 0 0 39 | deny-all-ingress-egress frontend, mypod ✔ ✔ ✖ ✖ 0 0 40 | test-network-policy mypod ✔ ✔ ✔ ✔ 3 1 41 | ---- 42 | 43 | The subcommand `version` renders the version of the released binary. 44 | 45 | [source,bash] 46 | ---- 47 | $ kubectl swiftnp version 48 | kubectl swiftnp v0.2.0 49 | ---- 50 | 51 | ## Building the binary from source 52 | 53 | The project requires Go 1.11 or higher as dependencies are defined with the help of Go Modules. 54 | First, activate Go Modules by setting the relevant environment variable. 55 | Next, create the platform-specific binary with the `build` command. 56 | 57 | [source,bash] 58 | ---- 59 | $ export GO111MODULES=on 60 | $ go build -o kubectl-swiftnp 61 | ---- 62 | 63 | Binaries for a wide range of other platforms can be created with the help of https://github.com/goreleaser/goreleaser[GoReleaser]. 64 | 65 | [source,bash] 66 | ---- 67 | $ goreleaser release --skip-validate --snapshot --rm-dist 68 | ---- 69 | 70 | To release a new version of the binaries to GitHub Releases, create a Git tag and remove the relevant flags in the command above. 71 | 72 | == Installation 73 | 74 | The binary must be placed on the `$PATH` named `kubectl-swiftnp`. Ensure that the binary has execution permissions. 75 | For more information, see the https://kubernetes.io/docs/tasks/extend-kubectl/kubectl-plugins/[official documentation on kubectl plugins]. -------------------------------------------------------------------------------- /client/kubernetes_client.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "k8s.io/client-go/kubernetes" 5 | "k8s.io/client-go/tools/clientcmd" 6 | ) 7 | 8 | func CreateClientset() (*kubernetes.Clientset, error) { 9 | loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() 10 | configOverrides := &clientcmd.ConfigOverrides{} 11 | kubeConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, configOverrides) 12 | 13 | config, err := kubeConfig.ClientConfig() 14 | if err != nil { 15 | return nil, err 16 | } 17 | 18 | clientset, err := kubernetes.NewForConfig(config) 19 | if err != nil { 20 | return nil, err 21 | } 22 | 23 | return clientset, nil 24 | } 25 | -------------------------------------------------------------------------------- /client/network_policy_access.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | networkingv1 "k8s.io/api/networking/v1" 5 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 6 | "k8s.io/client-go/kubernetes" 7 | ) 8 | 9 | func GetNetworkPolicies(clientset *kubernetes.Clientset, namespace string) (*networkingv1.NetworkPolicyList, error) { 10 | npi := clientset.NetworkingV1().NetworkPolicies(namespace) 11 | 12 | var label, field string 13 | listOptions := metav1.ListOptions{ 14 | LabelSelector: label, 15 | FieldSelector: field, 16 | } 17 | nps, err := npi.List(listOptions) 18 | if err != nil { 19 | return nil, err 20 | } 21 | return nps, nil 22 | } 23 | -------------------------------------------------------------------------------- /client/pod_access.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | corev1 "k8s.io/api/core/v1" 5 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 6 | "k8s.io/client-go/kubernetes" 7 | ) 8 | 9 | func GetPodsByLabelSelector(clientset *kubernetes.Clientset, namespace string, podSelector *metav1.LabelSelector) (*corev1.PodList, error) { 10 | podi := clientset.CoreV1().Pods(namespace) 11 | sel, err := massagePodSelector(podSelector) 12 | if err != nil { 13 | return nil, err 14 | } 15 | var field string 16 | listOptions := metav1.ListOptions{ 17 | LabelSelector: sel, 18 | FieldSelector: field, 19 | } 20 | pods, err := podi.List(listOptions) 21 | if err != nil { 22 | return nil, err 23 | } 24 | return pods, nil 25 | } 26 | 27 | func massagePodSelector(podSelector *metav1.LabelSelector) (string, error) { 28 | selector, err := metav1.LabelSelectorAsSelector(podSelector) 29 | if err != nil { 30 | return "", err 31 | } 32 | 33 | l := selector.String() 34 | if len(l) == 0 { 35 | return "", nil 36 | } 37 | 38 | return metav1.FormatLabelSelector(podSelector), nil 39 | } 40 | -------------------------------------------------------------------------------- /cmd/network_policy.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | "k8s.io/cli-runtime/pkg/genericclioptions" 6 | ) 7 | 8 | func NewNetworkPolicyCommand(streams genericclioptions.IOStreams) *cobra.Command { 9 | cmd := &cobra.Command{ 10 | Use: "swiftnp", 11 | Short: "Retrieves information about Network Policies", 12 | } 13 | 14 | cmd.AddCommand(newNetworkPolicyListCommand(streams)) 15 | cmd.AddCommand(newVersionCommand(streams.Out)) 16 | return cmd 17 | } -------------------------------------------------------------------------------- /cmd/network_policy_list.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | "github.com/bmuschko/kubectl-swiftnp/collector" 6 | "github.com/bmuschko/kubectl-swiftnp/renderer" 7 | "github.com/gosuri/uitable" 8 | "github.com/spf13/cobra" 9 | "io" 10 | "k8s.io/cli-runtime/pkg/genericclioptions" 11 | ) 12 | 13 | type networkPolicyListCmd struct { 14 | out io.Writer 15 | namespace string 16 | } 17 | 18 | func newNetworkPolicyListCommand(streams genericclioptions.IOStreams) *cobra.Command { 19 | list := &networkPolicyListCmd{out: streams.Out} 20 | 21 | cmd := &cobra.Command{ 22 | Use: "list [flags]", 23 | Short: "list Network Policies", 24 | RunE: func(cmd *cobra.Command, args []string) error { 25 | return list.run() 26 | }, 27 | } 28 | 29 | cmd.PersistentFlags().StringVarP(&list.namespace, "namespace", "n", "default", "the namespace used for querying for Network Policies") 30 | return cmd 31 | } 32 | 33 | func (a *networkPolicyListCmd) run() error { 34 | networkPolicies, err := collector.CollectNetworkPolicies(a.namespace) 35 | if err != nil { 36 | return err 37 | } 38 | 39 | a.printNetworkPolicies(networkPolicies) 40 | return nil 41 | } 42 | 43 | func (a *networkPolicyListCmd) printNetworkPolicies(nps []collector.NetworkPolicy) { 44 | if len(nps) > 0 { 45 | table := uitable.New() 46 | table.AddRow("NAME", "SELECTED-PODS", "INGRESS-POLICY", "EGRESS-POLICY", "INGRESS-RULE", "EGRESS-RULE", "FROM-COUNT", "TO-COUNT") 47 | for _, np := range nps { 48 | table.AddRow(np.Name, renderPodNames(np.SelectedPodNames), renderBoolean(np.PolicyType.Ingress), renderBoolean(np.PolicyType.Egress), renderBoolean(np.IngressRule), renderBoolean(np.EgressRule), np.FromCount, np.ToCount) 49 | } 50 | fmt.Fprintln(a.out, table) 51 | } else { 52 | fmt.Println("No resources found.") 53 | } 54 | } 55 | 56 | func renderPodNames(value []string) string { 57 | return renderLimitedString(renderer.JoinStrings(value)) 58 | } 59 | 60 | func renderLimitedString(value string) string { 61 | return renderer.LimitString(value, 30) 62 | } 63 | 64 | func renderBoolean(value bool) string { 65 | return renderer.BooleanIcon(value) 66 | } 67 | -------------------------------------------------------------------------------- /cmd/version.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "github.com/spf13/cobra" 7 | "io" 8 | ) 9 | 10 | const appLabel = "kubectl swiftnp" 11 | 12 | var version string 13 | 14 | // SetVersion set the application version for consumption in the output of the command. 15 | func SetVersion(v string) { 16 | version = v 17 | } 18 | 19 | type versionCmd struct { 20 | out io.Writer 21 | } 22 | 23 | func newVersionCommand(out io.Writer) *cobra.Command { 24 | version := &versionCmd{ 25 | out: out, 26 | } 27 | 28 | cmd := &cobra.Command{ 29 | Use: "version", 30 | Short: "print the version number and exit", 31 | RunE: func(cmd *cobra.Command, args []string) error { 32 | if len(args) != 0 { 33 | return errors.New("this command does not accept arguments") 34 | } 35 | return version.run() 36 | }, 37 | } 38 | return cmd 39 | } 40 | 41 | func (v *versionCmd) run() error { 42 | _, err := fmt.Fprintf(v.out, "%s %s\n", appLabel, version) 43 | if err != nil { 44 | return err 45 | } 46 | return nil 47 | } 48 | -------------------------------------------------------------------------------- /collector/collector.go: -------------------------------------------------------------------------------- 1 | package collector 2 | 3 | import ( 4 | "github.com/bmuschko/kubectl-swiftnp/client" 5 | corev1 "k8s.io/api/core/v1" 6 | networkingv1 "k8s.io/api/networking/v1" 7 | ) 8 | 9 | type NetworkPolicy struct { 10 | Name string 11 | PolicyType NetworkPolicyType 12 | SelectedPodNames []string 13 | IngressRule bool 14 | EgressRule bool 15 | FromCount int 16 | ToCount int 17 | } 18 | 19 | type NetworkPolicyType struct { 20 | Ingress bool 21 | Egress bool 22 | } 23 | 24 | func CollectNetworkPolicies(namespace string) ([]NetworkPolicy, error) { 25 | var networkPolicies []NetworkPolicy 26 | 27 | clientset, err := client.CreateClientset() 28 | if err != nil { 29 | return nil, err 30 | } 31 | 32 | nps, err := client.GetNetworkPolicies(clientset, namespace) 33 | if err != nil { 34 | return nil, err 35 | } 36 | 37 | for _, np := range nps.Items { 38 | networkPolicy := NetworkPolicy{Name: np.Name, PolicyType: policyTypesToStruct(np.Spec.PolicyTypes)} 39 | selectedPods, err := client.GetPodsByLabelSelector(clientset, namespace, &np.Spec.PodSelector) 40 | if err != nil { 41 | return nil, err 42 | } 43 | networkPolicy.SelectedPodNames = podListToNames(selectedPods) 44 | 45 | for _, i := range np.Spec.Ingress { 46 | networkPolicy.IngressRule = true 47 | networkPolicy.FromCount = networkPolicy.FromCount + len(i.From) 48 | } 49 | 50 | for _, e := range np.Spec.Egress { 51 | networkPolicy.EgressRule = true 52 | networkPolicy.ToCount = networkPolicy.ToCount + len(e.To) 53 | } 54 | 55 | networkPolicies = append(networkPolicies, networkPolicy) 56 | } 57 | 58 | return networkPolicies, nil 59 | } 60 | 61 | func policyTypesToStruct(pts []networkingv1.PolicyType) NetworkPolicyType { 62 | allTypes := NetworkPolicyType{} 63 | for _, pt := range pts { 64 | if pt == networkingv1.PolicyTypeIngress { 65 | allTypes.Ingress = true 66 | } 67 | if pt == networkingv1.PolicyTypeEgress { 68 | allTypes.Egress = true 69 | } 70 | } 71 | return allTypes 72 | } 73 | 74 | func podListToNames(pods *corev1.PodList) []string { 75 | var selectedPods []string 76 | for _, p := range pods.Items { 77 | selectedPods = append(selectedPods, p.Name) 78 | } 79 | return selectedPods 80 | } 81 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/bmuschko/kubectl-swiftnp 2 | 3 | go 1.12 4 | 5 | require ( 6 | github.com/evanphx/json-patch v4.2.0+incompatible // indirect 7 | github.com/fatih/color v1.7.0 // indirect 8 | github.com/gogo/protobuf v1.2.1 // indirect 9 | github.com/google/btree v1.0.0 // indirect 10 | github.com/google/gofuzz v1.0.0 // indirect 11 | github.com/googleapis/gnostic v0.2.0 // indirect 12 | github.com/gosuri/uitable v0.0.3 13 | github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc // indirect 14 | github.com/imdario/mergo v0.3.7 // indirect 15 | github.com/json-iterator/go v1.1.6 // indirect 16 | github.com/mattn/go-colorable v0.1.2 // indirect 17 | github.com/mattn/go-runewidth v0.0.4 // indirect 18 | github.com/modern-go/reflect2 v1.0.1 // indirect 19 | github.com/peterbourgon/diskv v2.0.1+incompatible // indirect 20 | github.com/pkg/errors v0.8.1 // indirect 21 | github.com/spf13/cobra v0.0.4 22 | golang.org/x/oauth2 v0.0.0-20190523182746-aaccbc9213b0 // indirect 23 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect 24 | gopkg.in/inf.v0 v0.9.1 // indirect 25 | k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b 26 | k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d 27 | k8s.io/cli-runtime v0.0.0-20190409023024-d644b00f3b79 28 | k8s.io/client-go v11.0.0+incompatible 29 | k8s.io/klog v0.3.2 // indirect 30 | k8s.io/kube-openapi v0.0.0-20190530181030-b52b5b0f5a7c // indirect 31 | k8s.io/utils v0.0.0-20190529001817-6999998975a7 // indirect 32 | sigs.k8s.io/kustomize v2.0.3+incompatible // indirect 33 | sigs.k8s.io/yaml v1.1.0 // indirect 34 | ) 35 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 3 | github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= 4 | github.com/PuerkitoBio/purell v1.0.0 h1:0GoNN3taZV6QI81IXgCbxMyEaJDXMSIjArYBCYzVVvs= 5 | github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= 6 | github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2 h1:JCHLVE3B+kJde7bIEo5N4J+ZbLhp0J1Fs+ulyRws4gE= 7 | github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= 8 | github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= 9 | github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= 10 | github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= 11 | github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= 12 | github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= 13 | github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 14 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 15 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 16 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 17 | github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633 h1:H2pdYOb3KQ1/YsqVWoWNLQO+fusocsw354rqGTZtAgw= 18 | github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= 19 | github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I= 20 | github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= 21 | github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= 22 | github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= 23 | github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= 24 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 25 | github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680 h1:ZktWZesgun21uEDrwW7iEV1zPCGQldM2atlJZ3TdvVM= 26 | github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 27 | github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1 h1:wSt/4CYxs70xbATrGXhokKF1i0tZjENLOo1ioIO13zk= 28 | github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= 29 | github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9 h1:tF+augKRWlWx0J0B7ZyyKSiTyV6E1zZe+7b3qQlcEf8= 30 | github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= 31 | github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501 h1:C1JKChikHGpXwT5UQDFaryIpDtyyGL/CR6C2kB7F1oc= 32 | github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= 33 | github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87 h1:zP3nY8Tk2E6RTkqGYrarZXuzh+ffyLDljLxCy1iJw80= 34 | github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= 35 | github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= 36 | github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= 37 | github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 38 | github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= 39 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 40 | github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= 41 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 42 | github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= 43 | github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= 44 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 45 | github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= 46 | github.com/googleapis/gnostic v0.2.0 h1:l6N3VoaVzTncYYW+9yOz2LJJammFZGBO13sqgEhpy9g= 47 | github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= 48 | github.com/gosuri/uitable v0.0.3 h1:9ZY4qCODg6JL1Ui4dL9LqCF4ghWnAOSV2h7xG98SkHE= 49 | github.com/gosuri/uitable v0.0.3/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= 50 | github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc h1:f8eY6cV/x1x+HLjOp4r72s/31/V2aTUtg5oKRRPf8/Q= 51 | github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= 52 | github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= 53 | github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI= 54 | github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= 55 | github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= 56 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= 57 | github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= 58 | github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs= 59 | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= 60 | github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= 61 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 62 | github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= 63 | github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a h1:TpvdAwDAt1K4ANVOfcihouRdvP+MgAfDWwBuct4l6ZY= 64 | github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= 65 | github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= 66 | github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= 67 | github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= 68 | github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 69 | github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y= 70 | github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= 71 | github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 72 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 73 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 74 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 75 | github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 76 | github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= 77 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 78 | github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= 79 | github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c h1:Hww8mOyEKTeON4bZn7FrlLismspbPc1teNRUVH7wLQ8= 80 | github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 81 | github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c h1:eSfnfIuwhxZyULg1NNuZycJcYkjYVGYe7FczwQReM6U= 82 | github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= 83 | github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= 84 | github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= 85 | github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= 86 | github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= 87 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 88 | github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 89 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 90 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 91 | github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= 92 | github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= 93 | github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= 94 | github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= 95 | github.com/spf13/cobra v0.0.4 h1:S0tLZ3VOKl2Te0hpq8+ke0eSJPfCnNTPiDlsfwi1/NE= 96 | github.com/spf13/cobra v0.0.4/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= 97 | github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= 98 | github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 99 | github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= 100 | github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 101 | github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= 102 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 103 | github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 104 | github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= 105 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 106 | github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= 107 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 108 | github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= 109 | github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= 110 | golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 h1:mKdxBk7AujPs8kU4m80U72y/zjbZ3UcXC7dClwKbUI0= 111 | golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 112 | golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 113 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 114 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg= 115 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 116 | golang.org/x/oauth2 v0.0.0-20190523182746-aaccbc9213b0 h1:xFEXbcD0oa/xhqQmMXztdZ0bWvexAWds+8c1gRN8nu0= 117 | golang.org/x/oauth2 v0.0.0-20190523182746-aaccbc9213b0/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 118 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw= 119 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 120 | golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 121 | golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 122 | golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= 123 | golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 124 | golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 125 | golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= 126 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 127 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= 128 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 129 | golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 130 | golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 131 | google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= 132 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 133 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 134 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 135 | gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= 136 | gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= 137 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 138 | gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= 139 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 140 | k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b h1:aBGgKJUM9Hk/3AE8WaZIApnTxG35kbuQba2w+SXqezo= 141 | k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= 142 | k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d h1:Jmdtdt1ZnoGfWWIIik61Z7nKYgO3J+swQJtPYsP9wHA= 143 | k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= 144 | k8s.io/cli-runtime v0.0.0-20190409023024-d644b00f3b79 h1:bZyxc0wzVA5KgUfAXZA6z872zDWmyslwfvrr175VF68= 145 | k8s.io/cli-runtime v0.0.0-20190409023024-d644b00f3b79/go.mod h1:qWnH3/b8sp/l7EvlDh7ulDU3UWA4P4N1NFbEEP791tM= 146 | k8s.io/client-go v11.0.0+incompatible h1:LBbX2+lOwY9flffWlJM7f1Ct8V2SRNiMRDFeiwnJo9o= 147 | k8s.io/client-go v11.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= 148 | k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= 149 | k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= 150 | k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= 151 | k8s.io/klog v0.3.2 h1:qvP/U6CcZ6qyi/qSHlJKdlAboCzo3mT0DAm0XAarpz4= 152 | k8s.io/klog v0.3.2/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= 153 | k8s.io/kube-openapi v0.0.0-20190530181030-b52b5b0f5a7c h1:hF9pxMkApz1zmi6bgixdchv/Y7P4sojbA42l5JH0lvM= 154 | k8s.io/kube-openapi v0.0.0-20190530181030-b52b5b0f5a7c/go.mod h1:nfDlWeOsu3pUf4yWGL+ERqohP4YsZcBJXWMK+gkzOA4= 155 | k8s.io/utils v0.0.0-20190529001817-6999998975a7 h1:5UOdmwfY+7XsXvo26XeCDu9GhHJPkO1z8Mcz5AHMnOE= 156 | k8s.io/utils v0.0.0-20190529001817-6999998975a7/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= 157 | sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0= 158 | sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= 159 | sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= 160 | sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= 161 | sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= 162 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/bmuschko/kubectl-swiftnp/cmd" 5 | "k8s.io/cli-runtime/pkg/genericclioptions" 6 | "os" 7 | ) 8 | 9 | var version = "undefined" 10 | 11 | func main() { 12 | cmd.SetVersion(version) 13 | 14 | networkPolicyCmd := cmd.NewNetworkPolicyCommand(genericclioptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr}) 15 | if err := networkPolicyCmd.Execute(); err != nil { 16 | os.Exit(1) 17 | } 18 | } -------------------------------------------------------------------------------- /renderer/renderer.go: -------------------------------------------------------------------------------- 1 | package renderer 2 | 3 | import "strings" 4 | 5 | func BooleanIcon(flag bool) string { 6 | if flag { 7 | return "✔" 8 | } 9 | 10 | return "✖" 11 | } 12 | 13 | func JoinStrings(allStrings []string) string { 14 | return strings.Join(allStrings, ", ") 15 | } 16 | 17 | func LimitString(fullString string, maxLength int) string { 18 | if len(fullString) > maxLength { 19 | return fullString[0:maxLength] + "..." 20 | } 21 | return fullString 22 | } 23 | --------------------------------------------------------------------------------