This repository has been archived by the owner on Aug 12, 2023. It is now read-only.
/
envoy.go
146 lines (120 loc) · 5.01 KB
/
envoy.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package proto
import (
"bufio"
"encoding/base64"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path"
"path/filepath"
"github.com/Clink-n-Clank/Eitri/internal/handler"
"github.com/Clink-n-Clank/Eitri/internal/log"
"github.com/spf13/cobra"
)
const (
envoyFlagSource = "source"
envoyFlagProto = "proto"
envoyFlagOutDesc = "out"
envoyFlagIsEncoded = "isBase64Encoded"
envoyFlagDefaultVal = ""
)
// GenerateEnvoyTranscodingCMD represents the new command.
var GenerateEnvoyTranscodingCMD = &cobra.Command{
Use: "envoy",
Short: "Build Envoy: transcoder: gRPC-JSON transcoder in Base 64",
Long: "Build Envoy: Generates transcode from proto file to use filter which allows a RESTful JSON API client to send requests to Envoy for gRPC",
Example: "Eitri envoy --out envoy/descriptors/virtual_pos_definition.pb --proto workspace/services-interfaces/coopnorge/scanandpay/vpos/v1beta1/virtual_pos_api.proto --source workspace/services-interfaces --isBase64Encoded",
Run: runEnvoyTranscodingGen,
}
func init() {
GenerateEnvoyTranscodingCMD.PersistentFlags().String(envoyFlagSource, envoyFlagDefaultVal, "Source a root folder where proto files are stored")
GenerateEnvoyTranscodingCMD.PersistentFlags().String(envoyFlagProto, envoyFlagDefaultVal, "Proto file to convert to descriptor that must be used in Envoy")
GenerateEnvoyTranscodingCMD.PersistentFlags().String(envoyFlagOutDesc, envoyFlagDefaultVal, "Where proto description must be created")
GenerateEnvoyTranscodingCMD.PersistentFlags().Bool(envoyFlagIsEncoded, false, "Encode Envoy description to base 64 or not")
}
func runEnvoyTranscodingGen(c *cobra.Command, args []string) {
input := []string{"-I"}
if pErr := c.ParseFlags(args); pErr != nil {
log.PrintError(fmt.Sprintf("failed to parse envoy command flags, error: %s", pErr.Error()))
return
}
log.PrintInfo("Generating proto descriptor for envoy...")
currentFolder, cPathHasErr := handler.FindCurrentFolder()
if cPathHasErr {
log.PrintError("unable to resolve current directory path...")
return
}
protoDescriptionFileName := "proto.description"
protoDescriptionFileName, input = envoyCmdParseInput(c, protoDescriptionFileName, input, currentFolder)
fd := exec.Command("protoc", input...)
fd.Stdout = os.Stdout
fd.Stderr = os.Stderr
fd.Dir = "."
if err := fd.Run(); err != nil {
log.PrintError(fmt.Sprintf("failed to run protoc, error: %s", err.Error()))
return
}
isEncodedToBase64, _ := c.Flags().GetBool(envoyFlagIsEncoded)
if envoySaveToFile(c, currentFolder, protoDescriptionFileName, isEncodedToBase64) {
return
}
log.PrintInfo("Done...")
}
func envoyCmdParseInput(c *cobra.Command, protoDescriptionFileName string, input []string, currentFolder string) (string, []string) {
if v, _ := c.Flags().GetString(envoyFlagOutDesc); v != envoyFlagDefaultVal {
protoDescriptionFileName = filepath.Base(v)
}
if v, _ := c.Flags().GetString(envoyFlagSource); v != envoyFlagDefaultVal {
input = append(input, v)
} else {
input = append(input, currentFolder)
}
input = append(input, "--descriptor_set_out="+protoDescriptionFileName)
if v, _ := c.Flags().GetString(envoyFlagProto); v != envoyFlagDefaultVal {
input = append(input, "--include_imports")
input = append(input, v)
}
return protoDescriptionFileName, input
}
func envoySaveToFile(c *cobra.Command, pathToStoreFile, protoDescriptionFileName string, isEncodedToBase64 bool) (hasErr bool) {
log.PrintInfo("Saving envoy proto description...")
protoFile, protoFileErr := os.Open(path.Join(pathToStoreFile, protoDescriptionFileName))
if protoFileErr != nil {
log.PrintError(fmt.Sprintf("failed to open %s to read content, error: %s...", protoDescriptionFileName, protoFileErr.Error()))
return true
}
protoDescriptionContent, protoDescriptionContentErr := ioutil.ReadAll(bufio.NewReader(protoFile))
if protoDescriptionContentErr != nil {
log.PrintError("failed to read proto description content...")
}
fileContent := string(protoDescriptionContent)
if isEncodedToBase64 {
log.PrintInfo("Encoding to Base64...")
fileContent = base64.StdEncoding.EncodeToString(protoDescriptionContent)
}
if v, _ := c.Flags().GetString(envoyFlagOutDesc); v != envoyFlagDefaultVal {
pathToStoreFile = v
}
fileInfo, fileInfoErr := os.Stat(pathToStoreFile)
if fileInfoErr != nil {
log.PrintError(fmt.Sprintf(
"unable to resolve path to update or create file of envoy proto description, error: %s",
fileInfoErr.Error(),
))
return
}
if fileInfo.IsDir() {
if cErr := handler.CreateFile(pathToStoreFile, protoDescriptionFileName, fileContent); cErr != nil {
log.PrintError(fmt.Sprintf("unable to create proto description file (%s), err: %s...", protoDescriptionFileName, cErr.Error()))
return true
}
} else {
if wErr := handler.OverwriteToFile(pathToStoreFile, fileContent); wErr != nil {
log.PrintError(fmt.Sprintf("unable to overwirte proto description file (%s), err: %s...", protoDescriptionFileName, wErr.Error()))
return true
}
}
log.PrintInfo(fmt.Sprintf("Envoy proto description saved: %s", pathToStoreFile))
return false
}