cortexapps-cli 1.21.0__tar.gz → 1.22.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/PKG-INFO +1 -1
  2. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/cli.py +13 -0
  3. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/deploys.py +3 -3
  4. cortexapps_cli-1.22.0/cortexapps_cli/commands/solutions.py +190 -0
  5. cortexapps_cli-1.22.0/cortexapps_cli/solutions/__init__.py +0 -0
  6. cortexapps_cli-1.22.0/cortexapps_cli/solutions/github-starter/README.md +50 -0
  7. cortexapps_cli-1.22.0/cortexapps_cli/solutions/github-starter/scorecards/github-readiness.yaml +15 -0
  8. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/pyproject.toml +1 -1
  9. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/LICENSE +0 -0
  10. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/README.rst +0 -0
  11. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/__init__.py +0 -0
  12. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/command_options.py +0 -0
  13. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/api_keys.py +0 -0
  14. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/audit_logs.py +0 -0
  15. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/backup.py +0 -0
  16. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/backup_commands/cortex_export.py +0 -0
  17. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/catalog.py +0 -0
  18. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/custom_data.py +0 -0
  19. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/custom_events.py +0 -0
  20. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/custom_metrics.py +0 -0
  21. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/dependencies.py +0 -0
  22. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/discovery_audit.py +0 -0
  23. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/docs.py +0 -0
  24. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/entity_relationship_types.py +0 -0
  25. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/entity_relationships.py +0 -0
  26. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/entity_types.py +0 -0
  27. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/gitops_logs.py +0 -0
  28. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/groups.py +0 -0
  29. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/initiatives.py +0 -0
  30. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations.py +0 -0
  31. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/apiiro.py +0 -0
  32. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/argocd.py +0 -0
  33. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/aws.py +0 -0
  34. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/azure_active_directory.py +0 -0
  35. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/azure_devops.py +0 -0
  36. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/azure_resources.py +0 -0
  37. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/bamboohr.py +0 -0
  38. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/bitbucket.py +0 -0
  39. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/bugsnag.py +0 -0
  40. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/buildkite.py +0 -0
  41. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/checkmarx_sast.py +0 -0
  42. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/circleci.py +0 -0
  43. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/clickup.py +0 -0
  44. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/codecov.py +0 -0
  45. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/coralogix.py +0 -0
  46. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/datadog.py +0 -0
  47. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/dynatrace.py +0 -0
  48. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/firehydrant.py +0 -0
  49. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/github.py +0 -0
  50. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/gitlab.py +0 -0
  51. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/incidentio.py +0 -0
  52. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/instana.py +0 -0
  53. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/jenkins.py +0 -0
  54. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/jira.py +0 -0
  55. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/launchdarkly.py +0 -0
  56. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/mend_sast.py +0 -0
  57. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/mend_sca.py +0 -0
  58. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/newrelic.py +0 -0
  59. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/okta.py +0 -0
  60. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/opsgenie.py +0 -0
  61. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/pagerduty.py +0 -0
  62. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/prometheus.py +0 -0
  63. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/rollbar.py +0 -0
  64. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/rootly.py +0 -0
  65. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/semgrep.py +0 -0
  66. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/sentry.py +0 -0
  67. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/servicenow.py +0 -0
  68. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/servicenow_cloud_observability.py +0 -0
  69. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/snyk.py +0 -0
  70. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/sonarqube.py +0 -0
  71. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/splunk_observability_cloud.py +0 -0
  72. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/splunk_on_call.py +0 -0
  73. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/sumologic.py +0 -0
  74. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/veracode.py +0 -0
  75. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/wiz.py +0 -0
  76. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/workday.py +0 -0
  77. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/integrations_commands/xmatters.py +0 -0
  78. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/ip_allowlist.py +0 -0
  79. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/on_call.py +0 -0
  80. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/packages.py +0 -0
  81. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/packages_commands/go.py +0 -0
  82. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/packages_commands/java.py +0 -0
  83. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/packages_commands/node.py +0 -0
  84. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/packages_commands/nuget.py +0 -0
  85. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/packages_commands/python.py +0 -0
  86. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/plugins.py +0 -0
  87. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/queries.py +0 -0
  88. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/rest.py +0 -0
  89. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/scim.py +0 -0
  90. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/scorecards.py +0 -0
  91. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/scorecards_commands/exemptions.py +0 -0
  92. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/secrets.py +0 -0
  93. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/teams.py +0 -0
  94. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/users.py +0 -0
  95. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/users_commands/roles.py +0 -0
  96. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/commands/workflows.py +0 -0
  97. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/cortex_client.py +0 -0
  98. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/models/team.py +0 -0
  99. {cortexapps_cli-1.21.0 → cortexapps_cli-1.22.0}/cortexapps_cli/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cortexapps-cli
