diff --git a/Makefile b/Makefile index 664e1287ff712..88165915240d2 100644 --- a/Makefile +++ b/Makefile @@ -487,6 +487,7 @@ gen: \ site/src/api/typesGenerated.ts \ coderd/rbac/object_gen.go \ codersdk/rbacresources_gen.go \ + site/src/api/rbacresources_gen.ts \ docs/admin/prometheus.md \ docs/cli.md \ docs/admin/audit-logs.md \ @@ -518,6 +519,7 @@ gen/mark-fresh: site/src/api/typesGenerated.ts \ coderd/rbac/object_gen.go \ codersdk/rbacresources_gen.go \ + site/src/api/rbacresources_gen.ts \ docs/admin/prometheus.md \ docs/cli.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 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 go run scripts/metricsdocgen/main.go ./scripts/pnpm_install.sh diff --git a/coderd/rbac/policy/policy.go b/coderd/rbac/policy/policy.go index 1fe635bec5e61..2390c9e30c785 100644 --- a/coderd/rbac/policy/policy.go +++ b/coderd/rbac/policy/policy.go @@ -39,6 +39,10 @@ type ActionDefinition struct { Description string } +func (d ActionDefinition) String() string { + return d.Description +} + func actDef(description string) ActionDefinition { return ActionDefinition{ Description: description, diff --git a/scripts/rbacgen/main.go b/scripts/rbacgen/main.go index 1eb186c1b5ce4..c08c6b4cac0f3 100644 --- a/scripts/rbacgen/main.go +++ b/scripts/rbacgen/main.go @@ -10,11 +10,11 @@ import ( "go/format" "go/parser" "go/token" - "html/template" "log" "os" "slices" "strings" + "text/template" "golang.org/x/xerrors" @@ -27,6 +27,9 @@ var rbacObjectTemplate string //go:embed codersdk.gotmpl var codersdkTemplate string +//go:embed typescript.tstmpl +var typescriptTemplate string + func usage() { _, _ = fmt.Println("Usage: rbacgen ") _, _ = fmt.Println("Must choose a template target.") @@ -43,6 +46,7 @@ func main() { os.Exit(1) } + formatSource := format.Source // 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. // So the argument switches the go template to use. @@ -52,8 +56,14 @@ func main() { source = codersdkTemplate case "rbac": source = rbacObjectTemplate + case "typescript": + source = typescriptTemplate + formatSource = func(src []byte) ([]byte, error) { + // No typescript formatting + return src, nil + } 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() os.Exit(2) } @@ -63,7 +73,7 @@ func main() { log.Fatalf("Generate source: %s", err.Error()) } - formatted, err := format.Source(out) + formatted, err := formatSource(out) if err != nil { log.Fatalf("Format template: %s", err.Error()) } diff --git a/scripts/rbacgen/typescript.tstmpl b/scripts/rbacgen/typescript.tstmpl new file mode 100644 index 0000000000000..459443ea5fb5f --- /dev/null +++ b/scripts/rbacgen/typescript.tstmpl @@ -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>> +> = { + {{- range $element := . }} + {{- if eq $element.Type "*" }}{{ continue }}{{ end }} + {{ $element.Type }}: { + {{- range $actionValue, $actionDescription := $element.Actions }} + {{ $actionValue }}: "{{ $actionDescription }}", + {{- end }} + }, + {{- end }} +}; diff --git a/site/src/api/rbacresources_gen.ts b/site/src/api/rbacresources_gen.ts new file mode 100644 index 0000000000000..37fe508fde89c --- /dev/null +++ b/site/src/api/rbacresources_gen.ts @@ -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>> +> = { + 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", + }, +};