Extend envoy to support resource translations
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
package {{ .Package }}
|
||||
|
||||
{{ template "header-gentext.tpl" }}
|
||||
{{ template "header-definitions.tpl" . }}
|
||||
|
||||
import (
|
||||
systemTypes "github.com/cortezaproject/corteza-server/system/types"
|
||||
{{- range .Imports }}
|
||||
{{ . }}
|
||||
{{- end }}
|
||||
)
|
||||
|
||||
{{- range .Def }}
|
||||
{{ $Component := .Component }}
|
||||
{{ $Resource := .Resource }}
|
||||
{{ $GoType := printf "types.%s" .Resource }}
|
||||
func (r *{{export $Component}}{{$Resource}}) EncodeTranslations() ([]*ResourceTranslation, error) {
|
||||
out := make([]*ResourceTranslation, 0, 10)
|
||||
|
||||
rr := r.Res.EncodeTranslations()
|
||||
rr.SetLanguage(defaultLanguage)
|
||||
res, ref, pp := r.ResourceTranslationParts()
|
||||
out = append(out, NewResourceTranslation(systemTypes.FromLocale(rr), res, ref, pp...))
|
||||
{{ if .Locale.Extended }}
|
||||
tmp, err := r.encodeTranslations()
|
||||
return append(out, tmp...), err
|
||||
{{ else }}
|
||||
return out, nil
|
||||
{{- end }}
|
||||
}
|
||||
{{- end }}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
package {{ .Package }}
|
||||
|
||||
{{ template "header-gentext.tpl" }}
|
||||
{{ template "header-definitions.tpl" . }}
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
{{- range .Imports }}
|
||||
{{ . }}
|
||||
{{- end }}
|
||||
)
|
||||
|
||||
|
||||
// Parse generates resource setting logic for each resource
|
||||
//
|
||||
// Resources with "envoy: false" are skipped
|
||||
//
|
||||
// This function is auto-generated
|
||||
func ParseResourceTranslation(res string) (string, *Ref, []*Ref, error) {
|
||||
if res == "" {
|
||||
return "", nil, nil, fmt.Errorf("empty resource")
|
||||
}
|
||||
|
||||
sp := "/"
|
||||
|
||||
if strings.Index(res, "corteza::") == 0 {
|
||||
res = res[9:]
|
||||
}
|
||||
|
||||
res = strings.TrimSpace(res)
|
||||
res = strings.TrimRight(res, sp)
|
||||
rr := strings.Split(res, sp)
|
||||
|
||||
// only service defined (corteza::system, corteza::compose, ...)
|
||||
if len(rr) == 1 {
|
||||
return "", nil, nil, fmt.Errorf("only service defined: %s", res)
|
||||
}
|
||||
|
||||
// full thing
|
||||
resourceType, path := rr[0], rr[1:]
|
||||
for p := 1; p < len(path); p++ {
|
||||
if path[p] == "*" {
|
||||
return "", nil, nil, fmt.Errorf("path wildcard not allowed for locale resources: '%s'", res)
|
||||
}
|
||||
}
|
||||
|
||||
// make the resource provide the slice of parent resources we should nest under
|
||||
switch resourceType {
|
||||
{{- range .Def }}
|
||||
case {{ unexport .Component "types" }}.{{ export .Resource }}ResourceTranslationType:
|
||||
if len(path) != {{ len .Locale.Resource.References }} {
|
||||
return "", nil, nil, fmt.Errorf("expecting {{ len .Locale.Resource.References }} reference components in path, got %d", len(path))
|
||||
}
|
||||
{{- if gt (len .Locale.Resource.References) 0 }}
|
||||
ref, pp, err := {{ export .Component .Resource }}ResourceTranslationReferences(
|
||||
{{- range $i, $r := .Locale.Resource.References }}
|
||||
// {{ unexport $r.Resource }}
|
||||
path[{{ $i }}],
|
||||
{{ end }}
|
||||
)
|
||||
return {{ unexport .Component "types" }}.{{ export .Resource }}ResourceTranslationType, ref, pp, err
|
||||
{{ else }}
|
||||
|
||||
// Component resource, no path
|
||||
return {{ unexport .Component "types" }}.{{ export .Resource }}ResourceTranslationType, nil, nil, nil
|
||||
{{- end }}
|
||||
{{- end}}
|
||||
}
|
||||
|
||||
// return unhandled resource as-is
|
||||
return resourceType, nil, nil, nil
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package {{ .Package }}
|
||||
|
||||
{{ template "header-gentext.tpl" }}
|
||||
{{ template "header-definitions.tpl" . }}
|
||||
|
||||
import (
|
||||
{{- range .Imports }}
|
||||
{{ . }}
|
||||
{{- end }}
|
||||
)
|
||||
|
||||
{{- range .Def }}
|
||||
{{- if .Locale }}
|
||||
{{- if gt (len .Locale.Resource.References) 0 }}
|
||||
// {{ export .Component .Resource }}ResourceTranslationReferences generates Locale references
|
||||
//
|
||||
// Resources with "envoy: false" are skipped
|
||||
//
|
||||
// This function is auto-generated
|
||||
func {{ export .Component .Resource }}ResourceTranslationReferences({{- range .Locale.Resource.References }}{{ unexport .Resource }} string, {{- end }}) (res *Ref, pp []*Ref, err error) {
|
||||
{{- range .Locale.Resource.References }}
|
||||
{{- if eq .Field "ID" }}
|
||||
res = &Ref{ResourceType: types.{{ export .Resource }}ResourceType, Identifiers: MakeIdentifiers({{ unexport .Resource }})}
|
||||
{{- else }}
|
||||
pp = append(pp, &Ref{ResourceType: types.{{ export .Resource }}ResourceType, Identifiers: MakeIdentifiers({{ unexport .Resource }})})
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
return
|
||||
}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -13,6 +13,10 @@ func Envoy(t *template.Template, dd []*def.Document) error {
|
||||
return List{
|
||||
"resource rbac parse": envoyResourceRbacUnmarshal,
|
||||
"resource rbac references": envoyResourceRbacReferences,
|
||||
|
||||
"resource translation": envoyResourceTranslation,
|
||||
"resource translation parse": envoyResourceTranslationUnmarshal,
|
||||
"resource translation references": envoyResourceTranslationReferences,
|
||||
}.Generate(t, dd)
|
||||
}
|
||||
|
||||
@@ -80,3 +84,85 @@ func envoyResourceRbacReferences(t *template.Template, dd []*def.Document) (err
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func envoyResourceTranslation(t *template.Template, dd []*def.Document) (err error) {
|
||||
const (
|
||||
templateName = "envoy/resource-resource_translation.go.tpl"
|
||||
outputPathTpl = "pkg/envoy/resource/resource_translation.gen.go"
|
||||
)
|
||||
|
||||
dd = filter(dd, func(d *def.Document) bool { return d.Envoy && d.Locale != nil })
|
||||
|
||||
// build list of component type imports
|
||||
ctImports := make([]string, 0)
|
||||
|
||||
w := tpl.Wrap{
|
||||
Package: "resource",
|
||||
Def: dd,
|
||||
Imports: append(collectImports(dd...), ctImports...),
|
||||
}
|
||||
|
||||
err = tpl.GoTemplate(outputPathTpl, t.Lookup(templateName), w)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func envoyResourceTranslationUnmarshal(t *template.Template, dd []*def.Document) (err error) {
|
||||
const (
|
||||
templateName = "envoy/resource-resource_translation_parse.go.tpl"
|
||||
outputPathTpl = "pkg/envoy/resource/resource_translation_parse.gen.go"
|
||||
)
|
||||
|
||||
dd = filter(dd, func(d *def.Document) bool { return d.Envoy && d.Locale != nil })
|
||||
|
||||
// build list of component type imports
|
||||
ctImports := make([]string, 0)
|
||||
for _, d := range dd {
|
||||
imp := d.Component + "Types " + cImport(d.Component, "types")
|
||||
if !slice.HasString(ctImports, imp) {
|
||||
ctImports = append(ctImports, imp)
|
||||
}
|
||||
}
|
||||
|
||||
w := tpl.Wrap{
|
||||
Package: "resource",
|
||||
Def: dd,
|
||||
Imports: append(collectImports(dd...), ctImports...),
|
||||
}
|
||||
|
||||
err = tpl.GoTemplate(outputPathTpl, t.Lookup(templateName), w)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func envoyResourceTranslationReferences(t *template.Template, dd []*def.Document) (err error) {
|
||||
const (
|
||||
templateName = "envoy/resource-resource_translation_references.go.tpl"
|
||||
outputPathTpl = "pkg/envoy/resource/resource_translation_references_%s.gen.go"
|
||||
)
|
||||
|
||||
dd = filter(dd, func(d *def.Document) bool { return d.Envoy && d.Locale != nil })
|
||||
|
||||
for component, perComponent := range partByComponent(dd) {
|
||||
|
||||
w := tpl.Wrap{
|
||||
Package: "resource",
|
||||
Component: component,
|
||||
Def: perComponent,
|
||||
Imports: append(collectImports(perComponent...), cImport(component, "types")),
|
||||
}
|
||||
|
||||
err = tpl.GoTemplate(fmt.Sprintf(outputPathTpl, component), t.Lookup(templateName), w)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user