Skip to content

Commit

Permalink
feat(template): add helm3 template like support
Browse files Browse the repository at this point in the history
This commit adds a feature in the CLI where you can generate `helm
template` like output for your manifests

Usage: python -m riocli template [OPTIONS] [FILES]...

  Print manifests with filled values

Options:
  -v, --values TEXT   path to values yaml file. key/values specified in the
                      values file can be used as variables in template yamls
  -s, --secrets TEXT  secret files are sops encoded value files. rio-cli
                      expects sops to be authorized for decoding files on this
                      computer
  --help              Show this message and exit.

Reviewed By: Ankit Gadiya
  • Loading branch information
pallabpain authored and ankitrgadiya committed Dec 14, 2022
1 parent 2f6ae51 commit ceb12c5
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 13 deletions.
6 changes: 4 additions & 2 deletions riocli/apply/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import Iterable

import click
from click_help_colors import HelpColorsCommand
from typing import Iterable

from riocli.apply.explain import explain
from riocli.apply.template import template
from riocli.apply.parse import Applier
from riocli.apply.util import process_files_values_secrets
from riocli.apply.explain import explain


@click.command(
Expand Down
22 changes: 14 additions & 8 deletions riocli/apply/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

from riocli.apply.resolver import ResolverCache
from riocli.config import Configuration
from riocli.utils import dump_all_yaml
from riocli.utils import run_bash
from riocli.utils.mermaid import mermaid_link, mermaid_safe

Expand Down Expand Up @@ -138,7 +139,11 @@ def delete(self, *args, **kwargs):
if obj in self.resolved_objects and 'manifest' in self.resolved_objects[obj]:
self._delete_manifest(obj, *args, **kwargs)

def parse_dependencies(self, check_missing=True, delete=False):
def print_resolved_manifests(self):
manifests = [o for _, o in self.objects.items()]
dump_all_yaml(manifests)

def parse_dependencies(self, check_missing=True, delete=False, template=False):
number_of_objects = 0
for f, data in self.files.items():
for model in data:
Expand All @@ -157,12 +162,13 @@ def parse_dependencies(self, check_missing=True, delete=False):
action = 'DELETE'
kind = node.split(":")[0]
expected_time = round(
self.EXPECTED_TIME.get(kind.lower(), 5)/60, 2)
self.EXPECTED_TIME.get(kind.lower(), 5) / 60, 2)
total_time = total_time + expected_time
resource_list.append([node, action, expected_time])

self._display_context(
total_time=total_time, total_objects=number_of_objects, resource_list=resource_list)
if not template:
self._display_context(
total_time=total_time, total_objects=number_of_objects, resource_list=resource_list)

if check_missing:
missing_resources = []
Expand All @@ -172,7 +178,7 @@ def parse_dependencies(self, check_missing=True, delete=False):

if missing_resources:
click.secho("missing resources found in yaml. " +
"Plese ensure the following are either available in your yaml" +
"Please ensure the following are either available in your yaml" +
"or created on the server. {}".format(set(missing_resources)), fg="red")
raise SystemExit(1)

Expand Down Expand Up @@ -269,7 +275,7 @@ def _add_graph_node(self, key):
def _add_graph_edge(self, dependent_key, key):
self.graph.add(dependent_key, key)
self.diagram.append('\t{}[{}] --> {}[{}] '.format(mermaid_safe(key),
key, mermaid_safe(dependent_key), dependent_key))
key, mermaid_safe(dependent_key), dependent_key))

# Dependency Resolution
def _parse_dependency(self, dependent_key, model):
Expand Down Expand Up @@ -372,7 +378,7 @@ def _display_context(self, total_time: int, total_objects: int, resource_list: t
['Resources', total_objects],
]
click.echo(tabulate(context, headers=headers,
tablefmt='simple', numalign='center'))
tablefmt='simple', numalign='center'))

# Display Resource Inventory
headers = []
Expand All @@ -382,7 +388,7 @@ def _display_context(self, total_time: int, total_objects: int, resource_list: t
col, _ = get_terminal_size()
click.secho(" " * col, bg='blue')
click.echo(tabulate(resource_list, headers=headers,
tablefmt='simple', numalign='center'))
tablefmt='simple', numalign='center'))
click.secho(" " * col, bg='blue')

@staticmethod
Expand Down
47 changes: 47 additions & 0 deletions riocli/apply/template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright 2022 Rapyuta Robotics
#
# 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
#
# http://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.

from typing import Iterable

import click
from click_help_colors import HelpColorsCommand

from riocli.apply.parse import Applier
from riocli.apply.util import process_files_values_secrets


@click.command(
'template',
cls=HelpColorsCommand,
help_headers_color='yellow',
help_options_color='green',
)
@click.option('--values', '-v',
help="path to values yaml file. key/values specified in the values file can be used as variables in template yamls")
@click.option('--secrets', '-s',
help="secret files are sops encoded value files. rio-cli expects sops to be authorized for decoding files on this computer")
@click.argument('files', nargs=-1)
def template(values: str, secrets: str, files: Iterable[str]) -> None:
"""
Print manifests with filled values
"""
glob_files, abs_values, abs_secrets = process_files_values_secrets(
files, values, secrets)

if len(glob_files) == 0:
click.secho('no files specified', fg='red')
raise SystemExit(1)

rc = Applier(glob_files, abs_values, abs_secrets)
rc.print_resolved_manifests()
7 changes: 4 additions & 3 deletions riocli/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,16 @@
from click_plugins import with_plugins
from pkg_resources import iter_entry_points

from riocli.chart import chart
from riocli.apply import apply, explain, delete
from riocli.apply import apply, explain, delete, template
from riocli.auth import auth
from riocli.build import build
from riocli.chart import chart
from riocli.completion import completion
from riocli.config import Configuration
from riocli.deployment import deployment
from riocli.device import device
from riocli.disk import disk
from riocli.managedservice import managedservice
from riocli.marketplace import marketplace
from riocli.network import network
from riocli.package import package
Expand All @@ -40,7 +41,6 @@
from riocli.secret import secret
from riocli.shell import shell, deprecated_repl
from riocli.static_route import static_route
from riocli.managedservice import managedservice


@with_plugins(iter_entry_points('riocli.plugins'))
Expand Down Expand Up @@ -94,3 +94,4 @@ def version():
cli.add_command(shell)
cli.add_command(deprecated_repl)
cli.add_command(managedservice)
cli.add_command(template)
7 changes: 7 additions & 0 deletions riocli/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ def inspect_with_format(obj: typing.Any, format_type: str):
raise Exception('Invalid format')


def dump_all_yaml(objs: typing.List):
"""
Dump multiple documents as YAML separated by triple dash (---)
"""
click.echo(yaml.dump_all(objs, allow_unicode=True, explicit_start=True))


def run_bash(cmd, bg=False):
cmd_parts = shlex.split(cmd)

Expand Down

0 comments on commit ceb12c5

Please sign in to comment.