Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[1.0.3] backports #3016

Merged
merged 16 commits into from
May 11, 2022
10 changes: 10 additions & 0 deletions CHANGELOG-1.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@

### Added

- [#2976](https://github.com/epiphany-platform/epiphany/issues/2976) - Allow for custom Terraform scripts
- [#1076](https://github.com/epiphany-platform/epiphany/issues/1076) - Add sorting entries in the inventory file

### Fixed

- [#2989](https://github.com/epiphany-platform/epiphany/issues/2989) - Task `Remove swap from /etc/fstab` does not remove swap entry from file
- [#2653](https://github.com/epiphany-platform/epiphany/issues/2653) - Epicli is failing in air-gapped infra mode
- [#3004](https://github.com/epiphany-platform/epiphany/issues/3004) - `disk_size_gb` hardcoded in `/usr/local/epicli/data/azure/defaults/infrastructure/virtual-machine.yml`
- [#2934](https://github.com/epiphany-platform/epiphany/issues/2934) - Duplicated entries in image-registry defaults (LTS)
- [#3065](https://github.com/epiphany-platform/epiphany/issues/3065) - Flag `delete_os_disk_on_termination` has no effect when removing cluster
- [#2996](https://github.com/epiphany-platform/epiphany/issues/2996) - Introduce the new configuration field to change a component name

## [1.0.2] 2022-01-26
Expand Down
12 changes: 2 additions & 10 deletions core/src/epicli/.devcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,8 @@ ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=$USER_UID

COPY cert/cert.md cert/*.crt /usr/local/share/ca-certificates/
COPY cert/cert.md cert/*.pem /
COPY cert/config-pre.sh /

RUN : INSTALL APT REQUIREMENTS \
&& export DEBIAN_FRONTEND=noninteractive \
&& /bin/bash /config-pre.sh \
&& apt-get -q update \
&& apt-get -q install -y --no-install-recommends \
apt-utils dialog \
Expand Down Expand Up @@ -54,14 +49,11 @@ RUN : INSTALL PIP REQUIREMENTS \
&& pip install --disable-pip-version-check --no-cache-dir --default-timeout=100 \
--requirement /requirements.txt \
&& pip install --disable-pip-version-check --no-cache-dir --default-timeout=100 \
poetry pylint pytest setuptools twine wheel

COPY cert/config-post.sh /
poetry pylint pytest pytest_mock setuptools twine wheel

RUN : SETUP USER, CERTS AND OTHERS \
&& groupadd --gid $USER_GID $USERNAME \
&& useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME \
&& echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
&& chmod ug=r,o= /etc/sudoers.d/$USERNAME \
&& setcap 'cap_net_bind_service=+ep' /usr/bin/ssh \
&& /bin/bash /config-post.sh
&& setcap 'cap_net_bind_service=+ep' /usr/bin/ssh
6 changes: 0 additions & 6 deletions core/src/epicli/.devcontainer/cert/cert.md

This file was deleted.

22 changes: 0 additions & 22 deletions core/src/epicli/.devcontainer/cert/config-post.sh

This file was deleted.

29 changes: 0 additions & 29 deletions core/src/epicli/.devcontainer/cert/config-pre.sh

This file was deleted.

7 changes: 5 additions & 2 deletions core/src/epicli/cli/engine/providers/any/APIProxy.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from cli.helpers.doc_list_helpers import select_first
from cli.helpers.Log import Log
from cli.models.AnsibleHostModel import AnsibleHostModel
from cli.models.AnsibleHostModel import AnsibleOrderedHostModel


class APIProxy:
Expand All @@ -22,5 +22,8 @@ def get_ips_for_feature(self, component_key):
for machine in component_config.machines:
machine_doc = select_first(self.config_docs,
lambda x: x.kind == 'infrastructure/machine' and x.name == machine)
result.append(AnsibleHostModel(machine_doc.specification.hostname, machine_doc.specification.ip))
result.append(AnsibleOrderedHostModel(machine_doc.specification.hostname, machine_doc.specification.ip))

result.sort()

return result
9 changes: 6 additions & 3 deletions core/src/epicli/cli/engine/providers/azure/APIProxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from cli.helpers.Log import LogPipe, Log
from cli.helpers.doc_list_helpers import select_first
from cli.helpers.naming_helpers import resource_name, cluster_tag
from cli.models.AnsibleHostModel import AnsibleHostModel
from cli.models.AnsibleHostModel import AnsibleOrderedHostModel

class APIProxy:
def __init__(self, cluster_model, config_docs):
Expand Down Expand Up @@ -54,7 +54,7 @@ def get_ips_for_feature(self, component_key):
look_for_public_ip = self.cluster_model.specification.cloud.use_public_ips
cluster = cluster_tag(self.cluster_prefix, self.cluster_name)
running_instances = self.run(self, f'az vm list-ip-addresses --ids $(az resource list --query "[?type==\'Microsoft.Compute/virtualMachines\' && tags.{component_key} == \'\' && tags.cluster == \'{cluster}\'].id" --output tsv)')
result = []
result: List[AnsibleOrderedHostModel] = []
for instance in running_instances:
if isinstance(instance, list):
instance = instance[0]
Expand All @@ -66,7 +66,10 @@ def get_ips_for_feature(self, component_key):
ip = instance['virtualMachine']['network']['publicIpAddresses'][0]['ipAddress']
else:
ip = instance['virtualMachine']['network']['privateIpAddresses'][0]
result.append(AnsibleHostModel(name, ip))
result.append(AnsibleOrderedHostModel(name, ip))

result.sort()

return result

def get_storage_account_primary_key(self, storage_account_name):
Expand Down
5 changes: 4 additions & 1 deletion core/src/epicli/cli/engine/schema/DefaultMerger.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ def merge_parent(self, files, doc):
merged_parent['version'] = VERSION
merge_objdict(merged_parent, doc)
return merged_parent
default_config = select_first(self.docs, lambda x: x.name == 'default' and x.kind == doc.kind)
default_doc = select_first(files, lambda x: x.name == 'default')
if default_config is not None:
merge_objdict(default_doc, default_config)
default_doc['version'] = VERSION
merge_objdict(default_doc, doc)
return default_doc
return default_doc
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ def __init__(self, cluster_model, infrastructure):

def run(self):
terraform_output_dir = get_terraform_path(self.cluster_model.specification.name)
# Remove generated .tf files (not tfstate).
remove_files_matching_glob(terraform_output_dir, '*.tf')

# Only remove epicli generated .tf files, not tfstate or user created files.
remove_files_matching_glob(terraform_output_dir, '[0-9][0-9][0-9]_*.tf')

templates = filter(lambda x: x.kind != 'infrastructure/cloud-init-custom-data', self.infrastructure)
for idx, doc in enumerate(templates):
Expand Down
4 changes: 3 additions & 1 deletion core/src/epicli/cli/epicli.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,9 @@ def delete_parser(subparsers):
sub_parser._action_groups.append(optional)

def run_delete(args):
if not query_yes_no('Do you really want to delete your cluster?'):
if not query_yes_no('''You are trying to delete your cluster.
If your configuration does not allow to keep the existing disks used in the cluster, you will lose your data.
Make sure your data is safe. Do you really want to delete your cluster?'''):
return 0
adjust_paths_from_build(args)
with DeleteEngine(args) as engine:
Expand Down
22 changes: 19 additions & 3 deletions core/src/epicli/cli/models/AnsibleHostModel.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
class AnsibleHostModel:
def __init__(self, name, ip):
self.name = name
self.ip = ip
def __init__(self, name: str, ip: str):
self.name: str = name
self.ip: str = ip

def __eq__(self, other) -> bool:
return (self.name == other.name and
self.ip == other.ip)

def __lt__(self, other) -> bool:
pass


class AnsibleOrderedHostModel(AnsibleHostModel):
"""
Sortable variant of AnsibleHostModel
"""

def __lt__(self, other) -> bool:
return self.name < other.name
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ specification:
sku: 18.04-LTS
version: "18.04.202103151" # Never put latest on anything! Need to always pin the version number but testing we can get away with it
storage_os_disk:
delete_on_termination: false
managed: false
caching: ReadWrite
create_option: FromImage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,6 @@ resource "azurerm_virtual_machine" "{{ specification.name }}" {
# windows specific stuff here maybe... hopefully never.
{%- endif %}

{%- if specification.storage_os_disk.managed != true %}
delete_os_disk_on_termination = "{{ specification.storage_os_disk.delete_on_termination | lower }}"
{%- endif %}

storage_os_disk {
name = "{{ specification.name }}-os-disk"
caching = "{{ specification.storage_os_disk.caching }}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ properties:
storage_os_disk:
type: object
properties:
delete_on_termination:
type: boolean
managed:
type: boolean
caching:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@
- sysctl

- name: Remove swap from /etc/fstab
mount:
backup: yes
fstype: swap
path: swap
lineinfile:
path: /etc/fstab
regexp: ^(?!#).*\sswap\s.*\d\s+\d$
state: absent
backup: yes
tags:
- disableswap

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
- name: Check routing configuration
become: true
command: ip route show default 0.0.0.0/0
register: ip_route_show_default

- name: Assert default route exists
assert:
that: ip_route_show_default.stdout_lines | length > 0
fail_msg: >-
No default route configured. At least one is required, read more in troubleshooting document.
quiet: true

- name: Validate metric values if multiple default routes exist
when: ip_route_show_default.stdout_lines | length > 1
block:
- name: Get metric values
become: true
shell: |-
set -o pipefail && \
ip route show default 0.0.0.0/0 | awk '{if (! /metric/) print 0; else for (x=1;x<NF;x++) if ($x == "metric") print $(x+1) }'
register: default_routing_configuration_metric_values
args:
executable: /bin/bash

- name: Assert two most prioritized default routes have unique metric
assert:
that: "default_routing_configuration_metric_values.stdout_lines[0] != default_routing_configuration_metric_values.stdout_lines[1]"
fail_msg: >-
At least two default routes have the same metric value.
Check routing configuration, read more in troubleshooting document.

- include_vars:
file: roles/common/vars/main.yml
name: common_vars

- name: Validate if ansible_default_ipv4.address matches address from inventory
when:
- common_vars.provider == "any"
- common_vars.specification.cloud is undefined
assert:
that: ansible_default_ipv4.address == ansible_host
fail_msg: >-
ansible_default_ipv4.address is {{ ansible_default_ipv4.address }} but inventory uses ip: {{ ansible_host }}.
Check default routing configuration, read more in troubleshooting document.
quiet: true
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

- include_tasks: check-os.yml

- include_tasks: check-routing.yml

- name: Check if existing PostgreSQL needs to be migrated to distribution installed from PostgreSQL repository
block:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,18 +74,22 @@ specification:
file_name: kube-scheduler-v1.14.6.tar
- name: "k8s.gcr.io/kube-proxy:v1.14.6"
file_name: kube-proxy-v1.14.6.tar
- name: "k8s.gcr.io/etcd:3.3.10"
file_name: etcd-3.3.10.tar
- name: "k8s.gcr.io/coredns:1.3.1"
file_name: coredns-1.3.1.tar
# Disable this dual entry because of validation issues.
# We leave it for reference.
# - name: "k8s.gcr.io/etcd:3.3.10"
# file_name: etcd-3.3.10.tar
# - name: "k8s.gcr.io/coredns:1.3.1"
# file_name: coredns-1.3.1.tar
- name: "coredns/coredns:1.5.0"
file_name: coredns-1.5.0.tar
- name: "k8s.gcr.io/pause:3.1"
file_name: pause-3.1.tar
- name: "quay.io/coreos/flannel:v0.11.0-amd64"
file_name: flannel-v0.11.0-amd64.tar
- name: "quay.io/coreos/flannel:v0.11.0"
file_name: flannel-v0.11.0.tar
# Disable this dual entry because of validation issues.
# We leave it for reference
# - name: "k8s.gcr.io/pause:3.1"
# file_name: pause-3.1.tar
# - name: "quay.io/coreos/flannel:v0.11.0-amd64"
# file_name: flannel-v0.11.0-amd64.tar
# - name: "quay.io/coreos/flannel:v0.11.0"
# file_name: flannel-v0.11.0.tar
- name: "calico/cni:v3.8.1"
file_name: cni-v3.8.1.tar
- name: "calico/kube-controllers:v3.8.1"
Expand Down Expand Up @@ -129,12 +133,14 @@ specification:
file_name: kube-scheduler-v1.17.4.tar
- name: "k8s.gcr.io/kube-proxy:v1.17.4"
file_name: kube-proxy-v1.17.4.tar
- name: "k8s.gcr.io/etcd:3.4.3-0"
file_name: etcd-3.4.3-0.tar
- name: "k8s.gcr.io/coredns:1.6.5"
file_name: coredns-1.6.5.tar
- name: "k8s.gcr.io/pause:3.1"
file_name: pause-3.1.tar
# Disable this dual entry because of validation issues.
# We leave it for reference.
# - name: "k8s.gcr.io/etcd:3.4.3-0"
# file_name: etcd-3.4.3-0.tar
# - name: "k8s.gcr.io/coredns:1.6.5"
# file_name: coredns-1.6.5.tar
# - name: "k8s.gcr.io/pause:3.1"
# file_name: pause-3.1.tar
# flannel
- name: "quay.io/coreos/flannel:v0.11.0-amd64"
file_name: flannel-v0.11.0-amd64.tar
Expand Down
Empty file.
Empty file.
Empty file.
Empty file.
26 changes: 26 additions & 0 deletions core/src/epicli/tests/engine/providers/any/test_APIProxy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from pytest_mock import MockerFixture

from cli.engine.providers.any.APIProxy import APIProxy
from cli.models.AnsibleHostModel import AnsibleOrderedHostModel
from tests.engine.providers.data.APIProxy_data import CLUSTER_MODEL, CONFIG_DOC


def test_get_ips_for_feature(mocker: MockerFixture):
"""
Make sure that hostnames in inventory are sorted.
"""

mocker.patch('cli.engine.providers.any.APIProxy.Log')
proxy = APIProxy(CLUSTER_MODEL('any'), CONFIG_DOC())

EXPECTED_RESULT = [
AnsibleOrderedHostModel('service-vm-0', '20.73.105.240'),
AnsibleOrderedHostModel('service-vm-1', '20.73.105.188'),
AnsibleOrderedHostModel('service-vm-2', '20.73.105.18'),
AnsibleOrderedHostModel('service-vm-3', '20.73.105.33'),
AnsibleOrderedHostModel('service-vm-4', '20.73.105.54')
]

result = proxy.get_ips_for_feature('service')

assert EXPECTED_RESULT == result
Empty file.
Empty file.
Loading