1 package cmd
2
3 import (
4 "fmt"
5 "io"
6 "os"
7
8 "github.com/linkerd/linkerd2/pkg/charts/linkerd2"
9 "github.com/linkerd/linkerd2/pkg/inject"
10 "github.com/spf13/cobra"
11 )
12
13 type resourceTransformerUninject struct {
14 values *linkerd2.Values
15 }
16
17 type resourceTransformerUninjectSilent struct {
18 values *linkerd2.Values
19 }
20
21 func runUninjectCmd(inputs []io.Reader, errWriter, outWriter io.Writer, values *linkerd2.Values, output string) int {
22 return transformInput(inputs, errWriter, outWriter, resourceTransformerUninject{values}, output)
23 }
24
25 func runUninjectSilentCmd(inputs []io.Reader, errWriter, outWriter io.Writer, values *linkerd2.Values, output string) int {
26 return transformInput(inputs, errWriter, outWriter, resourceTransformerUninjectSilent{values}, output)
27 }
28
29 func newCmdUninject() *cobra.Command {
30 var output string
31
32 cmd := &cobra.Command{
33 Use: "uninject [flags] CONFIG-FILE",
34 Short: "Remove the Linkerd proxy from a Kubernetes config",
35 Long: `Remove the Linkerd proxy from a Kubernetes config.
36
37 You can uninject resources contained in a single file, inside a folder and its
38 sub-folders, or coming from stdin.`,
39 Example: ` # Uninject all the deployments in the default namespace.
40 kubectl get deploy -o yaml | linkerd uninject - | kubectl apply -f -
41
42 # Download a resource and uninject it through stdin.
43 curl http://url.to/yml | linkerd uninject - | kubectl apply -f -
44
45 # Uninject all the resources inside a folder and its sub-folders.
46 linkerd uninject <folder> | kubectl apply -f -`,
47 RunE: func(cmd *cobra.Command, args []string) error {
48
49 if len(args) < 1 {
50 return fmt.Errorf("please specify a kubernetes resource file")
51 }
52
53 in, err := read(args[0])
54 if err != nil {
55 return err
56 }
57
58 exitCode := runUninjectCmd(in, os.Stderr, os.Stdout, nil, output)
59 os.Exit(exitCode)
60 return nil
61 },
62 }
63
64 cmd.Flags().StringVarP(&output, "output", "o", "yaml", "Output format, one of: json|yaml")
65
66 return cmd
67 }
68
69 func (rt resourceTransformerUninject) transform(bytes []byte) ([]byte, []inject.Report, error) {
70 conf := inject.NewResourceConfig(rt.values, inject.OriginWebhook, controlPlaneNamespace)
71
72 report, err := conf.ParseMetaAndYAML(bytes)
73 if err != nil {
74 return nil, nil, err
75 }
76
77 output, err := conf.Uninject(report)
78 if err != nil {
79 return nil, nil, err
80 }
81 if output == nil {
82 output = bytes
83 report.UnsupportedResource = true
84 }
85
86 return output, []inject.Report{*report}, nil
87 }
88
89 func (rt resourceTransformerUninjectSilent) transform(bytes []byte) ([]byte, []inject.Report, error) {
90 return resourceTransformerUninject(rt).transform(bytes)
91 }
92
93 func (resourceTransformerUninject) generateReport(reports []inject.Report, output io.Writer) {
94
95 output.Write([]byte("\n"))
96
97 for _, r := range reports {
98 if r.Uninjected.Proxy || r.Uninjected.ProxyInit {
99 output.Write([]byte(fmt.Sprintf("%s \"%s\" uninjected\n", r.Kind, r.Name)))
100 } else {
101 if r.Kind != "" {
102 output.Write([]byte(fmt.Sprintf("%s \"%s\" skipped\n", r.Kind, r.Name)))
103 } else {
104 output.Write([]byte(fmt.Sprintln("document missing \"kind\" field, skipped")))
105 }
106 }
107 }
108
109
110 output.Write([]byte("\n"))
111 }
112
113 func (resourceTransformerUninjectSilent) generateReport(reports []inject.Report, output io.Writer) {
114 }
115
View as plain text