def k3d_get(cluster): # Get k3d clusters try: logger.debug('Running: `k3d cluster list`') result = s.run(['k3d', 'cluster', 'list'], capture_output=True, check=True) k3d_clusters = result.stdout.decode('utf-8').splitlines() for cluster_info in k3d_clusters: found = re.findall('\\b{}\\b'.format(cluster), cluster_info) if found: return True # If cluster is not found return False except s.CalledProcessError as error: logger.critical(error.stderr.decode('utf-8')) raise click.Abort()
def info(ctx, kube_context): """Get info on accessing the platform""" kube_context = ctx.kube_context try: k1s_host = s.run([ 'kubectl', '--context', 'k3d-' + kube_context, '-n', 'k1s', 'get', 'ingressroute', 'ui', '-o', 'jsonpath={.spec.routes[0].match}' ], capture_output=True, check=True) k1s_host = k1s_host.stdout.decode('utf-8') k1s_host = k1s_host.split('`') k1s_url = k1s_host[1] logger.info('K1S can be accessed through the URL:') logger.info('https://' + k1s_url + '/') except s.CalledProcessError as error: logger.debug(error.stderr.decode('utf-8')) raise click.Abort()
def delete(ctx, kube_context): """Delete a k3d cluster""" # Check if the k3d cluster exists kube_context = ctx.kube_context if not k3d.k3d_get(kube_context): logger.error('K3D cluster \'' + kube_context + '\' doesn\'t exist') raise click.Abort() # Delete the k3d cluster try: logger.debug('Running: `k3d cluster delete`') _delete_cluster = s.run(['k3d', 'cluster', 'delete', kube_context], capture_output=False, check=True) except s.CalledProcessError as error: logger.critical('Could not delete k3d cluster' + error.stderr.decode('utf-8'))
def get_submodules(repo, submodules): # Based on provided submodules through arguments set the repo objects # that we want to work with if submodules == 'all': submodules = repo.submodules submodule_list = [] for submodule in submodules: submodule_list.append(submodule.name) submodules = submodule_list else: submodules = submodules.split(',') submodule_list = [] for submodule in submodules: submodule_list.append('platform/' + submodule) submodules = submodule_list logger.debug('The provided submodules are:') logger.debug(submodules) return (submodules)
def token(ctx, kube_context): """Get the platform token required by Kubernetes Dashboard""" kube_context = ctx.kube_context try: proc1 = s.Popen([ 'kubectl', '--context', 'k3d-' + kube_context, '-n', 'monitoring', 'describe', 'secret', 'k1s-admin' ], stdout=s.PIPE) proc2 = s.Popen(['grep', 'token:'], stdin=proc1.stdout, stdout=s.PIPE, universal_newlines=True) proc1.stdout.close() out = proc2.communicate()[0] logger.info('The platform token is:\n') logger.info(out) except s.CalledProcessError as error: logger.debug(error.stderr.decode('utf-8')) raise click.Abort()
def stop(ctx, kube_context): """Stop k3d cluster""" # Check the cluster status kube_context = ctx.kube_context if k3d.k3d_get(kube_context): if not kube.kubectl_info(kube_context): logger.info('K3D cluster \'' + kube_context + '\' is already stopped') raise click.Abort() elif not k3d.k3d_get(kube_context): logger.error('K3D cluster \'' + kube_context + '\' doesn\'t exist') raise click.Abort() # Stop the k3d cluster try: logger.debug('Running: `k3d cluster stop`') _stop_cluster = s.run(['k3d', 'cluster', 'stop', kube_context], capture_output=False, check=True) except s.CalledProcessError as error: logger.critical('Could not stop k3d cluster' + error.stderr.decode('utf-8'))
def kubectl_info(cluster): # Get kubectl cluster-info try: logger.debug('Running: `kubectl cluster-info`') result = s.run( ['kubectl', 'cluster-info', '--context', 'k3d-' + cluster], capture_output=True, check=True) logger.debug(result.stdout.decode('utf-8')) return True except s.CalledProcessError as error: logger.debug(error.stderr.decode('utf-8')) return False
def cli(ctx, kube_context): """Preflight checks to ensure all tools and versions are present""" # Check go try: go_ver = s.run(['go', 'version'], capture_output=True, check=True) logger.info('Found go.') logger.debug(go_ver.stdout.decode('utf-8')) except FileNotFoundError: logger.critical('go not found in PATH.') except s.CalledProcessError as error: logger.critical('go version returned something unexpected: ' + error.stderr.decode('utf-8')) # Check docker try: docker_ps = s.run(['docker', 'ps'], capture_output=True, check=True) logger.info('Found docker.') logger.debug(docker_ps.stdout.decode('utf-8')) except FileNotFoundError: logger.critical('docker not found in PATH.') except s.CalledProcessError as error: logger.critical('`docker ps` returned something unexpected: ' + error.stderr.decode('utf-8')) logger.critical('Please ensure the docker daemon is running and that ' 'your user is part of the docker group. See README') # Check helm 3 try: helm_ver = s.run(['helm', 'version', '--short'], capture_output=True, check=True) # Check that we have helm 3 if helm_ver.stdout.decode('utf-8')[1] != "3": logger.error( 'Old version of helm detected when running "helm" from PATH.') else: logger.info('Found helm.') logger.debug(helm_ver.stdout.decode('utf-8')) except FileNotFoundError: logger.critical('helm not found in PATH.') except s.CalledProcessError as error: logger.critical('helm version returned something unexpected: ' + error.stderr.decode('utf-8')) # Check k3d try: k3d_ver = s.run(['k3d', 'version'], capture_output=True, check=True) logger.info('Found k3d.') logger.debug(k3d_ver.stdout.decode('utf-8')) except FileNotFoundError: logger.critical('k3d not found in PATH.') except s.CalledProcessError as error: logger.critical('k3d version returned something unexpected: ' + error.stderr.decode('utf-8')) # Check skaffold try: skaffold_ver = s.run(['skaffold', 'version'], capture_output=True, check=True) logger.info('Found skaffold.') logger.debug(skaffold_ver.stdout.decode('utf-8')) except FileNotFoundError: logger.critical('skaffold not found in PATH.') except s.CalledProcessError as error: logger.critical('skaffold version returned something unexpected: ' + error.stderr.decode('utf-8')) # Check kubectl try: kubectl_ver = s.run(['kubectl', 'version', '--client=true'], capture_output=True, check=True) logger.info('Found kubectl.') logger.debug(kubectl_ver.stdout.decode('utf-8')) except FileNotFoundError: logger.critical('kubectl not found in PATH.') except s.CalledProcessError as error: logger.critical('kubectl version returned something unexpected: ' + error.stderr.decode('utf-8'))
def version(ctx, kube_context, submodules, repopath): """Check versions of services in git submodules You can provide a comma separated list of submodules or you can use 'all' for all submodules""" # Get the repo from arguments defaults to cwd repo = get_repo(repopath) submodules = get_submodules(repo, submodules) # Do something with the submodules all_sm_details = [] with click_spinner.spinner(): for submodule in submodules: logger.debug('Switched to submodule: ' + submodule) sm_details = {} sm_details['repo'] = submodule # Are we on an active branch? on a tag? if not then get sha? try: smrepo = git.Repo(submodule) sm_details['present'] = True except git.InvalidGitRepositoryError as error: logger.warning(submodule + ': not present') sm_details['present'] = False all_sm_details.append(sm_details) continue # Get branch try: branch = smrepo.active_branch.name sm_details['branch'] = branch # Check if remotes are ahead or behind origin = smrepo.remotes.origin origin.fetch() commits_behind = smrepo.iter_commits(branch + '..origin/' + branch) commits_ahead = smrepo.iter_commits('origin/' + branch + '..' + branch) sm_details['commits_ahead'] = sum(1 for c in commits_ahead) sm_details['commits_behind'] = sum(1 for c in commits_behind) except TypeError as error: sm_details['branch'] = '' logger.debug(error) # Check if we point to any tags points_at_tag = smrepo.git.tag('--points-at', 'HEAD') sm_details['tag'] = points_at_tag # Get sha of HEAD sha = smrepo.head.commit.hexsha sm_details['sha'] = sha # Add submodule details to the list all_sm_details.append(sm_details) logger.debug('Received following details about the platform submodules:') logger.debug(all_sm_details) for sm_details in all_sm_details: logger.info(sm_details['repo'] + ':') logger.info('Branch: ' + sm_details['branch']) logger.info('SHA: ' + sm_details['sha']) if sm_details['tag']: logger.info('Tag: ' + sm_details['tag']) if sm_details['commits_ahead'] > 0: logger.info('Ahead by: ' + str(sm_details['commits_ahead']) + ' commits') if sm_details['commits_behind'] > 0: logger.info('Behind by: ' + str(sm_details['commits_behind']) + ' commits')
def create(ctx, kube_context): """Create a k3d cluster""" # Check if k3d cluster is already created kube_context = ctx.kube_context if k3d.k3d_get(kube_context): logger.error('K3D cluster \'' + kube_context + '\' already exists') raise click.Abort() # Create the k3d cluster try: logger.debug('Running: `k3d cluster create`') _create_cluster = s.run(['k3d', 'cluster', 'create', '--k3s-server-arg', '--no-deploy=traefik', '--port', '80:80@loadbalancer', '--port', '443:443@loadbalancer', '--port', '8080:8080@loadbalancer', kube_context], capture_output=False, check=True) except s.CalledProcessError as error: logger.critical('Could not create k3d cluster' + error.stderr.decode('utf-8')) # Create required namespaces namespaces = [kube_context, 'traefik', 'monitoring'] for ns in namespaces: ns_exists = s.run(['kubectl', 'get', 'ns', ns, '--context', 'k3d-' + kube_context], capture_output=True) if ns_exists.returncode != 0: try: _app_ns = s.run(['kubectl', 'create', 'ns', ns, '--context', 'k3d-' + kube_context], check=True, stdout=s.DEVNULL) except s.CalledProcessError as error: logger.error('Something went wrong with namespace: ' + error.stderr.decode('utf-8')) raise click.Abort() else: logger.info('Skipping creation of ' + ns + ' namespace ' 'since it already exists.') # Apply traefik CRD definitions try: crd_path = 'infrastructure/k1s-traefik/manifests/001-crds.yaml' logger.debug('Running: `kubectl apply -f {}`'.format(crd_path)) _apply_crds = s.run(['kubectl', 'apply', '-f', crd_path], check=True, stdout=s.DEVNULL) except s.CalledProcessError as error: logger.critical('Could not apply traefik CRDs' + error.stderr.decode('utf-8'))