-
Notifications
You must be signed in to change notification settings - Fork 183
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Dominik Rosiek <[email protected]>
- Loading branch information
Dominik Rosiek
committed
Oct 31, 2023
1 parent
a6fb970
commit 29c4433
Showing
12 changed files
with
10,286 additions
and
392 deletions.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,3 +28,6 @@ go.work.sum | |
|
||
# Local values files | ||
values.local.yaml | ||
|
||
# Python cache | ||
__pycache__ |
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,118 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import argparse | ||
import json | ||
import re | ||
import sys | ||
|
||
import yaml | ||
from yaml.loader import SafeLoader | ||
|
||
DESCRIPTION = 'This program generates JSON schema from README.md table' | ||
|
||
def values_to_dictionary(path: str) -> dict: | ||
"""Reads given path as values.yaml and returns it as dict | ||
Args: | ||
path (str): path to the value.yaml | ||
Returns: | ||
dict: values.yaml as dict | ||
""" | ||
with open(path, encoding='utf-8') as file: | ||
values_yaml = file.read() | ||
values_yaml = re.sub(r'(\[\]|\{\})\n(\s+# )', r'\n\2', values_yaml, flags=re.M) | ||
values_yaml = re.sub(r'^(\s+)# ', r'\1', values_yaml, flags=re.M) | ||
return yaml.load(values_yaml, Loader=SafeLoader) | ||
|
||
def set_properties(values): | ||
properties = { | ||
'type': '', | ||
# 'required': [], | ||
# 'properties': {}, | ||
# 'default': '', | ||
'description': '', | ||
} | ||
|
||
if isinstance(values, dict): | ||
properties['type'] = 'object' | ||
properties['properties'] = {} | ||
for key in values.keys(): | ||
properties['properties'][key] = set_properties(values[key]) | ||
else: | ||
properties['default'] = values | ||
if isinstance(values, bool): | ||
properties['type'] = 'boolean' | ||
elif isinstance(values, int): | ||
properties['type'] = 'integer' | ||
elif isinstance(values, (list, set)): | ||
properties['type'] = 'array' | ||
elif isinstance(values, str): | ||
properties['type'] = 'string' | ||
else: | ||
properties['type'] = 'string' | ||
if not properties['default']: | ||
properties['default'] = "" | ||
|
||
return properties | ||
|
||
def extract_description_from_readme(path: str) -> dict: | ||
"""Reads given path as README.md and returns dict in the following form: | ||
``` | ||
{ | ||
configuration_key: configuration_default | ||
} | ||
``` | ||
Args: | ||
path (str): path to the README.md | ||
Returns: | ||
dict: {configuration_key: configuration_default,...} | ||
""" | ||
with open(path, encoding='utf-8') as file: | ||
readme = file.readlines() | ||
|
||
keys = {} | ||
|
||
for line in readme: | ||
match = re.match( | ||
r'^\|\s+`(?P<key>.*?)`\s+\|\s+(?P<description>.*?)\s+\|\s+(?P<value>.*?)\s+\|$', | ||
line) | ||
if match and match.group('key'): | ||
description = match.group('description').strip('`').strip('"') | ||
keys[match.group('key')] = description | ||
|
||
return keys | ||
|
||
if __name__ == '__main__': | ||
parser = argparse.ArgumentParser( | ||
prog = sys.argv[0], | ||
description = DESCRIPTION) | ||
parser.add_argument('--values', required=True) | ||
parser.add_argument('--readme', required=True) | ||
parser.add_argument('--output', required=True) | ||
parser.add_argument('--full-diff', required=False, action='store_true') | ||
args = parser.parse_args() | ||
|
||
values = values_to_dictionary(args.values) | ||
|
||
output = { | ||
"$schema": "http://json-schema.org/schema#", | ||
"type": "object", | ||
"properties": {}, | ||
} | ||
|
||
for key in values: | ||
output['properties'][key] = set_properties(values[key]) | ||
|
||
descriptions = extract_description_from_readme(args.readme) | ||
for key, description in descriptions.items(): | ||
a = output['properties'] | ||
subkeys = key.split(".") | ||
for i in range(0, len(subkeys)-1): | ||
a = a[subkeys[i]]['properties'] | ||
a[subkeys[-1]]['description'] = description | ||
with open(args.output, "w") as f: | ||
f.write(json.dumps(output, indent=2)) |
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,106 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import argparse | ||
import json | ||
import re | ||
import sys | ||
import os | ||
|
||
import yaml | ||
from yaml.loader import SafeLoader | ||
|
||
DESCRIPTION = "test" | ||
HEADER = """# Configuration | ||
To see all available configuration for our sub-charts, please refer to their documentation. | ||
- [Falco](https://github.com/falcosecurity/charts/tree/master/charts/falco#configuration) - All Falco properties should be prefixed with | ||
`falco.` in our values.yaml to override a property not listed below. | ||
- [Kube-Prometheus-Stack](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack#configuration) - All | ||
Kube Prometheus Stack properties should be prefixed with `kube-prometheus-stack.` in our values.yaml to override a property not listed | ||
below. | ||
- [Metrics Server](https://github.com/bitnami/charts/tree/master/bitnami/metrics-server/#parameters) - All Metrics Server properties should | ||
be prefixed with `metrics-server.` in our values.yaml to override a property not listed below. | ||
- [Tailing Sidecar Operator](https://github.com/SumoLogic/tailing-sidecar/tree/main/helm/tailing-sidecar-operator#configuration) - All | ||
Tailing Sidecar Operator properties should be prefixed with `tailing-sidecar-operator` in our values.yaml to override a property not | ||
listed below. | ||
- [OpenTelemetry Operator](https://github.com/open-telemetry/opentelemetry-helm-charts/tree/main/charts/opentelemetry-operator#opentelemetry-operator-helm-chart) - | ||
All OpenTelemetry Operator properties should be prefixed with `opentelemetry-operator` in our values.yaml to override a property listed | ||
below. | ||
The following table lists the configurable parameters of the Sumo Logic chart and their default values. | ||
| Parameter | Description | Default | | ||
| --- | --- | --- |""" | ||
|
||
FOOTER = """ | ||
[values.yaml]: values.yaml""" | ||
|
||
def build_default(data): | ||
return_value = {} | ||
if 'properties' in data: | ||
for key in data['properties']: | ||
return_value[key] = build_default(data['properties'][key]) | ||
return return_value | ||
elif 'items' in data: | ||
return [item['default'] for item in data['items']] | ||
else: | ||
return data['default'] | ||
|
||
def get_description(prefix, data): | ||
return_value = [] | ||
prefix = prefix.strip('.') | ||
description = data["description"] if 'description' in data else "" | ||
built_default = None | ||
|
||
if 'properties' in data: | ||
if not description: | ||
for key in data['properties']: | ||
if prefix == "": | ||
pref = key | ||
else: | ||
if "." in key: | ||
pref = f"{prefix}[{key}]" | ||
else: | ||
pref = f"{prefix}.{key}" | ||
return_value += get_description(pref, data['properties'][key]) | ||
return return_value | ||
else: | ||
built_default = build_default(data) | ||
|
||
if 'items' in data: | ||
built_default = build_default(data) | ||
|
||
default = json.dumps(built_default if built_default is not None else data['default']).strip('"').replace("|", "\|") | ||
if len(default) > 180: | ||
default = "See [values.yaml]" | ||
|
||
if default == "": | ||
default = "Nil" | ||
return_value.append(f'| `{prefix}` | {data["description"]} | `{default}` |') | ||
|
||
return return_value | ||
|
||
def main(schema, directory): | ||
readme = [HEADER] | ||
with open(schema) as f: | ||
data = json.loads(f.read()) | ||
readme += get_description("", data) | ||
readme.append(FOOTER) | ||
|
||
readme = "\n".join(readme) | ||
|
||
with open(os.path.join(directory, "README.md"), "w") as f: | ||
f.write(readme) | ||
|
||
|
||
if __name__ == '__main__': | ||
parser = argparse.ArgumentParser( | ||
prog = sys.argv[0], | ||
description = DESCRIPTION) | ||
parser.add_argument('--schema', required=True) | ||
parser.add_argument('--dir', required=True) | ||
parser.add_argument('--full-diff', required=False, action='store_true') | ||
args = parser.parse_args() | ||
|
||
main(args.schema, args.dir) |
Oops, something went wrong.