Skip to content

Commit

Permalink
Merge pull request #690 from Netcracker/feature/deprecated-kuber-version
Browse files Browse the repository at this point in the history
[CPREQ-10003] - deprecated kuber version
  • Loading branch information
koryaga authored Sep 12, 2024
2 parents 30059f8 + 85acb9c commit b1a42d1
Show file tree
Hide file tree
Showing 12 changed files with 100 additions and 22 deletions.
14 changes: 7 additions & 7 deletions .github/workflows/integration_tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ jobs:
steps:
- name: Checkout Repo
uses: actions/checkout@v3
- name: Set up Python 3.9
- name: Set up Python 3.12
uses: actions/setup-python@v4
with:
python-version: "3.9"
python-version: "3.12"
- name: Install software
run: pip3 install yq
- name: Parse kubernetes versions
Expand Down Expand Up @@ -48,10 +48,10 @@ jobs:
ssh-keyscan -H 172.17.0.1 >> ~/.ssh/known_hosts
- name: Test ssh connection
run: ssh -i ~/.ssh/id_rsa 172.17.0.1 echo "Test"
- name: Set up Python 3.9
- name: Set up Python 3.12
uses: actions/setup-python@v4
with:
python-version: "3.9"
python-version: "3.12"
- name: Install Kubemarine with dependencies
run: |
python -m pip install --upgrade pip
Expand Down Expand Up @@ -110,10 +110,10 @@ jobs:
run: sudo ifconfig docker0:0 172.17.1.1 up
- name: Test ssh connection
run: ssh -i ~/.ssh/id_rsa 172.17.0.1 echo "Test"
- name: Set up Python 3.9
- name: Set up Python 3.12
uses: actions/setup-python@v4
with:
python-version: "3.9"
python-version: "3.12"
- name: Install Kubemarine with dependencies
run: |
python -m pip install --upgrade pip
Expand Down Expand Up @@ -160,7 +160,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: "3.9"
python-version: "3.12"
- name: Install dependencies
run: pip install . && pip uninstall -y kubemarine
- name: Run scripts/thirdparties/sync.py
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: "3.9"
python-version: "3.12"
# Install coverage and kubemarine with all dependencies except ansible.
# Then uninstall only kubemarine to avoid ambiguity and to surely run coverage on sources.
- run: pip install coverage . && pip uninstall -y kubemarine
Expand All @@ -41,7 +41,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: "3.9"
python-version: "3.12"
# Install pylint and kubemarine with all dependencies except ansible.
# Then uninstall only kubemarine to avoid ambiguity and to surely run pylint on sources.
- run: pip install .[pylint] && pip install -r requirements-pyinstaller.txt && pip uninstall -y kubemarine
Expand All @@ -56,7 +56,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: "3.9"
python-version: "3.12"
- run: pip install radon xenon
# Use `radon cc {paths} -a` locally for full report per function
# xenon checks, if radon absolute result is A
Expand Down
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ COPY --from=go-build /opt/ipip_check.gz /opt/kubemarine/kubemarine/resources/scr
WORKDIR /opt/kubemarine/

