Migrate codegen for locale to CUE
This commit is contained in:
+10
-4
@@ -1,10 +1,16 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"github.com/cortezaproject/corteza-server/codegen/schema"
|
||||
"github.com/cortezaproject/corteza-server/codegen/schema"
|
||||
)
|
||||
|
||||
all: [...schema.#codegen] &
|
||||
rbacAccessControl +
|
||||
rbacTypes +
|
||||
// List of all codegen jobs for the entire platform
|
||||
//
|
||||
// How to run it?
|
||||
// @todo when this gets into
|
||||
// cue eval codegen/*.cue --out json -e platform | go run codegen/tool/*.go -v
|
||||
platform: [...schema.#codegen] &
|
||||
rbacAccessControl+
|
||||
rbacTypes+
|
||||
localeTypes+
|
||||
[] // placeholder
|
||||
|
||||
@@ -0,0 +1,206 @@
|
||||
package {{ .package }}
|
||||
|
||||
{{ template "gocode/header-gentext.tpl" }}
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
{{- range .imports }}
|
||||
{{ . }}
|
||||
{{- end }}
|
||||
"github.com/cortezaproject/corteza-server/pkg/actionlog"
|
||||
intAuth "github.com/cortezaproject/corteza-server/pkg/auth"
|
||||
"github.com/cortezaproject/corteza-server/pkg/errors"
|
||||
"github.com/cortezaproject/corteza-server/pkg/locale"
|
||||
"github.com/cortezaproject/corteza-server/pkg/options"
|
||||
"github.com/cortezaproject/corteza-server/store"
|
||||
systemTypes "github.com/cortezaproject/corteza-server/system/types"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
type (
|
||||
localeAccessControl interface {
|
||||
CanManageResourceTranslations(ctx context.Context) bool
|
||||
}
|
||||
|
||||
resourceTranslationsManager struct {
|
||||
actionlog actionlog.Recorder
|
||||
locale locale.Resource
|
||||
store store.Storer
|
||||
ac localeAccessController
|
||||
}
|
||||
|
||||
localeAccessController interface {
|
||||
CanManageResourceTranslations(context.Context) bool
|
||||
}
|
||||
|
||||
ResourceTranslationsManagerService interface {
|
||||
{{- range .resources }}
|
||||
{{ .expIdent }}(ctx context.Context, {{ range .references }}{{ . }} uint64, {{ end }}) (locale.ResourceTranslationSet, error)
|
||||
{{- end }}
|
||||
|
||||
Upsert(context.Context, locale.ResourceTranslationSet) error
|
||||
Locale() locale.Resource
|
||||
}
|
||||
)
|
||||
|
||||
var ErrNotAllowedToManageResourceTranslations = errors.Unauthorized("not allowed to manage resource translations")
|
||||
|
||||
func ResourceTranslationsManager(ls locale.Resource) *resourceTranslationsManager {
|
||||
return &resourceTranslationsManager{
|
||||
actionlog: DefaultActionlog,
|
||||
store: DefaultStore,
|
||||
ac: DefaultAccessControl,
|
||||
locale: ls,
|
||||
}
|
||||
}
|
||||
|
||||
func (svc resourceTranslationsManager) Upsert(ctx context.Context, rr locale.ResourceTranslationSet) (err error) {
|
||||
// User is allowed to manage resource translations when:
|
||||
// - managed resource translation strings are all for default language
|
||||
// or
|
||||
// - user is allowed to manage resource translations
|
||||
if rr.ContainsForeign(svc.Locale().Default().Tag) {
|
||||
if !svc.ac.CanManageResourceTranslations(ctx) {
|
||||
return ErrNotAllowedToManageResourceTranslations
|
||||
}
|
||||
}
|
||||
|
||||
for _, r := range rr {
|
||||
r.Msg = locale.SanitizeMessage(r.Msg)
|
||||
}
|
||||
|
||||
// @todo validation
|
||||
|
||||
me := intAuth.GetIdentityFromContext(ctx)
|
||||
|
||||
// - group by resource
|
||||
localeByRes := make(map[string]locale.ResourceTranslationSet)
|
||||
for _, r := range rr {
|
||||
localeByRes[r.Resource] = append(localeByRes[r.Resource], r)
|
||||
}
|
||||
|
||||
// - for each resource, fetch the current state
|
||||
sysLocale := make(systemTypes.ResourceTranslationSet, 0, len(rr))
|
||||
for res, rr := range localeByRes {
|
||||
current, _, err := store.SearchResourceTranslations(ctx, svc.store, systemTypes.ResourceTranslationFilter{
|
||||
Resource: res,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// get deltas and prepare upsert accordingly
|
||||
aux := current.New(rr)
|
||||
aux.Walk(func(cc *systemTypes.ResourceTranslation) error {
|
||||
cc.ID = nextID()
|
||||
cc.CreatedAt = *now()
|
||||
cc.CreatedBy = me.Identity()
|
||||
|
||||
return nil
|
||||
})
|
||||
sysLocale = append(sysLocale, aux...)
|
||||
|
||||
aux = current.Old(rr)
|
||||
_ = aux.Walk(func(cc *systemTypes.ResourceTranslation) error {
|
||||
cc.UpdatedAt = now()
|
||||
cc.UpdatedBy = me.Identity()
|
||||
return nil
|
||||
})
|
||||
sysLocale = append(sysLocale, aux...)
|
||||
}
|
||||
|
||||
err = store.UpsertResourceTranslation(ctx, svc.store, sysLocale...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Reload ALL resource translations
|
||||
// @todo we could probably do this more selectively and refresh only updated resources?
|
||||
_ = locale.Global().ReloadResourceTranslations(ctx)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (svc resourceTranslationsManager) Locale() locale.Resource {
|
||||
return svc.locale
|
||||
}
|
||||
|
||||
{{- range .resources }}
|
||||
|
||||
func (svc resourceTranslationsManager) {{ .expIdent }}(ctx context.Context, {{ range .references }}{{ . }} uint64, {{ end }}) (locale.ResourceTranslationSet, error) {
|
||||
var (
|
||||
err error
|
||||
out locale.ResourceTranslationSet
|
||||
res *types.{{ .expIdent }}
|
||||
k types.LocaleKey
|
||||
)
|
||||
|
||||
res, err = svc.load{{ .expIdent }}(ctx, svc.store, {{ range .references }}{{ . }}, {{ end }})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, tag := range svc.locale.Tags() {
|
||||
{{- range .keys}}
|
||||
{{- if not .customHandler }}
|
||||
k = types.{{ .struct }}
|
||||
out = append(out, &locale.ResourceTranslation{
|
||||
Resource: res.ResourceTranslation(),
|
||||
Lang: tag.String(),
|
||||
Key: k.Path,
|
||||
Msg: svc.locale.TResourceFor(tag, res.ResourceTranslation(), k.Path),
|
||||
})
|
||||
{{ end }}
|
||||
{{- end}}
|
||||
}
|
||||
|
||||
{{ if .extended }}
|
||||
tmp, err := svc.{{ .ident }}Extended(ctx, res)
|
||||
return append(out, tmp...), err
|
||||
{{- else }}
|
||||
return out, nil
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
{{- end }}
|
||||
|
||||
func updateTranslations(ctx context.Context, ac localeAccessControl, lsvc ResourceTranslationsManagerService, tt ...*locale.ResourceTranslation) error {
|
||||
if lsvc == nil || lsvc.Locale() == nil || lsvc.Locale().Default() == nil {
|
||||
// gracefully handle partial initializations
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
// assuming options will not change after start
|
||||
contentLang = lsvc.Locale().Default().Tag
|
||||
)
|
||||
|
||||
if options.Locale().ResourceTranslationsEnabled {
|
||||
contentLang = locale.GetContentLanguageFromContext(ctx)
|
||||
// Resource translations enabled
|
||||
if contentLang == language.Und {
|
||||
// If no content-language meta (HTTP header) info was
|
||||
// used, do not run update translations - we do not know
|
||||
// what is the language that we're sending in
|
||||
return nil
|
||||
}
|
||||
|
||||
if !lsvc.Locale().SupportedLang(contentLang) {
|
||||
// unsupported language
|
||||
return errors.InvalidData("unsupported language")
|
||||
}
|
||||
|
||||
if !ac.CanManageResourceTranslations(ctx) {
|
||||
return errors.Unauthorized("not allowed to manage resource translations")
|
||||
}
|
||||
}
|
||||
|
||||
locale.ResourceTranslationSet(tt).SetLanguage(contentLang)
|
||||
if err := lsvc.Upsert(ctx, tt); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
package {{ .package }}
|
||||
|
||||
{{ template "gocode/header-gentext.tpl" }}
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"github.com/cortezaproject/corteza-server/pkg/locale"
|
||||
)
|
||||
|
||||
type (
|
||||
LocaleKey struct {
|
||||
Name string
|
||||
Resource string
|
||||
Path string
|
||||
CustomHandler string
|
||||
}
|
||||
)
|
||||
|
||||
// Types and stuff
|
||||
const (
|
||||
{{- range .resources }}
|
||||
{{ .const }} = "{{ .type }}"
|
||||
{{- end }}
|
||||
)
|
||||
|
||||
var (
|
||||
// @todo can we remove LocaleKey struct for string constant?
|
||||
{{- range .resources }}
|
||||
{{- range .keys }}
|
||||
{{ .struct }} = LocaleKey{ Path: {{ printf "%q" .path }} }
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
)
|
||||
|
||||
{{- range .resources }}
|
||||
|
||||
// ResourceTranslation returns string representation of Locale resource for {{ .expIdent }} by calling {{ .expIdent }}ResourceTranslation fn
|
||||
//
|
||||
// Locale resource is in "{{ .type }}/..." format
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (r {{ .expIdent }}) ResourceTranslation() string {
|
||||
return {{ .expIdent }}ResourceTranslation({{ if .references }}{{ range .references }}r.{{ . }},{{ end }}{{ end }})
|
||||
}
|
||||
|
||||
// {{ .expIdent }}ResourceTranslation returns string representation of Locale resource for {{ .expIdent }}
|
||||
//
|
||||
// Locale resource is in the {{ .type }}/{{- if .references }}...{{ end }} format
|
||||
//
|
||||
// This function is auto-generated
|
||||
func {{ .expIdent }}ResourceTranslation({{ if .references }}{{ range .references }}{{ . }} uint64,{{ end }}{{ end }}) string {
|
||||
{{- if .references }}
|
||||
cpts := []interface{{"{}"}}{
|
||||
{{ .expIdent }}ResourceTranslationType,
|
||||
{{- range .references }}
|
||||
strconv.FormatUint({{ . }}, 10),
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
return fmt.Sprintf({{ .expIdent }}ResourceTranslationTpl(), cpts...)
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
func {{ .expIdent }}ResourceTranslationTpl() string {
|
||||
{{- if .references }}
|
||||
return "%s
|
||||
{{- range .references }}/%s{{- end }}"
|
||||
|
||||
{{- else }}
|
||||
return "%s"
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
func (r *{{ .expIdent }}) DecodeTranslations(tt locale.ResourceTranslationIndex) {
|
||||
var aux *locale.ResourceTranslation
|
||||
|
||||
{{- range .keys }}
|
||||
{{ if .decodeFunc }}
|
||||
{{ if not .extended }}
|
||||
r.{{ .decodeFunc }}(tt)
|
||||
{{- end}}
|
||||
{{ else }}
|
||||
if aux = tt.FindByKey({{ .struct }}.Path); aux != nil {
|
||||
r.{{ .fieldPath }} = aux.Msg
|
||||
}
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
|
||||
{{- if .extended }}
|
||||
r.decodeTranslations(tt)
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
func (r *{{ .expIdent }}) EncodeTranslations() (out locale.ResourceTranslationSet) {
|
||||
out = locale.ResourceTranslationSet{}
|
||||
{{- range .keys }}
|
||||
{{ if .encodeFunc }}
|
||||
{{ if not .extended }}
|
||||
out = append(out, r.{{ .encodeFunc }}()...)
|
||||
{{- end}}
|
||||
{{ else }}
|
||||
if r.{{ .fieldPath }} != "" {
|
||||
out = append(out, &locale.ResourceTranslation{
|
||||
Resource: r.ResourceTranslation(),
|
||||
Key: {{ .struct }}.Path,
|
||||
Msg: locale.SanitizeMessage(r.{{ .fieldPath }}),
|
||||
})
|
||||
}
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
|
||||
{{- if .extended }}
|
||||
out = append(out, r.encodeTranslations()...)
|
||||
{{- end }}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
{{- end }}
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/pkg/rbac"
|
||||
"github.com/cortezaproject/corteza-server/pkg/actionlog"
|
||||
{{- range .imports }}
|
||||
"{{ . }}"
|
||||
{{ . }}
|
||||
{{- end }}
|
||||
)
|
||||
|
||||
@@ -57,7 +57,7 @@ func (svc accessControl) List() (out []map[string]string) {
|
||||
{{- range .operations }}
|
||||
{
|
||||
"type": {{ .const }},
|
||||
"any": {{ .ctor }},
|
||||
"any": {{ .resFunc }}({{ range .references }}0,{{ end }}),
|
||||
"op": {{ printf "%q" .op }},
|
||||
},
|
||||
{{- end }}
|
||||
|
||||
@@ -38,7 +38,7 @@ const (
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (r {{ .goType }}) RbacResource() string {
|
||||
return {{ .resFunc }}({{ if not .component }}{{ range .references }}r.{{ . }},{{ end }}{{ end }})
|
||||
return {{ .resFunc }}({{ if not .component }}{{ range .references }}r.{{ .refField }},{{ end }}{{ end }})
|
||||
}
|
||||
|
||||
// {{ .resFunc }} returns string representation of RBAC resource for {{ .goType }}
|
||||
@@ -46,12 +46,12 @@ func (r {{ .goType }}) RbacResource() string {
|
||||
// RBAC resource is in the {{ .type }}/{{- if .references }}...{{ end }} format
|
||||
//
|
||||
// This function is auto-generated
|
||||
func {{ .resFunc }}({{ if not .component }}{{ range .references }}{{ . }} uint64,{{ end }}{{ end }}) string {
|
||||
func {{ .resFunc }}({{ if not .component }}{{ range .references }}{{ .param }} uint64,{{ end }}{{ end }}) string {
|
||||
{{- if .references }}
|
||||
cpts := []interface{{"{}"}}{{"{"}}{{ .goType }}ResourceType{{"}"}}
|
||||
{{- range .references }}
|
||||
if {{ . }} != 0 {
|
||||
cpts = append(cpts, strconv.FormatUint({{ . }}, 10))
|
||||
if {{ .param }} != 0 {
|
||||
cpts = append(cpts, strconv.FormatUint({{ .param }}, 10))
|
||||
} else {
|
||||
cpts = append(cpts, "*")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"github.com/cortezaproject/corteza-server/app"
|
||||
"github.com/cortezaproject/corteza-server/codegen/schema"
|
||||
"strings"
|
||||
)
|
||||
|
||||
localeService:
|
||||
[...schema.#codegen] &
|
||||
[
|
||||
// wrapped with additional for loop to trim out templates with empty types list
|
||||
for tpl in [
|
||||
for cmp in app.corteza.components {
|
||||
template: "gocode/locale/service.go.tpl"
|
||||
output: "\(cmp.ident)/service/locale.gen.go"
|
||||
payload: {
|
||||
package: "service"
|
||||
imports: [
|
||||
"\"github.com/cortezaproject/corteza-server/\(cmp.ident)/types\"",
|
||||
]
|
||||
|
||||
resources: [
|
||||
for res in cmp.resources if (res.locale != _|_) if (!res.locale.skipSvc) {
|
||||
expIdent: res.expIdent
|
||||
ident: res.ident
|
||||
|
||||
references: [ for field in res.locale.resource.references {strings.ToTitle(field)}]
|
||||
|
||||
extended: res.locale.extended
|
||||
|
||||
keys: [ for key in res.locale.keys if key.handlerFunc == _|_ {
|
||||
struct: key.struct
|
||||
|
||||
extended: extended
|
||||
customHandler: key.customHandler
|
||||
if key.serviceFunc != _|_ {serviceFunc: key.serviceFunc}
|
||||
}]
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
// skip empty type lists
|
||||
] if len(tpl.payload.resources) > 0 {tpl}]
|
||||
@@ -0,0 +1,55 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"github.com/cortezaproject/corteza-server/app"
|
||||
"github.com/cortezaproject/corteza-server/codegen/schema"
|
||||
"strings"
|
||||
)
|
||||
|
||||
localeTypes:
|
||||
[...schema.#codegen] &
|
||||
[
|
||||
// wrapped with additional for loop to trim out templates with empty types list
|
||||
for tpl in [
|
||||
for cmp in app.corteza.components {
|
||||
template: "gocode/locale/types.go.tpl"
|
||||
output: "\(cmp.ident)/types/locale.gen.go"
|
||||
payload: {
|
||||
package: "types"
|
||||
|
||||
resources: [
|
||||
for res in cmp.resources if res.locale != _|_ {
|
||||
expIdent: res.expIdent
|
||||
const: res.locale.resource.const
|
||||
type: res.locale.resource.type
|
||||
|
||||
references: [ for field in res.locale.resource.references {strings.ToTitle(field)}]
|
||||
|
||||
extended: res.locale.extended
|
||||
|
||||
keys: [ for key in res.locale.keys if key.handlerFunc == _|_ {
|
||||
struct: key.struct
|
||||
field: strings.ToTitle(key.name)
|
||||
|
||||
path: strings.Join([ for p in key.expandedPath {
|
||||
if p.var {"{{\(p.part)}}"}
|
||||
if !p.var {p.part}
|
||||
}], ".")
|
||||
|
||||
if !key.customHandler {
|
||||
fieldPath: strings.Join([ for p in key.expandedPath {
|
||||
strings.ToTitle(p.part)
|
||||
}], ".")
|
||||
}
|
||||
|
||||
"extended": extended
|
||||
if key.decodeFunc != _|_ {decodeFunc: key.decodeFunc}
|
||||
if key.encodeFunc != _|_ {encodeFunc: key.encodeFunc}
|
||||
|
||||
}]
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
// skip empty type lists
|
||||
] if len(tpl.payload.resources) > 0 {tpl}]
|
||||
@@ -1,8 +1,8 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"github.com/cortezaproject/corteza-server/codegen/schema"
|
||||
"github.com/cortezaproject/corteza-server/app"
|
||||
"github.com/cortezaproject/corteza-server/codegen/schema"
|
||||
"github.com/cortezaproject/corteza-server/app"
|
||||
)
|
||||
|
||||
rbacAccessControl:
|
||||
@@ -12,47 +12,53 @@ rbacAccessControl:
|
||||
template: "gocode/rbac/access_control.go.tpl"
|
||||
output: "\(cmp.ident)/service/access_control.gen.go"
|
||||
payload: {
|
||||
imports: [
|
||||
"github.com/cortezaproject/corteza-server/\(cmp.ident)/types",
|
||||
]
|
||||
package: "service"
|
||||
imports: [
|
||||
"\"github.com/cortezaproject/corteza-server/\(cmp.ident)/types\"",
|
||||
]
|
||||
|
||||
// All possible RBAC operations on component and resources
|
||||
// flattened
|
||||
operations: [
|
||||
for res in cmp.resources for op in res.rbac.operations {
|
||||
"op": op.handle
|
||||
"const": "types.\(res.expIdent)ResourceType"
|
||||
"ctor": "types.\(res.expIdent)RbacResource(\(len(res.rbac.resource.references)*"0,"))"
|
||||
"goType": res.goType
|
||||
"description": op.description
|
||||
"checkFuncName": op.checkFuncName
|
||||
"op": op.handle
|
||||
const: "types.\(res.expIdent)ResourceType"
|
||||
resFunc: "types.\(res.expIdent)RbacResource"
|
||||
goType: "types.\(res.expIdent)"
|
||||
description: op.description
|
||||
checkFuncName: op.checkFuncName
|
||||
|
||||
if len(res.parents) > 0 {
|
||||
references: [ for p in res.parents {p}, {param: "id", refField: "ID"}]
|
||||
}
|
||||
},
|
||||
for op in cmp.rbac.operations {
|
||||
"op": op.handle
|
||||
"const": "types.ComponentResourceType"
|
||||
"ctor": "types.ComponentRbacResource()"
|
||||
"goType": "types.Component"
|
||||
"description": op.description
|
||||
"checkFuncName": op.checkFuncName
|
||||
"component": true
|
||||
"op": op.handle
|
||||
const: "types.ComponentResourceType"
|
||||
resFunc: "types.ComponentRbacResource"
|
||||
goType: "types.Component"
|
||||
description: op.description
|
||||
checkFuncName: op.checkFuncName
|
||||
component: true
|
||||
},
|
||||
]
|
||||
|
||||
// Operation/resource validators, grouped by resource
|
||||
validation: [
|
||||
for res in cmp.resources {
|
||||
"label": res.ident
|
||||
"const": "types.\(res.expIdent)ResourceType"
|
||||
"funcName": "rbac\(res.expIdent)ResourceValidator"
|
||||
"references": res.rbac.resource.references
|
||||
"operations": [ for op in res.rbac.operations {op.handle}]
|
||||
label: res.ident
|
||||
const: "types.\(res.expIdent)ResourceType"
|
||||
funcName: "rbac\(res.expIdent)ResourceValidator"
|
||||
if len(res.parents) > 0 {
|
||||
references: [ for p in res.parents {p.refField}, "ID"]
|
||||
}
|
||||
operations: [ for op in res.rbac.operations {op.handle}]
|
||||
},
|
||||
{
|
||||
"label": "\(cmp.ident) component"
|
||||
"const": "types.ComponentResourceType"
|
||||
"funcName": "rbacComponentResourceValidator"
|
||||
"operations": [ for op in cmp.rbac.operations {op.handle}]
|
||||
label: "\(cmp.ident) component"
|
||||
const: "types.ComponentResourceType"
|
||||
funcName: "rbacComponentResourceValidator"
|
||||
operations: [ for op in cmp.rbac.operations {op.handle}]
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
+16
-15
@@ -3,7 +3,6 @@ package codegen
|
||||
import (
|
||||
"github.com/cortezaproject/corteza-server/app"
|
||||
"github.com/cortezaproject/corteza-server/codegen/schema"
|
||||
"strings"
|
||||
)
|
||||
|
||||
rbacTypes:
|
||||
@@ -19,23 +18,25 @@ rbacTypes:
|
||||
// Operation/resource validators, grouped by resource
|
||||
types: [
|
||||
for res in cmp.resources {
|
||||
"const": "\(res.expIdent)ResourceType"
|
||||
"type": res.rbac.resource.type
|
||||
"resFunc": "\(res.expIdent)RbacResource"
|
||||
"tplFunc": "\(res.expIdent)RbacResourceTpl"
|
||||
"attFunc": "\(res.expIdent)RbacAttributes"
|
||||
"goType": res.expIdent
|
||||
const: "\(res.expIdent)ResourceType"
|
||||
type: res.fqrn
|
||||
resFunc: "\(res.expIdent)RbacResource"
|
||||
tplFunc: "\(res.expIdent)RbacResourceTpl"
|
||||
attFunc: "\(res.expIdent)RbacAttributes"
|
||||
goType: res.expIdent
|
||||
|
||||
"references": [ for field in res.rbac.resource.references { strings.ToTitle(field) } ]
|
||||
if len(res.parents) > 0 {
|
||||
references: [ for p in res.parents {p}, {param: "id", refField: "ID"}]
|
||||
}
|
||||
},
|
||||
{
|
||||
"const": "ComponentResourceType"
|
||||
"type": cmp.rbac.resource.type
|
||||
"resFunc": "ComponentRbacResource"
|
||||
"tplFunc": "ComponentRbacResourceTpl"
|
||||
"attFunc": "ComponentRbacAttributes"
|
||||
"goType": "Component"
|
||||
"component": true
|
||||
const: "ComponentResourceType"
|
||||
type: cmp.fqrn
|
||||
resFunc: "ComponentRbacResource"
|
||||
tplFunc: "ComponentRbacResourceTpl"
|
||||
attFunc: "ComponentRbacAttributes"
|
||||
goType: "Component"
|
||||
component: true
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user