-
Notifications
You must be signed in to change notification settings - Fork 620
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #32450 from vespa-engine/move-secret-impl-to-open-…
…source Move secret model classes to container-disc
- Loading branch information
Showing
9 changed files
with
316 additions
and
0 deletions.
There are no files selected for viewing
40 changes: 40 additions & 0 deletions
40
container-disc/src/main/java/ai/vespa/secret/model/Key.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package ai.vespa.secret.model; | ||
|
||
import java.util.Objects; | ||
|
||
public record Key(VaultName vaultName, SecretName secretName) { | ||
|
||
public Key { | ||
Objects.requireNonNull(vaultName, "vaultName cannot be null"); | ||
Objects.requireNonNull(secretName, "secretName cannot be null"); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return vaultName.value() + "/" + secretName.value(); | ||
} | ||
|
||
public static Key fromString(String key) { | ||
String[] parts = key.split("/"); | ||
if (parts.length != 2) { | ||
throw new IllegalArgumentException("Key must be on the form 'vaultName/secretName'"); | ||
} | ||
return new Key(VaultName.of(parts[0]), SecretName.of(parts[1])); | ||
} | ||
|
||
|
||
/* Legacy constructor and methods for backwards compatibility */ | ||
|
||
public Key(String keyGroup, String keyName) { | ||
this(VaultName.of(keyGroup), SecretName.of(keyName)); | ||
} | ||
|
||
public String keyGroup() { | ||
return vaultName.value(); | ||
} | ||
|
||
public String keyName() { | ||
return secretName.value(); | ||
} | ||
|
||
} |
30 changes: 30 additions & 0 deletions
30
container-disc/src/main/java/ai/vespa/secret/model/Role.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package ai.vespa.secret.model; | ||
|
||
/** | ||
* @author gjoranv | ||
*/ | ||
public enum Role { | ||
|
||
READER("reader"), | ||
WRITER("writer"); | ||
|
||
private final String value; | ||
|
||
Role(String value) { | ||
this.value = value; | ||
} | ||
|
||
public String value() { | ||
return value; | ||
} | ||
|
||
public String forVault(VaultName vault) { | ||
return vault.value() + "-" + value; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return Role.class.getSimpleName() + "." + value; | ||
} | ||
|
||
} |
94 changes: 94 additions & 0 deletions
94
container-disc/src/main/java/ai/vespa/secret/model/Secret.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package ai.vespa.secret.model; | ||
|
||
import com.yahoo.text.Utf8; | ||
|
||
import java.util.Arrays; | ||
import java.util.Objects; | ||
|
||
public class Secret implements Comparable<Secret> { | ||
|
||
private final Key key; | ||
private final byte[] secret; | ||
private final SecretVersionId version; | ||
private final SecretVersionState state; | ||
|
||
public Secret(Key key, byte[] secret, SecretVersionId version) { | ||
this(key, secret, version, SecretVersionState.CURRENT); | ||
} | ||
|
||
public Secret(Key key, byte[] secret, SecretVersionId version, SecretVersionState state) { | ||
this.key = key; | ||
this.secret = secret; | ||
this.version = version; | ||
this.state = state; | ||
} | ||
|
||
public VaultName vaultName() { | ||
return key.vaultName(); | ||
} | ||
|
||
public SecretName secretName() { | ||
return key.secretName(); | ||
} | ||
|
||
public byte[] secret() { | ||
return secret; | ||
} | ||
|
||
public SecretValue secretValue() { | ||
return SecretValue.of(secretAsString()); | ||
} | ||
|
||
public String secretAsString() { return Utf8.toString(secret); } | ||
|
||
public SecretVersionId version() { | ||
return version; | ||
} | ||
|
||
public SecretVersionState state() { | ||
return state; | ||
} | ||
|
||
public static Key key(VaultName vaultName, SecretName secretName) { | ||
return new Key(vaultName, secretName); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
Secret that = (Secret) o; | ||
if ( ! (that.key.equals(key))) return false; | ||
if ( ! (Arrays.equals(that.secret, secret))) return false; | ||
if (! that.version.equals(version)) return false; | ||
return true; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(key, version, Arrays.hashCode(secret)); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "Secret{" + | ||
"key=" + key + | ||
", version=" + version + | ||
", state=" + state + | ||
", secret=<omitted>"+ | ||
'}'; | ||
} | ||
|
||
@Override | ||
public int compareTo(Secret o) { | ||
int v = key.vaultName().compareTo(o.key.vaultName()); | ||
if (v != 0) return v; | ||
int n = key.secretName().compareTo(o.key.secretName()); | ||
if (n != 0) return n; | ||
int s = state.compareTo(o.state); | ||
if (s != 0) return s; | ||
|
||
// Note: reversed for descending order | ||
return o.version.value().compareTo(version.value()); | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
container-disc/src/main/java/ai/vespa/secret/model/SecretName.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package ai.vespa.secret.model; | ||
|
||
import ai.vespa.validation.PatternedStringWrapper; | ||
|
||
import java.util.regex.Pattern; | ||
|
||
/** | ||
* @author gjoranv | ||
*/ | ||
public class SecretName extends PatternedStringWrapper<SecretName> { | ||
|
||
// TODO: reset max size to 64 when we have stopped using concatenated vault+secret names | ||
private static final Pattern namePattern = Pattern.compile("[.a-zA-Z0-9_-]{1,128}"); | ||
|
||
private SecretName(String name) { | ||
super(name, namePattern, "Secret name"); | ||
} | ||
|
||
public static SecretName of(String name) { | ||
return new SecretName(name); | ||
} | ||
|
||
} |
18 changes: 18 additions & 0 deletions
18
container-disc/src/main/java/ai/vespa/secret/model/SecretValue.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package ai.vespa.secret.model; | ||
|
||
/** | ||
* @author gjoranv | ||
*/ | ||
public record SecretValue(String value) { | ||
|
||
public SecretValue { | ||
if (value == null || value.isBlank()) { | ||
throw new IllegalArgumentException("Secret value cannot be null or empty"); | ||
} | ||
} | ||
|
||
public static SecretValue of(String value) { | ||
return new SecretValue(value); | ||
} | ||
|
||
} |
18 changes: 18 additions & 0 deletions
18
container-disc/src/main/java/ai/vespa/secret/model/SecretVersionId.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package ai.vespa.secret.model; | ||
|
||
/** | ||
* @author gjoranv | ||
*/ | ||
public record SecretVersionId(String value) { | ||
|
||
public SecretVersionId { | ||
if (value == null || value.isBlank()) { | ||
throw new IllegalArgumentException("Version id cannot be null or empty"); | ||
} | ||
} | ||
|
||
public static SecretVersionId of(String value) { | ||
return new SecretVersionId(value); | ||
} | ||
|
||
} |
65 changes: 65 additions & 0 deletions
65
container-disc/src/main/java/ai/vespa/secret/model/SecretVersionState.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package ai.vespa.secret.model; | ||
|
||
import java.util.logging.Logger; | ||
|
||
/** | ||
* @author gjoranv | ||
*/ | ||
public enum SecretVersionState { | ||
|
||
// DO NOT CHANGE THE ORDERING OF THESE ENUMS | ||
// They are used to sort lists of secret versions returned by the secret store. | ||
PENDING("PENDING", "Pending"), // Maps to AWSPENDING | ||
CURRENT("CURRENT", "Current"), // Maps to AWSCURRENT | ||
PREVIOUS("PREVIOUS", "Previous"), // Maps to AWSPREVIOUS | ||
DEPRECATED("DEPRECATED", "Deprecated"); | ||
// Deprecated versions have no staging labels in ASM, and will be garbage collected automatically | ||
|
||
private static final Logger log = Logger.getLogger(SecretVersionState.class.getName()); | ||
|
||
private final String serializedName; | ||
private final String prettyName; | ||
|
||
SecretVersionState(String serializedName, String prettyName) { | ||
this.serializedName =serializedName; | ||
this.prettyName = prettyName; | ||
} | ||
|
||
public String serialize() { | ||
return serializedName; | ||
} | ||
|
||
public String prettyName() { | ||
return prettyName; | ||
} | ||
|
||
// Ensure that toString cannot be directly used for serialization | ||
@Override | ||
public String toString() { | ||
return SecretVersionState.class.getSimpleName() + "." + serializedName; | ||
} | ||
|
||
public static SecretVersionState deserialize(String serializedName) { | ||
for (SecretVersionState state : values()) { | ||
if (state.serializedName.equals(serializedName)) | ||
return state; | ||
} | ||
throw new IllegalArgumentException("No such secret version state: " + serializedName); | ||
} | ||
|
||
public void validateTransition(SecretVersionState newState) { | ||
if (this == newState) { | ||
log.fine("Transition to the same state: " + newState); | ||
} | ||
if (this == PREVIOUS && newState != DEPRECATED) { | ||
throw new IllegalArgumentException("Cannot transition from PREVIOUS state to " + newState); | ||
} | ||
if (this == DEPRECATED) { | ||
throw new IllegalArgumentException("Cannot transition from DEPRECATED state: " + this); | ||
} | ||
if (newState == PENDING) { | ||
throw new IllegalArgumentException("Cannot transition to PENDING state: " + this + " -> " + newState); | ||
} | ||
} | ||
|
||
} |
22 changes: 22 additions & 0 deletions
22
container-disc/src/main/java/ai/vespa/secret/model/VaultName.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package ai.vespa.secret.model; | ||
|
||
import ai.vespa.validation.PatternedStringWrapper; | ||
|
||
import java.util.regex.Pattern; | ||
|
||
/** | ||
* @author gjoranv | ||
*/ | ||
public class VaultName extends PatternedStringWrapper<VaultName> { | ||
|
||
private static final Pattern namePattern = Pattern.compile("[.a-zA-Z0-9_-]{1,64}"); | ||
|
||
private VaultName(String name) { | ||
super(name, namePattern, "Vault name"); | ||
} | ||
|
||
public static VaultName of(String name) { | ||
return new VaultName(name); | ||
} | ||
|
||
} |
6 changes: 6 additions & 0 deletions
6
container-disc/src/main/java/ai/vespa/secret/model/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. | ||
|
||
@ExportPackage | ||
package ai.vespa.secret.model; | ||
|
||
import com.yahoo.osgi.annotation.ExportPackage; |