INFRA-1768 | Ashvin | Trim environment variables before save

This commit is contained in:
Ashvin Sharma
2023-04-06 23:03:14 +05:30
parent 890484c72d
commit e31ecedf89
8 changed files with 722 additions and 37 deletions

3
.gitignore vendored
View File

@@ -11,6 +11,7 @@
.classpath
.factorypath
.gradle
!/.idea/codeStyles/**
.idea
.vscode
.metadata
@@ -46,4 +47,4 @@ local.env
kubernetes_manifests
manifests
pipelines
pipeline_manifests
pipeline_manifests

560
.idea/codeStyles/Project.xml generated Normal file
View File

@@ -0,0 +1,560 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<option name="OTHER_INDENT_OPTIONS">
<value>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="2" />
</value>
</option>
<option name="RIGHT_MARGIN" value="100" />
<AndroidXmlCodeStyleSettings>
<option name="USE_CUSTOM_SETTINGS" value="true" />
<option name="LAYOUT_SETTINGS">
<value>
<option name="INSERT_BLANK_LINE_BEFORE_TAG" value="false" />
</value>
</option>
</AndroidXmlCodeStyleSettings>
<JSCodeStyleSettings version="0">
<option name="INDENT_CHAINED_CALLS" value="false" />
</JSCodeStyleSettings>
<JavaCodeStyleSettings>
<option name="INSERT_INNER_CLASS_IMPORTS" value="true" />
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
<value />
</option>
<option name="IMPORT_LAYOUT_TABLE">
<value>
<package name="" withSubpackages="true" static="true" />
<emptyLine />
<package name="" withSubpackages="true" static="false" />
</value>
</option>
</JavaCodeStyleSettings>
<Objective-C>
<option name="INDENT_NAMESPACE_MEMBERS" value="0" />
<option name="INDENT_C_STRUCT_MEMBERS" value="2" />
<option name="INDENT_CLASS_MEMBERS" value="2" />
<option name="INDENT_VISIBILITY_KEYWORDS" value="1" />
<option name="INDENT_INSIDE_CODE_BLOCK" value="2" />
<option name="KEEP_STRUCTURES_IN_ONE_LINE" value="true" />
<option name="FUNCTION_PARAMETERS_WRAP" value="5" />
<option name="FUNCTION_CALL_ARGUMENTS_WRAP" value="5" />
<option name="TEMPLATE_CALL_ARGUMENTS_WRAP" value="5" />
<option name="TEMPLATE_CALL_ARGUMENTS_ALIGN_MULTILINE" value="true" />
<option name="ALIGN_INIT_LIST_IN_COLUMNS" value="false" />
<option name="SPACE_BEFORE_SUPERCLASS_COLON" value="false" />
</Objective-C>
<Objective-C-extensions>
<option name="GENERATE_INSTANCE_VARIABLES_FOR_PROPERTIES" value="ASK" />
<option name="RELEASE_STYLE" value="IVAR" />
<option name="TYPE_QUALIFIERS_PLACEMENT" value="BEFORE" />
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cc" header="h" />
<pair source="c" header="h" />
</extensions>
</Objective-C-extensions>
<Python>
<option name="USE_CONTINUATION_INDENT_FOR_ARGUMENTS" value="true" />
</Python>
<ScalaCodeStyleSettings>
<option name="MULTILINE_STRING_CLOSING_QUOTES_ON_NEW_LINE" value="true" />
</ScalaCodeStyleSettings>
<TypeScriptCodeStyleSettings version="0">
<option name="INDENT_CHAINED_CALLS" value="false" />
</TypeScriptCodeStyleSettings>
<XML>
<option name="XML_ALIGN_ATTRIBUTES" value="false" />
</XML>
<codeStyleSettings language="CSS">
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="ECMA Script Level 4">
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
<option name="ALIGN_MULTILINE_FOR" value="false" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="1" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="BINARY_OPERATION_WRAP" value="1" />
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
<option name="TERNARY_OPERATION_WRAP" value="1" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="1" />
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
<option name="IF_BRACE_FORCE" value="3" />
<option name="DOWHILE_BRACE_FORCE" value="3" />
<option name="WHILE_BRACE_FORCE" value="3" />
<option name="FOR_BRACE_FORCE" value="3" />
</codeStyleSettings>
<codeStyleSettings language="HTML">
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="JAVA">
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
<option name="ALIGN_MULTILINE_RESOURCES" value="false" />
<option name="ALIGN_MULTILINE_FOR" value="false" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="1" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="THROWS_KEYWORD_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
<option name="BINARY_OPERATION_WRAP" value="1" />
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
<option name="TERNARY_OPERATION_WRAP" value="1" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="1" />
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
<option name="WRAP_COMMENTS" value="true" />
<option name="IF_BRACE_FORCE" value="3" />
<option name="DOWHILE_BRACE_FORCE" value="3" />
<option name="WHILE_BRACE_FORCE" value="3" />
<option name="FOR_BRACE_FORCE" value="3" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="JSON">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="JavaScript">
<option name="RIGHT_MARGIN" value="80" />
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
<option name="ALIGN_MULTILINE_FOR" value="false" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="1" />
<option name="BINARY_OPERATION_WRAP" value="1" />
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
<option name="TERNARY_OPERATION_WRAP" value="1" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="1" />
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
<option name="IF_BRACE_FORCE" value="3" />
<option name="DOWHILE_BRACE_FORCE" value="3" />
<option name="WHILE_BRACE_FORCE" value="3" />
<option name="FOR_BRACE_FORCE" value="3" />
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="ObjectiveC">
<option name="RIGHT_MARGIN" value="80" />
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1" />
<option name="BLANK_LINES_BEFORE_IMPORTS" value="0" />
<option name="BLANK_LINES_AFTER_IMPORTS" value="0" />
<option name="BLANK_LINES_AROUND_CLASS" value="0" />
<option name="BLANK_LINES_AROUND_METHOD" value="0" />
<option name="BLANK_LINES_AROUND_METHOD_IN_INTERFACE" value="0" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="false" />
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="1" />
<option name="ASSIGNMENT_WRAP" value="1" />
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="PROTO">
<option name="RIGHT_MARGIN" value="80" />
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="Python">
<option name="RIGHT_MARGIN" value="80" />
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="SASS">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="SCSS">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="TypeScript">
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="XML">
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:.*Style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_width</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_height</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_weight</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_margin</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_marginTop</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_marginBottom</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_marginStart</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_marginEnd</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_marginLeft</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_marginRight</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:padding</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:paddingTop</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:paddingBottom</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:paddingStart</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:paddingEnd</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:paddingLeft</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:paddingRight</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res-auto</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_NAMESPACE>http://schemas.android.com/tools</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
<codeStyleSettings language="protobuf">
<option name="RIGHT_MARGIN" value="80" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
</component>

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View File

@@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

View File

@@ -9,9 +9,6 @@ import com.navi.infra.portal.domain.JsonEntity;
import com.navi.infra.portal.domain.notification.Notification;
import com.navi.infra.portal.dto.manifest.CloneManifestRequest;
import com.navi.infra.portal.util.Mapper;
import org.hibernate.annotations.Type;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
@@ -22,7 +19,6 @@ import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
@@ -35,11 +31,11 @@ import javax.persistence.PreUpdate;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.persistence.UniqueConstraint;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.annotations.Type;
@Entity
@Getter
@@ -95,13 +91,25 @@ public class Manifest extends JsonEntity {
@PreUpdate
@PrePersist
private void preUpdateHook() {
sortSecrets();
trimAndSortSecrets();
}
private void sortSecrets() {
if (environmentVariables != null) {
environmentVariables.sort((o1, o2) -> o1.getName().compareToIgnoreCase(o2.getName()));
private void trimAndSortSecrets() {
if (environmentVariables == null) {
return;
}
trimEnvironmentVariables();
environmentVariables.sort((o1, o2) -> o1.getName().compareToIgnoreCase(o2.getName()));
}
private void trimEnvironmentVariables() {
for (SecretConfig environmentVariable : environmentVariables) {
final var value = environmentVariable.getValue();
if (value == null) {
continue;
}
environmentVariable.setValue(value.trim());
}
}
public void nullifyIds() {
@@ -216,7 +224,7 @@ public class Manifest extends JsonEntity {
String name = secretConfig.getName();
String value = secretConfig.getValue();
if (!value.equals(redactedValueString)) {
secrets.put(name, value);
secrets.put(name, value.trim());
}
secretConfig.setDefaultValue();
});

View File

@@ -131,7 +131,7 @@ public class ManifestService {
public ManifestResponse createOrUpdate(Manifest manifest) {
ManifestResponse manifestResponse = new ManifestResponse();
validateManifest(manifest, manifestResponse);
if (manifestResponse.getError().size() > 0) {
if (!manifestResponse.getError().isEmpty()) {
return manifestResponse;
}
if (!privilegeService.canWriteManifest(manifest)) {
@@ -140,19 +140,23 @@ public class ManifestService {
Manifest oldManifest = null;
if (manifest.getId() != null) {
oldManifest = manifestRepository.findById(manifest.getId()).orElseThrow(
() -> new RuntimeException("manifest with id " + manifest.getId() + "not found"));
() -> new RuntimeException("manifest with id " + manifest.getId() + "not found"));
oldManifest = addAllSecrets(oldManifest);
}
Manifest newManifest = manifest;
MapDiffUtil.MapDiffResult difference = null;
if (oldManifest != null) {
difference = getManifestDiff(newManifest, oldManifest);
difference = getManifestDiff(manifest, oldManifest);
}
final Manifest newManifest;
if (checkManifestDiff(difference)) {
logManifestDifference(newManifest, oldManifest);
logManifestDifference(manifest, oldManifest);
newManifest = saveManifestWithoutSecrets(manifest);
newManifest.addRedactedValuesToSuperSecrets();
} else {
newManifest = manifest;
}
if (difference != null) {
kubernetesManifestService.generateManifestsAndApply(newManifest, difference);
}
@@ -349,7 +353,7 @@ public class ManifestService {
* just secrets back to it to show it to UI
*/
@Transactional
public Manifest saveManifestWithoutSecrets(Manifest manifest) {
public Manifest saveManifestWithoutSecrets(final Manifest manifest) {
String secretsVersion = "0";
String superSecretsVersion = "0";
@@ -370,8 +374,8 @@ public class ManifestService {
}
manifest.updateShaInSecretConfig(secrets, superSecrets);
manifest = saveManifestWithAudit(manifest, secretsVersion, superSecretsVersion);
return addGivenSecrets(manifest, secrets);
var savedManifest = saveManifestWithAudit(manifest, secretsVersion, superSecretsVersion);
return addGivenSecrets(savedManifest, secrets);
}
private Manifest saveManifestWithAudit(Manifest newManifest, String secretsVersion, String superSecretsVersion) {
@@ -461,7 +465,7 @@ public class ManifestService {
return manifestDeepCopy;
}
private Manifest addGivenSecrets(Manifest manifest, Map<String, String> secrets) {
private Manifest addGivenSecrets(final Manifest manifest, Map<String, String> secrets) {
Manifest manifestDeepCopy = manifestDeepCopy(manifest);
if (!secrets.isEmpty()) {
manifestDeepCopy.addSecrets(secrets);

View File

@@ -1,14 +1,20 @@
package com.navi.infra.portal.service;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.skyscreamer.jsonassert.JSONAssert.assertEquals;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.navi.infra.portal.domain.manifest.Manifest;
import com.navi.infra.portal.domain.manifest.ManifestAudit;
import com.navi.infra.portal.dto.manifest.ManifestResponse;
import com.navi.infra.portal.provider.ExternalIntegrationProvider;
import com.navi.infra.portal.service.manifest.ManifestService;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.skyscreamer.jsonassert.JSONAssert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureTestEntityManager;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
@@ -21,13 +27,6 @@ import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.transaction.annotation.Transactional;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertThrows;
@SpringBootTest
@AutoConfigureTestEntityManager
public class ManifestServiceIntegrationTest extends ExternalIntegrationProvider {
@@ -56,8 +55,8 @@ public class ManifestServiceIntegrationTest extends ExternalIntegrationProvider
"-testapp-get.json");
String expectedManifestUpdateOutputJson = readFile("fixtures/manifest/expected_output/dev" +
"-testapp-update.json");
assertAll(() -> JSONAssert.assertEquals(expectedManifestGetOutputJson, actualManifestJson, false),
() -> JSONAssert.assertEquals(expectedManifestUpdateOutputJson, ActualManifestResponseJson, false));
assertAll(() -> assertEquals(expectedManifestGetOutputJson, actualManifestJson, false),
() -> assertEquals(expectedManifestUpdateOutputJson, ActualManifestResponseJson, false));
}
@Test
@@ -71,7 +70,7 @@ public class ManifestServiceIntegrationTest extends ExternalIntegrationProvider
ManifestResponse manifestResponse = manifestService.createOrUpdate(manifestRequest);
String ActualManifestResponseJson = manifestResponse.getManifest().convertToString();
String expectedManifestUpdateOutputJson = readFile("fixtures/manifest/expected_output/dev-testapp-dynamicConfig-create-or-update.json");
JSONAssert.assertEquals(expectedManifestUpdateOutputJson, ActualManifestResponseJson, false);
assertEquals(expectedManifestUpdateOutputJson, ActualManifestResponseJson, false);
}
@Test
@@ -86,7 +85,7 @@ public class ManifestServiceIntegrationTest extends ExternalIntegrationProvider
Manifest manifest = manifestService.fetchByNameAndEnvironment("testapp-dynamicConfig", "dev");
String actualManifestJson = manifest.convertToString();
String expectedManifestGetOutputJson = readFile("fixtures/manifest/expected_output/dev-testapp-dynamicConfig-render.json");
JSONAssert.assertEquals(expectedManifestGetOutputJson, actualManifestJson, false);
assertEquals(expectedManifestGetOutputJson, actualManifestJson, false);
}
@Test
@@ -134,7 +133,7 @@ public class ManifestServiceIntegrationTest extends ExternalIntegrationProvider
testEntityManager.persist(manifest);
Manifest fetchManifest = manifestService.fetchByNameAndEnvironment("testapp", "dev");
String actualManifestJson = fetchManifest.convertToString();
assertAll(() -> JSONAssert.assertEquals(expectedManifestGetOutputJson, actualManifestJson, false));
assertAll(() -> assertEquals(expectedManifestGetOutputJson, actualManifestJson, false));
}
@Test
@@ -150,7 +149,7 @@ public class ManifestServiceIntegrationTest extends ExternalIntegrationProvider
manifestService.createOrUpdate(manifestRequest);
Manifest fetchManifest = manifestService.fetchByNameAndEnvironment("testapp", "dev");
String actualManifestJson = fetchManifest.convertToString();
assertAll(() -> JSONAssert.assertEquals(expectedManifestGetOutputJson, actualManifestJson, false));
assertAll(() -> assertEquals(expectedManifestGetOutputJson, actualManifestJson, false));
}
@Test
@@ -164,7 +163,7 @@ public class ManifestServiceIntegrationTest extends ExternalIntegrationProvider
manifestService.createOrUpdate(manifestRequest);
Manifest fetchManifest = manifestService.fetchByNameAndEnvironment("test-clone", "dev");
String actualManifestJson = fetchManifest.convertToString();
assertAll(() -> JSONAssert.assertEquals(expectedManifestGetOutputJson, actualManifestJson, false));
assertAll(() -> assertEquals(expectedManifestGetOutputJson, actualManifestJson, false));
}
@Test
@@ -181,13 +180,13 @@ public class ManifestServiceIntegrationTest extends ExternalIntegrationProvider
List<ManifestAudit> audits = manifestService.fetchAllVersionsForManifestId(response.getManifest().getId());
ManifestAudit actualManifestAudit = audits.get(0);
JSONAssert.assertEquals(expectedManifestAudit.getData().get("manifest").toString(),actualManifestAudit.getData().get("manifest").toString(),false);
assertEquals(expectedManifestAudit.getData().get("manifest").toString(),actualManifestAudit.getData().get("manifest").toString(),false);
//we have to do all this because in manifest audit table manifest saved as string instead of jsonb object.
actualManifestAudit.setData("manifest", null);
actualManifestAudit.setManifestId(null);
actualManifestAudit.setId(null);
expectedManifestAudit.setData("manifest", null);
JSONAssert.assertEquals(expectedManifestAudit.convertToString(), actualManifestAudit.convertToString(), false);
assertEquals(expectedManifestAudit.convertToString(), actualManifestAudit.convertToString(), false);
}
@Test
@@ -210,4 +209,26 @@ public class ManifestServiceIntegrationTest extends ExternalIntegrationProvider
}
@Test
@WithMockUser(
value = "admin_user",
username = "admin@navi.com",
authorities = {"manifest.read", "manifest.read.dev", "manifest.write", "manifest.write",
"manifest.write.dev", "secret.read.dev", "secret.write.dev", "supersecret.read",
"supersecret.write", "team.Infra"},
password = "admin"
)
@DisplayName("should save environment variables after trimming spaces")
@Transactional
void shouldSaveEnvironmentVariablesAfterTrimmingSpaces() throws IOException {
var manifest = readFileToManifest("fixtures/manifest/manifest-with-spaced-env-var.json");
var expected = readFile(
"fixtures/manifest/expected_output/manifest-with-spaced-env-var.json");
manifestService.createOrUpdate(manifest);
var actualManifest = manifestService.fetchByNameAndEnvironment("manifest", "dev");
var actual = actualManifest.convertToString();
assertEquals(expected, actual, false);
}
}

