Skip to content

Commit

Permalink
epicli/upgrade: reusing existing shared-config + cleanups
Browse files Browse the repository at this point in the history
  • Loading branch information
sk4zuzu committed Jul 22, 2020
1 parent 9fd78b6 commit e5957c5
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 20 deletions.
10 changes: 5 additions & 5 deletions core/src/epicli/cli/engine/UpgradeEngine.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,29 +28,29 @@ def get_backup_dirs(self):
for d in os.listdir(self.build_dir):
bd = os.path.join(self.build_dir, d)
if os.path.isdir(bd) and re.match(r'backup_\d', d): result.append(bd)
return result
return result

def backup_build(self):
# check if there are backup dirs and if so take the latest to work with.
# Check if there are backup dirs and if so take the latest to work with
backup_dirs = self.get_backup_dirs()
if len(backup_dirs) > 0:
self.backup_build_dir = max(backup_dirs , key=os.path.getmtime)
self.logger.info(f'There is already a backup present. Using latest for upgrade: "{self.backup_build_dir}"')
return

# no backup dir so use the latest
# No backup dir so use the latest
backup_dir_name = f'backup_{int(round(time.time() * 1000))}'
self.backup_build_dir = os.path.join(self.build_dir, backup_dir_name )
self.logger.info(f'Backing up build dir to "{self.backup_build_dir}"')
shutil.copytree(self.build_dir, self.backup_build_dir)

def upgrade(self):
# backup existing build
# Backup existing build
self.backup_build()

# Run Ansible to upgrade infrastructure
with AnsibleRunner(build_dir=self.build_dir, backup_build_dir=self.backup_build_dir,
ansible_options=self.ansible_options) as ansible_runner:
ansible_runner.upgrade()

return 0
return 0
39 changes: 27 additions & 12 deletions core/src/epicli/cli/engine/ansible/AnsibleInventoryUpgrade.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import os

from ansible.parsing.dataloader import DataLoader
from ansible.inventory.manager import InventoryManager

from cli.helpers.Step import Step
from cli.helpers.build_saver import get_inventory_path_for_build, check_build_output_version, BUILD_LEGACY
from cli.helpers.build_saver import save_inventory, MANIFEST_FILE_NAME
from cli.helpers.data_loader import load_yamls_file
from cli.helpers.objdict_helpers import dict_to_objdict
from cli.helpers.doc_list_helpers import select_single

from cli.models.AnsibleHostModel import AnsibleHostModel
from cli.models.AnsibleInventoryItem import AnsibleInventoryItem
from cli.helpers.build_saver import save_inventory
from cli.helpers.objdict_helpers import dict_to_objdict


class AnsibleInventoryUpgrade(Step):
Expand All @@ -14,13 +20,14 @@ def __init__(self, build_dir, backup_build_dir):
self.build_dir = build_dir
self.backup_build_dir = backup_build_dir
self.cluster_model = None
self.shared_config = None

def __enter__(self):
super().__enter__()
return self

def __exit__(self, exc_type, exc_value, traceback):
super().__exit__(exc_type, exc_value, traceback)
super().__exit__(exc_type, exc_value, traceback)

def get_role(self, inventory, role_name):
for role in inventory:
Expand All @@ -32,21 +39,21 @@ def delete_role(self, inventory, role_name):
for i in range(len(inventory)):
if inventory[i].role == role_name:
del inventory[i]
return
return

def rename_role(self, inventory, role_name, new_role_name):
role = self.get_role(inventory, role_name)
if role != None:
role.role = new_role_name

def upgrade(self):
inventory_path = get_inventory_path_for_build(self.backup_build_dir)
inventory_path = get_inventory_path_for_build(self.backup_build_dir)
build_version = check_build_output_version(self.backup_build_dir)

self.logger.info(f'Loading backup Ansible inventory: {inventory_path}')
loaded_inventory = InventoryManager(loader = DataLoader(), sources=inventory_path)

# move loaded inventory to templating structure
# Move loaded inventory to templating structure
new_inventory = []
for key in loaded_inventory.groups:
if key != 'all' and key != 'ungrouped':
Expand All @@ -56,7 +63,7 @@ def upgrade(self):
new_hosts.append(AnsibleHostModel(host.address, host.vars['ansible_host']))
new_inventory.append(AnsibleInventoryItem(key, new_hosts))

# re-constructure cluster model with all data necessary to run required upgrade rolls
# Reconstruct cluster model with all data necessary to run required upgrade rolls
self.cluster_model = dict_to_objdict({
'provider': 'any',
'specification': {
Expand All @@ -67,6 +74,14 @@ def upgrade(self):
}
})

# Reuse shared config from existing manifest
# Shared config contains the use_ha_control_plane flag which is required during upgrades
path_to_manifest = os.path.join(self.backup_build_dir, MANIFEST_FILE_NAME)
if not os.path.isfile(path_to_manifest):
raise Exception('No manifest.yml inside the build folder')
manifest_docs = load_yamls_file(path_to_manifest)
self.shared_config = select_single(manifest_docs, lambda x: x.kind == 'configuration/shared-config')

if build_version == BUILD_LEGACY:
self.logger.info(f'Upgrading Ansible inventory Epiphany < 0.3.0')

Expand All @@ -79,7 +94,7 @@ def upgrade(self):
self.rename_role(new_inventory, 'kafka-exporter', 'kafka_exporter')
self.rename_role(new_inventory, 'haproxy_tls_termination', 'haproxy')

# remove linux and reboot roles if present
# Remove linux and reboot roles if present
self.delete_role(new_inventory, 'linux')
self.delete_role(new_inventory, 'reboot')
else:
Expand All @@ -91,21 +106,21 @@ def upgrade(self):
raise Exception('No kubernetes_master to use as repository')
master_node = master.hosts[0]

# add image_registry
# Add image_registry
image_registry = self.get_role(new_inventory, 'image_registry')
if image_registry == None:
hosts = []
hosts.append(AnsibleHostModel(master_node.name, master_node.ip))
new_inventory.append(AnsibleInventoryItem('image_registry', hosts))

# add repository
# Add repository
repository = self.get_role(new_inventory, 'repository')
if repository == None:
hosts = []
hosts.append(AnsibleHostModel(master_node.name, master_node.ip))
new_inventory.append(AnsibleInventoryItem('repository', hosts))

# save new inventory
# Save new inventory
save_inventory(new_inventory, self.cluster_model, self.build_dir)

return 0
return 0
6 changes: 3 additions & 3 deletions core/src/epicli/cli/engine/ansible/AnsibleVarsGenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ def populate_group_vars(self, ansible_dir):
main_vars['is_upgrade_run'] = self.is_upgrade_run
main_vars['roles_with_generated_vars'] = sorted(self.roles_with_generated_vars)

shared_config_doc = select_first(self.config_docs, lambda x: x.kind == 'configuration/shared-config')
shared_config_doc = self.inventory_upgrade.shared_config
if shared_config_doc == None:
shared_config_doc = load_yaml_obj(types.DEFAULT, 'common', 'configuration/shared-config')

self.set_vault_path(shared_config_doc)
main_vars.update(shared_config_doc.specification)

Expand All @@ -115,7 +115,7 @@ def set_vault_path(self, shared_config):
shared_config.specification.vault_tmp_file_location = Config().vault_password_location
cluster_name = self.get_cluster_name()
shared_config.specification.vault_location = get_ansible_vault_path(cluster_name)

def get_cluster_name(self):
if 'name' in self.cluster_model.specification.keys():
return self.cluster_model.specification.name
Expand Down

0 comments on commit e5957c5

Please sign in to comment.