3
- Version: 1.21.0
3
+ Version: 1.22.0
4
4
  Summary: Command Line Interface for cortexapps
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -41,6 +41,7 @@ import cortexapps_cli.commands.rest as rest
41
41
  import cortexapps_cli.commands.scim as scim
42
42
  import cortexapps_cli.commands.scorecards as scorecards
43
43
  import cortexapps_cli.commands.secrets as secrets
44
+ import cortexapps_cli.commands.solutions as solutions
44
45
  import cortexapps_cli.commands.teams as teams
45
46
  import cortexapps_cli.commands.users as users
46
47
  import cortexapps_cli.commands.workflows as workflows
@@ -85,6 +86,17 @@ def global_callback(
85
86
  if ctx.invoked_subcommand == "login":
86
87
  return
87
88
 
89
+ if ctx.invoked_subcommand == "solutions":
90
+ ctx.obj["_auth_params"] = {
91
+ "api_key": api_key,
92
+ "url": url,
93
+ "config_file": config_file,
94
+ "tenant": tenant,
95
+ "log_level": log_level,
96
+ "rate_limit": rate_limit,
97
+ }
98
+ return
99
+
88
100
  numeric_level = getattr(logging, log_level.upper(), None)
89
101
  if not isinstance(numeric_level, int):
90
102
  raise ValueError(f"Invalid log level: {log_level}")
@@ -264,6 +276,7 @@ app.add_typer(rest.app, name="rest")
264
276
  app.add_typer(scim.app, name="scim")
265
277
  app.add_typer(scorecards.app, name="scorecards")
266
278
  app.add_typer(secrets.app, name="secrets")
279
+ app.add_typer(solutions.app, name="solutions")
267
280
  app.add_typer(teams.app, name="teams")
268
281
  app.add_typer(users.app, name="users")
269
282
  app.command()(version)
@@ -1,5 +1,5 @@
1
1
  from collections import defaultdict
2
- from datetime import datetime
2
+ from datetime import datetime, timezone
3
3
  from enum import Enum
4
4
  import json
5
5
  from rich import print_json
@@ -168,7 +168,7 @@ def add(
168
168
 
169
169
  if customData:
170
170
  data["customData"] = dict(customData)
171
- data["timestamp"] = data["timestamp"].strftime('%Y-%m-%dT%H:%M:%SZ')
171
+ data["timestamp"] = data["timestamp"].astimezone(timezone.utc).strftime('%Y-%m-%dT%H:%M:%SZ')
172
172
 
173
173
  r = client.post("api/v1/catalog/" + tag + "/deploys", data=data)
174
174
  print_json(data=r)
@@ -236,7 +236,7 @@ def update_by_uuid(
236
236
  data["deployer"]["email"] = email
237
237
  if name:
238
238
  data["deployer"]["name"] = name
239
- data["timestamp"] = data["timestamp"].strftime('%Y-%m-%dT%H:%M:%SZ')
239
+ data["timestamp"] = data["timestamp"].astimezone(timezone.utc).strftime('%Y-%m-%dT%H:%M:%SZ')
240
240
 
241
241
  r = client.put("api/v1/catalog/" + tag + "/deploys/" + uuid, data=data)
242
242
  print_json(data=r)
@@ -0,0 +1,190 @@
1
+ import configparser
2
+ import logging
3
+ import os
4
+ import re
5
+ from importlib.resources import as_file, files
6
+
7
+ import typer
8
+ import yaml
9
+ from rich.console import Console
10
+ from rich.markdown import Markdown
11
+ from rich.table import Table
12
+
13
+ from cortexapps_cli.cortex_client import CortexClient
14
+
15
+ app = typer.Typer(help="Solutions commands", no_args_is_help=True)
16
+ console = Console()
17
+
18
+
19
+ def _solutions_root():
20
+ return files("cortexapps_cli.solutions")
21
+
22
+
23
+ def _list_solution_tags() -> list[str]:
24
+ root = _solutions_root()
25
+ return sorted(
26
+ item.name
27
+ for item in root.iterdir()
28
+ if item.is_dir() and not item.name.startswith("_")
29
+ )
30
+
31
+
32
+ def _parse_frontmatter(content: str) -> dict:
33
+ """Parse YAML frontmatter block from README content."""
34
+ match = re.match(r"^---\n(.*?)\n---\n", content, re.DOTALL)
35
+ if not match:
36
+ return {}
37
+ try:
38
+ return yaml.safe_load(match.group(1)) or {}
39
+ except yaml.YAMLError:
40
+ return {}
41
+
42
+
43
+ def _get_readme(tag: str) -> str | None:
44
+ """Return README.md content for a solution tag, or None if not found."""
45
+ try:
46
+ return (_solutions_root() / tag / "README.md").read_text(encoding="utf-8")
47
+ except Exception:
48
+ return None
49
+
50
+
51
+ def _build_client(ctx: typer.Context) -> CortexClient:
52
+ """Build a CortexClient from auth params stored by global_callback."""
53
+ params = ctx.obj.get("_auth_params", {})
54
+ api_key = params.get("api_key")
55
+ url = params.get("url")
56
+ config_file = params.get(
57
+ "config_file",
58
+ os.path.join(os.path.expanduser("~"), ".cortex", "config"),
59
+ )
60
+ tenant = params.get("tenant", "default")
61
+ log_level_str = params.get("log_level", "WARNING")
62
+ rate_limit = params.get("rate_limit")
63
+
64
+ if not os.path.isfile(config_file):
65
+ if not api_key:
66
+ typer.echo(
67
+ "Error: Authentication required. Run 'cortex login' first or set CORTEX_API_KEY."
68
+ )
69
+ raise typer.Exit(1)
70
+ else:
71
+ config = configparser.ConfigParser()
72
+ config.read(config_file)
73
+ if not api_key:
74
+ if tenant not in config:
75
+ typer.echo(
76
+ f"Error: Tenant '{tenant}' not found in config. Run 'cortex login' first."
77
+ )
78
+ raise typer.Exit(1)
79
+ api_key = config[tenant].get("api_key")
80
+ if not api_key:
81
+ typer.echo(
82
+ f"Error: No api_key found for tenant '{tenant}' in config. Run 'cortex login' first."
83
+ )
84
+ raise typer.Exit(1)
85
+ if not url:
86
+ url = config[tenant].get("base_url", "https://api.getcortexapp.com")
87
+
88
+ if not url:
89
+ url = "https://api.getcortexapp.com"
90
+
91
+ api_key = api_key.strip("\"' ")
92
+ url = url.strip("\"' /")
93
+
94
+ numeric_level = getattr(logging, log_level_str.upper(), logging.WARNING)
95
+ return CortexClient(api_key, tenant, numeric_level, url, rate_limit)
96
+
97
+
98
+ @app.command("list")
99
+ def list_solutions(ctx: typer.Context):
100
+ """List all available solutions."""
101
+ tags = _list_solution_tags()
102
+ table = Table(title="Available Solutions")
103
+ table.add_column("Tag", style="cyan", no_wrap=True)
104
+ table.add_column("Name")
105
+ table.add_column("Description")
106
+ for tag in tags:
107
+ readme = _get_readme(tag)
108
+ if readme is None:
109
+ continue
110
+ fm = _parse_frontmatter(readme)
111
+ table.add_row(tag, fm.get("name", tag), fm.get("description", ""))
112
+ console.print(table)
113
+
114
+
115
+ def _print_readme(text: str) -> None:
116
+ """Render README with left-justified headings and Rich Markdown body blocks."""
117
+ # Strip YAML frontmatter
118
+ body = re.sub(r"^---\n.*?\n---\n", "", text, flags=re.DOTALL).strip()
119
+
120
+ heading_styles = {"# ": "bold", "## ": "bold underline", "### ": "bold"}
121
+ pending: list[str] = []
122
+ in_code_block = False
123
+
124
+ def flush() -> None:
125
+ block = "\n".join(pending).strip()
126
+ if block:
127
+ console.print(Markdown(block))
128
+ pending.clear()
129
+
130
+ for line in body.split("\n"):
131
+ if line.startswith("```"):
132
+ if not in_code_block:
133
+ flush()
134
+ in_code_block = not in_code_block
135
+ continue
136
+
137
+ if in_code_block:
138
+ console.print(f" [cyan]{line}[/cyan]" if line else "")
139
+ continue
140
+
141
+ for prefix, style in heading_styles.items():
142
+ if line.startswith(prefix):
143
+ flush()
144
+ console.print(f"\n[{style}]{line[len(prefix):]}[/{style}]")
145
+ break
146
+ else:
147
+ pending.append(line)
148
+
149
+ flush()
150
+
151
+
152
+ @app.command()
153
+ def info(
154
+ ctx: typer.Context,
155
+ solution: str = typer.Option(..., "--solution", "-s", help="Solution tag"),
156
+ ):
157
+ """Show README for a solution."""
158
+ readme = _get_readme(solution)
159
+ if readme is None:
160
+ avail = ", ".join(_list_solution_tags())
161
+ typer.echo(f"Error: Solution '{solution}' not found. Available: {avail}")
162
+ raise typer.Exit(1)
163
+ _print_readme(readme)
164
+
165
+
166
+ @app.command()
167
+ def install(
168
+ ctx: typer.Context,
169
+ solution: str = typer.Option(..., "--solution", "-s", help="Solution tag"),
170
+ force: bool = typer.Option(False, "--force", help="Recreate entities if they already exist"),
171
+ show_info: bool = typer.Option(True, "--info/--no-info", help="Show solution README after installing"),
172
+ ):
173
+ """Install a solution into the current Cortex workspace."""
174
+ if solution not in _list_solution_tags():
175
+ avail = ", ".join(_list_solution_tags())
176
+ typer.echo(f"Error: Solution '{solution}' not found. Available: {avail}")
177
+ raise typer.Exit(1)
178
+
179
+ ctx.obj["client"] = _build_client(ctx)
180
+
181
+ import cortexapps_cli.commands.backup as backup
182
+
183
+ with as_file(_solutions_root() / solution) as solution_path:
184
+ backup.import_tenant(ctx, directory=str(solution_path), force=force)
185
+
186
+ if show_info:
187
+ readme = _get_readme(solution)
188
+ if readme:
189
+ console.print()
190
+ _print_readme(readme)
@@ -0,0 +1,50 @@
1
+ ---
2
+ name: GitHub Starter
3
+ description: Pre-configured scorecards for a GitHub-integrated Cortex workspace.
4
+ ---
5
+
6
+ # GitHub Starter
7
+
8
+ This solution provides a starting point for teams using GitHub with Cortex.
9
+
10
+ ## Overview
11
+
12
+ ```
13
+ ┌────────────────┐ GitHub integration ┌─────────────────┐
14
+ │ GitHub Repo │ ─────────────────────▶ │ Service Entity │
15
+ └────────────────┘ └────────┬────────┘
16
+ │ evaluated by
17
+
18
+ ┌─────────────────────┐
19
+ │ GitHub Readiness │
20
+ │ Scorecard │
21
+ ├─────────────────────┤
22
+ │ 🥉 Bronze │
23
+ │ git != null │
24
+ └─────────────────────┘
25
+ ```
26
+
27
+ ## What's Included
28
+
29
+ - **GitHub Readiness Scorecard** — checks that services have GitHub repositories configured
30
+
31
+ ## Prerequisites
32
+
33
+ - GitHub integration enabled in your Cortex workspace
34
+
35
+ ## Installation
36
+
37
+ ```
38
+ cortex solutions install -s github-starter
39
+ ```
40
+
41
+ To overwrite existing resources:
42
+
43
+ ```
44
+ cortex solutions install -s github-starter --force
45
+ ```
46
+
47
+ ## After Installing
48
+
49
+ Run `cortex scorecards list` to confirm the scorecard was imported, then navigate
50
+ to the Scorecards page in the Cortex UI to see scores across your services.
@@ -0,0 +1,15 @@
1
+ tag: github-readiness
2
+ name: GitHub Readiness
3
+ description: Basic checks for GitHub integration readiness
4
+ ladder:
5
+ levels:
6
+ - name: Bronze
7
+ rank: 1
8
+ description: Basic GitHub configuration
9
+ color: "#CD7F32"
10
+ rules:
11
+ - title: Has GitHub repository
12
+ description: Service has a GitHub repository configured
13
+ expression: "git != null"
14
+ weight: 1
15
+ level: Bronze
@@ -1,7 +1,7 @@
1
1
  [tool.poetry]
2
2
  name = "cortexapps-cli"
3
3
  # version will be incremented via command line as part of github actions build
4
- version = "1.21.0"
4
+ version = "1.22.0"
5
5
  description = "Command Line Interface for cortexapps"
6
6
  license = "MIT"
7
7
  authors = [
File without changes