Skip to content

Commit

Permalink
[TH2-5226] added 'enable component (min configuration)' test
Browse files Browse the repository at this point in the history
  • Loading branch information
Nikita-Smirnov-Exactpro committed Sep 13, 2024
1 parent 33a9a29 commit 39704a4
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 123 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import com.exactpro.th2.infraoperator.spec.strategy.redeploy.NonTerminalException;
import com.exactpro.th2.infraoperator.spec.strategy.redeploy.RetryableTaskQueue;
import com.exactpro.th2.infraoperator.spec.strategy.redeploy.tasks.TriggerRedeployTask;
import com.exactpro.th2.infraoperator.util.CustomResourceUtils;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.OwnerReference;
import io.fabric8.kubernetes.api.model.OwnerReferenceBuilder;
Expand All @@ -48,6 +47,8 @@
import java.util.concurrent.ConcurrentHashMap;

import static com.exactpro.th2.infraoperator.operator.HelmReleaseTh2Op.ANTECEDENT_LABEL_KEY_ALIAS;
import static com.exactpro.th2.infraoperator.util.CustomResourceUtils.annotationFor;
import static com.exactpro.th2.infraoperator.util.CustomResourceUtils.extractHashedName;
import static com.exactpro.th2.infraoperator.util.ExtractUtils.extractName;
import static com.exactpro.th2.infraoperator.util.ExtractUtils.extractNamespace;
import static com.exactpro.th2.infraoperator.util.KubernetesUtils.isNotActive;
Expand All @@ -74,7 +75,7 @@ protected AbstractTh2Operator(KubernetesClient kubClient) {

@Override
public void eventReceived(Action action, CR resource) {
String resourceLabel = CustomResourceUtils.annotationFor(resource);
String resourceLabel = annotationFor(resource);

try {
var cachedFingerprint = fingerprints.get(resourceLabel);
Expand Down Expand Up @@ -148,21 +149,28 @@ protected HelmRelease loadKubObj() {

protected void processEvent(Action action, CR resource) throws IOException {

String resourceLabel = CustomResourceUtils.annotationFor(resource);
String resourceLabel = annotationFor(resource);
logger.debug("Processing event {} for \"{}\"", action, resourceLabel);

if (resource.getSpec().getDisabled()) {
try {
deletedEvent(resource);
// TODO: work with Th2CustomResource should be encapsulated somewhere
// to void issues with choosing the right function to extract the name
Resource<HelmRelease> helmRelease = kubClient.resources(HelmRelease.class)
.inNamespace(extractNamespace(resource))
String namespace = extractNamespace(resource);
String helmReleaseName = extractHashedName(resource);
Resource<HelmRelease> helmReleaseResource = kubClient.resources(HelmRelease.class)
.inNamespace(namespace)
// name must be hashed if it exceeds the limit
.withName(CustomResourceUtils.extractHashedName(resource));
String helmReleaseLabel = CustomResourceUtils.annotationFor(helmRelease.get());
helmRelease.delete();
logger.info("Resource \"{}\" has been deleted", helmReleaseLabel);
.withName(helmReleaseName);
HelmRelease helmRelease = helmReleaseResource.get();
if (helmRelease == null) {
logger.info("Resource \"{}\" hasn't been deleted because it already doesn't exist", annotationFor(namespace, helmReleaseName, HelmRelease.class.getSimpleName()));
} else {
String helmReleaseLabel = annotationFor(helmRelease);
helmReleaseResource.delete();
logger.info("Resource \"{}\" has been deleted", helmReleaseLabel);
}
resource.getStatus().disabled("Resource has been disabled");
logger.info("Resource \"{}\" has been disabled, executing DELETE action", resourceLabel);
updateStatus(resource);
Expand Down Expand Up @@ -215,23 +223,23 @@ protected void deletedEvent(CR resource) {

// kubernetes objects will be removed when custom resource removed (through 'OwnerReference')

String resourceLabel = CustomResourceUtils.annotationFor(resource);
String resourceLabel = annotationFor(resource);
fingerprints.remove(resourceLabel);
// The HelmRelease name is hashed if Th2CustomResource name exceeds the limit
OperatorState.INSTANCE.removeHelmReleaseFromCache(
CustomResourceUtils.extractHashedName(resource),
extractHashedName(resource),
extractNamespace(resource)
);
}

protected void errorEvent(CR resource) {
String resourceLabel = CustomResourceUtils.annotationFor(resource);
String resourceLabel = annotationFor(resource);
fingerprints.remove(resourceLabel);
}

protected CR updateStatus(CR resource) {

String resourceLabel = CustomResourceUtils.annotationFor(resource);
String resourceLabel = annotationFor(resource);
var resClient = getResourceClient().getInstance();

try {
Expand Down Expand Up @@ -273,9 +281,7 @@ protected void setupAndCreateKubObj(CR resource) {

createKubObj(extractNamespace(resource), kubObj);

logger.info("Generated \"{}\" based on \"{}\""
, CustomResourceUtils.annotationFor(kubObj)
, CustomResourceUtils.annotationFor(resource));
logger.info("Generated \"{}\" based on \"{}\"" , annotationFor(kubObj) , annotationFor(resource));

String kubObjType = kubObj.getClass().getSimpleName();

Expand All @@ -289,14 +295,14 @@ protected void setupKubObj(CR resource, HelmRelease helmRelease) {
mapProperties(resource, helmRelease);

logger.info("Generated additional properties from \"{}\" for the resource \"{}\""
, CustomResourceUtils.annotationFor(resource)
, CustomResourceUtils.annotationFor(helmRelease));
, annotationFor(resource)
, annotationFor(helmRelease));

helmRelease.getMetadata().setOwnerReferences(List.of(createOwnerReference(resource)));

logger.info("Property \"OwnerReference\" with reference to \"{}\" has been set for the resource \"{}\""
, CustomResourceUtils.annotationFor(resource)
, CustomResourceUtils.annotationFor(helmRelease));
, annotationFor(resource)
, annotationFor(helmRelease));

}

Expand All @@ -305,8 +311,8 @@ protected void mapProperties(CR resource, HelmRelease helmRelease) {
var kubObjMD = helmRelease.getMetadata();
var resMD = resource.getMetadata();
String resName = resMD.getName();
String annotation = CustomResourceUtils.annotationFor(resource);
String finalName = CustomResourceUtils.extractHashedName(resource);
String annotation = annotationFor(resource);
String finalName = extractHashedName(resource);

if (!finalName.equals(resName)) {
logger.info("Name of resource \"{}\" exceeds limitations. Will be substituted with \"{}\"",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,14 @@
import com.exactpro.th2.infraoperator.spec.Th2CustomResource;
import com.exactpro.th2.infraoperator.spec.helmrelease.HelmRelease;
import io.fabric8.kubernetes.api.model.HasMetadata;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Objects;

import static com.exactpro.th2.infraoperator.util.ExtractUtils.extractName;
import static com.exactpro.th2.infraoperator.util.ExtractUtils.extractNamespace;
import static com.exactpro.th2.infraoperator.util.ExtractUtils.extractType;

public class CustomResourceUtils {

Expand All @@ -53,7 +49,7 @@ public static String annotationFor(String namespace, String kind, String resourc
return String.format("%s:%s/%s(commit-%s)", namespace, kind, resourceName, commitHash);
}

public static String annotationFor(HasMetadata resource) {
public static String annotationFor(@NotNull HasMetadata resource) {
return annotationFor(
resource.getMetadata().getNamespace(),
resource.getKind(),
Expand All @@ -62,47 +58,15 @@ public static String annotationFor(HasMetadata resource) {
);
}

@Nullable
public static HelmRelease search(List<HelmRelease> helmReleases, Th2CustomResource resource) {
String resFullName = extractHashedFullName(resource);
return helmReleases.stream()
.filter(hr -> {
var owner = extractOwnerFullName(hr);
return Objects.nonNull(owner) && owner.equals(resFullName);
}).findFirst()
.orElse(null);
}

public static String extractHashedName(Th2CustomResource customResource) {
return hashNameIfNeeded(extractName(customResource));
}

private static String extractHashedFullName(Th2CustomResource customResource) {
return concatFullName(extractNamespace(customResource), extractHashedName(customResource));
}

@Nullable
private static String extractOwnerFullName(HelmRelease helmRelease) {
var ownerReferences = helmRelease.getMetadata().getOwnerReferences();
if (!ownerReferences.isEmpty()) {
return concatFullName(extractNamespace(helmRelease), ownerReferences.get(0).getName());
} else {
logger.warn("[{}<{}>] doesn't have owner resource", extractType(helmRelease), extractFullName(helmRelease));
return null;
}
}

private static String extractFullName(HasMetadata obj) {
return concatFullName(extractNamespace(obj), extractName(obj));
}

private static String concatFullName(String namespace, String name) {
return namespace + "." + name;
}

public static String hashNameIfNeeded(String resName) {
if (resName.length() >= HelmRelease.NAME_LENGTH_LIMIT) {
return digest(resName);
String result = digest(resName);
logger.debug("Resource '{}' name has been hashed to '{}'", resName, result);
return result;
}
return resName;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2021-2021 Exactpro (Exactpro Systems Limited)
* Copyright 2021-2024 Exactpro (Exactpro Systems Limited)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,82 +16,44 @@

package com.exactpro.th2.infraoperator.util;

import com.exactpro.th2.infraoperator.spec.Th2CustomResource;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.ObjectMeta;
import org.junit.jupiter.api.Test;

import static com.exactpro.th2.infraoperator.spec.helmrelease.HelmRelease.NAME_LENGTH_LIMIT;
import static com.exactpro.th2.infraoperator.util.CustomResourceUtils.digest;
import static com.exactpro.th2.infraoperator.util.CustomResourceUtils.extractHashedName;
import static com.exactpro.th2.infraoperator.util.CustomResourceUtils.search;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.List;

import org.junit.jupiter.api.Test;

import com.exactpro.th2.infraoperator.spec.Th2CustomResource;
import com.exactpro.th2.infraoperator.spec.helmrelease.HelmRelease;

import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.ObjectMeta;
import io.fabric8.kubernetes.api.model.OwnerReference;

class CustomResourceUtilsTests {

private final String sourceNamespace = "namespace";
private static final String SOURCE_NAMESPACE = "namespace";

private final String sourceName = "123456789_123456789_123456789";
private static final String SOURCE_NAME = "123456789_123456789_123456789";

@Test
void extractHashedNameTest() {
var currentName = sourceName.substring(0, NAME_LENGTH_LIMIT - 1);
var currentName = SOURCE_NAME.substring(0, NAME_LENGTH_LIMIT - 1);
assertEquals(currentName, extractHashedName(createTh2CustomResource(currentName)));

currentName = sourceName.substring(0, NAME_LENGTH_LIMIT);
currentName = SOURCE_NAME.substring(0, NAME_LENGTH_LIMIT);
assertEquals(digest(currentName), extractHashedName(createTh2CustomResource(currentName)));

currentName = sourceName.substring(0, NAME_LENGTH_LIMIT + 1);
currentName = SOURCE_NAME.substring(0, NAME_LENGTH_LIMIT + 1);
assertEquals(digest(currentName), extractHashedName(createTh2CustomResource(currentName)));
}

@Test
void searchTest() {
List<HelmRelease> helmReleases = new ArrayList<>();
helmReleases.add(createHelmRelease(sourceName.substring(0, NAME_LENGTH_LIMIT - 1)));
helmReleases.add(createHelmRelease(digest(sourceName.substring(0, NAME_LENGTH_LIMIT))));
helmReleases.add(createHelmRelease(digest(sourceName.substring(0, NAME_LENGTH_LIMIT + 1))));

var th2CustomResource = createTh2CustomResource(sourceName.substring(0, NAME_LENGTH_LIMIT - 1));
assertEquals(helmReleases.get(0), search(helmReleases, th2CustomResource));

th2CustomResource = createTh2CustomResource(sourceName.substring(0, NAME_LENGTH_LIMIT));
assertEquals(helmReleases.get(1), search(helmReleases, th2CustomResource));

th2CustomResource = createTh2CustomResource(sourceName.substring(0, NAME_LENGTH_LIMIT + 1));
assertEquals(helmReleases.get(2), search(helmReleases, th2CustomResource));
}

private HelmRelease createHelmRelease(String name) {
HelmRelease helmRelease = createResource(HelmRelease.class, name);

List<OwnerReference> ownerReferences = new ArrayList<>();
var ownerReference = new OwnerReference();
ownerReference.setName(name);
ownerReferences.add(ownerReference);

when(helmRelease.getMetadata().getOwnerReferences()).thenReturn(ownerReferences);

return helmRelease;
}

private Th2CustomResource createTh2CustomResource(String name) {
return createResource(Th2CustomResource.class, name);
}

private <T extends HasMetadata> T createResource(Class<T> instanceClass, String name) {
T resource = mock(instanceClass);
ObjectMeta metaData = mock(ObjectMeta.class);
when(metaData.getNamespace()).thenReturn(sourceNamespace);
when(metaData.getNamespace()).thenReturn(SOURCE_NAMESPACE);
when(metaData.getName()).thenReturn(name);

when(resource.getMetadata()).thenReturn(metaData);
Expand Down
Loading

0 comments on commit 39704a4

Please sign in to comment.