package main import ( "fmt" "io/ioutil" "os" "sort" "strings" ) const permsFile = "website/content/docs/concepts/permissions.mdx" var ( iamScopes = []string{"Global", "Org"} infraScope = []string{"Project"} ) type Table struct { Header *Header Body *Body } type Header struct { Titles []string } type Body struct { Resources []*Resource } type Resource struct { Type string Scopes []string Endpoints []*Endpoint } type Endpoint struct { Path string Params map[string]string Actions []*Action } type Action struct { Name string Description string Examples []string } var table = &Table{ Header: &Header{ Titles: []string{ "Resource Type", "Applicable Scopes", "API Endpoint", "Parameters into Permissions Engine", "Available Actions / Examples", }, }, Body: &Body{ Resources: make([]*Resource, 0, 12), }, } func main() { table.Body.Resources = append(table.Body.Resources, account, authMethod, authToken, group, host, hostCatalog, hostSet, role, scope, session, target, user, ) fileContents, err := ioutil.ReadFile(permsFile) if err != nil { fmt.Println(err) os.Exit(1) } lines := strings.Split(string(fileContents), "\n") var pre, post []string var marker int for i, line := range lines { if strings.Contains(line, "BEGIN TABLE") { marker = i } pre = append(pre, line) if marker != 0 { break } } for i := marker + 1; i < len(lines); i++ { if !strings.Contains(lines[i], "END TABLE") { continue } marker = i break } for i := marker; i < len(lines); i++ { post = append(post, lines[i]) } final := fmt.Sprintf("%s\n\n%s\n\n%s", strings.Join(pre, "\n"), strings.Join(table.Marshal(), "\n"), strings.Join(post, "\n")) if err := ioutil.WriteFile(permsFile, []byte(final), 0644); err != nil { fmt.Println(err) os.Exit(1) } } func (t *Table) Marshal() (ret []string) { ret = append(ret, "") ret = append(ret, " ") ret = append(ret, t.Header.Marshal()...) ret = append(ret, " ") ret = append(ret, " ") ret = append(ret, t.Body.Marshal()...) ret = append(ret, " ") ret = append(ret, "
") return } func (h *Header) Marshal() (ret []string) { ret = append(ret, fmt.Sprintf(`%s`, indent(4))) for _, v := range h.Titles { ret = append(ret, fmt.Sprintf("%s%s", indent(6), v), ) } ret = append(ret, fmt.Sprintf(`%s`, indent(4))) return } func (b *Body) Marshal() (ret []string) { for _, v := range b.Resources { ret = append(ret, v.Marshal()...) } return } func (r *Resource) Marshal() (ret []string) { for i, v := range r.Endpoints { ret = append(ret, fmt.Sprintf(`%s`, indent(4))) if i == 0 { ret = append(ret, fmt.Sprintf(`%s%s`, indent(6), len(r.Endpoints), r.Type), fmt.Sprintf(`%s`, indent(6), len(r.Endpoints)), fmt.Sprintf(`%s`, indent(8)), fmt.Sprintf(`%s`, indent(6)), ) } ret = append(ret, v.Marshal()...) ret = append(ret, fmt.Sprintf(`%s`, indent(4))) } return } func (e *Endpoint) Marshal() (ret []string) { ret = append(ret, fmt.Sprintf(`%s`, indent(6)), fmt.Sprintf(`%s%s`, indent(8), escape(e.Path)), fmt.Sprintf(`%s`, indent(6)), fmt.Sprintf(`%s`, indent(6)), fmt.Sprintf(`%s`, indent(8)), fmt.Sprintf(`%s`, indent(6)), fmt.Sprintf(`%s`, indent(6)), fmt.Sprintf(`%s`, indent(8)), fmt.Sprintf(`%s`, indent(6)), ) return } func escape(s string) string { ret := strings.Replace(s, "<", "<", -1) return strings.Replace(ret, ">", ">", -1) } func indent(num int) string { return strings.Repeat(" ", num) } func sortedKeys(in map[string]string) []string { out := make([]string, 0, len(in)) for k := range in { out = append(out, k) } sort.Strings(out) return out } func clActions(typ string) []*Action { listVersion := strings.TrimPrefix(strings.TrimPrefix(typ, "an "), "a ") return []*Action{ { Name: "create", Description: fmt.Sprintf("Create %s", typ), Examples: []string{ "type=;actions=create", }, }, { Name: "list", Description: fmt.Sprintf("List %ss", listVersion), Examples: []string{ "type=;actions=list", }, }, } } func rudActions(typ string, pin bool) []*Action { ret := []*Action{ { Name: "read", Description: fmt.Sprintf("Read %s", typ), Examples: []string{ "id=;actions=read", }, }, { Name: "update", Description: fmt.Sprintf("Update %s", typ), Examples: []string{ "id=;actions=update", }, }, { Name: "delete", Description: fmt.Sprintf("Delete %s", typ), Examples: []string{ "id=;actions=delete", }, }, } if pin { ret[0].Examples = append(ret[0].Examples, "id=;type=;actions=read") ret[1].Examples = append(ret[1].Examples, "id=;type=;actions=update") ret[2].Examples = append(ret[2].Examples, "id=;type=;actions=delete") } return ret } var account = &Resource{ Type: "Account", Scopes: iamScopes, Endpoints: []*Endpoint{ { Path: "/accounts", Params: map[string]string{ "Type": "accounts", }, Actions: clActions("an account"), }, { Path: "/accounts/", Params: map[string]string{ "ID": "", "Type": "account", "Pin": "", }, Actions: append( rudActions("an account", true), &Action{ Name: "set-password", Description: "Set a password on an account, without requring the current password", Examples: []string{ "id=;actions=set-password", "id=;type=;actions=set-password", }, }, &Action{ Name: "change-password", Description: "Change a password on an account given the current password", Examples: []string{ "id=;actions=change-password", "id=;type=;actions=change-password", }, }, ), }, }, } var authMethod = &Resource{ Type: "Auth Method", Scopes: iamScopes, Endpoints: []*Endpoint{ { Path: "/auth-methods", Params: map[string]string{ "Type": "auth-method", }, Actions: clActions("an auth method"), }, { Path: "/auth-methods/", Params: map[string]string{ "ID": "", "Type": "auth-method", }, Actions: append( rudActions("an auth method", false), &Action{ Name: "authenticate", Description: "Authenticate to an auth method", Examples: []string{ "id=;actions=authenticate", }, }, ), }, }, } var authToken = &Resource{ Type: "Auth Token", Scopes: iamScopes, Endpoints: []*Endpoint{ { Path: "/auth-tokens", Params: map[string]string{ "Type": "auth-token", }, Actions: []*Action{ { Name: "list", Description: "List auth tokens", Examples: []string{ "type=;actions=list", }, }, }, }, { Path: "/auth-tokens/", Params: map[string]string{ "ID": "", "Type": "auth-token", }, Actions: []*Action{ { Name: "read", Description: "Read an auth token", Examples: []string{ "id=;actions=read", }, }, { Name: "delete", Description: "Delete an auth token", Examples: []string{ "id=;actions=delete", }, }, }, }, }, } var group = &Resource{ Type: "Group", Scopes: append(iamScopes, infraScope...), Endpoints: []*Endpoint{ { Path: "/groups", Params: map[string]string{ "Type": "group", }, Actions: clActions("a group"), }, { Path: "/groups/", Params: map[string]string{ "ID": "", "Type": "group", }, Actions: append( rudActions("a group", false), &Action{ Name: "add-members", Description: "Add members to a group", Examples: []string{ "id=;actions=add-members", }, }, &Action{ Name: "set-members", Description: "Set the full set of members on a group", Examples: []string{ "id=;actions=set-members", }, }, &Action{ Name: "remove-members", Description: "Remove members from a group", Examples: []string{ "id=;actions=remove-members", }, }, ), }, }, } var host = &Resource{ Type: "Host", Scopes: infraScope, Endpoints: []*Endpoint{ { Path: "/hosts", Params: map[string]string{ "Type": "host", }, Actions: clActions("a host"), }, { Path: "/hosts/", Params: map[string]string{ "ID": "", "Type": "host", "Pin": "", }, Actions: rudActions("a host", true), }, }, } var hostCatalog = &Resource{ Type: "Host Catalog", Scopes: infraScope, Endpoints: []*Endpoint{ { Path: "/host-catalogs", Params: map[string]string{ "Type": "host-catalog", }, Actions: clActions("a host catalog"), }, { Path: "/host-catalogs/", Params: map[string]string{ "ID": "", "Type": "host-catalog", }, Actions: rudActions("a host catalog", false), }, }, } var hostSet = &Resource{ Type: "Host Set", Scopes: infraScope, Endpoints: []*Endpoint{ { Path: "/host-sets", Params: map[string]string{ "Type": "host-set", }, Actions: clActions("a host set"), }, { Path: "/targets/", Params: map[string]string{ "ID": "", "Type": "host-set", "Pin": "", }, Actions: append( rudActions("a host set", true), &Action{ Name: "add-hosts", Description: "Add hosts to a host-set", Examples: []string{ "id=;actions=add-hosts", "id=;type=;actions=add-hosts", }, }, &Action{ Name: "set-hosts", Description: "Set the full set of hosts on a host set", Examples: []string{ "id=;actions=set-hosts", "id=;type=;actions=set-hosts", }, }, &Action{ Name: "remove-hosts", Description: "Remove hosts from a host set", Examples: []string{ "id=;actions=remove-hosts", "id=;type=;actions=remove-hosts", }, }, ), }, }, } var role = &Resource{ Type: "Role", Scopes: append(iamScopes, infraScope...), Endpoints: []*Endpoint{ { Path: "/roles", Params: map[string]string{ "Type": "role", }, Actions: clActions("a role"), }, { Path: "/roles/", Params: map[string]string{ "ID": "", "Type": "role", }, Actions: append( rudActions("a role", false), &Action{ Name: "add-principals", Description: "Add principals to a role", Examples: []string{ "id=;actions=add-principals", }, }, &Action{ Name: "set-principals", Description: "Set the full set of principals on a role", Examples: []string{ "id=;actions=set-principals", }, }, &Action{ Name: "remove-principals", Description: "Remove principals from a role", Examples: []string{ "id=;actions=remove-principals", }, }, &Action{ Name: "add-grants", Description: "Add grants to a role", Examples: []string{ "id=;actions=add-grants", }, }, &Action{ Name: "set-grants", Description: "Set the full set of grants on a role", Examples: []string{ "id=;actions=set-grants", }, }, &Action{ Name: "remove-grants", Description: "Remove grants from a role", Examples: []string{ "id=;actions=remove-grants", }, }, ), }, }, } var scope = &Resource{ Type: "Scope", Scopes: iamScopes, Endpoints: []*Endpoint{ { Path: "/scopes", Params: map[string]string{ "Type": "scope", }, Actions: clActions("a scope"), }, { Path: "/scopes/", Params: map[string]string{ "ID": "", "Type": "scope", }, Actions: rudActions("a scope", false), }, }, } var session = &Resource{ Type: "Session", Scopes: infraScope, Endpoints: []*Endpoint{ { Path: "/sessions", Params: map[string]string{ "Type": "session", }, Actions: []*Action{ { Name: "list", Description: "List sessions", Examples: []string{ "type=;actions=list", }, }, }, }, { Path: "/session/", Params: map[string]string{ "ID": "", "Type": "session", }, Actions: []*Action{ { Name: "read", Description: "Read a session", Examples: []string{ "id=;actions=read", }, }, { Name: "cancel", Description: "Cancel a session", Examples: []string{ "id=;actions=cancel", }, }, }, }, }, } var target = &Resource{ Type: "Target", Scopes: infraScope, Endpoints: []*Endpoint{ { Path: "/targets", Params: map[string]string{ "Type": "target", }, Actions: clActions("a target"), }, { Path: "/targets/", Params: map[string]string{ "ID": "", "Type": "target", }, Actions: append( rudActions("a target", false), &Action{ Name: "add-host-sets", Description: "Add host sets to a target", Examples: []string{ "id=;actions=add-host-sets", }, }, &Action{ Name: "set-host-sets", Description: "Set the full set of host sets on a target", Examples: []string{ "id=;actions=set-host-sets", }, }, &Action{ Name: "remove-host-sets", Description: "Remove host sets from a target", Examples: []string{ "id=;actions=remove-host-sets", }, }, &Action{ Name: "authorize-session", Description: "Authorize a session via the target", Examples: []string{ "id=;actions=authorize-session", }, }, ), }, }, } var user = &Resource{ Type: "User", Scopes: iamScopes, Endpoints: []*Endpoint{ { Path: "/users", Params: map[string]string{ "Type": "user", }, Actions: clActions("a user"), }, { Path: "/users/", Params: map[string]string{ "ID": "", "Type": "user", }, Actions: append( rudActions("a user", false), &Action{ Name: "add-accounts", Description: "Add accounts to a user", Examples: []string{ "id=;actions=add-accounts", }, }, &Action{ Name: "set-accounts", Description: "Set the full set of accounts on a user", Examples: []string{ "id=;actions=set-accounts", }, }, &Action{ Name: "remove-accounts", Description: "Remove accounts from a user", Examples: []string{ "id=;actions=remove-accounts", }, }, ), }, }, }