Skip to content

Commit

Permalink
Merge pull request #133 from perfectsense/feature/picocli
Browse files Browse the repository at this point in the history
Picocli implementation
  • Loading branch information
JC authored Aug 25, 2020
2 parents 75f228a + a0b3089 commit 03d9dd3
Show file tree
Hide file tree
Showing 19 changed files with 217 additions and 157 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
## 0.99.2 (Unreleased)
## 0.99.2 (August 25th, 2020)

ENHANCEMENTS:

* [126](https://github.com/perfectsense/gyro-azure-provider/issues/126): Support subscription from auth properties file.
* [128](https://github.com/perfectsense/gyro-azure-provider/issues/128): Support remote file backend
* [130](https://github.com/perfectsense/gyro-azure-provider/issues/130): Add `exists(String file)` and `copy(String source, String dest)` methods to FileBackend.

## 0.99.1 (July 6th, 2020)

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Load the Azure provider in your project by consuming it as a `plugin` directive

```shell
@repository: 'https://artifactory.psdops.com/gyro-releases'
@plugin: 'gyro:gyro-azure-provider:0.99.0'
@plugin: 'gyro:gyro-azure-provider:0.99.2'
```

#### Authentication ####
Expand Down
8 changes: 5 additions & 3 deletions src/main/java/gyro/azure/AbstractAzureCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@
import gyro.lang.ast.Node;
import gyro.lang.ast.block.FileNode;
import gyro.util.Bug;
import io.airlift.airline.Option;
import org.apache.commons.lang3.StringUtils;
import picocli.CommandLine.Option;

public abstract class AbstractAzureCommand {

@Option(name = "--credential", description = "The azure credentials to be used as defined in the project init file. When not specified the 'default' credential is used.")
@Option(names = "--credential", description = "The azure credentials to be used as defined in the project init file. When not specified the 'default' credential is used.")
private String credential;

private RootScope scope;
Expand Down Expand Up @@ -91,7 +91,9 @@ public Azure getClient() {
.get("azure::" + getCredential());

if (credentials == null) {
throw new GyroException(String.format("No credentials with name - '%s' found. Check the your project init file.", getCredential()));
throw new GyroException(String.format(
"No credentials with name - '%s' found. Check the your project init file.",
getCredential()));
}

return AzureResource.createClient((AzureCredentials) credentials);
Expand Down
69 changes: 18 additions & 51 deletions src/main/java/gyro/azure/AzureCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,62 +16,29 @@

package gyro.azure;

import java.util.List;

import gyro.azure.keyvault.AbstractVaultCommand;
import gyro.azure.network.AbstractApplicationGatewayCommand;
import gyro.azure.keyvault.AzureKeyVaultCommand;
import gyro.azure.network.AzureApplicationGatewayCommand;
import gyro.core.command.GyroCommand;
import io.airlift.airline.Arguments;
import io.airlift.airline.Cli;
import io.airlift.airline.Command;
import io.airlift.airline.Help;
import org.reflections.Reflections;
import org.reflections.util.ClasspathHelper;

@Command(name = "azure", description = "CLI command for all things azure")
public class AzureCommand implements GyroCommand {

public static Reflections reflections;

@Arguments(description = "", required = true)
private List<String> arguments;

public static Reflections getReflections() {
if (reflections == null) {
reflections = new Reflections(new org.reflections.util.ConfigurationBuilder()
.setUrls(ClasspathHelper.forPackage("gyro.azure")));
}

return reflections;
import picocli.CommandLine.Command;

@Command(name = "azure",
description = "Manage azure assets.",
synopsisHeading = "%n",
header = "Add, remove, or list assets part of key-vault and application-gateway.",
descriptionHeading = "%nDescription:%n%n",
parameterListHeading = "%nParameters:%n",
optionListHeading = "%nOptions:%n",
commandListHeading = "%nCommands:%n",
usageHelpWidth = 100,
subcommands = {
AzureKeyVaultCommand.class,
AzureApplicationGatewayCommand.class
}
)
public class AzureCommand implements GyroCommand {

@Override
public void execute() throws Exception {
Cli.CliBuilder<Object> builder = Cli.builder("azure")
.withDescription("CLI command for all things azure")
.withDefaultCommand(Help.class)
.withCommands(Help.class);

// Vault command loader
AbstractVaultCommand.setVaultCommand(builder);

// Application gateway command loader
AbstractApplicationGatewayCommand.setApplicationGatewayCommand(builder);

Cli<Object> gitParser = builder.build();

Object command = gitParser.parse(arguments);

if (command instanceof Runnable) {
((Runnable) command).run();
} else if (command instanceof GyroCommand) {
((GyroCommand) command).execute();
} else {
throw new IllegalStateException(String.format(
"[%s] must be an instance of [%s] or [%s]!",
command.getClass().getName(),
Runnable.class.getName(),
GyroCommand.class.getName()));
}
}
}
19 changes: 6 additions & 13 deletions src/main/java/gyro/azure/keyvault/AbstractVaultCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,17 @@

package gyro.azure.keyvault;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;

import com.microsoft.azure.management.Azure;
import com.microsoft.azure.management.keyvault.Vault;
import gyro.azure.AbstractAzureCommand;
import gyro.azure.AzureCommand;
import gyro.core.GyroException;
import gyro.core.command.GyroCommand;
import gyro.core.resource.Resource;
import gyro.core.scope.RootScope;
import io.airlift.airline.Cli;
import io.airlift.airline.Help;

public abstract class AbstractVaultCommand extends AbstractAzureCommand implements GyroCommand {
public abstract class AbstractVaultCommand extends AbstractAzureCommand implements GyroCommand, Callable<Integer> {

public static Vault getVault(String vaultResourceName, RootScope scope, Azure client) {
Resource resource = scope.findResource("azure::key-vault::" + vaultResourceName);
Expand All @@ -55,12 +51,9 @@ Vault getVault(String vaultResourceName) {
return getVault(vaultResourceName, scope, client);
}

public static void setVaultCommand(Cli.CliBuilder<Object> builder) {
List<Class<?>> subTypesOf = new ArrayList<>(AzureCommand.getReflections().getSubTypesOf(AbstractVaultCommand.class));

builder.withGroup("key-vault")
.withDescription("Manage azure key-vault secrets, keys and certificates")
.withDefaultCommand(Help.class)
.withCommands(subTypesOf);
@Override
public Integer call() throws Exception {
execute();
return 0;
}
}
17 changes: 11 additions & 6 deletions src/main/java/gyro/azure/keyvault/AddVaultCertificateCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,22 @@
import com.psddev.dari.util.ObjectUtils;
import gyro.core.GyroCore;
import gyro.core.GyroException;
import io.airlift.airline.Arguments;
import io.airlift.airline.Command;
import io.airlift.airline.Option;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;

@Command(name = "add-certificate", description = "Add a certificate to an Azure key vault")
@Command(name = "add-certificate",
header = "Add a certificate to an Azure key vault.",
synopsisHeading = "%n",
parameterListHeading = "%nParameters:%n",
optionListHeading = "%nOptions:%n",
usageHelpWidth = 100)
public class AddVaultCertificateCommand extends AbstractVaultCommand {

@Arguments(description = "The command requires three arguments. <vault-name>: the key-vault resource name used in the config to which the certificate would be added. <cert-name>: name of the certificate to be added. <path>: the path to the certificate file (.pfx)", required = true)
@Parameters(description = "The command requires three arguments. <vault-name>: the key-vault resource name used in the config to which the certificate would be added. <cert-name>: name of the certificate to be added. <path>: the path to the certificate file (.pfx)", arity = "1")
private List<String> arguments;

@Option(name = { "--password" }, description = "Password used to encrypt the certificate file")
@Option(names = "--password", description = "Password used to encrypt the certificate file.", arity = "0..1", interactive = true)
private String password;

@Override
Expand Down
25 changes: 15 additions & 10 deletions src/main/java/gyro/azure/keyvault/AddVaultSecretCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,32 @@
import com.psddev.dari.util.ObjectUtils;
import gyro.core.GyroCore;
import gyro.core.GyroException;
import io.airlift.airline.Arguments;
import io.airlift.airline.Command;
import io.airlift.airline.Option;
import org.joda.time.DateTime;

@Command(name = "add-secret", description = "Add a secret to an Azure key vault")
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;

@Command(name = "add-secret",
header = "Add a secret to an Azure key vault.",
synopsisHeading = "%n",
parameterListHeading = "%nParameters:%n",
optionListHeading = "%nOptions:%n",
usageHelpWidth = 100)
public class AddVaultSecretCommand extends AbstractVaultCommand {

@Arguments(description = "The command requires three arguments. <vault-name>: the key-vault resource name used in the config to which the secret would be added. <secret-name>: name of the secret to be added. <value>: the secret value", required = true)
@Parameters(description = "The command requires three arguments. <vault-name>: the key-vault resource name used in the config to which the secret would be added. <secret-name>: name of the secret to be added. <value>: the secret value", arity = "1")
private List<String> arguments;

@Option(name = { "--content-type" }, description = "Content type for the secret")
@Option(names = "--content-type", description = "Content type for the secret.")
private String contentType;

@Option(name = { "--expires" }, description = "A date time value value in UTC specifying the expiration time. Format 'YYYY-MM-DDTHH:MM:SS.sssZ'")
@Option(names = "--expires", description = "A date time value value in UTC specifying the expiration time. Format 'YYYY-MM-DDTHH:MM:SS.sssZ'.")
private String expires;

@Option(name = { "--not-before" }, description = "A date time value value in UTC specifying the expiration not before a specific time. Format 'YYYY-MM-DDTHH:MM:SS.sssZ'")
@Option(names = "--not-before", description = "A date time value value in UTC specifying the expiration not before a specific time. Format 'YYYY-MM-DDTHH:MM:SS.sssZ'.")
private String notBefore;

@Option(name = { "--enabled" }, description = "Enable/Disable the secret. Defaults to 'false'")
@Option(names = "--enabled", description = "Enable/Disable the secret. Defaults to 'false'.")
private boolean enabled;

@Override
Expand Down
26 changes: 26 additions & 0 deletions src/main/java/gyro/azure/keyvault/AzureKeyVaultCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package gyro.azure.keyvault;

import gyro.core.command.GyroCommandGroup;
import picocli.CommandLine;

@CommandLine.Command(name = "key-vault",
description = "Manage azure key-vault secrets, keys and certificates.",
synopsisHeading = "%n",
header = "Add, remove, or list certificates and secrets of key-vault.",
descriptionHeading = "%nDescription:%n%n",
parameterListHeading = "%nParameters:%n",
optionListHeading = "%nOptions:%n",
commandListHeading = "%nCommands:%n",
usageHelpWidth = 100,
subcommands = {
AddVaultCertificateCommand.class,
AddVaultSecretCommand.class,
ListVaultCertificateCommand.class,
ListVaultSecretCommand.class,
RemoveVaultCertificateCommand.class,
RemoveVaultSecretCommand.class
}
)
public class AzureKeyVaultCommand implements GyroCommandGroup {

}
25 changes: 15 additions & 10 deletions src/main/java/gyro/azure/keyvault/ListVaultCertificateCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,28 @@
package gyro.azure.keyvault;

import java.util.List;
import java.util.stream.Collectors;

import com.microsoft.azure.PagedList;
import com.microsoft.azure.keyvault.models.CertificateItem;
import com.microsoft.azure.management.keyvault.Vault;
import com.microsoft.azure.management.network.ApplicationGatewaySslCertificate;
import gyro.core.GyroCore;
import gyro.core.GyroException;
import io.airlift.airline.Arguments;
import io.airlift.airline.Command;
import io.airlift.airline.Option;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;

@Command(name = "list-certificate", description = "List all certificates present in an Azure key vault")
@Command(name = "list-certificate",
header = "List all certificates present in an Azure key vault.",
synopsisHeading = "%n",
parameterListHeading = "%nParameters:%n",
optionListHeading = "%nOptions:%n",
usageHelpWidth = 100)
public class ListVaultCertificateCommand extends AbstractVaultCommand {

@Arguments(description = "The command requires one argument. <vault-name>: the key-vault resource name used in the config whose certificates would be listed", required = true)
@Parameters(description = "The command requires one argument. <vault-name>: the key-vault resource name used in the config whose certificates would be listed.", arity = "1")
private List<String> arguments;

@Option(name = "--show-thumbprint", description = "Show thumbprint of the certificate")
@Option(names = "--show-thumbprint", description = "Show thumbprint of the certificate.")
private boolean showThumbprint;

@Override
Expand All @@ -49,14 +52,16 @@ public void execute() throws Exception {
if (!certificateItemPagedList.isEmpty()) {
certificateItemPagedList.loadAll();

for (CertificateItem certificate: certificateItemPagedList) {
for (CertificateItem certificate : certificateItemPagedList) {
StringBuilder sb = new StringBuilder();
sb.append("\n***********************");
sb.append(String.format("\nName: %s", certificate.identifier().name()));
sb.append(String.format("\nVersion: %s", certificate.identifier().version()));

if (showThumbprint) {
sb.append(String.format("\nThumbprint: %s", certificate.x509Thumbprint() != null ? new String(certificate.x509Thumbprint()) : null));
sb.append(String.format(
"\nThumbprint: %s",
certificate.x509Thumbprint() != null ? new String(certificate.x509Thumbprint()) : null));
}

GyroCore.ui().write(sb.toString());
Expand Down
17 changes: 11 additions & 6 deletions src/main/java/gyro/azure/keyvault/ListVaultSecretCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,18 @@
import com.microsoft.azure.management.keyvault.Vault;
import gyro.core.GyroCore;
import gyro.core.GyroException;
import io.airlift.airline.Arguments;
import io.airlift.airline.Command;

@Command(name = "list-secret", description = "List all secrets present in an Azure key vault")
import picocli.CommandLine.Command;
import picocli.CommandLine.Parameters;

@Command(name = "list-secret",
header = "List all secrets present in an Azure key vault.",
synopsisHeading = "%n",
parameterListHeading = "%nParameters:%n",
optionListHeading = "%nOptions:%n",
usageHelpWidth = 100)
public class ListVaultSecretCommand extends AbstractVaultCommand {

@Arguments(description = "The command requires one argument. <vault-name>: the key-vault resource name used in the config whose secrets would be listed", required = true)
@Parameters(description = "The command requires one argument. <vault-name>: the key-vault resource name used in the config whose secrets would be listed.", arity = "1")
private List<String> arguments;

@Override
Expand All @@ -27,7 +32,7 @@ public void execute() throws Exception {
if (!secretItemPagedList.isEmpty()) {
secretItemPagedList.loadAll();

for (SecretItem secret: secretItemPagedList) {
for (SecretItem secret : secretItemPagedList) {
StringBuilder sb = new StringBuilder();
sb.append("\n***********************");
sb.append(String.format("\nName: %s", secret.identifier().name()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,18 @@
import com.microsoft.azure.management.keyvault.Vault;
import gyro.core.GyroCore;
import gyro.core.GyroException;
import io.airlift.airline.Arguments;
import io.airlift.airline.Command;

@Command(name = "remove-certificate", description = "Remove a certificate from an Azure key vault")
import picocli.CommandLine.Command;
import picocli.CommandLine.Parameters;

@Command(name = "remove-certificate",
description = "Remove a certificate from an Azure key vault",
synopsisHeading = "%n",
parameterListHeading = "%nParameters:%n",
optionListHeading = "%nOptions:%n",
usageHelpWidth = 100)
public class RemoveVaultCertificateCommand extends AbstractVaultCommand {

@Arguments(description = "The command requires two arguments. <vault-name>: the key-vault resource name used in the config from which the certificate would be removed. <cert-name>: name of the certificate to be removed.", required = true)
@Parameters(description = "The command requires two arguments. <vault-name>: the key-vault resource name used in the config from which the certificate would be removed. <cert-name>: name of the certificate to be removed.", arity = "1")
private List<String> arguments;

@Override
Expand Down
Loading

0 comments on commit 03d9dd3

Please sign in to comment.