-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding docs generation and example docs files
Adds logic to auto-generate a documentation directory and provides two docs files
- Loading branch information
1 parent
2e89c65
commit 9c124a4
Showing
8 changed files
with
182 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# management.cattle.io/v3 | ||
|
||
## GlobalRole | ||
|
||
### Validation Checks | ||
Note: all checks are bypassed if the GlobalRole is being deleted | ||
|
||
#### Escalation Prevention | ||
Users can only change GlobalRoles which have less permissions than they do. This is to prevents privilege escalation. | ||
|
||
## RoleTemplate | ||
|
||
### Validation Checks | ||
Note: all checks are bypassed if the RoleTemplate is being deleted | ||
|
||
#### Circular Reference | ||
Circular references to webhooks (a inherits b, b inherits a) are not allowed. More specifically, if "roleTemplate1" is included in the `roleTemplateNames` of "roleTemplate2", then "roleTemplate2" must not be included in the `roleTemplateNames` of "roleTemplate1". This checks prevents the creation of roles whose end-state cannot be resolved. | ||
|
||
#### Rules Without Verbs | ||
Rules without verbs are not peritted. The `rules` included in a roleTemplate are of the same type as the rules used by standard kubernetes RBAC types (such as `Roles` from `rbac.authorization.k8s.io/v1`). Because of this, they inherit the same restrictions as these types, including this one. | ||
|
||
#### Escalation Prevention | ||
Users can only change RoleTemplates which have less permissions than they do. This prevents privilege escalation. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
|
||
"golang.org/x/exp/slices" | ||
) | ||
|
||
// docFileName defines the name of the files that will be aggregated into overall docs | ||
const docFileExtension = ".md" | ||
|
||
type docFile struct { | ||
content []byte | ||
resource string | ||
group string | ||
version string | ||
} | ||
|
||
func generateDocs(resourcesBaseDir, outputFilePath string) error { | ||
outputFile, err := os.OpenFile(outputFilePath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) | ||
if err != nil { | ||
return err | ||
} | ||
docFiles, err := getDocFiles(resourcesBaseDir) | ||
if err != nil { | ||
return fmt.Errorf("unable to create documentation: %w", err) | ||
} | ||
currentGroup := "" | ||
for _, docFile := range docFiles { | ||
newGroup := docFile.group | ||
if newGroup != currentGroup { | ||
// our group has changed, output a new group header | ||
_, err = fmt.Fprintf(outputFile, "# %s/%s \n \n", docFile.group, docFile.version) | ||
if err != nil { | ||
return fmt.Errorf("unable to write group header for %s/%s: %w", docFile.group, docFile.version, err) | ||
} | ||
currentGroup = newGroup | ||
} | ||
|
||
_, err = fmt.Fprintf(outputFile, "## %s \n\n", docFile.resource) | ||
if err != nil { | ||
return fmt.Errorf("unable to write resource header for %s: %w", docFile.resource, err) | ||
} | ||
|
||
lines := strings.Split(string(docFile.content), "\n") | ||
for i, line := range lines { | ||
newLine := line | ||
if i < len(lines)-1 { | ||
// last line doesn't need a newLine re-added | ||
newLine += "\n" | ||
} | ||
if strings.HasPrefix(line, "#") { | ||
// this line is a markdown header. Since the group header is the top-level indent, indent this down one line | ||
newLine = "#" + line | ||
} | ||
_, err := outputFile.WriteString(newLine) | ||
if err != nil { | ||
return fmt.Errorf("unable to write content for %s/%s.%s: %w", docFile.group, docFile.version, docFile.resource, err) | ||
} | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
// getDocFiles finds all markdown files recursively in resourcesBaseDir and converts them to docFiles. Returns in a sorted order, | ||
// first by group, then by resourceName | ||
func getDocFiles(baseDir string) ([]docFile, error) { | ||
entries, err := os.ReadDir(baseDir) | ||
if err != nil { | ||
return nil, fmt.Errorf("unable to list entries in directory %s: %w", baseDir, err) | ||
} | ||
var docFiles []docFile | ||
for _, entry := range entries { | ||
entryPath := filepath.Join(baseDir, entry.Name()) | ||
if entry.IsDir() { | ||
subDocFiles, err := getDocFiles(entryPath) | ||
if err != nil { | ||
return nil, err | ||
} | ||
docFiles = append(docFiles, subDocFiles...) | ||
} | ||
if filepath.Ext(entry.Name()) == docFileExtension { | ||
content, err := os.ReadFile(filepath.Join(baseDir, entry.Name())) | ||
if err != nil { | ||
return nil, fmt.Errorf("unable to read file content for %s: %w", entryPath, err) | ||
} | ||
var newDir, resource, version, group string | ||
newDir, _ = filepath.Split(baseDir) | ||
newDir, version = filepath.Split(newDir[:len(newDir)-1]) | ||
newDir, group = filepath.Split(newDir[:len(newDir)-1]) | ||
resource = strings.TrimSuffix(entry.Name(), docFileExtension) | ||
if newDir == "" || resource == "" || version == "" || group == "" { | ||
return nil, fmt.Errorf("unable to extract gvr from %s, got group %s, version %s, resource %s", baseDir, group, version, resource) | ||
} | ||
docFiles = append(docFiles, docFile{ | ||
content: content, | ||
resource: resource, | ||
group: group, | ||
version: version, | ||
}) | ||
} | ||
} | ||
// if the groups differ, sort based on the group. If the groups are the same, sort based on the resource | ||
slices.SortFunc(docFiles, func(a, b docFile) bool { | ||
if a.group < b.group { | ||
return true | ||
} else if a.group == b.group { | ||
return a.resource < b.resource | ||
} | ||
return false | ||
}) | ||
|
||
return docFiles, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 8 additions & 0 deletions
8
pkg/resources/management.cattle.io/v3/globalrole/GlobalRole.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
## Validation Checks | ||
|
||
Note: all checks are bypassed if the GlobalRole is being deleted | ||
|
||
### Escalation Prevention | ||
|
||
Users can only change GlobalRoles which have less permissions than they do. This is to prevents privilege escalation. | ||
|
16 changes: 16 additions & 0 deletions
16
pkg/resources/management.cattle.io/v3/roletemplate/RoleTemplate.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
## Validation Checks | ||
|
||
Note: all checks are bypassed if the RoleTemplate is being deleted | ||
|
||
### Circular Reference | ||
|
||
Circular references to webhooks (a inherits b, b inherits a) are not allowed. More specifically, if "roleTemplate1" is included in the `roleTemplateNames` of "roleTemplate2", then "roleTemplate2" must not be included in the `roleTemplateNames` of "roleTemplate1". This checks prevents the creation of roles whose end-state cannot be resolved. | ||
|
||
### Rules Without Verbs | ||
|
||
Rules without verbs are not peritted. The `rules` included in a roleTemplate are of the same type as the rules used by standard kubernetes RBAC types (such as `Roles` from `rbac.authorization.k8s.io/v1`). Because of this, they inherit the same restrictions as these types, including this one. | ||
|
||
### Escalation Prevention | ||
|
||
Users can only change RoleTemplates which have less permissions than they do. This prevents privilege escalation. | ||
|