Newer
Older
"path/filepath"
"strings"
spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound"
"github.com/openconfig/ygot/genutil"
"github.com/openconfig/ygot/ygen"
log "github.com/sirupsen/logrus"
"github.com/spf13/viper"
codes "google.golang.org/grpc/codes"
"google.golang.org/grpc/peer"
status "google.golang.org/grpc/status"
)
// write takes a ygen.Generatedcode struct and writes the Go code
// snippets contained within it to the io.Writer, w, provided as an argument.
// The output includes a package header which is generated.
func write(ctx context.Context, code *ygen.GeneratedGoCode, path string, sbiType spb.Type) error {
if err := os.Mkdir(path, 0755); err != nil {
if err.(*fs.PathError).Err.Error() != "file exists" {
return err
}
}
switch sbiType {
case spb.Type_PLUGIN:
return writePlugin(code, path)
case spb.Type_CONTAINERISED:
default:
return fmt.Errorf("invalid sbi type provided")
}
}
func removePort(ip net.Addr) (string, error) {
addr, ok := ip.(*net.TCPAddr)
if !ok {
return "", fmt.Errorf("invalid type assertion")
}
return addr.IP.String(), nil
}
func writeCsbi(ctx context.Context, code *ygen.GeneratedGoCode, path string) error {
p, ok := peer.FromContext(ctx)
if !ok || p == nil {
e := fmt.Errorf("no peer information in context %v", ctx)
log.Error(e)
return status.Errorf(codes.Aborted, "%v", e)
}
controller, err := removePort(p.Addr)
if err != nil {
log.Error(err)
return status.Errorf(codes.Aborted, "%v", err)
}
writerViper.Set("controller", net.JoinHostPort(controller, "55055"))
writerViper.Set("target", target)
if err := writerViper.WriteConfigAs(filepath.Join(path, ".csbi.toml")); err != nil {
return err
}
if err := copyFile(path, "csbi.go"); err != nil {
return err
}
if err := copyFile(path, "go.mod"); err != nil {
return err
}
if err := copyFile(path, "go.sum"); err != nil {
return err
}
}
func writePlugin(code *ygen.GeneratedGoCode, path string) error {
err := writeCode(path, code)
if err != nil {
return err
}
return writeGoMod(path)
dstFile := filepath.Join(path, filename)
cmd := exec.Command("cp", srcFile, dstFile)
cmd.Stderr = &stderr
err := cmd.Run()
return err
}
log.WithFields(log.Fields{
"source file": srcFile,
"dst file": dstFile,
return nil
}
func writeCode(path string, code *ygen.GeneratedGoCode) error {
code.CommonHeader = strings.TrimSuffix(code.CommonHeader, ")\n")
code.CommonHeader = code.CommonHeader + pluginImportAmendmend
code.Structs = append(code.Structs, pluginStruct)
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
file := filepath.Join(path, "gostructs.go")
generatedCode := genutil.OpenFile(file)
defer genutil.SyncFile(generatedCode)
// Write the package header to the supplier writer.
fmt.Fprint(generatedCode, code.CommonHeader)
fmt.Fprint(generatedCode, code.OneOffHeader)
// Write the returned Go code out. First the Structs - which is the struct
// definitions for the generated YANG entity, followed by the enumerations.
for _, snippet := range code.Structs {
fmt.Fprintln(generatedCode, snippet)
}
for _, snippet := range code.Enums {
fmt.Fprintln(generatedCode, snippet)
}
// Write the generated enumeration map out.
fmt.Fprintln(generatedCode, code.EnumMap)
// Write the schema out if it was received.
if len(code.JSONSchemaCode) > 0 {
fmt.Fprintln(generatedCode, code.JSONSchemaCode)
}
if len(code.EnumTypeMap) > 0 {
fmt.Fprintln(generatedCode, code.EnumTypeMap)
}
return nil
}
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
func writeGoMod(path string) error {
// Read dependencies from JSON file
deps, err := os.ReadFile(filepath.Join("resources", "plugin_deps.json"))
if err != nil {
return err
}
module := GoMod{}
if err := json.Unmarshal(deps, &module); err != nil {
return err
}
// Create go.mod in destination directory and write template
file := filepath.Join(path, "go.mod")
goMod, err := os.OpenFile(file, os.O_CREATE|os.O_WRONLY, 0755)
if err != nil {
return err
}
defer goMod.Sync()
templater := template.New("goMod").Delims("<<", ">>")
_, err = templater.Parse(pluginGoModTemplate)
if err != nil {
return err
}
return templater.Execute(goMod, module)
}