Adding Response Structures to PKI Config (#18376)
This commit is contained in:
parent
91446e129e
commit
e05c8931b9
|
@ -30,6 +30,8 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/hashicorp/vault/sdk/helper/testhelpers/schema"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/armon/go-metrics"
|
"github.com/armon/go-metrics"
|
||||||
|
@ -550,7 +552,6 @@ func generateURLSteps(t *testing.T, caCert, caKey string, intdata, reqdata map[s
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !reflect.DeepEqual(entries, expected) {
|
if !reflect.DeepEqual(entries, expected) {
|
||||||
return fmt.Errorf("expected urls\n%#v\ndoes not match provided\n%#v\n", expected, entries)
|
return fmt.Errorf("expected urls\n%#v\ndoes not match provided\n%#v\n", expected, entries)
|
||||||
}
|
}
|
||||||
|
@ -1983,6 +1984,7 @@ func TestBackend_PathFetchCertList(t *testing.T) {
|
||||||
Data: rootData,
|
Data: rootData,
|
||||||
MountPoint: "pki/",
|
MountPoint: "pki/",
|
||||||
})
|
})
|
||||||
|
|
||||||
if resp != nil && resp.IsError() {
|
if resp != nil && resp.IsError() {
|
||||||
t.Fatalf("failed to generate root, %#v", resp)
|
t.Fatalf("failed to generate root, %#v", resp)
|
||||||
}
|
}
|
||||||
|
@ -2003,6 +2005,16 @@ func TestBackend_PathFetchCertList(t *testing.T) {
|
||||||
Data: urlsData,
|
Data: urlsData,
|
||||||
MountPoint: "pki/",
|
MountPoint: "pki/",
|
||||||
})
|
})
|
||||||
|
schema.ValidateResponse(t, schema.GetResponseSchema(t, b.Route("config/urls"), logical.UpdateOperation), resp, true)
|
||||||
|
|
||||||
|
resp, err = b.HandleRequest(context.Background(), &logical.Request{
|
||||||
|
Operation: logical.ReadOperation,
|
||||||
|
Path: "config/urls",
|
||||||
|
Storage: storage,
|
||||||
|
MountPoint: "pki/",
|
||||||
|
})
|
||||||
|
schema.ValidateResponse(t, schema.GetResponseSchema(t, b.Route("config/urls"), logical.ReadOperation), resp, true)
|
||||||
|
|
||||||
if resp != nil && resp.IsError() {
|
if resp != nil && resp.IsError() {
|
||||||
t.Fatalf("failed to config urls, %#v", resp)
|
t.Fatalf("failed to config urls, %#v", resp)
|
||||||
}
|
}
|
||||||
|
@ -2410,6 +2422,8 @@ func TestBackend_Root_Idempotency(t *testing.T) {
|
||||||
resp, err = CBWrite(b, s, "config/ca", map[string]interface{}{
|
resp, err = CBWrite(b, s, "config/ca", map[string]interface{}{
|
||||||
"pem_bundle": pemBundleRootCA,
|
"pem_bundle": pemBundleRootCA,
|
||||||
})
|
})
|
||||||
|
schema.ValidateResponse(t, schema.GetResponseSchema(t, b.Route("config/ca"), logical.UpdateOperation), resp, true)
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, resp, "expected ca info")
|
require.NotNil(t, resp, "expected ca info")
|
||||||
firstImportedKeys := resp.Data["imported_keys"].([]string)
|
firstImportedKeys := resp.Data["imported_keys"].([]string)
|
||||||
|
@ -6013,11 +6027,16 @@ func TestPKI_TemplatedAIAs(t *testing.T) {
|
||||||
b, s := CreateBackendWithStorage(t)
|
b, s := CreateBackendWithStorage(t)
|
||||||
|
|
||||||
// Setting templated AIAs should succeed.
|
// Setting templated AIAs should succeed.
|
||||||
_, err := CBWrite(b, s, "config/cluster", map[string]interface{}{
|
resp, err := CBWrite(b, s, "config/cluster", map[string]interface{}{
|
||||||
"path": "http://localhost:8200/v1/pki",
|
"path": "http://localhost:8200/v1/pki",
|
||||||
"aia_path": "http://localhost:8200/cdn/pki",
|
"aia_path": "http://localhost:8200/cdn/pki",
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
schema.ValidateResponse(t, schema.GetResponseSchema(t, b.Route("config/cluster"), logical.UpdateOperation), resp, true)
|
||||||
|
|
||||||
|
resp, err = CBRead(b, s, "config/cluster")
|
||||||
|
require.NoError(t, err)
|
||||||
|
schema.ValidateResponse(t, schema.GetResponseSchema(t, b.Route("config/cluster"), logical.ReadOperation), resp, true)
|
||||||
|
|
||||||
aiaData := map[string]interface{}{
|
aiaData := map[string]interface{}{
|
||||||
"crl_distribution_points": "{{cluster_path}}/issuer/{{issuer_id}}/crl/der",
|
"crl_distribution_points": "{{cluster_path}}/issuer/{{issuer_id}}/crl/der",
|
||||||
|
@ -6046,7 +6065,7 @@ func TestPKI_TemplatedAIAs(t *testing.T) {
|
||||||
"enable_templating": false,
|
"enable_templating": false,
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
resp, err := CBWrite(b, s, "root/generate/internal", rootData)
|
resp, err = CBWrite(b, s, "root/generate/internal", rootData)
|
||||||
requireSuccessNonNilResponse(t, resp, err)
|
requireSuccessNonNilResponse(t, resp, err)
|
||||||
issuerId := string(resp.Data["issuer_id"].(issuerID))
|
issuerId := string(resp.Data["issuer_id"].(issuerID))
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,8 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/hashicorp/vault/sdk/helper/testhelpers/schema"
|
||||||
|
|
||||||
"github.com/hashicorp/vault/api"
|
"github.com/hashicorp/vault/api"
|
||||||
vaulthttp "github.com/hashicorp/vault/http"
|
vaulthttp "github.com/hashicorp/vault/http"
|
||||||
"github.com/hashicorp/vault/sdk/logical"
|
"github.com/hashicorp/vault/sdk/logical"
|
||||||
|
@ -90,8 +92,11 @@ func TestBackend_CRLConfig(t *testing.T) {
|
||||||
"auto_rebuild_grace_period": tc.autoRebuildGracePeriod,
|
"auto_rebuild_grace_period": tc.autoRebuildGracePeriod,
|
||||||
})
|
})
|
||||||
requireSuccessNonNilResponse(t, resp, err)
|
requireSuccessNonNilResponse(t, resp, err)
|
||||||
|
schema.ValidateResponse(t, schema.GetResponseSchema(t, b.Route("config/crl"), logical.UpdateOperation), resp, true)
|
||||||
|
|
||||||
resp, err = CBRead(b, s, "config/crl")
|
resp, err = CBRead(b, s, "config/crl")
|
||||||
|
schema.ValidateResponse(t, schema.GetResponseSchema(t, b.Route("config/crl"), logical.ReadOperation), resp, true)
|
||||||
|
|
||||||
requireSuccessNonNilResponse(t, resp, err)
|
requireSuccessNonNilResponse(t, resp, err)
|
||||||
requireFieldsSetInResp(t, resp, "disable", "expiry", "ocsp_disable", "auto_rebuild", "auto_rebuild_grace_period")
|
requireFieldsSetInResp(t, resp, "disable", "expiry", "ocsp_disable", "auto_rebuild", "auto_rebuild_grace_period")
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/vault/sdk/helper/testhelpers/schema"
|
||||||
|
|
||||||
"github.com/hashicorp/vault/sdk/logical"
|
"github.com/hashicorp/vault/sdk/logical"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -371,6 +373,7 @@ func TestIntegration_AutoIssuer(t *testing.T) {
|
||||||
"issuer_name": "root-1",
|
"issuer_name": "root-1",
|
||||||
"key_type": "ec",
|
"key_type": "ec",
|
||||||
})
|
})
|
||||||
|
|
||||||
requireSuccessNonNilResponse(t, resp, err)
|
requireSuccessNonNilResponse(t, resp, err)
|
||||||
issuerIdOne := resp.Data["issuer_id"]
|
issuerIdOne := resp.Data["issuer_id"]
|
||||||
require.NotEmpty(t, issuerIdOne)
|
require.NotEmpty(t, issuerIdOne)
|
||||||
|
@ -381,12 +384,15 @@ func TestIntegration_AutoIssuer(t *testing.T) {
|
||||||
requireSuccessNonNilResponse(t, resp, err)
|
requireSuccessNonNilResponse(t, resp, err)
|
||||||
require.Equal(t, issuerIdOne, resp.Data["default"])
|
require.Equal(t, issuerIdOne, resp.Data["default"])
|
||||||
|
|
||||||
|
schema.ValidateResponse(t, schema.GetResponseSchema(t, b.Route("config/issuers"), logical.ReadOperation), resp, true)
|
||||||
|
|
||||||
// Enable the new config option.
|
// Enable the new config option.
|
||||||
_, err = CBWrite(b, s, "config/issuers", map[string]interface{}{
|
resp, err = CBWrite(b, s, "config/issuers", map[string]interface{}{
|
||||||
"default": issuerIdOne,
|
"default": issuerIdOne,
|
||||||
"default_follows_latest_issuer": true,
|
"default_follows_latest_issuer": true,
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
schema.ValidateResponse(t, schema.GetResponseSchema(t, b.Route("config/issuers"), logical.UpdateOperation), resp, true)
|
||||||
|
|
||||||
// Now generate the second root; it should become default.
|
// Now generate the second root; it should become default.
|
||||||
resp, err = CBWrite(b, s, "root/generate/internal", map[string]interface{}{
|
resp, err = CBWrite(b, s, "root/generate/internal", map[string]interface{}{
|
||||||
|
|
|
@ -2,6 +2,7 @@ package pki
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"github.com/hashicorp/vault/sdk/framework"
|
"github.com/hashicorp/vault/sdk/framework"
|
||||||
"github.com/hashicorp/vault/sdk/logical"
|
"github.com/hashicorp/vault/sdk/logical"
|
||||||
|
@ -21,6 +22,28 @@ secret key and certificate.`,
|
||||||
Operations: map[logical.Operation]framework.OperationHandler{
|
Operations: map[logical.Operation]framework.OperationHandler{
|
||||||
logical.UpdateOperation: &framework.PathOperation{
|
logical.UpdateOperation: &framework.PathOperation{
|
||||||
Callback: b.pathImportIssuers,
|
Callback: b.pathImportIssuers,
|
||||||
|
Responses: map[int][]framework.Response{
|
||||||
|
http.StatusOK: {{
|
||||||
|
Description: "OK",
|
||||||
|
Fields: map[string]*framework.FieldSchema{
|
||||||
|
"mapping": {
|
||||||
|
Type: framework.TypeMap,
|
||||||
|
Description: "A mapping of issuer_id to key_id for all issuers included in this request",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"imported_keys": {
|
||||||
|
Type: framework.TypeCommaStringSlice,
|
||||||
|
Description: "Net-new keys imported as a part of this request",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"imported_issuers": {
|
||||||
|
Type: framework.TypeCommaStringSlice,
|
||||||
|
Description: "Net-new issuers imported as a part of this request",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
},
|
||||||
// Read more about why these flags are set in backend.go.
|
// Read more about why these flags are set in backend.go.
|
||||||
ForwardPerformanceStandby: true,
|
ForwardPerformanceStandby: true,
|
||||||
ForwardPerformanceSecondary: true,
|
ForwardPerformanceSecondary: true,
|
||||||
|
@ -58,13 +81,44 @@ func pathConfigIssuers(b *backend) *framework.Path {
|
||||||
Default: false,
|
Default: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
Operations: map[logical.Operation]framework.OperationHandler{
|
Operations: map[logical.Operation]framework.OperationHandler{
|
||||||
logical.ReadOperation: &framework.PathOperation{
|
logical.ReadOperation: &framework.PathOperation{
|
||||||
Callback: b.pathCAIssuersRead,
|
Callback: b.pathCAIssuersRead,
|
||||||
|
Responses: map[int][]framework.Response{
|
||||||
|
http.StatusOK: {{
|
||||||
|
Description: "OK",
|
||||||
|
Fields: map[string]*framework.FieldSchema{
|
||||||
|
"default": {
|
||||||
|
Type: framework.TypeString,
|
||||||
|
Description: `Reference (name or identifier) to the default issuer.`,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"default_follows_latest_issuer": {
|
||||||
|
Type: framework.TypeBool,
|
||||||
|
Description: `Whether the default issuer should automatically follow the latest generated or imported issuer. Defaults to false.`,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
logical.UpdateOperation: &framework.PathOperation{
|
logical.UpdateOperation: &framework.PathOperation{
|
||||||
Callback: b.pathCAIssuersWrite,
|
Callback: b.pathCAIssuersWrite,
|
||||||
|
Responses: map[int][]framework.Response{
|
||||||
|
http.StatusOK: {{
|
||||||
|
Description: "OK",
|
||||||
|
Fields: map[string]*framework.FieldSchema{
|
||||||
|
"default": {
|
||||||
|
Type: framework.TypeString,
|
||||||
|
Description: `Reference (name or identifier) to the default issuer.`,
|
||||||
|
},
|
||||||
|
"default_follows_latest_issuer": {
|
||||||
|
Type: framework.TypeBool,
|
||||||
|
Description: `Whether the default issuer should automatically follow the latest generated or imported issuer. Defaults to false.`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
},
|
||||||
// Read more about why these flags are set in backend.go.
|
// Read more about why these flags are set in backend.go.
|
||||||
ForwardPerformanceStandby: true,
|
ForwardPerformanceStandby: true,
|
||||||
ForwardPerformanceSecondary: true,
|
ForwardPerformanceSecondary: true,
|
||||||
|
@ -90,6 +144,23 @@ func pathReplaceRoot(b *backend) *framework.Path {
|
||||||
Operations: map[logical.Operation]framework.OperationHandler{
|
Operations: map[logical.Operation]framework.OperationHandler{
|
||||||
logical.UpdateOperation: &framework.PathOperation{
|
logical.UpdateOperation: &framework.PathOperation{
|
||||||
Callback: b.pathCAIssuersWrite,
|
Callback: b.pathCAIssuersWrite,
|
||||||
|
Responses: map[int][]framework.Response{
|
||||||
|
http.StatusOK: {{
|
||||||
|
Description: "OK",
|
||||||
|
Fields: map[string]*framework.FieldSchema{
|
||||||
|
"default": {
|
||||||
|
Type: framework.TypeString,
|
||||||
|
Description: `Reference (name or identifier) to the default issuer.`,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"default_follows_latest_issuer": {
|
||||||
|
Type: framework.TypeBool,
|
||||||
|
Description: `Whether the default issuer should automatically follow the latest generated or imported issuer. Defaults to false.`,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
},
|
||||||
// Read more about why these flags are set in backend.go.
|
// Read more about why these flags are set in backend.go.
|
||||||
ForwardPerformanceStandby: true,
|
ForwardPerformanceStandby: true,
|
||||||
ForwardPerformanceSecondary: true,
|
ForwardPerformanceSecondary: true,
|
||||||
|
@ -209,11 +280,34 @@ func pathConfigKeys(b *backend) *framework.Path {
|
||||||
Operations: map[logical.Operation]framework.OperationHandler{
|
Operations: map[logical.Operation]framework.OperationHandler{
|
||||||
logical.UpdateOperation: &framework.PathOperation{
|
logical.UpdateOperation: &framework.PathOperation{
|
||||||
Callback: b.pathKeyDefaultWrite,
|
Callback: b.pathKeyDefaultWrite,
|
||||||
|
Responses: map[int][]framework.Response{
|
||||||
|
http.StatusOK: {{
|
||||||
|
Description: "OK",
|
||||||
|
Fields: map[string]*framework.FieldSchema{
|
||||||
|
"default": {
|
||||||
|
Type: framework.TypeString,
|
||||||
|
Description: `Reference (name or identifier) to the default issuer.`,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
},
|
||||||
ForwardPerformanceStandby: true,
|
ForwardPerformanceStandby: true,
|
||||||
ForwardPerformanceSecondary: true,
|
ForwardPerformanceSecondary: true,
|
||||||
},
|
},
|
||||||
logical.ReadOperation: &framework.PathOperation{
|
logical.ReadOperation: &framework.PathOperation{
|
||||||
Callback: b.pathKeyDefaultRead,
|
Callback: b.pathKeyDefaultRead,
|
||||||
|
Responses: map[int][]framework.Response{
|
||||||
|
http.StatusOK: {{
|
||||||
|
Description: "OK",
|
||||||
|
Fields: map[string]*framework.FieldSchema{
|
||||||
|
"default": {
|
||||||
|
Type: framework.TypeString,
|
||||||
|
Description: `Reference (name or identifier) to the default issuer.`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
},
|
||||||
ForwardPerformanceStandby: false,
|
ForwardPerformanceStandby: false,
|
||||||
ForwardPerformanceSecondary: false,
|
ForwardPerformanceSecondary: false,
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,6 +3,7 @@ package pki
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"github.com/asaskevich/govalidator"
|
"github.com/asaskevich/govalidator"
|
||||||
"github.com/hashicorp/vault/sdk/framework"
|
"github.com/hashicorp/vault/sdk/framework"
|
||||||
|
@ -41,9 +42,70 @@ For example: http://cdn.example.com/pr1/pki`,
|
||||||
Operations: map[logical.Operation]framework.OperationHandler{
|
Operations: map[logical.Operation]framework.OperationHandler{
|
||||||
logical.UpdateOperation: &framework.PathOperation{
|
logical.UpdateOperation: &framework.PathOperation{
|
||||||
Callback: b.pathWriteCluster,
|
Callback: b.pathWriteCluster,
|
||||||
|
Responses: map[int][]framework.Response{
|
||||||
|
http.StatusOK: {{
|
||||||
|
Description: "OK",
|
||||||
|
Fields: map[string]*framework.FieldSchema{
|
||||||
|
"path": {
|
||||||
|
Type: framework.TypeString,
|
||||||
|
Description: `Canonical URI to this mount on this performance
|
||||||
|
replication cluster's external address. This is for resolving AIA URLs and
|
||||||
|
providing the {{cluster_path}} template parameter but might be used for other
|
||||||
|
purposes in the future.
|
||||||
|
|
||||||
|
This should only point back to this particular PR replica and should not ever
|
||||||
|
point to another PR cluster. It may point to any node in the PR replica,
|
||||||
|
including standby nodes, and need not always point to the active node.
|
||||||
|
|
||||||
|
For example: https://pr1.vault.example.com:8200/v1/pki`,
|
||||||
|
},
|
||||||
|
"aia_path": {
|
||||||
|
Type: framework.TypeString,
|
||||||
|
Description: `Optional URI to this mount's AIA distribution
|
||||||
|
point; may refer to an external non-Vault responder. This is for resolving AIA
|
||||||
|
URLs and providing the {{cluster_aia_path}} template parameter and will not
|
||||||
|
be used for other purposes. As such, unlike path above, this could safely
|
||||||
|
be an insecure transit mechanism (like HTTP without TLS).
|
||||||
|
|
||||||
|
For example: http://cdn.example.com/pr1/pki`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
logical.ReadOperation: &framework.PathOperation{
|
logical.ReadOperation: &framework.PathOperation{
|
||||||
Callback: b.pathReadCluster,
|
Callback: b.pathReadCluster,
|
||||||
|
Responses: map[int][]framework.Response{
|
||||||
|
http.StatusOK: {{
|
||||||
|
Description: "OK",
|
||||||
|
Fields: map[string]*framework.FieldSchema{
|
||||||
|
"path": {
|
||||||
|
Type: framework.TypeString,
|
||||||
|
Description: `Canonical URI to this mount on this performance
|
||||||
|
replication cluster's external address. This is for resolving AIA URLs and
|
||||||
|
providing the {{cluster_path}} template parameter but might be used for other
|
||||||
|
purposes in the future.
|
||||||
|
|
||||||
|
This should only point back to this particular PR replica and should not ever
|
||||||
|
point to another PR cluster. It may point to any node in the PR replica,
|
||||||
|
including standby nodes, and need not always point to the active node.
|
||||||
|
|
||||||
|
For example: https://pr1.vault.example.com:8200/v1/pki`,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"aia_path": {
|
||||||
|
Type: framework.TypeString,
|
||||||
|
Description: `Optional URI to this mount's AIA distribution
|
||||||
|
point; may refer to an external non-Vault responder. This is for resolving AIA
|
||||||
|
URLs and providing the {{cluster_aia_path}} template parameter and will not
|
||||||
|
be used for other purposes. As such, unlike path above, this could safely
|
||||||
|
be an insecure transit mechanism (like HTTP without TLS).
|
||||||
|
|
||||||
|
For example: http://cdn.example.com/pr1/pki`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package pki
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/vault/helper/constants"
|
"github.com/hashicorp/vault/helper/constants"
|
||||||
|
@ -110,9 +111,141 @@ existing CRL and OCSP paths will return the unified CRL instead of a response ba
|
||||||
Operations: map[logical.Operation]framework.OperationHandler{
|
Operations: map[logical.Operation]framework.OperationHandler{
|
||||||
logical.ReadOperation: &framework.PathOperation{
|
logical.ReadOperation: &framework.PathOperation{
|
||||||
Callback: b.pathCRLRead,
|
Callback: b.pathCRLRead,
|
||||||
|
Responses: map[int][]framework.Response{
|
||||||
|
http.StatusOK: {{
|
||||||
|
Description: "OK",
|
||||||
|
Fields: map[string]*framework.FieldSchema{
|
||||||
|
"expiry": {
|
||||||
|
Type: framework.TypeString,
|
||||||
|
Description: `The amount of time the generated CRL should be
|
||||||
|
valid; defaults to 72 hours`,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"disable": {
|
||||||
|
Type: framework.TypeBool,
|
||||||
|
Description: `If set to true, disables generating the CRL entirely.`,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"ocsp_disable": {
|
||||||
|
Type: framework.TypeBool,
|
||||||
|
Description: `If set to true, ocsp unauthorized responses will be returned.`,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"ocsp_expiry": {
|
||||||
|
Type: framework.TypeString,
|
||||||
|
Description: `The amount of time an OCSP response will be valid (controls
|
||||||
|
the NextUpdate field); defaults to 12 hours`,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"auto_rebuild": {
|
||||||
|
Type: framework.TypeBool,
|
||||||
|
Description: `If set to true, enables automatic rebuilding of the CRL`,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"auto_rebuild_grace_period": {
|
||||||
|
Type: framework.TypeString,
|
||||||
|
Description: `The time before the CRL expires to automatically rebuild it, when enabled. Must be shorter than the CRL expiry. Defaults to 12h.`,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"enable_delta": {
|
||||||
|
Type: framework.TypeBool,
|
||||||
|
Description: `Whether to enable delta CRLs between authoritative CRL rebuilds`,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"delta_rebuild_interval": {
|
||||||
|
Type: framework.TypeString,
|
||||||
|
Description: `The time between delta CRL rebuilds if a new revocation has occurred. Must be shorter than the CRL expiry. Defaults to 15m.`,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"cross_cluster_revocation": {
|
||||||
|
Type: framework.TypeBool,
|
||||||
|
Description: `Whether to enable a global, cross-cluster revocation queue.
|
||||||
|
Must be used with auto_rebuild=true.`,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"unified_crl": {
|
||||||
|
Type: framework.TypeBool,
|
||||||
|
Description: `If set to true enables global replication of revocation entries,
|
||||||
|
also enabling unified versions of OCSP and CRLs if their respective features are enabled.
|
||||||
|
disable for CRLs and ocsp_disable for OCSP.`,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"unified_crl_on_existing_paths": {
|
||||||
|
Type: framework.TypeBool,
|
||||||
|
Description: `If set to true,
|
||||||
|
existing CRL and OCSP paths will return the unified CRL instead of a response based on cluster-local data`,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
logical.UpdateOperation: &framework.PathOperation{
|
logical.UpdateOperation: &framework.PathOperation{
|
||||||
Callback: b.pathCRLWrite,
|
Callback: b.pathCRLWrite,
|
||||||
|
Responses: map[int][]framework.Response{
|
||||||
|
http.StatusOK: {{
|
||||||
|
Description: "OK",
|
||||||
|
Fields: map[string]*framework.FieldSchema{
|
||||||
|
"expiry": {
|
||||||
|
Type: framework.TypeString,
|
||||||
|
Description: `The amount of time the generated CRL should be
|
||||||
|
valid; defaults to 72 hours`,
|
||||||
|
Default: "72h",
|
||||||
|
},
|
||||||
|
"disable": {
|
||||||
|
Type: framework.TypeBool,
|
||||||
|
Description: `If set to true, disables generating the CRL entirely.`,
|
||||||
|
},
|
||||||
|
"ocsp_disable": {
|
||||||
|
Type: framework.TypeBool,
|
||||||
|
Description: `If set to true, ocsp unauthorized responses will be returned.`,
|
||||||
|
},
|
||||||
|
"ocsp_expiry": {
|
||||||
|
Type: framework.TypeString,
|
||||||
|
Description: `The amount of time an OCSP response will be valid (controls
|
||||||
|
the NextUpdate field); defaults to 12 hours`,
|
||||||
|
Default: "1h",
|
||||||
|
},
|
||||||
|
"auto_rebuild": {
|
||||||
|
Type: framework.TypeBool,
|
||||||
|
Description: `If set to true, enables automatic rebuilding of the CRL`,
|
||||||
|
},
|
||||||
|
"auto_rebuild_grace_period": {
|
||||||
|
Type: framework.TypeString,
|
||||||
|
Description: `The time before the CRL expires to automatically rebuild it, when enabled. Must be shorter than the CRL expiry. Defaults to 12h.`,
|
||||||
|
Default: "12h",
|
||||||
|
},
|
||||||
|
"enable_delta": {
|
||||||
|
Type: framework.TypeBool,
|
||||||
|
Description: `Whether to enable delta CRLs between authoritative CRL rebuilds`,
|
||||||
|
},
|
||||||
|
"delta_rebuild_interval": {
|
||||||
|
Type: framework.TypeString,
|
||||||
|
Description: `The time between delta CRL rebuilds if a new revocation has occurred. Must be shorter than the CRL expiry. Defaults to 15m.`,
|
||||||
|
Default: "15m",
|
||||||
|
},
|
||||||
|
"cross_cluster_revocation": {
|
||||||
|
Type: framework.TypeBool,
|
||||||
|
Description: `Whether to enable a global, cross-cluster revocation queue.
|
||||||
|
Must be used with auto_rebuild=true.`,
|
||||||
|
Required: false,
|
||||||
|
},
|
||||||
|
"unified_crl": {
|
||||||
|
Type: framework.TypeBool,
|
||||||
|
Description: `If set to true enables global replication of revocation entries,
|
||||||
|
also enabling unified versions of OCSP and CRLs if their respective features are enabled.
|
||||||
|
disable for CRLs and ocsp_disable for OCSP.`,
|
||||||
|
Required: false,
|
||||||
|
},
|
||||||
|
"unified_crl_on_existing_paths": {
|
||||||
|
Type: framework.TypeBool,
|
||||||
|
Description: `If set to true,
|
||||||
|
existing CRL and OCSP paths will return the unified CRL instead of a response based on cluster-local data`,
|
||||||
|
Required: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
},
|
||||||
// Read more about why these flags are set in backend.go.
|
// Read more about why these flags are set in backend.go.
|
||||||
ForwardPerformanceStandby: true,
|
ForwardPerformanceStandby: true,
|
||||||
ForwardPerformanceSecondary: true,
|
ForwardPerformanceSecondary: true,
|
||||||
|
|
|
@ -3,6 +3,7 @@ package pki
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/asaskevich/govalidator"
|
"github.com/asaskevich/govalidator"
|
||||||
|
@ -48,9 +49,74 @@ to be set on all PR secondary clusters.`,
|
||||||
Operations: map[logical.Operation]framework.OperationHandler{
|
Operations: map[logical.Operation]framework.OperationHandler{
|
||||||
logical.UpdateOperation: &framework.PathOperation{
|
logical.UpdateOperation: &framework.PathOperation{
|
||||||
Callback: b.pathWriteURL,
|
Callback: b.pathWriteURL,
|
||||||
|
Responses: map[int][]framework.Response{
|
||||||
|
http.StatusOK: {{
|
||||||
|
Description: "OK",
|
||||||
|
Fields: map[string]*framework.FieldSchema{
|
||||||
|
"issuing_certificates": {
|
||||||
|
Type: framework.TypeCommaStringSlice,
|
||||||
|
Description: `Comma-separated list of URLs to be used
|
||||||
|
for the issuing certificate attribute. See also RFC 5280 Section 4.2.2.1.`,
|
||||||
|
},
|
||||||
|
"crl_distribution_points": {
|
||||||
|
Type: framework.TypeCommaStringSlice,
|
||||||
|
Description: `Comma-separated list of URLs to be used
|
||||||
|
for the CRL distribution points attribute. See also RFC 5280 Section 4.2.1.13.`,
|
||||||
|
},
|
||||||
|
"ocsp_servers": {
|
||||||
|
Type: framework.TypeCommaStringSlice,
|
||||||
|
Description: `Comma-separated list of URLs to be used
|
||||||
|
for the OCSP servers attribute. See also RFC 5280 Section 4.2.2.1.`,
|
||||||
|
},
|
||||||
|
"enable_templating": {
|
||||||
|
Type: framework.TypeBool,
|
||||||
|
Description: `Whether or not to enabling templating of the
|
||||||
|
above AIA fields. When templating is enabled the special values '{{issuer_id}}'
|
||||||
|
and '{{cluster_path}}' are available, but the addresses are not checked for
|
||||||
|
URI validity until issuance time. This requires /config/cluster's path to be
|
||||||
|
set on all PR Secondary clusters.`,
|
||||||
|
Default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
logical.ReadOperation: &framework.PathOperation{
|
logical.ReadOperation: &framework.PathOperation{
|
||||||
Callback: b.pathReadURL,
|
Callback: b.pathReadURL,
|
||||||
|
Responses: map[int][]framework.Response{
|
||||||
|
http.StatusOK: {{
|
||||||
|
Description: "OK",
|
||||||
|
Fields: map[string]*framework.FieldSchema{
|
||||||
|
"issuing_certificates": {
|
||||||
|
Type: framework.TypeCommaStringSlice,
|
||||||
|
Description: `Comma-separated list of URLs to be used
|
||||||
|
for the issuing certificate attribute. See also RFC 5280 Section 4.2.2.1.`,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"crl_distribution_points": {
|
||||||
|
Type: framework.TypeCommaStringSlice,
|
||||||
|
Description: `Comma-separated list of URLs to be used
|
||||||
|
for the CRL distribution points attribute. See also RFC 5280 Section 4.2.1.13.`,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"ocsp_servers": {
|
||||||
|
Type: framework.TypeCommaStringSlice,
|
||||||
|
Description: `Comma-separated list of URLs to be used
|
||||||
|
for the OCSP servers attribute. See also RFC 5280 Section 4.2.2.1.`,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"enable_templating": {
|
||||||
|
Type: framework.TypeBool,
|
||||||
|
Description: `Whether or not to enable templating of the
|
||||||
|
above AIA fields. When templating is enabled the special values '{{issuer_id}}'
|
||||||
|
and '{{cluster_path}}' are available, but the addresses are not checked for
|
||||||
|
URI validity until issuance time. This requires /config/cluster's path to be
|
||||||
|
set on all PR Secondary clusters.`,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:improvement
|
||||||
|
openapi: Add openapi response definitions to pki/config_*.go
|
||||||
|
```
|
Loading…
Reference in New Issue