* add ad for compute-vm refactor * Exclue nic_type from validated fields, add split of main.tf and template.tf * boot disk * fix examples and fixtures * attached disks * fix further examples and module-level tests * remove extra file * fix mig examples * finish refactoring variables * align fast and other modules * refactor(compute-vm): align examples and ADR with the newly implemented interface This commit addresses the remaining references of the `instance_type` and `confidential_compute` parameters in the testing environment and updates the ADR. * feat(compute-vm): add network_performance_config to instance and templates This change implements the usage of the `network_performance_tier` variable we added earlier into the actual Terraform resources. --------- Co-authored-by: Wiktor Niesiobędzki <wiktorn@google.com>
148 lines
4.7 KiB
Python
Executable File
148 lines
4.7 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# Copyright 2024 Google LLC
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# https://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
'''Format Terraform code blocks with tftest directives in README files.'''
|
|
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import click
|
|
import marko
|
|
|
|
# Add fabric root to sys.path to import from tests
|
|
FABRIC_ROOT = Path(__file__).resolve().parents[1]
|
|
sys.path.append(str(FABRIC_ROOT))
|
|
|
|
try:
|
|
from tests.examples.utils import get_tftest_directive
|
|
except ImportError:
|
|
print('Error: Could not import tests.examples.utils', file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
|
|
def find_readme_files(paths):
|
|
'''Find all README.md files in the given paths.'''
|
|
files_to_check = []
|
|
for path in paths:
|
|
if os.path.isfile(path) and os.path.basename(path) == 'README.md':
|
|
files_to_check.append(path)
|
|
elif os.path.isdir(path):
|
|
for root, _, files in os.walk(path):
|
|
if 'README.md' in files:
|
|
files_to_check.append(os.path.join(root, 'README.md'))
|
|
return files_to_check
|
|
|
|
|
|
def find_examples(content):
|
|
'''Find all Terraform examples with tftest directives in the markdown content.'''
|
|
doc = marko.parse(content)
|
|
examples = []
|
|
last_header = None
|
|
index = 0
|
|
for child in doc.children:
|
|
if isinstance(child, marko.block.Heading):
|
|
last_header = child.children[0].children
|
|
index = 0
|
|
continue
|
|
if not isinstance(child, marko.block.FencedCode):
|
|
continue
|
|
index += 1
|
|
if child.lang not in ('hcl', 'tfvars'):
|
|
continue
|
|
code = child.children[0].children
|
|
directive = get_tftest_directive(code)
|
|
# identical logic to pytest tests filtering
|
|
if directive is None:
|
|
continue
|
|
if 'skip' in directive.args:
|
|
continue
|
|
example_id = f'{last_header}:{index}'
|
|
examples.append((example_id, child.lang, code))
|
|
return examples
|
|
|
|
|
|
def format_example(code):
|
|
'''Format a single Terraform example using terraform fmt.'''
|
|
try:
|
|
proc = subprocess.run(['terraform', 'fmt', '-'], input=code, text=True,
|
|
capture_output=True, check=True)
|
|
return proc.stdout, None
|
|
except subprocess.CalledProcessError as e:
|
|
return code, e.stderr
|
|
|
|
|
|
def replace_examples(content, formatted_examples):
|
|
'''Replace the original examples with the formatted ones in the markdown content.'''
|
|
new_content = content
|
|
for lang, original_code, formatted_code in formatted_examples:
|
|
if original_code != formatted_code:
|
|
old_block = f'```{lang}\n{original_code}```'
|
|
new_block = f'```{lang}\n{formatted_code}```'
|
|
new_content = new_content.replace(old_block, new_block)
|
|
return new_content
|
|
|
|
|
|
@click.command()
|
|
@click.argument('paths', type=click.Path(exists=True), nargs=-1)
|
|
@click.option('--check', is_flag=True,
|
|
help='Check if files need formatting without changing them.')
|
|
def main(paths, check):
|
|
'''Format Terraform code blocks with tftest directives in README files.
|
|
|
|
PATHS can be specific README.md files or directories to search recursively.
|
|
If no paths are provided, searches the current directory recursively.
|
|
'''
|
|
if not paths:
|
|
paths = ('.',)
|
|
files_to_check = find_readme_files(paths)
|
|
has_changes = False
|
|
for file_path in files_to_check:
|
|
try:
|
|
with open(file_path, 'r') as f:
|
|
content = f.read()
|
|
examples = find_examples(content)
|
|
formatted_examples = []
|
|
file_changed = False
|
|
file_output = []
|
|
for example_id, lang, code in examples:
|
|
formatted_code, error = format_example(code)
|
|
if error:
|
|
file_output.append(f' ❌ {example_id}')
|
|
formatted_examples.append((lang, code, code))
|
|
else:
|
|
if formatted_code != code:
|
|
file_output.append(f' ✅ {example_id}')
|
|
file_changed = True
|
|
has_changes = True
|
|
formatted_examples.append((lang, code, formatted_code))
|
|
if file_output:
|
|
print(f'{file_path}:')
|
|
for line in file_output:
|
|
print(line)
|
|
if file_changed and not check:
|
|
new_content = replace_examples(content, formatted_examples)
|
|
with open(file_path, 'w') as f:
|
|
f.write(new_content)
|
|
except Exception as e:
|
|
print(f'Error processing {file_path}: {e}', file=sys.stderr)
|
|
if check and has_changes:
|
|
sys.exit(1)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|