forked from joeholley/supergloo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmtls.go
107 lines (98 loc) · 3.25 KB
/
mtls.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package upstream
import (
"fmt"
"path/filepath"
"github.com/pkg/errors"
v1 "github.com/solo-io/gloo/projects/gloo/pkg/api/v1"
skclients "github.com/solo-io/solo-kit/pkg/api/v1/clients"
"github.com/solo-io/supergloo/cli/pkg/flagutils"
"github.com/solo-io/supergloo/cli/pkg/helpers/clients"
"github.com/solo-io/supergloo/cli/pkg/options"
"github.com/solo-io/supergloo/cli/pkg/surveyutils"
"github.com/spf13/cobra"
)
const (
certChain = "cert-chain.pem"
key = "key.pem"
rootCa = "root-cert.pem"
)
func setUpstreamTlsCmd(opts *options.Options) *cobra.Command {
cmd := &cobra.Command{
Use: "mtls",
Short: "edit mtls settings for a Gloo upstream",
PreRunE: func(cmd *cobra.Command, args []string) error {
if opts.Interactive {
us, err := surveyutils.SurveyUpstream(opts.Ctx)
if err != nil {
return err
}
opts.Metadata.Namespace = us.Namespace
opts.Metadata.Name = us.Name
mesh, err := surveyutils.SurveyMesh("select the mesh which you would like to connect to", opts.Ctx)
if err != nil {
return err
}
opts.EditUpstream.MtlsMesh = options.ResourceRefValue(mesh)
}
if err := validateSetUpstreamCmd(opts); err != nil {
return err
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
if err := editUpstream(opts); err != nil {
return err
}
fmt.Printf("successfully updated upstream %s.%s", opts.Metadata.Namespace, opts.Metadata.Name)
return nil
},
}
flagutils.AddUpstreamTlsFlags(cmd.PersistentFlags(), &opts.EditUpstream)
return cmd
}
func editUpstream(opts *options.Options) error {
usClient := clients.MustUpstreamClient()
usRef := opts.Metadata
us, err := usClient.Read(usRef.Namespace, usRef.Name, skclients.ReadOpts{})
if err != nil {
return errors.Wrapf(err, "unable to find upstream %s.%s", usRef.Namespace, usRef.Name)
}
meshRef := opts.EditUpstream.MtlsMesh
folderRoot := "/etc/certs"
meshFolderPath := fmt.Sprintf("/%s/%s", meshRef.Namespace, meshRef.Name)
sslConfig := &v1.UpstreamSslConfig{
SslSecrets: &v1.UpstreamSslConfig_SslFiles{
SslFiles: &v1.SSLFiles{
TlsCert: filepath.Join(folderRoot, meshFolderPath, certChain),
TlsKey: filepath.Join(folderRoot, meshFolderPath, key),
RootCa: filepath.Join(folderRoot, meshFolderPath, rootCa),
},
},
}
us.UpstreamSpec.SslConfig = sslConfig
_, err = usClient.Write(us, skclients.WriteOpts{
OverwriteExisting: true,
})
if err != nil {
return errors.Wrapf(err, "unable to save upstream %s.%s after editing ssl config", usRef.Namespace, usRef.Name)
}
return nil
}
func validateSetUpstreamCmd(opts *options.Options) error {
if opts.EditUpstream.MtlsMesh.Namespace == "" || opts.EditUpstream.MtlsMesh.Name == "" {
return fmt.Errorf("mesh resource name and namespace must be specified")
}
if opts.Metadata.Namespace == "" || opts.Metadata.Name == "" {
return fmt.Errorf("upstream name and namespace must be specified")
}
// Check validity of mesh resource
if !opts.Interactive {
meshClient := clients.MustMeshClient()
meshRef := opts.EditUpstream.MtlsMesh
_, err := meshClient.Read(meshRef.Namespace, meshRef.Name, skclients.ReadOpts{Ctx: opts.Ctx})
if err != nil {
return errors.Wrapf(err, "unable to find mesh %s.%s", meshRef.Namespace, meshRef.Name)
}
}
return nil
}