View File

@@ -0,0 +1,43 @@
{
"version": 46,
"environmentVariables": [
{
"name": "var1",
"type": "CONFIG",
"sha256": "e209a6f1ba44c54eb5b58b6f2c0c2d67cad59607ef058a363a0d318af77fd04d",
"value": "value1"
},
{
"name": "var2",
"type": "SECRET",
"sha256": "0537d481f73a757334328052da3af9626ced97028e20b849f6115c22cd765197",
"value": "value2"
},
{
"name": "var3",
"type": "SUPER_SECRET",
"sha256": "89dc6ae7f06a9f46b565af03eab0ece0bf6024d3659b7e3a1d03573cfeb0b59d",
"value": "value3"
}
],
"deployment": {
"loadBalancers": [],
"alerts": {},
"cluster": "spike.np.navi-tech.in",
"instance": {},
"exposedPorts": [],
"allowEgress": [],
"healthCheck": {},
"hpa": {},
"timeout": 1500,
"namespace": "dev"
},
"team": {
"name": "Infra"
},
"labels": {
"micrometer-prometheus": "enabled"
},
"environment": "dev",
"name": "manifest"
}

View File

@@ -0,0 +1,43 @@
{
"version": 46,
"environmentVariables": [
{
"name": "var1",
"type": "CONFIG",
"sha256": "e209a6f1ba44c54eb5b58b6f2c0c2d67cad59607ef058a363a0d318af77fd04d",
"value": " value1"
},
{
"name": "var2",
"type": "SECRET",
"sha256": "0537d481f73a757334328052da3af9626ced97028e20b849f6115c22cd765197",
"value": "value2 "
},
{
"name": "var3",
"type": "SUPER_SECRET",
"sha256": "89dc6ae7f06a9f46b565af03eab0ece0bf6024d3659b7e3a1d03573cfeb0b59d",
"value": " value3 "
}
],
"deployment": {
"loadBalancers": [],
"alerts": {},
"cluster": "spike.np.navi-tech.in",
"instance": {},
"exposedPorts": [],
"allowEgress": [],
"healthCheck": {},
"hpa": {},
"timeout": 1500,
"namespace": "dev"
},
"team": {
"name": "Infra"
},
"labels": {
"micrometer-prometheus": "enabled"
},
"environment": "dev",
"name": "manifest"
}