chore: generate rbac resource types to typescript (#13975)

* chore: generate rbac resource types to typescript

The existing typesGenerated.ts cannot support this as the generator
only inspects the types, not the values. So traversing the value AST
would have to be added. The rbac gen is already used for the sdk,
this extends it to the typescript
This commit is contained in:
Steven Masley
2024-07-23 05:07:52 -10:00
committed by GitHub
parent b817c863ef
commit ecc356f5a9
5 changed files with 196 additions and 3 deletions

View File

@ -487,6 +487,7 @@ gen: \
site/src/api/typesGenerated.ts \ site/src/api/typesGenerated.ts \
coderd/rbac/object_gen.go \ coderd/rbac/object_gen.go \
codersdk/rbacresources_gen.go \ codersdk/rbacresources_gen.go \
site/src/api/rbacresources_gen.ts \
docs/admin/prometheus.md \ docs/admin/prometheus.md \
docs/cli.md \ docs/cli.md \
docs/admin/audit-logs.md \ docs/admin/audit-logs.md \
@ -518,6 +519,7 @@ gen/mark-fresh:
site/src/api/typesGenerated.ts \ site/src/api/typesGenerated.ts \
coderd/rbac/object_gen.go \ coderd/rbac/object_gen.go \
codersdk/rbacresources_gen.go \ codersdk/rbacresources_gen.go \
site/src/api/rbacresources_gen.ts \
docs/admin/prometheus.md \ docs/admin/prometheus.md \
docs/cli.md \ docs/cli.md \
docs/admin/audit-logs.md \ docs/admin/audit-logs.md \
@ -622,6 +624,10 @@ coderd/rbac/object_gen.go: scripts/rbacgen/rbacobject.gotmpl scripts/rbacgen/mai
codersdk/rbacresources_gen.go: scripts/rbacgen/codersdk.gotmpl scripts/rbacgen/main.go coderd/rbac/object.go coderd/rbac/policy/policy.go codersdk/rbacresources_gen.go: scripts/rbacgen/codersdk.gotmpl scripts/rbacgen/main.go coderd/rbac/object.go coderd/rbac/policy/policy.go
go run scripts/rbacgen/main.go codersdk > codersdk/rbacresources_gen.go go run scripts/rbacgen/main.go codersdk > codersdk/rbacresources_gen.go
site/src/api/rbacresources_gen.ts: scripts/rbacgen/codersdk.gotmpl scripts/rbacgen/main.go coderd/rbac/object.go coderd/rbac/policy/policy.go
go run scripts/rbacgen/main.go typescript > site/src/api/rbacresources_gen.ts
docs/admin/prometheus.md: scripts/metricsdocgen/main.go scripts/metricsdocgen/metrics docs/admin/prometheus.md: scripts/metricsdocgen/main.go scripts/metricsdocgen/metrics
go run scripts/metricsdocgen/main.go go run scripts/metricsdocgen/main.go
./scripts/pnpm_install.sh ./scripts/pnpm_install.sh

View File

@ -39,6 +39,10 @@ type ActionDefinition struct {
Description string Description string
} }
func (d ActionDefinition) String() string {
return d.Description
}
func actDef(description string) ActionDefinition { func actDef(description string) ActionDefinition {
return ActionDefinition{ return ActionDefinition{
Description: description, Description: description,

View File

@ -10,11 +10,11 @@ import (
"go/format" "go/format"
"go/parser" "go/parser"
"go/token" "go/token"
"html/template"
"log" "log"
"os" "os"
"slices" "slices"
"strings" "strings"
"text/template"
"golang.org/x/xerrors" "golang.org/x/xerrors"
@ -27,6 +27,9 @@ var rbacObjectTemplate string
//go:embed codersdk.gotmpl //go:embed codersdk.gotmpl
var codersdkTemplate string var codersdkTemplate string
//go:embed typescript.tstmpl
var typescriptTemplate string
func usage() { func usage() {
_, _ = fmt.Println("Usage: rbacgen <codersdk|rbac>") _, _ = fmt.Println("Usage: rbacgen <codersdk|rbac>")
_, _ = fmt.Println("Must choose a template target.") _, _ = fmt.Println("Must choose a template target.")
@ -43,6 +46,7 @@ func main() {
os.Exit(1) os.Exit(1)
} }
formatSource := format.Source
// It did not make sense to have 2 different generators that do essentially // It did not make sense to have 2 different generators that do essentially
// the same thing, but different format for the BE and the sdk. // the same thing, but different format for the BE and the sdk.
// So the argument switches the go template to use. // So the argument switches the go template to use.
@ -52,8 +56,14 @@ func main() {
source = codersdkTemplate source = codersdkTemplate
case "rbac": case "rbac":
source = rbacObjectTemplate source = rbacObjectTemplate
case "typescript":
source = typescriptTemplate
formatSource = func(src []byte) ([]byte, error) {
// No typescript formatting
return src, nil
}
default: default:
_, _ = fmt.Fprintf(os.Stderr, "%q is not a valid templte target\n", flag.Args()[0]) _, _ = fmt.Fprintf(os.Stderr, "%q is not a valid template target\n", flag.Args()[0])
usage() usage()
os.Exit(2) os.Exit(2)
} }
@ -63,7 +73,7 @@ func main() {
log.Fatalf("Generate source: %s", err.Error()) log.Fatalf("Generate source: %s", err.Error())
} }
formatted, err := format.Source(out) formatted, err := formatSource(out)
if err != nil { if err != nil {
log.Fatalf("Format template: %s", err.Error()) log.Fatalf("Format template: %s", err.Error())
} }

View File

@ -0,0 +1,19 @@
// Code generated by rbacgen/main.go. DO NOT EDIT.
import type { RBACAction, RBACResource } from "./typesGenerated";
// RBACResourceActions maps RBAC resources to their possible actions.
// Descriptions are included to document the purpose of each action.
// Source is in 'coderd/rbac/policy/policy.go'.
export const RBACResourceActions: Partial<
Record<RBACResource, Partial<Record<RBACAction, string>>>
> = {
{{- range $element := . }}
{{- if eq $element.Type "*" }}{{ continue }}{{ end }}
{{ $element.Type }}: {
{{- range $actionValue, $actionDescription := $element.Actions }}
{{ $actionValue }}: "{{ $actionDescription }}",
{{- end }}
},
{{- end }}
};

View File

@ -0,0 +1,154 @@
// Code generated by rbacgen/main.go. DO NOT EDIT.
import type { RBACAction, RBACResource } from "./typesGenerated";
// RBACResourceActions maps RBAC resources to their possible actions.
// Descriptions are included to document the purpose of each action.
// Source is in 'coderd/rbac/policy/policy.go'.
export const RBACResourceActions: Partial<
Record<RBACResource, Partial<Record<RBACAction, string>>>
> = {
api_key: {
create: "create an api key",
delete: "delete an api key",
read: "read api key details (secrets are not stored)",
update: "update an api key, eg expires",
},
assign_org_role: {
assign: "ability to assign org scoped roles",
create: "ability to create/delete/edit custom roles within an organization",
delete: "ability to delete org scoped roles",
read: "view what roles are assignable",
},
assign_role: {
assign: "ability to assign roles",
create: "ability to create/delete/edit custom roles",
delete: "ability to unassign roles",
read: "view what roles are assignable",
},
audit_log: {
create: "create new audit log entries",
read: "read audit logs",
},
debug_info: {
read: "access to debug routes",
},
deployment_config: {
read: "read deployment config",
update: "updating health information",
},
deployment_stats: {
read: "read deployment stats",
},
file: {
create: "create a file",
read: "read files",
},
group: {
create: "create a group",
delete: "delete a group",
read: "read groups",
update: "update a group",
},
license: {
create: "create a license",
delete: "delete license",
read: "read licenses",
},
oauth2_app: {
create: "make an OAuth2 app.",
delete: "delete an OAuth2 app",
read: "read OAuth2 apps",
update: "update the properties of the OAuth2 app.",
},
oauth2_app_code_token: {
create: "",
delete: "",
read: "",
},
oauth2_app_secret: {
create: "",
delete: "",
read: "",
update: "",
},
organization: {
create: "create an organization",
delete: "delete an organization",
read: "read organizations",
update: "update an organization",
},
organization_member: {
create: "create an organization member",
delete: "delete member",
read: "read member",
update: "update an organization member",
},
provisioner_daemon: {
create: "create a provisioner daemon",
delete: "delete a provisioner daemon",
read: "read provisioner daemon",
update: "update a provisioner daemon",
},
provisioner_keys: {
create: "create a provisioner key",
delete: "delete a provisioner key",
read: "read provisioner keys",
},
replicas: {
read: "read replicas",
},
system: {
create: "create system resources",
delete: "delete system resources",
read: "view system resources",
update: "update system resources",
},
tailnet_coordinator: {
create: "",
delete: "",
read: "",
update: "",
},
template: {
create: "create a template",
delete: "delete a template",
read: "read template",
update: "update a template",
view_insights: "view insights",
},
user: {
create: "create a new user",
delete: "delete an existing user",
read: "read user data",
read_personal: "read personal user data like user settings and auth links",
update: "update an existing user",
update_personal: "update personal data",
},
workspace: {
application_connect: "connect to workspace apps via browser",
create: "create a new workspace",
delete: "delete workspace",
read: "read workspace data to view on the UI",
ssh: "ssh into a given workspace",
start: "allows starting a workspace",
stop: "allows stopping a workspace",
update: "edit workspace settings (scheduling, permissions, parameters)",
},
workspace_dormant: {
application_connect: "connect to workspace apps via browser",
create: "create a new workspace",
delete: "delete workspace",
read: "read workspace data to view on the UI",
ssh: "ssh into a given workspace",
start: "allows starting a workspace",
stop: "allows stopping a workspace",
update: "edit workspace settings (scheduling, permissions, parameters)",
},
workspace_proxy: {
create: "create a workspace proxy",
delete: "delete a workspace proxy",
read: "read and use a workspace proxy",
update: "update a workspace proxy",
},
};