-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(config): Added json schema generator for providers #7
base: master
Are you sure you want to change the base?
Changes from all commits
8770168
11c3b20
5142804
9552b81
d0ed13c
9a8be65
4835374
7a630d5
933f6db
60f2116
6652c55
f6e67ea
dc8c03c
47091f2
c6a19bf
c1227cb
fd14c79
55bd7b9
7398b44
1e9535f
1afe916
5aabd92
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package com.netflix.spinnaker.halyard.cli.command.v1; | ||
|
||
import java.lang.reflect.Field; | ||
import java.util.HashMap; | ||
|
||
import com.beust.jcommander.Parameter; | ||
import com.netflix.spinnaker.halyard.config.model.v1.node.Providers; | ||
|
||
import lombok.Data; | ||
import net.minidev.json.JSONObject; | ||
@Data | ||
public class EnrichMetadata { | ||
public JSONObject providersFields = Providers.providersMetadata(); | ||
|
||
public void addProviderCommandFields(String providerName, Field[] fields) { | ||
JSONObject providerFields = (JSONObject) ((JSONObject) providersFields.get("providers")).get(providerName); | ||
if (providersFields != null && providerFields != null) { | ||
for (Field f : fields) { | ||
if (f.getAnnotation(Parameter.class) != null && providerFields.get(f.getName()) != null) { | ||
if (f.getAnnotation(Parameter.class).required() == true) { | ||
((HashMap<String, Object>) providerFields.get(f.getName())).put("required", true); | ||
} | ||
if (f.getAnnotation(Parameter.class).description() != "") { | ||
((HashMap<String, Object>) providerFields.get(f.getName())) | ||
.put("description", f.getAnnotation(Parameter.class).description()); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
public void addAccountCommandFields(String providerName, Field[] fields) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add new line above |
||
JSONObject accountfields = (JSONObject) ((JSONObject) ((JSONObject) providersFields.get("providers")).get(providerName)) | ||
.get("accountFields"); | ||
if (providersFields != null && accountfields != null) { | ||
for (Field f : fields) { | ||
if (f.getAnnotation(Parameter.class) != null && accountfields.get(f.getName()) != null) { | ||
if (f.getAnnotation(Parameter.class).required() == true) { | ||
((HashMap<String, Object>) accountfields.get(f.getName())).put("required", true); | ||
} | ||
if (f.getAnnotation(Parameter.class).description() != "") { | ||
((HashMap<String, Object>) accountfields.get(f.getName())) | ||
.put("description", f.getAnnotation(Parameter.class).description()); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
public void addBakeryCommandFields(String providerName, Field[] fields) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add new line above |
||
JSONObject bakeryDefaultsFields = (JSONObject) ((JSONObject) ((JSONObject) providersFields.get("providers")) | ||
.get(providerName)).get("bakeryDefaultsFields"); | ||
if (providersFields != null && bakeryDefaultsFields != null) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. might want to use |
||
for (Field f : fields) { | ||
if (f.getAnnotation(Parameter.class) != null && bakeryDefaultsFields.get(f.getName()) != null) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. might want to use |
||
if (f.getAnnotation(Parameter.class).required() == true) { | ||
((HashMap<String, Object>) bakeryDefaultsFields.get(f.getName())).put("required", true); | ||
} | ||
if (f.getAnnotation(Parameter.class).description() != "") { | ||
((HashMap<String, Object>) bakeryDefaultsFields.get(f.getName())) | ||
.put("description", f.getAnnotation(Parameter.class).description()); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package com.netflix.spinnaker.halyard.cli.command.v1; | ||
|
||
import com.netflix.spinnaker.halyard.cli.command.v1.config.providers.AbstractProviderCommand; | ||
import com.netflix.spinnaker.halyard.cli.command.v1.config.providers.account.AbstractAddAccountCommand; | ||
import com.netflix.spinnaker.halyard.cli.command.v1.config.providers.bakery.AbstractEditBakeryDefaultsCommand; | ||
import com.netflix.spinnaker.halyard.config.model.v1.node.Provider.ProviderType; | ||
import com.netflix.spinnaker.halyard.config.model.v1.node.Providers; | ||
import java.lang.reflect.Field; | ||
import java.util.Arrays; | ||
import lombok.Data; | ||
import net.minidev.json.JSONObject; | ||
|
||
@Data | ||
public class GenerateMetadata { | ||
public static JSONObject generateMetadata() { | ||
EnrichMetadata em = new EnrichMetadata(); | ||
for (ProviderType provider : ProviderType.values()) { | ||
try { | ||
Class<?> providerCommandClass = translateProviderCommandType(provider.getName()); | ||
Field[] providerCommandFields = getFields(providerCommandClass); | ||
em.addProviderCommandFields(provider.getName(), providerCommandFields); | ||
|
||
} catch (IllegalArgumentException e) { | ||
// ignoring because it doesn't matter | ||
} | ||
} | ||
for (ProviderType provider : ProviderType.values()) { | ||
try { | ||
Class<?> addBakeryCommandClass = translateEditBakeryCommandType(provider.getName()); | ||
Field[] addBakeryCommandFields = getFields(addBakeryCommandClass); | ||
em.addBakeryCommandFields(provider.getName(), addBakeryCommandFields); | ||
} catch (IllegalArgumentException e) { | ||
// ignoring because it doesn't matter | ||
} | ||
} | ||
for (ProviderType provider : ProviderType.values()) { | ||
try { | ||
Class<?> addCommandClass = translateAddAccountCommandType(provider.getName()); | ||
Field[] addCommandFields = getFields(addCommandClass); | ||
em.addAccountCommandFields(provider.getName(), addCommandFields); | ||
} catch (IllegalArgumentException e) { | ||
// ignoring because it doesn't matter | ||
} | ||
} | ||
return em.getProvidersFields(); | ||
} | ||
|
||
public static Class<? extends AbstractAddAccountCommand> translateAddAccountCommandType( | ||
String providerName) { | ||
Class<?> providerClass = Providers.translateProviderType(providerName); | ||
|
||
String addAccountCommandClass = | ||
providerClass | ||
.getName() | ||
.replaceAll( | ||
"com.netflix.spinnaker.halyard.config.model.v1.providers", | ||
"com.netflix.spinnaker.halyard.cli.command.v1.config.providers") | ||
.replaceAll("Provider", "AddAccountCommand"); | ||
try { | ||
return (Class<? extends AbstractAddAccountCommand>) Class.forName(addAccountCommandClass); | ||
} catch (ClassNotFoundException e) { | ||
throw new IllegalArgumentException( | ||
"No account for class \"" + addAccountCommandClass + "\" found", e); | ||
} | ||
} | ||
|
||
public static Class<? extends AbstractEditBakeryDefaultsCommand> translateEditBakeryCommandType( | ||
String providerName) { | ||
Class<?> providerClass = Providers.translateProviderType(providerName); | ||
|
||
String editBakeryDefaultsCommand = | ||
providerClass | ||
.getName() | ||
.replaceAll( | ||
"com.netflix.spinnaker.halyard.config.model.v1.providers", | ||
"com.netflix.spinnaker.halyard.cli.command.v1.config.providers") | ||
.replaceAll("Provider", "EditBakeryDefaultsCommand"); | ||
try { | ||
return (Class<? extends AbstractEditBakeryDefaultsCommand>) | ||
Class.forName(editBakeryDefaultsCommand); | ||
} catch (ClassNotFoundException e) { | ||
throw new IllegalArgumentException( | ||
"No account for class \"" + editBakeryDefaultsCommand + "\" found", e); | ||
} | ||
} | ||
|
||
public static Class<? extends AbstractProviderCommand> translateProviderCommandType( | ||
String providerName) { | ||
Class<?> providerClass = Providers.translateProviderType(providerName); | ||
|
||
String editBakeryDefaultsCommand = | ||
providerClass | ||
.getName() | ||
.replaceAll( | ||
"com.netflix.spinnaker.halyard.config.model.v1.providers", | ||
"com.netflix.spinnaker.halyard.cli.command.v1.config.providers") | ||
.replaceAll("Provider", "EditProviderCommand"); | ||
try { | ||
return (Class<? extends AbstractEditBakeryDefaultsCommand>) | ||
Class.forName(editBakeryDefaultsCommand); | ||
} catch (ClassNotFoundException e) { | ||
throw new IllegalArgumentException( | ||
"No account for class \"" + editBakeryDefaultsCommand + "\" found", e); | ||
} | ||
} | ||
|
||
public static Field[] getFields(Class<?> c) { | ||
Field[] extendedFields = c.getSuperclass().getDeclaredFields(); | ||
Field[] fields = c.getDeclaredFields(); | ||
Field[] allFields = new Field[extendedFields.length + fields.length]; | ||
Arrays.setAll( | ||
allFields, | ||
i -> (i < extendedFields.length ? extendedFields[i] : fields[i - extendedFields.length])); | ||
return allFields; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
|
||
package com.netflix.spinnaker.halyard.config.model.v1.node; | ||
|
||
import java.lang.reflect.Field; | ||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
|
||
import lombok.Data; | ||
import net.minidev.json.JSONObject; | ||
|
||
@Data | ||
public class ProviderDescriptor { | ||
public JSONObject allProviderFields = new JSONObject(); | ||
public JSONObject providersFields = new JSONObject(); | ||
|
||
public JSONObject initialProviderFields() { | ||
// Fields for most providers: enabled, account, primaryAccount | ||
JSONObject providerFields = new JSONObject(); | ||
Field[] initialFields = Provider.class.getDeclaredFields(); | ||
for (Field field : initialFields) { | ||
providerFields.put(field.getName(), fieldType(field)); | ||
} | ||
return providerFields; | ||
} | ||
|
||
public JSONObject initialAccountFields() { | ||
// Fields for most accounts: name, version ect | ||
JSONObject accountFields = new JSONObject(); | ||
Field[] initialFields = Account.class.getDeclaredFields(); | ||
for (Field field : initialFields) { | ||
accountFields.put(field.getName(), fieldType(field)); | ||
} | ||
return accountFields; | ||
} | ||
|
||
public JSONObject initialBakeryFields() { | ||
JSONObject bakeryFields = new JSONObject(); | ||
Field[] initialFields = BakeryDefaults.class.getDeclaredFields(); | ||
for (Field field : initialFields) { | ||
bakeryFields.put(field.getName(), fieldType(field)); | ||
} | ||
return bakeryFields; | ||
} | ||
|
||
public void addProviderField(String providerName, Field[] extraFields) { | ||
// some providers e.g aws, appengine have extra fields | ||
JSONObject addFields = initialProviderFields(); | ||
for (Field field : extraFields) { | ||
addFields.put(field.getName(), fieldType(field)); | ||
} | ||
if (providerName != null) { | ||
providersFields.put(providerName, addFields); | ||
} | ||
} | ||
|
||
public void addAccountField(String providerName, Field[] fields) { | ||
JSONObject accountFields = initialAccountFields(); | ||
for (Field field : fields) { | ||
accountFields.put(field.getName(), fieldType(field)); | ||
} | ||
if (providersFields != null && providersFields.get(providerName) != null) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. might want to use |
||
((HashMap<String, Object>) providersFields.get(providerName)).put("accountFields", accountFields); | ||
|
||
} | ||
} | ||
|
||
public void addBakeryField(String providerName, Field[] fields) { | ||
JSONObject bakeryFields = initialBakeryFields(); | ||
for (Field field : fields) { | ||
bakeryFields.put(field.getName(), fieldType(field)); | ||
} | ||
if (providersFields != null && providersFields.get(providerName) != null) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. might want to use |
||
((HashMap<String, Object>) providersFields.get(providerName)).put("useBakeryDefaults", "boolean"); | ||
((HashMap<String, Object>) providersFields.get(providerName)).put("bakeryDefaultsFields", bakeryFields); | ||
} | ||
} | ||
|
||
public JSONObject allProviderFields() { | ||
allProviderFields.put("providers", providersFields); | ||
return allProviderFields; | ||
} | ||
|
||
public JSONObject fieldType(Field field) { | ||
JSONObject typeWrapper = new JSONObject(); | ||
if (field.getAnnotation(LocalFile.class) != null) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. might want to use |
||
typeWrapper.put("type", "upload"); | ||
} else if (field.getAnnotation(Secret.class) != null) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. might want to use |
||
typeWrapper.put("type", "password"); | ||
} else if (field.getType().isEnum()) { | ||
Object[] objects = field.getType().getEnumConstants(); | ||
List<Object> enumConstantsList = new ArrayList<>(); | ||
for (Object obj : objects) { | ||
enumConstantsList.add(obj); | ||
} | ||
typeWrapper.put("enum", enumConstantsList); | ||
typeWrapper.put("type", "string"); | ||
|
||
} else if (field.getType() == (List.class) && !field.getName().equals("accounts")) { | ||
// assume a list is a list of strings | ||
typeWrapper.put("type", "stringlist"); | ||
} else { | ||
typeWrapper.put("type", field.getType().getSimpleName().toLowerCase()); | ||
} | ||
return typeWrapper; | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why the double cast?
(JSONObject) ((JSONObject)....