Skip to content

Commit dd08b90

Browse files
committed
feat: add check-status command that report in JSON the validation and sync status of organizations
1 parent 49203f2 commit dd08b90

2 files changed

Lines changed: 169 additions & 0 deletions

File tree

otterdog/cli.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,60 @@ def plan(organizations: list[str], no_web_ui, repo_filter, update_webhooks, upda
462462
),
463463
)
464464

465+
@cli.command(cls=StdCommand, short_help="Check for sync with live configuration on GitHub.")
466+
@click.option(
467+
"-n",
468+
"--no-web-ui",
469+
is_flag=True,
470+
show_default=True,
471+
default=False,
472+
help="skip settings retrieved via web ui",
473+
)
474+
@click.option(
475+
"-r",
476+
"--repo-filter",
477+
show_default=True,
478+
default="*",
479+
help="a valid shell pattern to match repository names to be included",
480+
)
481+
@click.option(
482+
"--update-webhooks",
483+
is_flag=True,
484+
show_default=True,
485+
default=False,
486+
help="updates webhook with secrets regardless of changes",
487+
)
488+
@click.option(
489+
"--update-secrets",
490+
is_flag=True,
491+
show_default=True,
492+
default=False,
493+
help="updates secrets regardless of changes",
494+
)
495+
@click.option(
496+
"--update-filter",
497+
show_default=True,
498+
default="*",
499+
help="a valid shell pattern to match webhook urls / secret names to be included for update",
500+
)
501+
def check_status(organizations: list[str], no_web_ui, repo_filter, update_webhooks, update_secrets, update_filter):
502+
"""
503+
Check the status of current configuration (validity and wether it is in sync with the GitHub live configuration).
504+
Output JSON with the status of each organization.
505+
"""
506+
from otterdog.operations.check_status import CheckStatusOperation
507+
508+
_execute_operation(
509+
organizations,
510+
CheckStatusOperation(
511+
no_web_ui=no_web_ui,
512+
repo_filter=repo_filter,
513+
update_webhooks=update_webhooks,
514+
update_secrets=update_secrets,
515+
update_filter=update_filter,
516+
),
517+
)
518+
465519

466520
@cli.command(cls=StdCommand, short_help="Show changes to another local configuration.")
467521
@click.option(
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# *******************************************************************************
2+
# Copyright (c) 2023-2024 Eclipse Foundation and others.
3+
# This program and the accompanying materials are made available
4+
# under the terms of the Eclipse Public License 2.0
5+
# which is available at http://www.eclipse.org/legal/epl-v20.html
6+
# SPDX-License-Identifier: EPL-2.0
7+
# *******************************************************************************
8+
9+
from __future__ import annotations
10+
11+
from typing import TYPE_CHECKING
12+
13+
from otterdog.models.webhook import Webhook
14+
15+
from .diff_operation import DiffOperation, DiffStatus
16+
17+
from json import dumps as json_dumps
18+
19+
if TYPE_CHECKING:
20+
from typing import Any
21+
22+
from otterdog.config import OtterdogConfig
23+
from otterdog.models import LivePatch, ModelObject
24+
from otterdog.utils import Change, IndentingPrinter
25+
26+
27+
class CheckStatusOperation(DiffOperation):
28+
"""
29+
Check the status of current configuration (validity and wether it is in sync with the GitHub live configuration)
30+
"""
31+
32+
def __init__(
33+
self,
34+
no_web_ui: bool,
35+
repo_filter: str,
36+
update_webhooks: bool,
37+
update_secrets: bool,
38+
update_filter: str,
39+
):
40+
super().__init__(no_web_ui, repo_filter, update_webhooks, update_secrets, update_filter)
41+
self.orgs_status = []
42+
43+
def init(self, config: OtterdogConfig, printer: IndentingPrinter) -> None:
44+
super().init(config, printer)
45+
46+
def pre_execute(self) -> None: ...
47+
48+
def post_execute(self) -> None:
49+
self.printer.println(json_dumps(self.orgs_status, indent=2))
50+
51+
def resolve_secrets(self) -> bool:
52+
return False
53+
54+
async def handle_finish(self, org_id: str, diff_status: DiffStatus, validation_status: ValidationStatus, patches: list[LivePatch]) -> int:
55+
self.orgs_status.append({
56+
"org_id": org_id,
57+
"validation_status": {
58+
"is_valid": validation_status.total_notices() == 0,
59+
"infos": validation_status.infos,
60+
"warnings": validation_status.warnings,
61+
"errors": validation_status.errors,
62+
},
63+
"sync_status": {
64+
"in_sync": validation_status.total_notices() == 0 and not patches,
65+
"additions": diff_status.additions,
66+
"changes": diff_status.differences,
67+
"deletions": diff_status.deletions,
68+
},
69+
})
70+
71+
return 0
72+
73+
async def validate(self, expected_org: GitHubOrganization, jsonnet_config: JsonnetConfig) -> ValidationStatus:
74+
return await self._validator.validate(expected_org, jsonnet_config, self.gh_client, False)
75+
76+
def handle_validation_status(self, validation_status: ValidationStatus) -> bool:
77+
return validation_status.errors == 0
78+
79+
def _print_project_header(
80+
self,
81+
org_config: OrganizationConfig,
82+
org_index: int | None = None,
83+
org_count: int | None = None,
84+
) -> None: ...
85+
86+
def handle_add_object(
87+
self,
88+
org_id: str,
89+
model_object: ModelObject,
90+
parent_object: ModelObject | None = None,
91+
) -> None: ...
92+
93+
def handle_delete_object(
94+
self,
95+
org_id: str,
96+
model_object: ModelObject,
97+
parent_object: ModelObject | None = None,
98+
) -> None: ...
99+
100+
def handle_modified_object(
101+
self,
102+
org_id: str,
103+
modified_object: dict[str, Change[Any]],
104+
forced_update: bool,
105+
current_object: ModelObject,
106+
expected_object: ModelObject,
107+
parent_object: ModelObject | None = None,
108+
) -> int:
109+
110+
settings_to_change = 0
111+
for k, _v in modified_object.items():
112+
if not current_object.is_read_only_key(k):
113+
settings_to_change += 1
114+
115+
return settings_to_change

0 commit comments

Comments
 (0)