Support secret_id_bound_cidrs replacing bound_cidr_list for AppRole (#24)

The latter parameter is deprecated in Vault. The connector now supports
both while the former one is deprecated and will be removed when it is
removed from Vault.
This commit is contained in:
Stefan Kalscheuer 2018-11-19 15:21:10 +01:00
parent c1ec929147
commit 9caeac4cba
4 changed files with 118 additions and 17 deletions

View File

@ -8,6 +8,7 @@ refactoring of the internal SSL handling (#17)
* [improvement] Build environment and tests now compatible with Java 10 * [improvement] Build environment and tests now compatible with Java 10
* [dependencies] Updated dependencies to fix vulnerabilities (i.e. CVE-2018-7489) * [dependencies] Updated dependencies to fix vulnerabilities (i.e. CVE-2018-7489)
* [deprecation] `VaultConnectorFactory` is deprecated in favor of `VaultConnectorBuilder` with identical API (#18) * [deprecation] `VaultConnectorFactory` is deprecated in favor of `VaultConnectorBuilder` with identical API (#18)
* [deprecation] `AppRoleBuilder#withBoundCidrList(List)` is deprecated in favor of `AppRoleBuilder#withSecretIdBoundCidrs(List)` (#24)
## 0.7.1 [2018-03-17] ## 0.7.1 [2018-03-17]
* [improvement] Added automatic module name for JPMS compatibility * [improvement] Added automatic module name for JPMS compatibility

View File

@ -41,6 +41,8 @@ public final class AppRole {
private List<String> boundCidrList; private List<String> boundCidrList;
private List<String> secretIdBoundCidrs;
private List<String> policies; private List<String> policies;
@JsonProperty("secret_id_num_uses") @JsonProperty("secret_id_num_uses")
@ -73,24 +75,57 @@ public final class AppRole {
/** /**
* Construct complete {@link AppRole} object. * Construct complete {@link AppRole} object.
* *
* @param name Role name (required) * @param name Role name (required)
* @param id Role ID (optional) * @param id Role ID (optional)
* @param bindSecretId Bind secret ID (optional) * @param bindSecretId Bind secret ID (optional)
* @param boundCidrList Whitelist of subnets in CIDR notation (optional) * @param secretIdBoundCidrs Whitelist of subnets in CIDR notation (optional)
* @param policies List of policies (optional) * @param policies List of policies (optional)
* @param secretIdNumUses Maximum number of uses per secret (optional) * @param secretIdNumUses Maximum number of uses per secret (optional)
* @param secretIdTtl Maximum TTL in seconds for secrets (optional) * @param secretIdTtl Maximum TTL in seconds for secrets (optional)
* @param tokenTtl Token TTL in seconds (optional) * @param tokenTtl Token TTL in seconds (optional)
* @param tokenMaxTtl Maximum token TTL in seconds, including renewals (optional) * @param tokenMaxTtl Maximum token TTL in seconds, including renewals (optional)
* @param period Duration in seconds, if set the token is a periodic token (optional) * @param period Duration in seconds, if set the token is a periodic token (optional)
*/ */
public AppRole(final String name, final String id, final Boolean bindSecretId, final List<String> boundCidrList, public AppRole(final String name, final String id, final Boolean bindSecretId, final List<String> secretIdBoundCidrs,
final List<String> policies, final Integer secretIdNumUses, final Integer secretIdTtl, final List<String> policies, final Integer secretIdNumUses, final Integer secretIdTtl,
final Integer tokenTtl, final Integer tokenMaxTtl, final Integer period) { final Integer tokenTtl, final Integer tokenMaxTtl, final Integer period) {
this.name = name; this.name = name;
this.id = id; this.id = id;
this.bindSecretId = bindSecretId; this.bindSecretId = bindSecretId;
this.secretIdBoundCidrs = secretIdBoundCidrs;
this.policies = policies;
this.secretIdNumUses = secretIdNumUses;
this.secretIdTtl = secretIdTtl;
this.tokenTtl = tokenTtl;
this.tokenMaxTtl = tokenMaxTtl;
this.period = period;
}
/**
* Construct complete {@link AppRole} object.
*
* This constructor is used for transition from {@code bound_cidr_list} to {@code secret_id_bound_cidrs} only.
*
* @param name Role name (required)
* @param id Role ID (optional)
* @param bindSecretId Bind secret ID (optional)
* @param boundCidrList Whitelist of subnets in CIDR notation (optional)
* @param secretIdBoundCidrs Whitelist of subnets in CIDR notation (optional)
* @param policies List of policies (optional)
* @param secretIdNumUses Maximum number of uses per secret (optional)
* @param secretIdTtl Maximum TTL in seconds for secrets (optional)
* @param tokenTtl Token TTL in seconds (optional)
* @param tokenMaxTtl Maximum token TTL in seconds, including renewals (optional)
* @param period Duration in seconds, if set the token is a periodic token (optional)
*/
AppRole(final String name, final String id, final Boolean bindSecretId, final List<String> boundCidrList,
final List<String> secretIdBoundCidrs, final List<String> policies, final Integer secretIdNumUses,
final Integer secretIdTtl, final Integer tokenTtl, final Integer tokenMaxTtl, final Integer period) {
this.name = name;
this.id = id;
this.bindSecretId = bindSecretId;
this.boundCidrList = boundCidrList; this.boundCidrList = boundCidrList;
this.secretIdBoundCidrs = secretIdBoundCidrs;
this.policies = policies; this.policies = policies;
this.secretIdNumUses = secretIdNumUses; this.secretIdNumUses = secretIdNumUses;
this.secretIdTtl = secretIdTtl; this.secretIdTtl = secretIdTtl;
@ -122,14 +157,18 @@ public final class AppRole {
/** /**
* @return list of bound CIDR subnets * @return list of bound CIDR subnets
* @deprecated Use {@link #getSecretIdBoundCidrs()} instead, as this parameter is deprecated in Vault.
*/ */
@Deprecated
public List<String> getBoundCidrList() { public List<String> getBoundCidrList() {
return boundCidrList; return boundCidrList;
} }
/** /**
* @param boundCidrList list of subnets in CIDR notation to bind role to * @param boundCidrList list of subnets in CIDR notation to bind role to
* @deprecated Use {@link #setSecretIdBoundCidrs(List)} instead, as this parameter is deprecated in Vault.
*/ */
@Deprecated
@JsonSetter("bound_cidr_list") @JsonSetter("bound_cidr_list")
public void setBoundCidrList(final List<String> boundCidrList) { public void setBoundCidrList(final List<String> boundCidrList) {
this.boundCidrList = boundCidrList; this.boundCidrList = boundCidrList;
@ -137,7 +176,9 @@ public final class AppRole {
/** /**
* @return list of subnets in CIDR notation as comma-separated {@link String} * @return list of subnets in CIDR notation as comma-separated {@link String}
* @deprecated Use {@link #getSecretIdBoundCidrsString()} instead, as this parameter is deprecated in Vault.
*/ */
@Deprecated
@JsonGetter("bound_cidr_list") @JsonGetter("bound_cidr_list")
@JsonInclude(JsonInclude.Include.NON_EMPTY) @JsonInclude(JsonInclude.Include.NON_EMPTY)
public String getBoundCidrListString() { public String getBoundCidrListString() {
@ -146,6 +187,36 @@ public final class AppRole {
return String.join(",", boundCidrList); return String.join(",", boundCidrList);
} }
/**
* @return list of bound CIDR subnets
* @since 0.8 replaces {@link #getBoundCidrList()}
*/
public List<String> getSecretIdBoundCidrs() {
return secretIdBoundCidrs;
}
/**
* @param secretIdBoundCidrs List of subnets in CIDR notation to bind secrets of this role to.
* @since 0.8 replaces {@link #setBoundCidrList(List)}
*/
@JsonSetter("secret_id_bound_cidrs")
public void setSecretIdBoundCidrs(final List<String> secretIdBoundCidrs) {
this.secretIdBoundCidrs = secretIdBoundCidrs;
}
/**
* @return List of subnets in CIDR notation as comma-separated {@link String}
* @since 0.8 replaces {@link #getBoundCidrListString()} ()}
*/
@JsonGetter("secret_id_bound_cidrs")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public String getSecretIdBoundCidrsString() {
if (secretIdBoundCidrs == null || secretIdBoundCidrs.isEmpty()) {
return "";
}
return String.join(",", secretIdBoundCidrs);
}
/** /**
* @return list of policies * @return list of policies
*/ */

View File

@ -30,6 +30,7 @@ public final class AppRoleBuilder {
private String id; private String id;
private Boolean bindSecretId; private Boolean bindSecretId;
private List<String> boundCidrList; private List<String> boundCidrList;
private List<String> secretIdBoundCidrs;
private List<String> policies; private List<String> policies;
private Integer secretIdNumUses; private Integer secretIdNumUses;
private Integer secretIdTtl; private Integer secretIdTtl;
@ -93,12 +94,26 @@ public final class AppRoleBuilder {
* *
* @param boundCidrList List of CIDR blocks which can perform login * @param boundCidrList List of CIDR blocks which can perform login
* @return self * @return self
* @deprecated Use {@link #withSecretIdBoundCidrs(List)} instead, as this parameter is deprecated in Vault.
*/ */
@Deprecated
public AppRoleBuilder withBoundCidrList(final List<String> boundCidrList) { public AppRoleBuilder withBoundCidrList(final List<String> boundCidrList) {
this.boundCidrList = boundCidrList; this.boundCidrList = boundCidrList;
return this; return this;
} }
/**
* Set bound CIDR blocks.
*
* @param secretIdBoundCidrs List of CIDR blocks which can perform login
* @return self
* @since 0.8 replaces {@link #withBoundCidrList(List)}
*/
public AppRoleBuilder withSecretIdBoundCidrs(final List<String> secretIdBoundCidrs) {
this.secretIdBoundCidrs = secretIdBoundCidrs;
return this;
}
/** /**
* Add a CIDR block to list of bound blocks. * Add a CIDR block to list of bound blocks.
* *
@ -106,9 +121,15 @@ public final class AppRoleBuilder {
* @return self * @return self
*/ */
public AppRoleBuilder withCidrBlock(final String cidrBlock) { public AppRoleBuilder withCidrBlock(final String cidrBlock) {
if (boundCidrList == null) if (boundCidrList == null) {
boundCidrList = new ArrayList<>(); boundCidrList = new ArrayList<>();
}
boundCidrList.add(cidrBlock); boundCidrList.add(cidrBlock);
if (secretIdBoundCidrs == null) {
secretIdBoundCidrs = new ArrayList<>();
}
secretIdBoundCidrs.add(cidrBlock);
return this; return this;
} }
@ -204,6 +225,7 @@ public final class AppRoleBuilder {
id, id,
bindSecretId, bindSecretId,
boundCidrList, boundCidrList,
secretIdBoundCidrs,
policies, policies,
secretIdNumUses, secretIdNumUses,
secretIdTtl, secretIdTtl,

View File

@ -51,8 +51,8 @@ public class AppRoleBuilderTest {
private static final Integer TOKEN_MAX_TTL = 9600; private static final Integer TOKEN_MAX_TTL = 9600;
private static final Integer PERIOD = 1234; private static final Integer PERIOD = 1234;
private static final String JSON_MIN = "{\"role_name\":\"" + NAME + "\"}"; private static final String JSON_MIN = "{\"role_name\":\"" + NAME + "\"}";
private static final String JSON_FULL = String.format("{\"role_name\":\"%s\",\"role_id\":\"%s\",\"bind_secret_id\":%s,\"bound_cidr_list\":\"%s\",\"policies\":\"%s\",\"secret_id_num_uses\":%d,\"secret_id_ttl\":%d,\"token_ttl\":%d,\"token_max_ttl\":%d,\"period\":%d}", private static final String JSON_FULL = String.format("{\"role_name\":\"%s\",\"role_id\":\"%s\",\"bind_secret_id\":%s,\"bound_cidr_list\":\"%s\",\"secret_id_bound_cidrs\":\"%s\",\"policies\":\"%s\",\"secret_id_num_uses\":%d,\"secret_id_ttl\":%d,\"token_ttl\":%d,\"token_max_ttl\":%d,\"period\":%d}",
NAME, ID, BIND_SECRET_ID, CIDR_1, POLICY, SECRET_ID_NUM_USES, SECRET_ID_TTL, TOKEN_TTL, TOKEN_MAX_TTL, PERIOD); NAME, ID, BIND_SECRET_ID, CIDR_1, CIDR_1, POLICY, SECRET_ID_NUM_USES, SECRET_ID_TTL, TOKEN_TTL, TOKEN_MAX_TTL, PERIOD);
@BeforeAll @BeforeAll
public static void init() { public static void init() {
@ -69,6 +69,7 @@ public class AppRoleBuilderTest {
assertThat(role.getId(), is(nullValue())); assertThat(role.getId(), is(nullValue()));
assertThat(role.getBindSecretId(), is(nullValue())); assertThat(role.getBindSecretId(), is(nullValue()));
assertThat(role.getBoundCidrList(), is(nullValue())); assertThat(role.getBoundCidrList(), is(nullValue()));
assertThat(role.getSecretIdBoundCidrs(), is(nullValue()));
assertThat(role.getPolicies(), is(nullValue())); assertThat(role.getPolicies(), is(nullValue()));
assertThat(role.getSecretIdNumUses(), is(nullValue())); assertThat(role.getSecretIdNumUses(), is(nullValue()));
assertThat(role.getSecretIdTtl(), is(nullValue())); assertThat(role.getSecretIdTtl(), is(nullValue()));
@ -89,6 +90,7 @@ public class AppRoleBuilderTest {
.withId(ID) .withId(ID)
.withBindSecretID(BIND_SECRET_ID) .withBindSecretID(BIND_SECRET_ID)
.withBoundCidrList(BOUND_CIDR_LIST) .withBoundCidrList(BOUND_CIDR_LIST)
.withSecretIdBoundCidrs(BOUND_CIDR_LIST)
.withPolicies(POLICIES) .withPolicies(POLICIES)
.withSecretIdNumUses(SECRET_ID_NUM_USES) .withSecretIdNumUses(SECRET_ID_NUM_USES)
.withSecretIdTtl(SECRET_ID_TTL) .withSecretIdTtl(SECRET_ID_TTL)
@ -100,6 +102,7 @@ public class AppRoleBuilderTest {
assertThat(role.getId(), is(ID)); assertThat(role.getId(), is(ID));
assertThat(role.getBindSecretId(), is(BIND_SECRET_ID)); assertThat(role.getBindSecretId(), is(BIND_SECRET_ID));
assertThat(role.getBoundCidrList(), is(BOUND_CIDR_LIST)); assertThat(role.getBoundCidrList(), is(BOUND_CIDR_LIST));
assertThat(role.getSecretIdBoundCidrs(), is(BOUND_CIDR_LIST));
assertThat(role.getPolicies(), is(POLICIES)); assertThat(role.getPolicies(), is(POLICIES));
assertThat(role.getSecretIdNumUses(), is(SECRET_ID_NUM_USES)); assertThat(role.getSecretIdNumUses(), is(SECRET_ID_NUM_USES));
assertThat(role.getSecretIdTtl(), is(SECRET_ID_TTL)); assertThat(role.getSecretIdTtl(), is(SECRET_ID_TTL));
@ -128,12 +131,16 @@ public class AppRoleBuilderTest {
role = new AppRoleBuilder(NAME).withCidrBlock(CIDR_2).build(); role = new AppRoleBuilder(NAME).withCidrBlock(CIDR_2).build();
assertThat(role.getBoundCidrList(), hasSize(1)); assertThat(role.getBoundCidrList(), hasSize(1));
assertThat(role.getBoundCidrList(), contains(CIDR_2)); assertThat(role.getBoundCidrList(), contains(CIDR_2));
assertThat(role.getSecretIdBoundCidrs(), hasSize(1));
assertThat(role.getSecretIdBoundCidrs(), contains(CIDR_2));
role = new AppRoleBuilder(NAME) role = new AppRoleBuilder(NAME)
.withBoundCidrList(BOUND_CIDR_LIST) .withSecretIdBoundCidrs(BOUND_CIDR_LIST)
.withCidrBlock(CIDR_2) .withCidrBlock(CIDR_2)
.build(); .build();
assertThat(role.getBoundCidrList(), hasSize(2)); assertThat(role.getBoundCidrList(), hasSize(1));
assertThat(role.getBoundCidrList(), contains(CIDR_1, CIDR_2)); assertThat(role.getBoundCidrList(), contains(CIDR_2));
assertThat(role.getSecretIdBoundCidrs(), hasSize(2));
assertThat(role.getSecretIdBoundCidrs(), contains(CIDR_1, CIDR_2));
/* Add single policy */ /* Add single policy */
role = new AppRoleBuilder(NAME).withPolicy(POLICY_2).build(); role = new AppRoleBuilder(NAME).withPolicy(POLICY_2).build();