Skip to content

Commit 14e3da6

Browse files
authored
Owls 104212 - Changes to shorten the generated volume names and container names for converted aux images (#3669)
* Changes to truncate the generated volume name for the converted v8 auxiliary images when the name is longer than 63 characters.
1 parent cffe01c commit 14e3da6

File tree

18 files changed

+231
-126
lines changed

18 files changed

+231
-126
lines changed

common/src/main/java/oracle/kubernetes/common/AuxiliaryImageConstants.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ private AuxiliaryImageConstants() {
1010
}
1111

1212
public static final String AUXILIARY_IMAGE_TARGET_PATH = "/tmpAuxiliaryImage";
13-
public static final String AUXILIARY_IMAGE_VOLUME_NAME_PREFIX = "aux-image-volume-";
13+
public static final String AUXILIARY_IMAGE_VOLUME_NAME_PREFIX = "ai-vol-";
1414
public static final String AUXILIARY_IMAGE_INIT_CONTAINER_WRAPPER_SCRIPT = "/weblogic-operator/scripts/auxImage.sh";
1515
public static final String AUXILIARY_IMAGE_INIT_CONTAINER_NAME_PREFIX = "operator-aux-container";
1616
public static final String AUXILIARY_IMAGE_DEFAULT_INIT_CONTAINER_COMMAND

common/src/main/java/oracle/kubernetes/common/CommonConstants.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ private CommonConstants() {
99
//not called
1010
}
1111

12-
public static final String COMPATIBILITY_MODE = "compatibility-mode-";
12+
public static final String COMPATIBILITY_MODE = "compat-";
1313
public static final String API_VERSION_V9 = "weblogic.oracle/v9";
1414
public static final String API_VERSION_V8 = "weblogic.oracle/v8";
1515

common/src/main/java/oracle/kubernetes/common/utils/CommonUtils.java

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,20 @@
33

44
package oracle.kubernetes.common.utils;
55

6+
import java.nio.charset.StandardCharsets;
7+
import java.security.MessageDigest;
8+
import java.security.NoSuchAlgorithmException;
9+
import java.util.Optional;
10+
611
import oracle.kubernetes.common.CommonConstants;
712

813
public class CommonUtils {
914

15+
private static CheckedFunction<String, String> getMD5Hash = CommonUtils::getMD5Hash;
16+
17+
public static final int MAX_ALLOWED_VOLUME_NAME_LENGTH = 63;
18+
public static final String VOLUME_NAME_SUFFIX = "-volume";
19+
1020
private CommonUtils() {
1121
//not called
1222
}
@@ -33,4 +43,45 @@ public static String toDns1123LegalName(String value) {
3343
return value.toLowerCase().replace('_', '-');
3444
}
3545

46+
/**
47+
* Returns a truncated volume name if the name exceeds the max allowed limit of characters for volume name.
48+
* @param volumeName volume name
49+
* @return truncated volume name if the name exceeds the limit, else return volumeName
50+
* @throws NoSuchAlgorithmException Thrown when particular cryptographic algorithm
51+
* is not available in the environment.
52+
*/
53+
public static String getLegalVolumeName(String volumeName) throws NoSuchAlgorithmException {
54+
return volumeName.length() > (MAX_ALLOWED_VOLUME_NAME_LENGTH)
55+
? getShortName(volumeName)
56+
: volumeName;
57+
}
58+
59+
60+
private static String getShortName(String resourceName) throws NoSuchAlgorithmException {
61+
String volumeSuffix = Optional.ofNullable(getMD5Hash.apply(resourceName)).orElse("");
62+
return resourceName.substring(0, MAX_ALLOWED_VOLUME_NAME_LENGTH - volumeSuffix.length()) + volumeSuffix;
63+
}
64+
65+
/**
66+
* Gets the MD5 hash of a string.
67+
*
68+
* @param data input string
69+
* @return MD5 hash value of the data, null in case of an exception.
70+
*/
71+
public static String getMD5Hash(String data) throws NoSuchAlgorithmException {
72+
return bytesToHex(MessageDigest.getInstance("MD5").digest(data.getBytes(StandardCharsets.UTF_8)));
73+
}
74+
75+
private static String bytesToHex(byte[] hash) {
76+
StringBuilder result = new StringBuilder();
77+
for (byte b : hash) {
78+
result.append(String.format("%02x", b));
79+
}
80+
return result.toString();
81+
}
82+
83+
@FunctionalInterface
84+
public interface CheckedFunction<T, R> {
85+
R apply(T t) throws NoSuchAlgorithmException;
86+
}
3687
}

common/src/main/java/oracle/kubernetes/common/utils/SchemaConversionUtils.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ public class SchemaConversionUtils {
5959
private static final String DOLLAR_SPEC_AS_SERVERPOD = "$.spec.adminServer.serverPod";
6060

6161
public static final String INTERNAL = "Internal";
62+
6263
/**
6364
* The list of failure reason strings. Hard-coded here to match the values in DomainFailureReason.
6465
* Validated in tests in the operator.
@@ -683,7 +684,15 @@ private boolean hasMatchingVolumeMountName(Object volumeMount, Map<String, Objec
683684
return getDNS1123auxiliaryImageVolumeName(auxiliaryImage.get(VOLUME)).equals(((Map)volumeMount).get("name"));
684685
}
685686

686-
public static String getDNS1123auxiliaryImageVolumeName(Object name) {
687+
private static String getDNS1123auxiliaryImageVolumeName(Object name) {
688+
try {
689+
return CommonUtils.getLegalVolumeName(getVolumeName(name));
690+
} catch (Exception ex) {
691+
return getVolumeName(name);
692+
}
693+
}
694+
695+
private static String getVolumeName(Object name) {
687696
return CommonUtils.toDns1123LegalName(CommonConstants.COMPATIBILITY_MODE
688697
+ AuxiliaryImageConstants.AUXILIARY_IMAGE_VOLUME_NAME_PREFIX + name);
689698
}

common/src/test/java/oracle/kubernetes/common/utils/SchemaConversionUtilsTest.java

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import java.io.IOException;
77
import java.io.InputStream;
8+
import java.security.NoSuchAlgorithmException;
89
import java.util.ArrayList;
910
import java.util.Collections;
1011
import java.util.HashMap;
@@ -15,6 +16,8 @@
1516
import java.util.Optional;
1617

1718
import com.meterware.simplestub.Memento;
19+
import com.meterware.simplestub.StaticStubSupport;
20+
import oracle.kubernetes.common.CommonConstants;
1821
import org.junit.jupiter.api.AfterEach;
1922
import org.junit.jupiter.api.BeforeEach;
2023
import org.junit.jupiter.api.Test;
@@ -24,6 +27,7 @@
2427

2528
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
2629
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasNoJsonPath;
30+
import static oracle.kubernetes.common.AuxiliaryImageConstants.AUXILIARY_IMAGE_VOLUME_NAME_PREFIX;
2731
import static oracle.kubernetes.common.CommonConstants.API_VERSION_V8;
2832
import static oracle.kubernetes.common.CommonConstants.API_VERSION_V9;
2933
import static org.hamcrest.Matchers.contains;
@@ -47,11 +51,16 @@ class SchemaConversionUtilsTest {
4751
private final ConversionAdapter converterv8 = new ConversionAdapter(API_VERSION_V8);
4852
private Map<String, Object> v8Domain;
4953

54+
private static CommonUtils.CheckedFunction<String, String> getMD5Hash = SchemaConversionUtilsTest::getMD5Hash;
55+
56+
private static String getMD5Hash(String s) throws NoSuchAlgorithmException {
57+
throw new NoSuchAlgorithmException();
58+
}
59+
5060
@BeforeEach
5161
public void setUp() throws Exception {
5262
mementos.add(CommonTestUtils.silenceLogger());
5363
mementos.add(BaseTestUtils.silenceJsonPathLogger());
54-
5564
v8Domain = readAsYaml(DOMAIN_V8_AUX_IMAGE30_YAML);
5665
}
5766

@@ -606,4 +615,35 @@ void testV8DomainWebLogicCredentialsSecretWithNamespace_remove() {
606615

607616
assertThat(converter.getDomain(), hasNoJsonPath("$.spec.webLogicCredentialsSecret.namespace"));
608617
}
618+
619+
@Test
620+
void testV8DomainWithLongAuxiliaryImageVolumeName_convertedVolumeNameIsTruncated() throws NoSuchAlgorithmException {
621+
Map<String, Object> auxImageVolume = ((Map<String, Object>)
622+
((List<Object>) getDomainSpec(v8Domain).get("auxiliaryImageVolumes")).get(0));
623+
auxImageVolume.put("name", "test-domain-aux-image-volume-test-domain-aux-image-volume");
624+
getDomainSpec(v8Domain).put("auxiliaryImageVolumes", Collections.singletonList(auxImageVolume));
625+
626+
converter.convert(v8Domain);
627+
628+
assertThat(converter.getDomain(), hasJsonPath("$.spec.serverPod.volumes[0].name",
629+
equalTo(CommonUtils.getLegalVolumeName(CommonUtils.toDns1123LegalName(CommonConstants.COMPATIBILITY_MODE
630+
+ AUXILIARY_IMAGE_VOLUME_NAME_PREFIX + (String)auxImageVolume.get("name"))))));
631+
}
632+
633+
@Test
634+
void testV8DomainWithLongAuxiliaryImageVolumeNameAndMessageDigestThrowsException_volumeNameIsNotChanged()
635+
throws NoSuchFieldException {
636+
mementos.add(StaticStubSupport.install(CommonUtils.class, "getMD5Hash", getMD5Hash));
637+
638+
Map<String, Object> auxImageVolume = ((Map<String, Object>)
639+
((List<Object>) getDomainSpec(v8Domain).get("auxiliaryImageVolumes")).get(0));
640+
auxImageVolume.put("name", "test-domain-aux-image-volume-test-domain-aux-image-volume");
641+
getDomainSpec(v8Domain).put("auxiliaryImageVolumes", Collections.singletonList(auxImageVolume));
642+
643+
converter.convert(v8Domain);
644+
645+
assertThat(converter.getDomain(), hasJsonPath("$.spec.serverPod.volumes[0].name",
646+
equalTo(CommonUtils.toDns1123LegalName(CommonConstants.COMPATIBILITY_MODE
647+
+ AUXILIARY_IMAGE_VOLUME_NAME_PREFIX + "test-domain-aux-image-volume-test-domain-aux-image-volume"))));
648+
}
609649
}

common/src/test/resources/oracle/kubernetes/common/utils/converted-domain-sample-2.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ spec:
3434
adminServer:
3535
serverPod:
3636
volumes:
37-
- name: compatibility-mode-aux-image-volume-auxiliaryimagevolume1
37+
- name: compat-ai-vol-auxiliaryimagevolume1
3838
emptyDir: {
3939
}
4040
initContainers:
41-
- name: compatibility-mode-operator-aux-container1
41+
- name: compat-operator-aux-container1
4242
image: model-in-image:WLS-AI-v1
4343
command:
4444
- /weblogic-operator/scripts/auxImage.sh
@@ -53,14 +53,14 @@ spec:
5353
- name: AUXILIARY_IMAGE_CONTAINER_IMAGE
5454
value: model-in-image:WLS-AI-v1
5555
- name: AUXILIARY_IMAGE_CONTAINER_NAME
56-
value: compatibility-mode-operator-aux-container1
56+
value: compat-operator-aux-container1
5757
volumeMounts:
58-
- name: compatibility-mode-aux-image-volume-auxiliaryimagevolume1
58+
- name: compat-ai-vol-auxiliaryimagevolume1
5959
mountPath: /tmpAuxiliaryImage
6060
- name: weblogic-scripts-cm-volume
6161
mountPath: /weblogic-operator/scripts
6262
volumeMounts:
63-
- name: compatibility-mode-aux-image-volume-auxiliaryimagevolume1
63+
- name: compat-ai-vol-auxiliaryimagevolume1
6464
mountPath: /auxiliary
6565
env:
6666
- name: AUXILIARY_IMAGE_PATHS

common/src/test/resources/oracle/kubernetes/common/utils/converted-domain-sample.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ spec:
3434
cpu: 250m
3535
memory: 768Mi
3636
volumes:
37-
- name: compatibility-mode-aux-image-volume-auxiliaryimagevolume1
37+
- name: compat-ai-vol-auxiliaryimagevolume1
3838
emptyDir: {
3939
}
4040
initContainers:
41-
- name: compatibility-mode-operator-aux-container1
41+
- name: compat-operator-aux-container1
4242
image: model-in-image:WLS-AI-v1
4343
command:
4444
- /weblogic-operator/scripts/auxImage.sh
@@ -53,14 +53,14 @@ spec:
5353
- name: AUXILIARY_IMAGE_CONTAINER_IMAGE
5454
value: model-in-image:WLS-AI-v1
5555
- name: AUXILIARY_IMAGE_CONTAINER_NAME
56-
value: compatibility-mode-operator-aux-container1
56+
value: compat-operator-aux-container1
5757
volumeMounts:
58-
- name: compatibility-mode-aux-image-volume-auxiliaryimagevolume1
58+
- name: compat-ai-vol-auxiliaryimagevolume1
5959
mountPath: /tmpAuxiliaryImage
6060
- name: weblogic-scripts-cm-volume
6161
mountPath: /weblogic-operator/scripts
6262
volumeMounts:
63-
- name: compatibility-mode-aux-image-volume-auxiliaryimagevolume1
63+
- name: compat-ai-vol-auxiliaryimagevolume1
6464
mountPath: /auxiliary
6565
adminServer:
6666
adminChannelPortForwardingEnabled: false

documentation/4.0/content/managing-domains/model-in-image/auxiliary-images.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -198,21 +198,21 @@ spec:
198198
- name: AUXILIARY_IMAGE_CONTAINER_IMAGE
199199
value: model-in-image:WLS-AI-v1
200200
- name: AUXILIARY_IMAGE_CONTAINER_NAME
201-
value: compatibility-mode-operator-aux-container1
201+
value: compat-operator-aux-container1
202202
image: model-in-image:WLS-AI-v1
203203
imagePullPolicy: IfNotPresent
204-
name: compatibility-mode-operator-aux-container1
204+
name: compat-operator-aux-container1
205205
volumeMounts:
206206
- mountPath: /tmpAuxiliaryImage
207-
name: compatibility-mode-aux-image-volume-auxiliaryimagevolume1
207+
name: compat-ai-vol-auxiliaryimagevolume1
208208
- mountPath: /weblogic-operator/scripts
209209
name: weblogic-scripts-cm-volume
210210
volumeMounts:
211211
- mountPath: /auxiliary
212-
name: compatibility-mode-aux-image-volume-auxiliaryimagevolume1
212+
name: compat-ai-vol-auxiliaryimagevolume1
213213
volumes:
214214
- emptyDir: {}
215-
name: compatibility-mode-aux-image-volume-auxiliaryimagevolume1
215+
name: compat-ai-vol-auxiliaryimagevolume1
216216
```
217217

218218
### Domain upgrade tool to manually upgrade the `weblogic.oracle/v8` schema domain resource

integration-tests/src/test/java/oracle/weblogic/kubernetes/ItAuxV8DomainImplicitUpgrade.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ void testMultipleAuxImagesV8Domain() {
277277
assertNotNull(containerList, "/spec/serverPod/InitContainers is null");
278278
containerList.forEach(container -> {
279279
logger.info("The Init Container name is: {0} ", container.getName());
280-
if (container.getName().equalsIgnoreCase("compatibility-mode-operator-aux-container1")) {
280+
if (container.getName().equalsIgnoreCase("compat-operator-aux-container1")) {
281281
logger.info("The Compatiblity Init Container found");
282282
foundCompatiblityContainer = true;
283283
}

operator/src/main/java/oracle/kubernetes/operator/helpers/JobStepContext.java

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package oracle.kubernetes.operator.helpers;
55

66
import java.io.File;
7+
import java.security.NoSuchAlgorithmException;
78
import java.util.ArrayList;
89
import java.util.Collections;
910
import java.util.List;
@@ -27,6 +28,7 @@
2728
import io.kubernetes.client.openapi.models.V1VolumeMount;
2829
import oracle.kubernetes.common.helpers.AuxiliaryImageEnvVars;
2930
import oracle.kubernetes.common.logging.MessageKeys;
31+
import oracle.kubernetes.common.utils.CommonUtils;
3032
import oracle.kubernetes.operator.DomainSourceType;
3133
import oracle.kubernetes.operator.IntrospectorConfigMapConstants;
3234
import oracle.kubernetes.operator.KubernetesConstants;
@@ -40,7 +42,6 @@
4042
import oracle.kubernetes.operator.logging.LoggingFactory;
4143
import oracle.kubernetes.operator.processing.EffectiveServerSpec;
4244
import oracle.kubernetes.operator.tuning.TuningParameters;
43-
import oracle.kubernetes.operator.utils.ChecksumUtils;
4445
import oracle.kubernetes.operator.wlsconfig.WlsDomainConfig;
4546
import oracle.kubernetes.operator.work.NextAction;
4647
import oracle.kubernetes.operator.work.Packet;
@@ -54,6 +55,8 @@
5455
import static oracle.kubernetes.common.CommonConstants.COMPATIBILITY_MODE;
5556
import static oracle.kubernetes.common.CommonConstants.SCRIPTS_MOUNTS_PATH;
5657
import static oracle.kubernetes.common.CommonConstants.SCRIPTS_VOLUME;
58+
import static oracle.kubernetes.common.utils.CommonUtils.MAX_ALLOWED_VOLUME_NAME_LENGTH;
59+
import static oracle.kubernetes.common.utils.CommonUtils.VOLUME_NAME_SUFFIX;
5760
import static oracle.kubernetes.operator.DomainStatusUpdater.createKubernetesFailureSteps;
5861
import static oracle.kubernetes.operator.helpers.AffinityHelper.getDefaultAntiAffinity;
5962
import static oracle.kubernetes.utils.OperatorUtils.emptyToNull;
@@ -72,12 +75,11 @@ public class JobStepContext extends BasePodStepContext {
7275
private static final LoggingFacade LOGGER = LoggingFactory.getLogger("Operator", "Operator");
7376
private static final String WEBLOGIC_OPERATOR_SCRIPTS_INTROSPECT_DOMAIN_SH =
7477
"/weblogic-operator/scripts/introspectDomain.sh";
75-
private static final int MAX_ALLOWED_VOLUME_NAME_LENGTH = 63;
76-
private static final String VOLUME_NAME_SUFFIX = "-volume";
7778
private static final String CONFIGMAP_TYPE = "cm";
7879
private static final String SECRET_TYPE = "st";
7980
// domainTopology is null if this is 1st time we're running job for this domain
8081
private final WlsDomainConfig domainTopology;
82+
private static CommonUtils.CheckedFunction<String, String> getMD5Hash = CommonUtils::getMD5Hash;
8183
private V1Job jobModel;
8284
private Step conflictStep;
8385

@@ -508,18 +510,23 @@ protected V1Container createPrimaryContainer() {
508510
}
509511

510512
private String getVolumeName(String resourceName, String type) {
511-
return getName(resourceName, type);
513+
try {
514+
return getLegalVolumeName(resourceName, type);
515+
} catch (Exception ex) {
516+
LOGGER.severe(MessageKeys.EXCEPTION, ex);
517+
return resourceName;
518+
}
512519
}
513520

514-
private String getName(String resourceName, String type) {
515-
return resourceName.length() > (MAX_ALLOWED_VOLUME_NAME_LENGTH - VOLUME_NAME_SUFFIX.length())
516-
? getShortName(resourceName, type)
517-
: resourceName + VOLUME_NAME_SUFFIX;
521+
private String getLegalVolumeName(String volumeName, String type) throws NoSuchAlgorithmException {
522+
return volumeName.length() > (MAX_ALLOWED_VOLUME_NAME_LENGTH - VOLUME_NAME_SUFFIX.length())
523+
? getShortName(volumeName, type)
524+
: volumeName + VOLUME_NAME_SUFFIX;
518525
}
519526

520-
private String getShortName(String resourceName, String type) {
527+
private String getShortName(String resourceName, String type) throws NoSuchAlgorithmException {
521528
String volumeSuffix = VOLUME_NAME_SUFFIX + "-" + type + "-"
522-
+ Optional.ofNullable(ChecksumUtils.getMD5Hash(resourceName)).orElse("");
529+
+ Optional.ofNullable(getMD5Hash.apply(resourceName)).orElse("");
523530
return resourceName.substring(0, MAX_ALLOWED_VOLUME_NAME_LENGTH - volumeSuffix.length()) + volumeSuffix;
524531
}
525532

0 commit comments

Comments
 (0)