RUN apt update && \
pip3 install --no-cache-dir setuptools wheel && \
pip3 install --no-cache-dir build && \
python3 -m build -n && \
# In any if branch delete source code, but preserve specific directories for different service aims
Expand Down
10 changes: 10 additions & 0 deletions documentation/Kubecheck.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ This section provides information about the Kubecheck functionality.
- [229 Audit Policy Configuration](#229-audit-policy-configuration)
- [231 Audit Daemon Rules](#231-audit-daemon-rules)
- [232 Kernel Parameters Configuration](#232-kernel-parameters-configuration)
- [235 Kubernetes version](#235-kubernetes-version)
- [Report File Generation](#report-file-generation)
- [HTML Report](#html-report)
- [CSV Report](#csv-report)
Expand Down Expand Up @@ -437,6 +438,7 @@ The task tree is as follows:
* audit
* policy
* admission
* version
* etcd
* health_status
* control_plane
Expand Down Expand Up @@ -778,6 +780,14 @@ This test compares the kernel parameters on the nodes
with the parameters specified in the inventory or with the default parameters.
If the configured parameters are not presented, the test fails.

##### 235 Kubernetes version

*Task*: `kubernetes.version`

This test checks if used kubernetes version is deprecated in current kubemarine release.
It means, that this version is going to be excluded from support in future kubemarine soon.
So it's recommended to update kubernetes version to new one.

### Report File Generation

In addition to the resulting table in the log output, the same report is presented in the form of files.
Expand Down
6 changes: 4 additions & 2 deletions kubemarine/kubernetes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -892,11 +892,13 @@ def verify_allowed_version(version: str) -> str:
return version


def verify_supported_version(target_version: str, logger: log.EnhancedLogger) -> None:
def verify_supported_version(target_version: str, logger: log.EnhancedLogger) -> bool:
minor_version = utils.minor_version(target_version)
supported_versions = static.KUBERNETES_VERSIONS['kubernetes_versions']
if not supported_versions.get(minor_version, {}).get("supported", False):
logger.warning(f"Specified target Kubernetes version {target_version!r} - is not supported!")
logger.warning(f"Specified target Kubernetes version {target_version!r} - is deprecated!")
return False
return True


def expect_kubernetes_version(cluster: KubernetesCluster, version: str,
Expand Down
29 changes: 21 additions & 8 deletions kubemarine/procedures/check_paas.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def _check_same_os(cluster: KubernetesCluster) -> None:
different_os = set(os_ids.values())
if len(different_os) > 1:
cluster.log.warning(
f"Nodes have different OS families or versions, packages versions cannot be checked. "
f"Nodes have different OS families or versions, packages versions cannot be checked."
f"List of (OS family, version): {list(different_os)}")
raise TestFailure(f"Nodes have different OS families or versions")

Expand Down Expand Up @@ -1021,7 +1021,7 @@ def verify_modprobe_rules(cluster: KubernetesCluster) -> None:
else:
raise TestFailure('invalid',
hint=f"Modprobe rules do not match those loaded in modprobe on cluster nodes. Check "
f"manually what the differences are and make changes on the appropriate nodes.")
f"the differences manually and make changes on the appropriate nodes.")


def verify_sysctl_config(cluster: KubernetesCluster) -> None:
Expand All @@ -1042,7 +1042,7 @@ def verify_sysctl_config(cluster: KubernetesCluster) -> None:
else:
raise TestFailure('invalid',
hint=f"Some configured kernel parameters are not loaded on the cluster nodes.\n"
f"Check manually what the differences are, and make changes on the appropriate nodes.")
f"Check the differences manually and make changes on the appropriate nodes.")


def verify_system_audit_rules(cluster: KubernetesCluster) -> None:
Expand All @@ -1063,7 +1063,7 @@ def verify_system_audit_rules(cluster: KubernetesCluster) -> None:
else:
raise TestFailure('invalid',
hint=f"Some configured Audit rules are not loaded on the cluster nodes.\n"
f"Check manually what the differences are, and make changes on the appropriate nodes.")
f"Check the differences manually and make changes on the appropriate nodes.")


def etcd_health_status(cluster: KubernetesCluster) -> None:
Expand Down Expand Up @@ -1565,6 +1565,18 @@ def kubernetes_admission_status(cluster: KubernetesCluster) -> None:
cluster.log.debug(kube_admission_status)
tc.success(results='enabled')

def verify_kubernetes_version(cluster: KubernetesCluster) -> None:
"""
The method checks if used kubernetes version is deprecated in kubemarine
"""
with TestCase(cluster, '225', "Kubernetes", "Version") as tc:
target_version = cluster.inventory['services']['kubeadm']['kubernetesVersion']
if not kubernetes.verify_supported_version(target_version, cluster.log):
raise TestWarn(f"Kubernetes version {target_version} is deprecated",
hint=f"Used Kubernetes version is deprecated and will be excluded from support "
f"in future Kubemarine releases. Please plan upgrade to the newer version.")

tc.success(results='Kubernetes version is OK')

def geo_check(cluster: KubernetesCluster) -> None:
"""
Expand Down Expand Up @@ -1602,7 +1614,7 @@ def geo_check(cluster: KubernetesCluster) -> None:

peers = yaml.safe_load(io.StringIO(peers_result))
if len(peers) == 0:
raise TestFailure("configuration error", hint="geo-monitor instance has no peers")
raise TestFailure("configuration error", hint="geo-monitor instance has no peers.")

for peer in peers:
status = peer["clusterIpStatus"]
Expand Down Expand Up @@ -1632,7 +1644,7 @@ def geo_check(cluster: KubernetesCluster) -> None:

with TestCase(cluster, '226', "Geo Monitor", "Geo check - Pod-to-service") as tc_svc:
if not status_collected:
raise TestFailure("configuration error", hint="DNS check failed with error, statuses not collected")
raise TestFailure("configuration error", hint="DNS check failed with error, statuses not collected.")

if svc_status["failed"]:
raise TestFailure("found unavailable peer services",
Expand All @@ -1643,7 +1655,7 @@ def geo_check(cluster: KubernetesCluster) -> None:

with TestCase(cluster, '226', "Geo Monitor", "Geo check - Pod-to-pod") as tc_pod:
if not status_collected:
raise TestFailure("configuration error", hint="DNS check failed with error, statuses not collected")
raise TestFailure("configuration error", hint="DNS check failed with error, statuses not collected.")

if pod_status["failed"]:
raise TestFailure("found unavailable peer pod",
Expand Down Expand Up @@ -1699,7 +1711,7 @@ def verify_apparmor_config(cluster: KubernetesCluster) -> None:
tc.success(results='valid')
else:
raise TestFailure('invalid',
hint=f"Some nodes do not have properly configured Apparmor service")
hint=f"Some nodes do not have properly configured Apparmor service.")
else:
tc.success(results='skipped')

Expand Down Expand Up @@ -1789,6 +1801,7 @@ def verify_apparmor_config(cluster: KubernetesCluster) -> None:
'policy': kubernetes_audit_policy_configuration,
},
'admission': kubernetes_admission_status,
'version': verify_kubernetes_version,
},
'etcd': {
"health_status": etcd_health_status
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This section can be changed manually, but it is also synchronized automatically with the 'compatibility_map' section below.
kubernetes_versions:
v1.26:
supported: true
supported: false
v1.27:
supported: true
v1.28:
Expand Down
14 changes: 14 additions & 0 deletions scripts/thirdparties/src/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from kubemarine.core import static
from .compatibility import KubernetesVersions
from .software import InternalCompatibility, UpgradeConfig, CompatibilityMap, SoftwareType
from .software.defaults import KubemarineDefaults
from .software.kubernetes_images import KubernetesImagesResolver, KubernetesImages
from .software.packages import Packages
from .software.plugins import ManifestResolver, Plugins, ManifestsEnrichment
Expand All @@ -27,6 +28,7 @@

class Synchronization:
def __init__(self,
defaults: KubemarineDefaults,
compatibility: InternalCompatibility,
kubernetes_versions: KubernetesVersions,
images_resolver: KubernetesImagesResolver,
Expand All @@ -35,6 +37,7 @@ def __init__(self,
manifests_enrichment: ManifestsEnrichment,
upgrade_config: UpgradeConfig,
):
self.defaults = defaults
self.compatibility = compatibility
self.kubernetes_versions = kubernetes_versions
self.images_resolver = images_resolver
Expand All @@ -44,6 +47,8 @@ def __init__(self,
self.upgrade_config = upgrade_config

def run(self) -> SummaryTracker:
self.validate()

tracker = SummaryTracker(self.kubernetes_versions.compatibility_map)

software: List[SoftwareType] = [
Expand Down Expand Up @@ -75,3 +80,12 @@ def run(self) -> SummaryTracker:

tracker.print()
return tracker

def validate(self) -> None:
# Validate version
default_version = self.defaults.default_version()
if default_version not in self.kubernetes_versions.compatibility_map:
raise Exception(f"Kubemarine default version {default_version} "
f"does not exist in compatibility map. "
f"Default version should be updated before excluding it from support."
)
29 changes: 29 additions & 0 deletions scripts/thirdparties/src/software/defaults.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copyright 2021-2023 NetCracker Technology Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from kubemarine.core import utils

# pylint: disable=bad-builtin

YAML = utils.yaml_structure_preserver()
RESOURCE_PATH = utils.get_internal_resource_path("resources/configurations/defaults.yaml")


class KubemarineDefaults:
def __init__(self) -> None:
with utils.open_internal(RESOURCE_PATH) as stream:
self._defaults = YAML.load(stream)

def default_version(self) -> str:
return str(self._defaults['services']['kubeadm']['kubernetesVersion'])
3 changes: 2 additions & 1 deletion scripts/thirdparties/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from src.software.kubernetes_images import KubernetesImagesResolver
from src.software.plugins import ManifestResolver, ManifestsEnrichment
from src.software.thirdparties import ThirdpartyResolver

from src.software.defaults import KubemarineDefaults

if __name__ == '__main__':
if platform.system() != 'Linux':
Expand All @@ -46,6 +46,7 @@

args = parser.parse_args()
Synchronization(
KubemarineDefaults(),
InternalCompatibility(),
KubernetesVersions(),
KubernetesImagesResolver(),
Expand Down
4 changes: 4 additions & 0 deletions test/unit/tools/thirdparties/stub.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
from scripts.thirdparties.src.software.kubernetes_images import KubernetesImagesResolver
from scripts.thirdparties.src.software.plugins import ManifestResolver, ManifestsEnrichment
from scripts.thirdparties.src.software.thirdparties import ThirdpartyResolver
from scripts.thirdparties.src.software.defaults import KubemarineDefaults

from scripts.thirdparties.src.tracker import SummaryTracker


Expand Down Expand Up @@ -163,6 +165,7 @@ def store(self):

class FakeSynchronization(Synchronization):
def __init__(self,
defaults: KubemarineDefaults,
compatibility: FakeInternalCompatibility,
kubernetes_versions: FakeKubernetesVersions,
images_resolver: FakeKubernetesImagesResolver,
Expand All @@ -171,6 +174,7 @@ def __init__(self,
upgrade_config=FakeUpgradeConfig(),
):
super().__init__(
defaults,
compatibility,
kubernetes_versions,
images_resolver,
Expand Down
4 changes: 4 additions & 0 deletions test/unit/tools/thirdparties/test_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from copy import deepcopy
from typing import List, Dict, ContextManager
from unittest import mock

from test.unit import utils as test_utils
from test.unit.tools.thirdparties.stub import (
FakeSynchronization, FakeInternalCompatibility, FakeKubernetesVersions,
Expand All @@ -30,6 +31,7 @@
from kubemarine.plugins import builtin
from kubemarine.plugins.manifest import Manifest, Processor, Identity
from scripts.thirdparties.src.software import thirdparties, plugins, kubernetes_images
from scripts.thirdparties.src.software.defaults import KubemarineDefaults
from scripts.thirdparties.src.software.plugins import (
ManifestResolver, ManifestsEnrichment,
ERROR_UNEXPECTED_IMAGE, ERROR_SUSPICIOUS_ABA_VERSIONS
Expand All @@ -47,6 +49,7 @@

class SynchronizationTest(unittest.TestCase):
def setUp(self) -> None:
self.defaults = KubemarineDefaults()
self.compatibility = FakeInternalCompatibility()
self.kubernetes_versions = FakeKubernetesVersions()
self.images_resolver = FakeKubernetesImagesResolver()
Expand Down Expand Up @@ -580,6 +583,7 @@ def load_compatibility_map_mocked(filename: str) -> dict:

def run_sync(self) -> SummaryTracker:
return FakeSynchronization(
self.defaults,
self.compatibility,
self.kubernetes_versions,
self.images_resolver,
Expand Down

0 comments on commit b1a42d1

Please sign in to comment.