Skip to content

Commit 87d901c

Browse files
Merge pull request #69 from baloise-incubator/feat/sync-apps-enhancement
Feat/sync apps enhancement
2 parents 907ef8c + a3ac7c8 commit 87d901c

1 file changed

Lines changed: 61 additions & 40 deletions

File tree

gitopscli/commands/sync_apps.py

Lines changed: 61 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import os
33
import shutil
44
import uuid
5-
from pprint import pformat
65

76
from ruamel.yaml import YAML
87

@@ -64,39 +63,67 @@ def sync_apps_command(
6463

6564

6665
def __sync_apps(apps_git, root_git):
66+
logging.info("Apps repository: %s", apps_git.get_clone_url())
67+
logging.info("Root repository: %s", root_git.get_clone_url())
68+
6769
repo_apps = __get_repo_apps(apps_git)
68-
apps_config_file, app_file_name, apps_from_other_repos = __find_apps_config_from_repo(apps_git, root_git)
70+
logging.info("Found %s app(s) in apps repository: %s", len(repo_apps), ", ".join(repo_apps))
71+
72+
repo_apps.add("test-app")
73+
74+
logging.info("Searching apps repository in root repository's 'apps/' directory...")
75+
apps_config_file, apps_config_file_name, current_repo_apps, apps_from_other_repos = __find_apps_config_from_repo(
76+
apps_git, root_git
77+
)
78+
if apps_config_file is None:
79+
raise GitOpsException(f"Could't find config file for apps repository in root repository's 'apps/' directory")
80+
81+
if current_repo_apps == repo_apps:
82+
logging.info("Root repository already up-to-date. I'm done here.")
83+
return
84+
6985
__check_if_app_already_exists(repo_apps, apps_from_other_repos)
70-
merge_yaml_element(apps_config_file, "applications", repo_apps, True)
71-
__commit_and_push(apps_git, root_git, app_file_name)
86+
87+
logging.info("Sync applications in root repository's %s.", apps_config_file_name)
88+
merge_yaml_element(apps_config_file, "applications", dict.fromkeys(repo_apps, {}), True)
89+
__commit_and_push(apps_git, root_git, apps_config_file_name)
7290

7391

7492
def __find_apps_config_from_repo(apps_git, root_git):
75-
logging.info("Searching for %s in apps/", apps_git.get_clone_url())
7693
yaml = YAML()
77-
# List for all entries in .applications from each config repository
78-
apps_from_other_repos = []
94+
apps_from_other_repos = [] # List for all entries in .applications from each config repository
7995
found_app_config_file = None
8096
found_app_config_file_name = None
81-
app_file_entries = __get_bootstrap_entries(root_git)
82-
for app_file in app_file_entries:
83-
app_file_name = "apps/" + app_file["name"] + ".yaml"
84-
logging.info("Analyzing %s", app_file_name)
97+
found_app_config_apps = set()
98+
bootstrap_entries = __get_bootstrap_entries(root_git)
99+
for bootstrap_entry in bootstrap_entries:
100+
if "name" not in bootstrap_entry:
101+
raise GitOpsException("Every bootstrap entry must have a 'name' property.")
102+
app_file_name = "apps/" + bootstrap_entry["name"] + ".yaml"
103+
logging.info("Analyzing %s in root repository", app_file_name)
85104
app_config_file = root_git.get_full_file_path(app_file_name)
86-
with open(app_config_file, "r") as stream:
87-
app_config_content = yaml.load(stream)
105+
try:
106+
with open(app_config_file, "r") as stream:
107+
app_config_content = yaml.load(stream)
108+
except FileNotFoundError as ex:
109+
raise GitOpsException(f"File '{app_file_name}' not found in root repository.") from ex
110+
if "repository" not in app_config_content:
111+
raise GitOpsException(f"Cannot find key 'repository' in '{app_file_name}'")
88112
if app_config_content["repository"] == apps_git.get_clone_url():
89-
logging.info("Found repository in %s", app_file_name)
113+
logging.info("Found apps repository in %s", app_file_name)
90114
found_app_config_file = app_config_file
91115
found_app_config_file_name = app_file_name
116+
found_app_config_apps = __get_applications_from_app_config(app_config_content)
92117
else:
93-
if "applications" in app_config_content and app_config_content["applications"] is not None:
94-
apps_from_other_repos += app_config_content["applications"].keys()
95-
if found_app_config_file is None:
96-
raise GitOpsException(
97-
f"Could't find config file with .repository={apps_git.get_clone_url()} in apps/ directory"
98-
)
99-
return found_app_config_file, found_app_config_file_name, apps_from_other_repos
118+
apps_from_other_repos += __get_applications_from_app_config(app_config_content)
119+
return found_app_config_file, found_app_config_file_name, found_app_config_apps, apps_from_other_repos
120+
121+
122+
def __get_applications_from_app_config(app_config):
123+
apps = []
124+
if "applications" in app_config and app_config["applications"] is not None:
125+
apps += app_config["applications"].keys()
126+
return set(apps)
100127

101128

102129
def __commit_and_push(apps_git, root_git, app_file_name):
@@ -106,35 +133,29 @@ def __commit_and_push(apps_git, root_git, app_file_name):
106133

107134

108135
def __get_bootstrap_entries(root_git):
109-
yaml = YAML()
110136
root_git.checkout("master")
111137
bootstrap_values_file = root_git.get_full_file_path("bootstrap/values.yaml")
112-
with open(bootstrap_values_file, "r") as stream:
113-
bootstrap = yaml.load(stream)
114-
return bootstrap["bootstrap"]
138+
try:
139+
with open(bootstrap_values_file, "r") as stream:
140+
bootstrap_yaml = YAML().load(stream)
141+
except FileNotFoundError as ex:
142+
raise GitOpsException("File 'bootstrap/values.yaml' not found in root repository.") from ex
143+
if "bootstrap" not in bootstrap_yaml:
144+
raise GitOpsException("Cannot find key 'bootstrap' in 'bootstrap/values.yaml'")
145+
return bootstrap_yaml["bootstrap"]
115146

116147

117148
def __get_repo_apps(apps_git):
118149
apps_git.checkout("master")
119150
repo_dir = apps_git.get_full_file_path(".")
120-
apps_dirs = __get_application_directories(repo_dir)
121-
logging.info("Apps in %s\n%s", apps_git.get_clone_url(), pformat(apps_dirs))
122-
return apps_dirs
123-
124-
125-
def __get_application_directories(full_file_path):
126-
app_dirs = [
151+
return {
127152
name
128-
for name in os.listdir(full_file_path)
129-
if os.path.isdir(os.path.join(full_file_path, name)) and not name.startswith(".")
130-
]
131-
apps = {}
132-
for app_dir in app_dirs:
133-
apps[app_dir] = {}
134-
return apps
153+
for name in os.listdir(repo_dir)
154+
if os.path.isdir(os.path.join(repo_dir, name)) and not name.startswith(".")
155+
}
135156

136157

137158
def __check_if_app_already_exists(apps_dirs, apps_from_other_repos):
138159
for app_key in apps_dirs:
139160
if app_key in apps_from_other_repos:
140-
raise GitOpsException(f"application: {app_key} already exists in a different repository")
161+
raise GitOpsException(f"application '{app_key}' already exists in a different repository")

0 commit comments

Comments
 (0)