[AMBARI-23130] Retrieve cluster template as artifact with passwords filtered out.#931
Conversation
…ids on server restart (benyoka)
…eature-AMBARI-14714
…eature-AMBARI-14714
…eature-AMBARI-14714
…nto AMBARI-23130-branch-feature-AMBARI-14714
…nto AMBARI-23130-branch-feature-AMBARI-14714
|
Refer to this link for build results (access rights to CI server needed): |
rnettleton
left a comment
There was a problem hiding this comment.
This patch looks fine to me, just a few minor comments/questions below.
Can you please also ask @echekanskiy to review, since I think he implemented the original version of the SecretReference code?
Thanks.
| Multimap<String, String> passwordProperties) { | ||
| return propertyMap.entrySet().stream().map(entry -> { | ||
| String propertyType = entry.getKey(); | ||
| String newValue = passwordProperties.get(configType).contains(propertyType) ? |
There was a problem hiding this comment.
Minor issue: If a configuration type is listed in a Blueprint/Cluster Creation template that is not a match with any known configuration type, will this throw a NullPointerException?
This might be a problem in cases where the cluster creation template has an error (mis-spelled config type name) or if a custom config type is specified that the stacks do not include.
Maybe we should catch this error here and log appropriately, if the code doesn't already filter out "unknown" config types at some other level.
There was a problem hiding this comment.
Guava multimaps return an empty collection if the key is not in the map, that's one of their cool features.
| public static final String CLUSTER_NAME_PROPERTY = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + CLUSTER_NAME; | ||
| public static final String SERVICE_NAME_PROPERTY = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + SERVICE_NAME; | ||
|
|
||
| public static final String PROVISION_REQUEST_ARTIFACT_NAME = "provision_cluster_request"; |
There was a problem hiding this comment.
Minor concern:
I think this change is fine the way it is, but we might want to consider refactoring this in the future.
It may make more sense to keep any details about specific types of artifacts out of this class, and have a more generic strategy defined to allow for modifications of retrieved artifacts before the artifacts are returned to the caller.
Even having a static list of registered "filtering" or "updating" interfaces in this class might be better, and allow the resource provider code to only interact with that strategy interface.
As I mentioned, this current change is fine, but we might want to consider refactoring this if we find that other artifact types need to be persisted, and then retrieved in some custom fashion.
| Configuration replacedConfiguration = | ||
| SecretReference.replacePasswordsInConfigurations(configuration, passwordProperties); | ||
| return Configurable.convertConfigToMap(replacedConfiguration); | ||
| } |
There was a problem hiding this comment.
Can you please extract this lambda expression to a function that can be referenced and tested more easily?
There was a problem hiding this comment.
This method simply transforms a map with a lambda that is only 3 statements. I don't think further decomposition should be needed.
| entry.getKey(), | ||
| applyToAllConfigurations(entry.getValue(), transform)); | ||
| } | ||
| }).collect(toMap(Map.Entry::getKey, Map.Entry::getValue)); |
There was a problem hiding this comment.
Can you please extract this lambda expression to a function that can be referenced and tested more easily?
There was a problem hiding this comment.
I broke it up to smaller methods. I don't think it improves testing (the algorithm should be tested as a whole), on the other hand it hopefully improves readability.
| catch (StackAccessException ex) { | ||
| throw new IllegalArgumentException(ex); | ||
| } | ||
| }).collect(toList()); |
There was a problem hiding this comment.
Can you please extract this lambda expression to a function that can be referenced and tested more easily?
There was a problem hiding this comment.
This is a very simple lambda (a simple method call within a try - catch - re-throw). I don't think it makes sense to decompose it further.
| return getAllPasswordPropertiesInternal(metaInfo.getStacks()); | ||
| } | ||
|
|
||
| private static SetMultimap<String, String> getAllPasswordPropertiesInternal(Collection<StackInfo> stacks) { |
There was a problem hiding this comment.
Making this non-private would allow testing without the need for PowerMock.
There was a problem hiding this comment.
Powermock is needed because of the static call to AmbariServer.getController(), not because this method is private.
There was a problem hiding this comment.
I meant that this method could be tested instead of the one that calls AmbariServer.getController(). Most of the logic is in this one.
| Map<String, Map<String, String>> replacedConfigProps = configTypeEntry.getValue().entrySet().stream().collect( | ||
| toMap(Map.Entry::getKey, e -> replacePasswordsInPropertyMap(e.getValue(), configType, passwordProperties))); | ||
| return new SimpleEntry<>(configType, replacedConfigProps); | ||
| }).collect(toMap(Map.Entry::getKey, Map.Entry::getValue)); |
There was a problem hiding this comment.
Can you please extract these lambda expressions to a function that can be referenced and tested more easily?
There was a problem hiding this comment.
I am thinking on a simplification.
| SECRET_PREFIX + ":" + configType + ":" + propertyType : | ||
| entry.getValue(); | ||
| return new SimpleEntry<>(propertyType, newValue); | ||
| }).collect(toMap(Map.Entry::getKey, Map.Entry::getValue)); |
There was a problem hiding this comment.
Can you please extract this lambda expression to a function that can be referenced and tested more easily?
There was a problem hiding this comment.
This is another a very simple map transformation written in java-8-lambda style rather as for-loop. I don't think further decomposition would add anything to readability or testability. I changed the indentation though to make it more readable.
|
Refer to this link for build results (access rights to CI server needed): |
|
Refer to this link for build results (access rights to CI server needed): |
|
Refer to this link for build results (access rights to CI server needed): |
What changes were proposed in this pull request?
Cluster templates are saved as artifacts during blueprint cluster creation and can be retrieved via the artifact resource provider API. Passwords are replaced with references during retrieval.
How was this patch tested?
Tested manually. Wrote new unit tests. Unit test results:
Tests run: 4834, Failures: 150, Errors: 301, Skipped: 73