def __init__(self, file): """ Parse course.yml contents into instances. """ self.config = Config() self._dict = yaml.load(file) if not self.config.helm_args: self.config.helm_args = self._dict.get('helm_args') self.helm = HelmClient(default_helm_arguments=self.config.helm_args) self._repositories = [] self._charts = [] for name, repository in self._dict.get('repositories', {}).iteritems(): repository['name'] = name self._repositories.append(Repository(repository, self.helm)) for name, chart in self._dict.get('charts', {}).iteritems(): self._charts.append(Chart({name: chart}, self.helm)) for repo in self._repositories: type(repo) if not self.config.local_development: logging.debug("Installing repository: {}".format(repo)) repo.install() self.helm.repo_update() if not self.config.local_development: self._compare_required_versions()
def __init__(self, name, revision, updated, status, chart, app_version, namespace): self._dict = { 'name': name, 'revision': revision, 'updated': updated, 'status': status, 'chart': chart, 'app_version': app_version, 'namespace': namespace, } self.helm = HelmClient()
def run(self): super().run() region_name = self.get_variable('AWS_REGION') role_arn = self.get_variable('ROLE_ARN') session_name = self.get_variable('SESSION_NAME') cluster_name = self.get_variable('CLUSTER_NAME') chart = self.get_variable('CHART') release_name = self.get_variable('RELEASE_NAME') namespace = self.get_variable('NAMESPACE') set = self.get_variable('SET') values = self.get_variable('VALUES') session = botocore.session.get_session() eks_client_factory = EKSClientFactory(session) eks_client = eks_client_factory.get_eks_client( region_name=region_name, role_arn=role_arn, role_session_name=session_name) # Role Session Name is hardcoded to EKSGetTokenAuth # I do not patch this method for compatibility reasons sts_client_factory = STSClientFactory(session) sts_client = sts_client_factory.get_sts_client(region_name=region_name, role_arn=role_arn) cluster = eks_client.describe_cluster(name=cluster_name) token = TokenGenerator(sts_client).get_token(cluster_name) self._create_kubeconfig(cluster, token) # Add Bitbucket Pipeline environment for bitbucket_env in ('bitbucket_build_number', 'bitbucket_repo_slug', 'bitbucket_commit', 'bitbucket_tag', 'bitbucket_step_triggerer_uuid'): if bitbucket_env.upper() in self.env: env_value = os.environ[bitbucket_env.upper()] if bitbucket_env == 'bitbucket_step_triggerer_uuid': env_value = env_value.replace('{', '').replace('}', '') set.append(f'"bitbucket.{bitbucket_env}={env_value}"') try: helm_client = HelmClient(chart) helm_client.namespace = namespace helm_client.release = release_name helm_client.set = set helm_client.values = values helm_client_result = helm_client.install() except HelmChartNotFoundError as error: self.fail(message=f'No valid helm chart found at path {error}') except HelmError as error: self.fail(message=error) self.success(message=helm_client_result)
class Release(object): """ Description: - Active helm release Arguments: - name: release name - revision: revisioning number - updated: last updated date - status: Helm status - chart: chart name - app-version: chart version - namespace: installed namespace Attributes: - deployed: Returns list of Release() with `DEPLOYED` status - failed: Return list of Release() with `FAILED` status """ def __init__(self, name, revision, updated, status, chart, app_version, namespace): self._dict = { 'name': name, 'revision': revision, 'updated': updated, 'status': status, 'chart': chart, 'app_version': app_version, 'namespace': namespace, } self.helm = HelmClient() def __getattr__(self, key): return self._dict.get(key) def __str__(self): return str(self._dict) @property def deployed(self): """Boolean test for Releas().status.""" if self.status == 'DEPLOYED': return True return False @property def failed(self): """Boolean test for Release().status""" if self.status == 'FAILED': return True return False def rollback(self): """ Roll back current release """ return self.helm.rollback(self.name, self.revision)
class Course(object): """ Description: - Top level class for the attributes of the course.yml file - Parses yaml file into various Reckoner classes Arguments: - file (File) Attributes: - config: Instance of Config() - helm: Instance of HelmClient() - charts: List of Chart() instances - repositories: List of Repository() instances """ def __init__(self, file): """ Parse course.yml contents into instances. """ self.config = Config() self._dict = yaml.load(file) if not self.config.helm_args: self.config.helm_args = self._dict.get('helm_args') self.helm = HelmClient(default_helm_arguments=self.config.helm_args) self._repositories = [] self._charts = [] for name, repository in self._dict.get('repositories', {}).iteritems(): repository['name'] = name self._repositories.append(Repository(repository, self.helm)) for name, chart in self._dict.get('charts', {}).iteritems(): self._charts.append(Chart({name: chart}, self.helm)) for repo in self._repositories: type(repo) if not self.config.local_development: logging.debug("Installing repository: {}".format(repo)) repo.install() self.helm.repo_update() if not self.config.local_development: self._compare_required_versions() def __str__(self): return str(self._dict) @property def repositories(self): """ Course repositories """ return self._repositories def __getattr__(self, key): return self._dict.get(key) @property def charts(self): """ List of Chart() instances """ return self._charts def plot(self, charts_to_install): """ Accepts charts_to_install, an interable of the names of the charts to install. This method compares the charts in the argument to the charts in the course and calls Chart.install() """ _charts = [] _failed_charts = [] self._charts_to_install = [] try: iter(charts_to_install) except TypeError: charts_to_install = charts_to_install for chart in self.charts: if chart.release_name in charts_to_install: self._charts_to_install.append(chart) for chart in self._charts_to_install: logging.info("Installing {}".format(chart.release_name)) try: chart.install(namespace=self.namespace, context=self.context) except (Exception, ReckonerCommandException), e: if type(e) == ReckonerCommandException: logging.error(e.stderr) if type(e) == Exception: logging.error(e) logging.error('Helm upgrade failed. Rolling back {}'.format(chart.release_name)) logging.debug(traceback.format_exc()) chart.rollback _failed_charts.append(chart) if _failed_charts: logging.error("ERROR: Some charts failed to install and were rolled back") for chart in _failed_charts: logging.error(" - {}".format(chart.release_name)) return True