rename SecureVariables to Variables throughout

This commit is contained in:
Tim Gross
2022-08-26 14:03:56 -04:00
parent 91c81ba984
commit d1faead371
53 changed files with 1201 additions and 1208 deletions

View File

@@ -442,8 +442,8 @@ func (s HTTPServer) registerHandlers(enableDebug bool) {
s.mux.HandleFunc("/v1/namespace", s.wrap(s.NamespaceCreateRequest))
s.mux.HandleFunc("/v1/namespace/", s.wrap(s.NamespaceSpecificRequest))
s.mux.Handle("/v1/vars", wrapCORS(s.wrap(s.SecureVariablesListRequest)))
s.mux.Handle("/v1/var/", wrapCORSWithAllowedMethods(s.wrap(s.SecureVariableSpecificRequest), "HEAD", "GET", "PUT", "DELETE"))
s.mux.Handle("/v1/vars", wrapCORS(s.wrap(s.VariablesListRequest)))
s.mux.Handle("/v1/var/", wrapCORSWithAllowedMethods(s.wrap(s.VariableSpecificRequest), "HEAD", "GET", "PUT", "DELETE"))
uiConfigEnabled := s.agent.config.UI != nil && s.agent.config.UI.Enabled

View File

@@ -623,24 +623,24 @@ func TestHTTP_FuzzySearch_AllContext(t *testing.T) {
})
}
func TestHTTP_PrefixSearch_SecureVariables(t *testing.T) {
func TestHTTP_PrefixSearch_Variables(t *testing.T) {
ci.Parallel(t)
testPath := "alpha/beta/charlie"
testPathPrefix := "alpha/beta"
httpTest(t, nil, func(s *TestAgent) {
sv := mock.SecureVariableEncrypted()
sv := mock.VariableEncrypted()
state := s.Agent.server.State()
sv.Path = testPath
setResp := state.SVESet(8000, &structs.SVApplyStateRequest{
Op: structs.SVOpSet,
setResp := state.VarSet(8000, &structs.VarApplyStateRequest{
Op: structs.VarOpSet,
Var: sv,
})
require.NoError(t, setResp.Error)
data := structs.SearchRequest{Prefix: testPathPrefix, Context: structs.SecureVariables}
data := structs.SearchRequest{Prefix: testPathPrefix, Context: structs.Variables}
req, err := http.NewRequest("POST", "/v1/search", encodeReq(data))
require.NoError(t, err)
@@ -650,14 +650,14 @@ func TestHTTP_PrefixSearch_SecureVariables(t *testing.T) {
require.NoError(t, err)
res := resp.(structs.SearchResponse)
matchedVars := res.Matches[structs.SecureVariables]
matchedVars := res.Matches[structs.Variables]
require.Len(t, matchedVars, 1)
require.Equal(t, testPath, matchedVars[0])
require.Equal(t, "8000", header(respW, "X-Nomad-Index"))
})
}
func TestHTTP_FuzzySearch_SecureVariables(t *testing.T) {
func TestHTTP_FuzzySearch_Variables(t *testing.T) {
ci.Parallel(t)
testPath := "alpha/beta/charlie"
@@ -665,15 +665,15 @@ func TestHTTP_FuzzySearch_SecureVariables(t *testing.T) {
httpTest(t, nil, func(s *TestAgent) {
state := s.Agent.server.State()
sv := mock.SecureVariableEncrypted()
sv := mock.VariableEncrypted()
sv.Path = testPath
setResp := state.SVESet(8000, &structs.SVApplyStateRequest{
Op: structs.SVOpSet,
setResp := state.VarSet(8000, &structs.VarApplyStateRequest{
Op: structs.VarOpSet,
Var: sv,
})
require.NoError(t, setResp.Error)
data := structs.FuzzySearchRequest{Text: testPathText, Context: structs.SecureVariables}
data := structs.FuzzySearchRequest{Text: testPathText, Context: structs.Variables}
req, err := http.NewRequest("POST", "/v1/search/", encodeReq(data))
require.NoError(t, err)
@@ -683,7 +683,7 @@ func TestHTTP_FuzzySearch_SecureVariables(t *testing.T) {
require.NoError(t, err)
res := resp.(structs.FuzzySearchResponse)
matchedVars := res.Matches[structs.SecureVariables]
matchedVars := res.Matches[structs.Variables]
require.Len(t, matchedVars, 1)
require.Equal(t, testPath, matchedVars[0].ID)
require.Equal(t, []string{
@@ -693,7 +693,7 @@ func TestHTTP_FuzzySearch_SecureVariables(t *testing.T) {
})
}
func TestHTTP_PrefixSearch_SecureVariables_ACL(t *testing.T) {
func TestHTTP_PrefixSearch_Variables_ACL(t *testing.T) {
ci.Parallel(t)
testPath := "alpha/beta/charlie"
@@ -702,19 +702,19 @@ func TestHTTP_PrefixSearch_SecureVariables_ACL(t *testing.T) {
httpACLTest(t, nil, func(s *TestAgent) {
state := s.Agent.server.State()
ns := mock.Namespace()
sv1 := mock.SecureVariableEncrypted()
sv1 := mock.VariableEncrypted()
sv1.Path = testPath
sv2 := sv1.Copy()
sv2.Namespace = ns.Name
require.NoError(t, state.UpsertNamespaces(7000, []*structs.Namespace{ns}))
setResp := state.SVESet(8000, &structs.SVApplyStateRequest{
Op: structs.SVOpSet,
setResp := state.VarSet(8000, &structs.VarApplyStateRequest{
Op: structs.VarOpSet,
Var: sv1,
})
require.NoError(t, setResp.Error)
setResp = state.SVESet(8001, &structs.SVApplyStateRequest{
Op: structs.SVOpSet,
setResp = state.VarSet(8001, &structs.VarApplyStateRequest{
Op: structs.VarOpSet,
Var: &sv2,
})
require.NoError(t, setResp.Error)
@@ -722,12 +722,12 @@ func TestHTTP_PrefixSearch_SecureVariables_ACL(t *testing.T) {
rootToken := s.RootToken
defNSToken := mock.CreatePolicyAndToken(t, state, 8002, "default",
mock.NamespacePolicyWithSecureVariables(
mock.NamespacePolicyWithVariables(
"default", "read", []string{},
map[string][]string{"*": []string{"read", "list"}}))
ns1NSToken := mock.CreatePolicyAndToken(t, state, 8004, "ns-"+ns.Name,
mock.NamespacePolicyWithSecureVariables(
mock.NamespacePolicyWithVariables(
ns.Name, "read", []string{},
map[string][]string{"*": []string{"read", "list"}}))
@@ -776,7 +776,7 @@ func TestHTTP_PrefixSearch_SecureVariables_ACL(t *testing.T) {
tC := tC
data := structs.SearchRequest{
Prefix: testPathPrefix,
Context: structs.SecureVariables,
Context: structs.Variables,
QueryOptions: structs.QueryOptions{
AuthToken: tC.token.SecretID,
Namespace: tC.namespace,
@@ -796,7 +796,7 @@ func TestHTTP_PrefixSearch_SecureVariables_ACL(t *testing.T) {
}
require.NoError(t, err)
res := resp.(structs.SearchResponse)
matchedVars := res.Matches[structs.SecureVariables]
matchedVars := res.Matches[structs.Variables]
require.Len(t, matchedVars, tC.expectedCount)
for _, mv := range matchedVars {
require.Equal(t, testPath, mv)
@@ -807,7 +807,7 @@ func TestHTTP_PrefixSearch_SecureVariables_ACL(t *testing.T) {
})
}
func TestHTTP_FuzzySearch_SecureVariables_ACL(t *testing.T) {
func TestHTTP_FuzzySearch_Variables_ACL(t *testing.T) {
ci.Parallel(t)
testPath := "alpha/beta/charlie"
@@ -816,19 +816,19 @@ func TestHTTP_FuzzySearch_SecureVariables_ACL(t *testing.T) {
httpACLTest(t, nil, func(s *TestAgent) {
state := s.Agent.server.State()
ns := mock.Namespace()
sv1 := mock.SecureVariableEncrypted()
sv1 := mock.VariableEncrypted()
sv1.Path = testPath
sv2 := sv1.Copy()
sv2.Namespace = ns.Name
require.NoError(t, state.UpsertNamespaces(7000, []*structs.Namespace{ns}))
setResp := state.SVESet(8000, &structs.SVApplyStateRequest{
Op: structs.SVOpSet,
setResp := state.VarSet(8000, &structs.VarApplyStateRequest{
Op: structs.VarOpSet,
Var: sv1,
})
require.NoError(t, setResp.Error)
setResp = state.SVESet(8001, &structs.SVApplyStateRequest{
Op: structs.SVOpSet,
setResp = state.VarSet(8001, &structs.VarApplyStateRequest{
Op: structs.VarOpSet,
Var: &sv2,
})
require.NoError(t, setResp.Error)
@@ -891,7 +891,7 @@ func TestHTTP_FuzzySearch_SecureVariables_ACL(t *testing.T) {
t.Run(tC.desc, func(t *testing.T) {
data := structs.FuzzySearchRequest{
Text: testPathText,
Context: structs.SecureVariables,
Context: structs.Variables,
QueryOptions: structs.QueryOptions{
AuthToken: tC.token.SecretID,
Namespace: tcNS(tC),
@@ -911,7 +911,7 @@ func TestHTTP_FuzzySearch_SecureVariables_ACL(t *testing.T) {
}
res := resp.(structs.FuzzySearchResponse)
matchedVars := res.Matches[structs.SecureVariables]
matchedVars := res.Matches[structs.Variables]
require.Len(t, matchedVars, tC.expectedCount)
for _, mv := range matchedVars {
require.Equal(t, testPath, mv.ID)

View File

@@ -9,83 +9,83 @@ import (
"github.com/hashicorp/nomad/nomad/structs"
)
func (s *HTTPServer) SecureVariablesListRequest(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
func (s *HTTPServer) VariablesListRequest(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
if req.Method != "GET" {
return nil, CodedError(http.StatusMethodNotAllowed, ErrInvalidMethod)
}
args := structs.SecureVariablesListRequest{}
args := structs.VariablesListRequest{}
if s.parse(resp, req, &args.Region, &args.QueryOptions) {
return nil, nil
}
var out structs.SecureVariablesListResponse
if err := s.agent.RPC(structs.SecureVariablesListRPCMethod, &args, &out); err != nil {
var out structs.VariablesListResponse
if err := s.agent.RPC(structs.VariablesListRPCMethod, &args, &out); err != nil {
return nil, err
}
setMeta(resp, &out.QueryMeta)
if out.Data == nil {
out.Data = make([]*structs.SecureVariableMetadata, 0)
out.Data = make([]*structs.VariableMetadata, 0)
}
return out.Data, nil
}
func (s *HTTPServer) SecureVariableSpecificRequest(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
func (s *HTTPServer) VariableSpecificRequest(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
path := strings.TrimPrefix(req.URL.Path, "/v1/var/")
if len(path) == 0 {
return nil, CodedError(http.StatusBadRequest, "missing secure variable path")
return nil, CodedError(http.StatusBadRequest, "missing variable path")
}
switch req.Method {
case http.MethodGet:
return s.secureVariableQuery(resp, req, path)
return s.variableQuery(resp, req, path)
case http.MethodPut, http.MethodPost:
return s.secureVariableUpsert(resp, req, path)
return s.variableUpsert(resp, req, path)
case http.MethodDelete:
return s.secureVariableDelete(resp, req, path)
return s.variableDelete(resp, req, path)
default:
return nil, CodedError(http.StatusBadRequest, ErrInvalidMethod)
}
}
func (s *HTTPServer) secureVariableQuery(resp http.ResponseWriter, req *http.Request,
func (s *HTTPServer) variableQuery(resp http.ResponseWriter, req *http.Request,
path string) (interface{}, error) {
args := structs.SecureVariablesReadRequest{
args := structs.VariablesReadRequest{
Path: path,
}
if s.parse(resp, req, &args.Region, &args.QueryOptions) {
return nil, nil
}
var out structs.SecureVariablesReadResponse
if err := s.agent.RPC(structs.SecureVariablesReadRPCMethod, &args, &out); err != nil {
var out structs.VariablesReadResponse
if err := s.agent.RPC(structs.VariablesReadRPCMethod, &args, &out); err != nil {
return nil, err
}
setMeta(resp, &out.QueryMeta)
if out.Data == nil {
return nil, CodedError(http.StatusNotFound, "secure variable not found")
return nil, CodedError(http.StatusNotFound, "variable not found")
}
return out.Data, nil
}
func (s *HTTPServer) secureVariableUpsert(resp http.ResponseWriter, req *http.Request,
func (s *HTTPServer) variableUpsert(resp http.ResponseWriter, req *http.Request,
path string) (interface{}, error) {
// Parse the SecureVariable
var SecureVariable structs.SecureVariableDecrypted
if err := decodeBody(req, &SecureVariable); err != nil {
// Parse the Variable
var Variable structs.VariableDecrypted
if err := decodeBody(req, &Variable); err != nil {
return nil, CodedError(http.StatusBadRequest, err.Error())
}
if len(SecureVariable.Items) == 0 {
return nil, CodedError(http.StatusBadRequest, "secure variable missing required Items object")
if len(Variable.Items) == 0 {
return nil, CodedError(http.StatusBadRequest, "variable missing required Items object")
}
SecureVariable.Path = path
Variable.Path = path
args := structs.SecureVariablesApplyRequest{
Op: structs.SVOpSet,
Var: &SecureVariable,
args := structs.VariablesApplyRequest{
Op: structs.VarOpSet,
Var: &Variable,
}
s.parseWriteRequest(req, &args.WriteRequest)
@@ -93,12 +93,12 @@ func (s *HTTPServer) secureVariableUpsert(resp http.ResponseWriter, req *http.Re
if isCas, checkIndex, err := parseCAS(req); err != nil {
return nil, err
} else if isCas {
args.Op = structs.SVOpCAS
args.Op = structs.VarOpCAS
args.Var.ModifyIndex = checkIndex
}
var out structs.SecureVariablesApplyResponse
if err := s.agent.RPC(structs.SecureVariablesApplyRPCMethod, &args, &out); err != nil {
var out structs.VariablesApplyResponse
if err := s.agent.RPC(structs.VariablesApplyRPCMethod, &args, &out); err != nil {
// This handles the cases where there is an error in the CAS checking
// function that renders it unable to return the conflicting variable
@@ -124,13 +124,13 @@ func (s *HTTPServer) secureVariableUpsert(resp http.ResponseWriter, req *http.Re
return out.Output, nil
}
func (s *HTTPServer) secureVariableDelete(resp http.ResponseWriter, req *http.Request,
func (s *HTTPServer) variableDelete(resp http.ResponseWriter, req *http.Request,
path string) (interface{}, error) {
args := structs.SecureVariablesApplyRequest{
Op: structs.SVOpDelete,
Var: &structs.SecureVariableDecrypted{
SecureVariableMetadata: structs.SecureVariableMetadata{
args := structs.VariablesApplyRequest{
Op: structs.VarOpDelete,
Var: &structs.VariableDecrypted{
VariableMetadata: structs.VariableMetadata{
Path: path,
},
},
@@ -141,12 +141,12 @@ func (s *HTTPServer) secureVariableDelete(resp http.ResponseWriter, req *http.Re
if isCas, checkIndex, err := parseCAS(req); err != nil {
return nil, err
} else if isCas {
args.Op = structs.SVOpDeleteCAS
args.Op = structs.VarOpDeleteCAS
args.Var.ModifyIndex = checkIndex
}
var out structs.SecureVariablesApplyResponse
if err := s.agent.RPC(structs.SecureVariablesApplyRPCMethod, &args, &out); err != nil {
var out structs.VariablesApplyResponse
if err := s.agent.RPC(structs.VariablesApplyRPCMethod, &args, &out); err != nil {
// This handles the cases where there is an error in the CAS checking
// function that renders it unable to return the conflicting variable

View File

@@ -25,7 +25,7 @@ var (
}
)
func TestHTTP_SecureVariables(t *testing.T) {
func TestHTTP_Variables(t *testing.T) {
ci.Parallel(t)
httpTest(t, cb, func(s *TestAgent) {
@@ -36,14 +36,14 @@ func TestHTTP_SecureVariables(t *testing.T) {
req, err := http.NewRequest("LOLWUT", "/v1/vars", nil)
require.NoError(t, err)
respW := httptest.NewRecorder()
_, err = s.Server.SecureVariablesListRequest(respW, req)
_, err = s.Server.VariablesListRequest(respW, req)
require.EqualError(t, err, ErrInvalidMethod)
})
t.Run("error_parse_list", func(t *testing.T) {
req, err := http.NewRequest("GET", "/v1/vars?wait=99a", nil)
require.NoError(t, err)
respW := httptest.NewRecorder()
_, _ = s.Server.SecureVariablesListRequest(respW, req)
_, _ = s.Server.VariablesListRequest(respW, req)
require.Equal(t, http.StatusBadRequest, respW.Code)
require.Equal(t, "Invalid wait time", string(respW.Body.Bytes()))
})
@@ -51,7 +51,7 @@ func TestHTTP_SecureVariables(t *testing.T) {
req, err := http.NewRequest("GET", "/v1/vars?region=bad", nil)
require.NoError(t, err)
respW := httptest.NewRecorder()
obj, err := s.Server.SecureVariablesListRequest(respW, req)
obj, err := s.Server.VariablesListRequest(respW, req)
require.EqualError(t, err, "No path to region")
require.Nil(t, obj)
})
@@ -62,11 +62,11 @@ func TestHTTP_SecureVariables(t *testing.T) {
respW := httptest.NewRecorder()
// Make the request
obj, err := s.Server.SecureVariablesListRequest(respW, req)
obj, err := s.Server.VariablesListRequest(respW, req)
require.NoError(t, err)
// add vars and test a populated backend
svMap := mock.SecureVariables(4, 4)
svMap := mock.Variables(4, 4)
svs := svMap.List()
svs[3].Path = svs[0].Path + "/child"
for _, sv := range svs {
@@ -79,7 +79,7 @@ func TestHTTP_SecureVariables(t *testing.T) {
respW = httptest.NewRecorder()
// Make the request
obj, err = s.Server.SecureVariablesListRequest(respW, req)
obj, err = s.Server.VariablesListRequest(respW, req)
require.NoError(t, err)
// Check for the index
@@ -88,7 +88,7 @@ func TestHTTP_SecureVariables(t *testing.T) {
require.NotZero(t, respW.HeaderMap.Get("X-Nomad-LastContact"))
// Check the output (the 4 we register )
require.Len(t, obj.([]*structs.SecureVariableMetadata), 4)
require.Len(t, obj.([]*structs.VariableMetadata), 4)
// test prefix query
req, err = http.NewRequest("GET", "/v1/vars?prefix="+svs[0].Path, nil)
@@ -96,9 +96,9 @@ func TestHTTP_SecureVariables(t *testing.T) {
respW = httptest.NewRecorder()
// Make the request
obj, err = s.Server.SecureVariablesListRequest(respW, req)
obj, err = s.Server.VariablesListRequest(respW, req)
require.NoError(t, err)
require.Len(t, obj.([]*structs.SecureVariableMetadata), 2)
require.Len(t, obj.([]*structs.VariableMetadata), 2)
})
rpcResetSV(s)
@@ -106,7 +106,7 @@ func TestHTTP_SecureVariables(t *testing.T) {
req, err := http.NewRequest("LOLWUT", "/v1/var/does/not/exist", nil)
require.NoError(t, err)
respW := httptest.NewRecorder()
obj, err := s.Server.SecureVariableSpecificRequest(respW, req)
obj, err := s.Server.VariableSpecificRequest(respW, req)
require.EqualError(t, err, ErrInvalidMethod)
require.Nil(t, obj)
})
@@ -114,7 +114,7 @@ func TestHTTP_SecureVariables(t *testing.T) {
req, err := http.NewRequest("GET", "/v1/var/does/not/exist?wait=99a", nil)
require.NoError(t, err)
respW := httptest.NewRecorder()
_, _ = s.Server.SecureVariableSpecificRequest(respW, req)
_, _ = s.Server.VariableSpecificRequest(respW, req)
require.Equal(t, http.StatusBadRequest, respW.Code)
require.Equal(t, "Invalid wait time", string(respW.Body.Bytes()))
})
@@ -122,7 +122,7 @@ func TestHTTP_SecureVariables(t *testing.T) {
req, err := http.NewRequest("GET", "/v1/var/does/not/exist?region=bad", nil)
require.NoError(t, err)
respW := httptest.NewRecorder()
obj, err := s.Server.SecureVariableSpecificRequest(respW, req)
obj, err := s.Server.VariableSpecificRequest(respW, req)
require.EqualError(t, err, "No path to region")
require.Nil(t, obj)
})
@@ -131,8 +131,8 @@ func TestHTTP_SecureVariables(t *testing.T) {
req, err := http.NewRequest("GET", "/v1/var/", nil)
require.NoError(t, err)
respW := httptest.NewRecorder()
obj, err := s.Server.SecureVariableSpecificRequest(respW, req)
require.EqualError(t, err, "missing secure variable path")
obj, err := s.Server.VariableSpecificRequest(respW, req)
require.EqualError(t, err, "missing variable path")
require.Nil(t, obj)
})
t.Run("query_unset_variable", func(t *testing.T) {
@@ -140,21 +140,21 @@ func TestHTTP_SecureVariables(t *testing.T) {
req, err := http.NewRequest("GET", "/v1/var/not/real", nil)
require.NoError(t, err)
respW := httptest.NewRecorder()
obj, err := s.Server.SecureVariableSpecificRequest(respW, req)
require.EqualError(t, err, "secure variable not found")
obj, err := s.Server.VariableSpecificRequest(respW, req)
require.EqualError(t, err, "variable not found")
require.Nil(t, obj)
})
t.Run("query", func(t *testing.T) {
// Use RPC to make a test variable
out := new(structs.SecureVariableDecrypted)
sv1 := mock.SecureVariable()
out := new(structs.VariableDecrypted)
sv1 := mock.Variable()
require.NoError(t, rpcWriteSV(s, sv1, out))
// Query a variable
req, err := http.NewRequest("GET", "/v1/var/"+sv1.Path, nil)
require.NoError(t, err)
respW := httptest.NewRecorder()
obj, err := s.Server.SecureVariableSpecificRequest(respW, req)
obj, err := s.Server.VariableSpecificRequest(respW, req)
require.NoError(t, err)
// Check for the index
@@ -163,17 +163,17 @@ func TestHTTP_SecureVariables(t *testing.T) {
require.NotZero(t, respW.HeaderMap.Get("X-Nomad-LastContact"))
// Check the output
require.Equal(t, out, obj.(*structs.SecureVariableDecrypted))
require.Equal(t, out, obj.(*structs.VariableDecrypted))
})
rpcResetSV(s)
sv1 := mock.SecureVariable()
sv1 := mock.Variable()
t.Run("error_parse_create", func(t *testing.T) {
buf := encodeBrokenReq(&sv1)
req, err := http.NewRequest("PUT", "/v1/var/"+sv1.Path, buf)
require.NoError(t, err)
respW := httptest.NewRecorder()
obj, err := s.Server.SecureVariableSpecificRequest(respW, req)
obj, err := s.Server.VariableSpecificRequest(respW, req)
require.EqualError(t, err, "unexpected EOF")
require.Nil(t, obj)
})
@@ -182,7 +182,7 @@ func TestHTTP_SecureVariables(t *testing.T) {
req, err := http.NewRequest("PUT", "/v1/var/does/not/exist?region=bad", buf)
require.NoError(t, err)
respW := httptest.NewRecorder()
obj, err := s.Server.SecureVariableSpecificRequest(respW, req)
obj, err := s.Server.VariableSpecificRequest(respW, req)
require.EqualError(t, err, "No path to region")
require.Nil(t, obj)
})
@@ -193,8 +193,8 @@ func TestHTTP_SecureVariables(t *testing.T) {
req, err := http.NewRequest("PUT", "/v1/var/"+sv1.Path, buf)
require.NoError(t, err)
respW := httptest.NewRecorder()
obj, err := s.Server.SecureVariableSpecificRequest(respW, req)
require.EqualError(t, err, "secure variable missing required Items object")
obj, err := s.Server.VariableSpecificRequest(respW, req)
require.EqualError(t, err, "variable missing required Items object")
require.Nil(t, obj)
})
t.Run("create", func(t *testing.T) {
@@ -202,13 +202,13 @@ func TestHTTP_SecureVariables(t *testing.T) {
req, err := http.NewRequest("PUT", "/v1/var/"+sv1.Path, buf)
require.NoError(t, err)
respW := httptest.NewRecorder()
obj, err := s.Server.SecureVariableSpecificRequest(respW, req)
obj, err := s.Server.VariableSpecificRequest(respW, req)
require.NoError(t, err)
// Test the returned object and rehydrate to a SecureVariableDecrypted
// Test the returned object and rehydrate to a VariableDecrypted
require.NotNil(t, obj)
sv1, ok := obj.(*structs.SecureVariableDecrypted)
require.True(t, ok, "Unable to convert obj to SecureVariableDecrypted")
sv1, ok := obj.(*structs.VariableDecrypted)
require.True(t, ok, "Unable to convert obj to VariableDecrypted")
// Check for the index
require.NotZero(t, respW.HeaderMap.Get("X-Nomad-Index"))
@@ -235,7 +235,7 @@ func TestHTTP_SecureVariables(t *testing.T) {
respW := httptest.NewRecorder()
// Make the request
obj, err := s.Server.SecureVariableSpecificRequest(respW, req)
obj, err := s.Server.VariableSpecificRequest(respW, req)
require.EqualError(t, err, "unexpected EOF")
var cErr HTTPCodedError
require.ErrorAs(t, err, &cErr)
@@ -253,12 +253,12 @@ func TestHTTP_SecureVariables(t *testing.T) {
respW := httptest.NewRecorder()
// Make the request
obj, err := s.Server.SecureVariableSpecificRequest(respW, req)
obj, err := s.Server.VariableSpecificRequest(respW, req)
require.EqualError(t, err, "No path to region")
require.Nil(t, obj)
})
t.Run("update", func(t *testing.T) {
sv := mock.SecureVariable()
sv := mock.Variable()
require.NoError(t, rpcWriteSV(s, sv, sv))
svU := sv.Copy()
@@ -270,13 +270,13 @@ func TestHTTP_SecureVariables(t *testing.T) {
respW := httptest.NewRecorder()
// Make the request
obj, err := s.Server.SecureVariableSpecificRequest(respW, req)
obj, err := s.Server.VariableSpecificRequest(respW, req)
require.NoError(t, err)
// Test the returned object and rehydrate to a SecureVariableDecrypted
// Test the returned object and rehydrate to a VariableDecrypted
require.NotNil(t, obj)
out, ok := obj.(*structs.SecureVariableDecrypted)
require.True(t, ok, "Unable to convert obj to SecureVariableDecrypted")
out, ok := obj.(*structs.VariableDecrypted)
require.True(t, ok, "Unable to convert obj to VariableDecrypted")
// Check for the index
require.NotZero(t, respW.HeaderMap.Get("X-Nomad-Index"))
@@ -284,7 +284,7 @@ func TestHTTP_SecureVariables(t *testing.T) {
{
// Check that written varible does not equal the input to rule out input mutation
require.NotEqual(t, &svU.SecureVariableMetadata, out.SecureVariableMetadata)
require.NotEqual(t, &svU.VariableMetadata, out.VariableMetadata)
// Update the input token with the updated metadata so that we
// can use a simple equality check
@@ -294,7 +294,7 @@ func TestHTTP_SecureVariables(t *testing.T) {
}
})
t.Run("update-cas", func(t *testing.T) {
sv := mock.SecureVariable()
sv := mock.Variable()
require.NoError(t, rpcWriteSV(s, sv, sv))
svU := sv.Copy()
@@ -308,14 +308,14 @@ func TestHTTP_SecureVariables(t *testing.T) {
respW := httptest.NewRecorder()
// Make the request
obj, err := s.Server.SecureVariableSpecificRequest(respW, req)
obj, err := s.Server.VariableSpecificRequest(respW, req)
require.NoError(t, err)
require.Equal(t, http.StatusConflict, respW.Result().StatusCode)
// Evaluate the conflict variable
require.NotNil(t, obj)
conflict, ok := obj.(*structs.SecureVariableDecrypted)
require.True(t, ok, "Expected *structs.SecureVariableDecrypted, got %T", obj)
conflict, ok := obj.(*structs.VariableDecrypted)
require.True(t, ok, "Expected *structs.VariableDecrypted, got %T", obj)
require.Equal(t, conflict, sv)
// Check for the index
@@ -335,13 +335,13 @@ func TestHTTP_SecureVariables(t *testing.T) {
respW := httptest.NewRecorder()
// Make the request
obj, err := s.Server.SecureVariableSpecificRequest(respW, req)
obj, err := s.Server.VariableSpecificRequest(respW, req)
require.NoError(t, err)
// Test the returned object and rehydrate to a SecureVariableDecrypted
// Test the returned object and rehydrate to a VariableDecrypted
require.NotNil(t, obj)
sv1, ok := obj.(*structs.SecureVariableDecrypted)
require.True(t, ok, "Unable to convert obj to SecureVariableDecrypted")
sv1, ok := obj.(*structs.VariableDecrypted)
require.True(t, ok, "Unable to convert obj to VariableDecrypted")
// Check for the index
require.NotZero(t, respW.HeaderMap.Get("X-Nomad-Index"))
@@ -362,13 +362,13 @@ func TestHTTP_SecureVariables(t *testing.T) {
require.NotNil(t, out)
require.NotEqual(t, sv, out)
require.NotEqual(t, svU.SecureVariableMetadata, out.SecureVariableMetadata)
require.NotEqual(t, svU.VariableMetadata, out.VariableMetadata)
// Update the input token with the updated metadata so that we
// can use a simple equality check
svU.CreateIndex, svU.ModifyIndex = out.CreateIndex, out.ModifyIndex
svU.CreateTime, svU.ModifyTime = out.CreateTime, out.ModifyTime
require.Equal(t, svU.SecureVariableMetadata, out.SecureVariableMetadata)
require.Equal(t, svU.VariableMetadata, out.VariableMetadata)
// fmt writes sorted output of maps for testability.
require.Equal(t, fmt.Sprint(svU.Items), fmt.Sprint(out.Items))
@@ -377,7 +377,7 @@ func TestHTTP_SecureVariables(t *testing.T) {
rpcResetSV(s)
t.Run("error_rpc_delete", func(t *testing.T) {
sv1 := mock.SecureVariable()
sv1 := mock.Variable()
require.NoError(t, rpcWriteSV(s, sv1, nil))
// Make the HTTP request
@@ -386,12 +386,12 @@ func TestHTTP_SecureVariables(t *testing.T) {
respW := httptest.NewRecorder()
// Make the request
obj, err := s.Server.SecureVariableSpecificRequest(respW, req)
obj, err := s.Server.VariableSpecificRequest(respW, req)
require.EqualError(t, err, "No path to region")
require.Nil(t, obj)
})
t.Run("delete-cas", func(t *testing.T) {
sv := mock.SecureVariable()
sv := mock.Variable()
require.NoError(t, rpcWriteSV(s, sv, nil))
sv, err := rpcReadSV(s, sv.Namespace, sv.Path)
require.NoError(t, err)
@@ -403,14 +403,14 @@ func TestHTTP_SecureVariables(t *testing.T) {
respW := httptest.NewRecorder()
// Make the request
obj, err := s.Server.SecureVariableSpecificRequest(respW, req)
obj, err := s.Server.VariableSpecificRequest(respW, req)
require.NoError(t, err)
require.Equal(t, http.StatusConflict, respW.Result().StatusCode)
// Evaluate the conflict variable
require.NotNil(t, obj)
conflict, ok := obj.(*structs.SecureVariableDecrypted)
require.True(t, ok, "Expected *structs.SecureVariableDecrypted, got %T", obj)
conflict, ok := obj.(*structs.VariableDecrypted)
require.True(t, ok, "Expected *structs.VariableDecrypted, got %T", obj)
require.True(t, sv.Equals(*conflict))
// Check for the index
@@ -431,7 +431,7 @@ func TestHTTP_SecureVariables(t *testing.T) {
respW := httptest.NewRecorder()
// Make the request
obj, err := s.Server.SecureVariableSpecificRequest(respW, req)
obj, err := s.Server.VariableSpecificRequest(respW, req)
require.NoError(t, err)
require.Nil(t, obj)
}
@@ -443,7 +443,7 @@ func TestHTTP_SecureVariables(t *testing.T) {
}
})
t.Run("delete", func(t *testing.T) {
sv1 := mock.SecureVariable()
sv1 := mock.Variable()
require.NoError(t, rpcWriteSV(s, sv1, nil))
// Make the HTTP request
@@ -452,7 +452,7 @@ func TestHTTP_SecureVariables(t *testing.T) {
respW := httptest.NewRecorder()
// Make the request
obj, err := s.Server.SecureVariableSpecificRequest(respW, req)
obj, err := s.Server.VariableSpecificRequest(respW, req)
require.NoError(t, err)
require.Nil(t, obj)
@@ -479,25 +479,25 @@ func encodeBrokenReq(obj interface{}) io.ReadCloser {
return ioutil.NopCloser(bytes.NewReader(b))
}
// rpcReadSV lets this test read a secure variable using the RPC endpoint
func rpcReadSV(s *TestAgent, ns, p string) (*structs.SecureVariableDecrypted, error) {
checkArgs := structs.SecureVariablesReadRequest{Path: p, QueryOptions: structs.QueryOptions{Namespace: ns, Region: "global"}}
var checkResp structs.SecureVariablesReadResponse
err := s.Agent.RPC(structs.SecureVariablesReadRPCMethod, &checkArgs, &checkResp)
// rpcReadSV lets this test read a variable using the RPC endpoint
func rpcReadSV(s *TestAgent, ns, p string) (*structs.VariableDecrypted, error) {
checkArgs := structs.VariablesReadRequest{Path: p, QueryOptions: structs.QueryOptions{Namespace: ns, Region: "global"}}
var checkResp structs.VariablesReadResponse
err := s.Agent.RPC(structs.VariablesReadRPCMethod, &checkArgs, &checkResp)
return checkResp.Data, err
}
// rpcWriteSV lets this test write a secure variable using the RPC endpoint
func rpcWriteSV(s *TestAgent, sv, out *structs.SecureVariableDecrypted) error {
// rpcWriteSV lets this test write a variable using the RPC endpoint
func rpcWriteSV(s *TestAgent, sv, out *structs.VariableDecrypted) error {
args := structs.SecureVariablesApplyRequest{
Op: structs.SVOpSet,
args := structs.VariablesApplyRequest{
Op: structs.VarOpSet,
Var: sv,
WriteRequest: structs.WriteRequest{Namespace: sv.Namespace, Region: "global"},
}
var resp structs.SecureVariablesApplyResponse
err := s.Agent.RPC(structs.SecureVariablesApplyRPCMethod, &args, &resp)
var resp structs.VariablesApplyResponse
err := s.Agent.RPC(structs.VariablesApplyRPCMethod, &args, &resp)
if err != nil {
return err
}
@@ -507,39 +507,39 @@ func rpcWriteSV(s *TestAgent, sv, out *structs.SecureVariableDecrypted) error {
return nil
}
// rpcResetSV lists all the secure variables for every namespace in the global
// rpcResetSV lists all the variables for every namespace in the global
// region and deletes them using the RPC endpoints
func rpcResetSV(s *TestAgent) {
var lArgs structs.SecureVariablesListRequest
var lResp structs.SecureVariablesListResponse
var lArgs structs.VariablesListRequest
var lResp structs.VariablesListResponse
lArgs = structs.SecureVariablesListRequest{
lArgs = structs.VariablesListRequest{
QueryOptions: structs.QueryOptions{
Namespace: "*",
Region: "global",
},
}
err := s.Agent.RPC(structs.SecureVariablesListRPCMethod, &lArgs, &lResp)
err := s.Agent.RPC(structs.VariablesListRPCMethod, &lArgs, &lResp)
require.NoError(s.T, err)
dArgs := structs.SecureVariablesApplyRequest{
Op: structs.SVOpDelete,
Var: &structs.SecureVariableDecrypted{},
dArgs := structs.VariablesApplyRequest{
Op: structs.VarOpDelete,
Var: &structs.VariableDecrypted{},
WriteRequest: structs.WriteRequest{
Region: "global",
},
}
var dResp structs.SecureVariablesApplyResponse
var dResp structs.VariablesApplyResponse
for _, v := range lResp.Data {
dArgs.Var.Path = v.Path
dArgs.Var.Namespace = v.Namespace
err := s.Agent.RPC(structs.SecureVariablesApplyRPCMethod, &dArgs, &dResp)
err := s.Agent.RPC(structs.VariablesApplyRPCMethod, &dArgs, &dResp)
require.NoError(s.T, err)
}
err = s.Agent.RPC(structs.SecureVariablesListRPCMethod, &lArgs, &lResp)
err = s.Agent.RPC(structs.VariablesListRPCMethod, &lArgs, &lResp)
require.NoError(s.T, err)
require.Equal(s.T, 0, len(lResp.Data))
}

View File

@@ -619,28 +619,28 @@ func Commands(metaPtr *Meta, agentUi cli.Ui) map[string]cli.CommandFactory {
Meta: meta,
}, nil
},
"operator secure-variables keyring": func() (cli.Command, error) {
return &OperatorSecureVariablesKeyringCommand{
"operator root keyring": func() (cli.Command, error) {
return &OperatorRootKeyringCommand{
Meta: meta,
}, nil
},
"operator secure-variables keyring install": func() (cli.Command, error) {
return &OperatorSecureVariablesKeyringInstallCommand{
"operator root keyring install": func() (cli.Command, error) {
return &OperatorRootKeyringInstallCommand{
Meta: meta,
}, nil
},
"operator secure-variables keyring list": func() (cli.Command, error) {
return &OperatorSecureVariablesKeyringListCommand{
"operator root keyring list": func() (cli.Command, error) {
return &OperatorRootKeyringListCommand{
Meta: meta,
}, nil
},
"operator secure-variables keyring remove": func() (cli.Command, error) {
return &OperatorSecureVariablesKeyringRemoveCommand{
"operator root keyring remove": func() (cli.Command, error) {
return &OperatorRootKeyringRemoveCommand{
Meta: meta,
}, nil
},
"operator secure-variables keyring rotate": func() (cli.Command, error) {
return &OperatorSecureVariablesKeyringRotateCommand{
"operator root keyring rotate": func() (cli.Command, error) {
return &OperatorRootKeyringRotateCommand{
Meta: meta,
}, nil
},

View File

@@ -10,67 +10,67 @@ import (
"github.com/hashicorp/nomad/api"
)
// OperatorSecureVariablesKeyringCommand is a Command implementation
// that handles querying, installing, and removing secure variables
// OperatorRootKeyringCommand is a Command implementation
// that handles querying, installing, and removing root
// encryption keys from a keyring.
type OperatorSecureVariablesKeyringCommand struct {
type OperatorRootKeyringCommand struct {
Meta
}
func (c *OperatorSecureVariablesKeyringCommand) Help() string {
func (c *OperatorRootKeyringCommand) Help() string {
helpText := `
Usage: nomad operator secure-variables keyring [options]
Usage: nomad operator root keyring [options]
Manages encryption keys used for storing secure variables. This command may be
used to examine active encryption keys in the cluster, rotate keys, add new
keys from backups, or remove unused keys.
Manages encryption keys used for storing variables and signing workload
identities. This command may be used to examine active encryption keys
in the cluster, rotate keys, add new keys from backups, or remove unused keys.
If ACLs are enabled, all subcommands requires a management token.
Rotate the encryption key:
$ nomad operator secure-variables keyring rotate
$ nomad operator root keyring rotate
List all encryption key metadata:
$ nomad operator secure-variables keyring list
$ nomad operator root keyring list
Remove an encryption key from the keyring:
$ nomad operator secure-variables keyring remove <key ID>
$ nomad operator root keyring remove <key ID>
Install an encryption key from backup:
$ nomad operator secure-variables keyring install <path to .json file>
$ nomad operator root keyring install <path to .json file>
Please see individual subcommand help for detailed usage information.
`
return strings.TrimSpace(helpText)
}
func (c *OperatorSecureVariablesKeyringCommand) Synopsis() string {
return "Manages secure variables encryption keys"
func (c *OperatorRootKeyringCommand) Synopsis() string {
return "Manages root encryption keys"
}
func (c *OperatorSecureVariablesKeyringCommand) AutocompleteFlags() complete.Flags {
func (c *OperatorRootKeyringCommand) AutocompleteFlags() complete.Flags {
return c.Meta.AutocompleteFlags(FlagSetClient)
}
func (c *OperatorSecureVariablesKeyringCommand) AutocompleteArgs() complete.Predictor {
func (c *OperatorRootKeyringCommand) AutocompleteArgs() complete.Predictor {
return complete.PredictNothing
}
func (c *OperatorSecureVariablesKeyringCommand) Name() string {
return "secure-variables keyring"
func (c *OperatorRootKeyringCommand) Name() string {
return "root keyring"
}
func (c *OperatorSecureVariablesKeyringCommand) Run(args []string) int {
func (c *OperatorRootKeyringCommand) Run(args []string) int {
return cli.RunResultHelp
}
// renderSecureVariablesKeysResponse is a helper for formatting the
// renderVariablesKeysResponse is a helper for formatting the
// keyring API responses
func renderSecureVariablesKeysResponse(keys []*api.RootKeyMeta, verbose bool) string {
func renderVariablesKeysResponse(keys []*api.RootKeyMeta, verbose bool) string {
length := fullId
if !verbose {
length = 8

View File

@@ -12,18 +12,18 @@ import (
"github.com/posener/complete"
)
// OperatorSecureVariablesKeyringInstallCommand is a Command
// implementation that handles installing secure variables encryption
// OperatorRootKeyringInstallCommand is a Command
// implementation that handles installing variables encryption
// keys from a keyring.
type OperatorSecureVariablesKeyringInstallCommand struct {
type OperatorRootKeyringInstallCommand struct {
Meta
}
func (c *OperatorSecureVariablesKeyringInstallCommand) Help() string {
func (c *OperatorRootKeyringInstallCommand) Help() string {
helpText := `
Usage: nomad operator secure-variables keyring install [options] <filepath>
Usage: nomad operator root keyring install [options] <filepath>
Install a new encryption key used for storing secure variables and workload
Install a new encryption key used for storing variables and workload
identity signing. The key file must be a JSON file previously written by Nomad
to the keystore. The key file will be read from stdin by specifying "-",
otherwise a path to the file is expected.
@@ -37,26 +37,26 @@ General Options:
return strings.TrimSpace(helpText)
}
func (c *OperatorSecureVariablesKeyringInstallCommand) Synopsis() string {
return "Installs a secure variables encryption key"
func (c *OperatorRootKeyringInstallCommand) Synopsis() string {
return "Installs a root encryption key"
}
func (c *OperatorSecureVariablesKeyringInstallCommand) AutocompleteFlags() complete.Flags {
func (c *OperatorRootKeyringInstallCommand) AutocompleteFlags() complete.Flags {
return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient),
complete.Flags{
"-verbose": complete.PredictNothing,
})
}
func (c *OperatorSecureVariablesKeyringInstallCommand) AutocompleteArgs() complete.Predictor {
func (c *OperatorRootKeyringInstallCommand) AutocompleteArgs() complete.Predictor {
return complete.PredictFiles("*.json")
}
func (c *OperatorSecureVariablesKeyringInstallCommand) Name() string {
return "secure-variables keyring install"
func (c *OperatorRootKeyringInstallCommand) Name() string {
return "root keyring install"
}
func (c *OperatorSecureVariablesKeyringInstallCommand) Run(args []string) int {
flags := c.Meta.FlagSet("secure-variables keyring install", FlagSetClient)
func (c *OperatorRootKeyringInstallCommand) Run(args []string) int {
flags := c.Meta.FlagSet("root keyring install", FlagSetClient)
flags.Usage = func() { c.Ui.Output(c.Help()) }
if err := flags.Parse(args); err != nil {

View File

@@ -7,15 +7,15 @@ import (
"github.com/posener/complete"
)
// OperatorSecureVariablesKeyringListCommand is a Command
// implementation that lists the secure variables encryption keys.
type OperatorSecureVariablesKeyringListCommand struct {
// OperatorRootKeyringListCommand is a Command
// implementation that lists the variables encryption keys.
type OperatorRootKeyringListCommand struct {
Meta
}
func (c *OperatorSecureVariablesKeyringListCommand) Help() string {
func (c *OperatorRootKeyringListCommand) Help() string {
helpText := `
Usage: nomad operator secure-variables keyring list [options]
Usage: nomad operator root keyring list [options]
List the currently installed keys. This list returns key metadata and not
sensitive key material.
@@ -35,29 +35,29 @@ Keyring Options:
return strings.TrimSpace(helpText)
}
func (c *OperatorSecureVariablesKeyringListCommand) Synopsis() string {
return "Lists the secure variables encryption keys"
func (c *OperatorRootKeyringListCommand) Synopsis() string {
return "Lists the root encryption keys"
}
func (c *OperatorSecureVariablesKeyringListCommand) AutocompleteFlags() complete.Flags {
func (c *OperatorRootKeyringListCommand) AutocompleteFlags() complete.Flags {
return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient),
complete.Flags{
"-verbose": complete.PredictNothing,
})
}
func (c *OperatorSecureVariablesKeyringListCommand) AutocompleteArgs() complete.Predictor {
func (c *OperatorRootKeyringListCommand) AutocompleteArgs() complete.Predictor {
return complete.PredictNothing
}
func (c *OperatorSecureVariablesKeyringListCommand) Name() string {
return "secure-variables keyring list"
func (c *OperatorRootKeyringListCommand) Name() string {
return "root keyring list"
}
func (c *OperatorSecureVariablesKeyringListCommand) Run(args []string) int {
func (c *OperatorRootKeyringListCommand) Run(args []string) int {
var verbose bool
flags := c.Meta.FlagSet("secure-variables keyring list", FlagSetClient)
flags := c.Meta.FlagSet("root keyring list", FlagSetClient)
flags.Usage = func() { c.Ui.Output(c.Help()) }
flags.BoolVar(&verbose, "verbose", false, "")
@@ -83,6 +83,6 @@ func (c *OperatorSecureVariablesKeyringListCommand) Run(args []string) int {
c.Ui.Error(fmt.Sprintf("error: %s", err))
return 1
}
c.Ui.Output(renderSecureVariablesKeysResponse(resp, verbose))
c.Ui.Output(renderVariablesKeysResponse(resp, verbose))
return 0
}

View File

@@ -8,16 +8,16 @@ import (
"github.com/posener/complete"
)
// OperatorSecureVariablesKeyringRemoveCommand is a Command
// implementation that handles removeing secure variables encryption
// OperatorRootKeyringRemoveCommand is a Command
// implementation that handles removeing variables encryption
// keys from a keyring.
type OperatorSecureVariablesKeyringRemoveCommand struct {
type OperatorRootKeyringRemoveCommand struct {
Meta
}
func (c *OperatorSecureVariablesKeyringRemoveCommand) Help() string {
func (c *OperatorRootKeyringRemoveCommand) Help() string {
helpText := `
Usage: nomad operator secure-variables keyring remove [options] <key ID>
Usage: nomad operator root keyring remove [options] <key ID>
Remove an encryption key from the cluster. This operation may only be
performed on keys that are not the active key.
@@ -31,26 +31,26 @@ General Options:
return strings.TrimSpace(helpText)
}
func (c *OperatorSecureVariablesKeyringRemoveCommand) Synopsis() string {
return "Removes a secure variables encryption key"
func (c *OperatorRootKeyringRemoveCommand) Synopsis() string {
return "Removes a root encryption key"
}
func (c *OperatorSecureVariablesKeyringRemoveCommand) AutocompleteFlags() complete.Flags {
func (c *OperatorRootKeyringRemoveCommand) AutocompleteFlags() complete.Flags {
return c.Meta.AutocompleteFlags(FlagSetClient)
}
func (c *OperatorSecureVariablesKeyringRemoveCommand) AutocompleteArgs() complete.Predictor {
func (c *OperatorRootKeyringRemoveCommand) AutocompleteArgs() complete.Predictor {
return complete.PredictAnything
}
func (c *OperatorSecureVariablesKeyringRemoveCommand) Name() string {
return "secure-variables keyring remove"
func (c *OperatorRootKeyringRemoveCommand) Name() string {
return "root keyring remove"
}
func (c *OperatorSecureVariablesKeyringRemoveCommand) Run(args []string) int {
func (c *OperatorRootKeyringRemoveCommand) Run(args []string) int {
var verbose bool
flags := c.Meta.FlagSet("secure-variables keyring remove", FlagSetClient)
flags := c.Meta.FlagSet("root keyring remove", FlagSetClient)
flags.Usage = func() { c.Ui.Output(c.Help()) }
flags.BoolVar(&verbose, "verbose", false, "")

View File

@@ -8,15 +8,15 @@ import (
"github.com/posener/complete"
)
// OperatorSecureVariablesKeyringRotateCommand is a Command
// implementation that rotates the secure variables encryption key.
type OperatorSecureVariablesKeyringRotateCommand struct {
// OperatorRootKeyringRotateCommand is a Command
// implementation that rotates the variables encryption key.
type OperatorRootKeyringRotateCommand struct {
Meta
}
func (c *OperatorSecureVariablesKeyringRotateCommand) Help() string {
func (c *OperatorRootKeyringRotateCommand) Help() string {
helpText := `
Usage: nomad operator secure-variables keyring rotate [options]
Usage: nomad operator root keyring rotate [options]
Generate a new encryption key for all future variables.
@@ -40,11 +40,11 @@ Keyring Options:
return strings.TrimSpace(helpText)
}
func (c *OperatorSecureVariablesKeyringRotateCommand) Synopsis() string {
return "Rotates the secure variables encryption key"
func (c *OperatorRootKeyringRotateCommand) Synopsis() string {
return "Rotates the root encryption key"
}
func (c *OperatorSecureVariablesKeyringRotateCommand) AutocompleteFlags() complete.Flags {
func (c *OperatorRootKeyringRotateCommand) AutocompleteFlags() complete.Flags {
return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient),
complete.Flags{
"-full": complete.PredictNothing,
@@ -52,18 +52,18 @@ func (c *OperatorSecureVariablesKeyringRotateCommand) AutocompleteFlags() comple
})
}
func (c *OperatorSecureVariablesKeyringRotateCommand) AutocompleteArgs() complete.Predictor {
func (c *OperatorRootKeyringRotateCommand) AutocompleteArgs() complete.Predictor {
return complete.PredictNothing
}
func (c *OperatorSecureVariablesKeyringRotateCommand) Name() string {
return "secure-variables keyring rotate"
func (c *OperatorRootKeyringRotateCommand) Name() string {
return "root keyring rotate"
}
func (c *OperatorSecureVariablesKeyringRotateCommand) Run(args []string) int {
func (c *OperatorRootKeyringRotateCommand) Run(args []string) int {
var rotateFull, verbose bool
flags := c.Meta.FlagSet("secure-variables keyring rotate", FlagSetClient)
flags := c.Meta.FlagSet("root keyring rotate", FlagSetClient)
flags.Usage = func() { c.Ui.Output(c.Help()) }
flags.BoolVar(&rotateFull, "full", false, "full key rotation")
flags.BoolVar(&verbose, "verbose", false, "")
@@ -91,6 +91,6 @@ func (c *OperatorSecureVariablesKeyringRotateCommand) Run(args []string) int {
c.Ui.Error(fmt.Sprintf("error: %s", err))
return 1
}
c.Ui.Output(renderSecureVariablesKeysResponse([]*api.RootKeyMeta{resp}, verbose))
c.Ui.Output(renderVariablesKeysResponse([]*api.RootKeyMeta{resp}, verbose))
return 0
}

View File

@@ -198,7 +198,7 @@ func parseQuotaLimits(result *[]*api.QuotaLimit, list *ast.ObjectList) error {
valid := []string{
"region",
"region_limit",
"secure_variables_limit",
"variables_limit",
}
if err := helper.CheckHCLKeys(o.Val, valid); err != nil {
return err

View File

@@ -121,7 +121,7 @@ limit {
memory = 1000
memory_max = 1000
}
secure_variables_limit = 1000
variables_limit = 1000
}
`)
@@ -137,7 +137,7 @@ var defaultJsonQuotaSpec = strings.TrimSpace(`
"MemoryMB": 1000,
"MemoryMaxMB": 1000
},
"SecureVariablesLimit": 1000
"VariablesLimit": 1000
}
]
}

View File

@@ -158,7 +158,7 @@ func formatQuotaLimits(spec *api.QuotaSpec, usages map[string]*api.QuotaUsage) s
sort.Sort(api.QuotaLimitSort(spec.Limits))
limits := make([]string, len(spec.Limits)+1)
limits[0] = "Region|CPU Usage|Memory Usage|Memory Max Usage|Network Usage|Secure Variables Usage"
limits[0] = "Region|CPU Usage|Memory Usage|Memory Max Usage|Network Usage|Variables Usage"
i := 0
for _, specLimit := range spec.Limits {
i++
@@ -186,7 +186,7 @@ func formatQuotaLimits(spec *api.QuotaSpec, usages map[string]*api.QuotaUsage) s
memoryMax := fmt.Sprintf("- / %s", formatQuotaLimitInt(specLimit.RegionLimit.MemoryMaxMB))
net := fmt.Sprintf("- / %s", formatQuotaLimitInt(&specBits))
vars := fmt.Sprintf("- / %s", formatQuotaLimitInt(specLimit.SecureVariablesLimit))
vars := fmt.Sprintf("- / %s", formatQuotaLimitInt(specLimit.VariablesLimit))
limits[i] = fmt.Sprintf("%s|%s|%s|%s|%s|%s", specLimit.Region, cpu, memory, memoryMax, net, vars)
continue
}
@@ -207,7 +207,7 @@ func formatQuotaLimits(spec *api.QuotaSpec, usages map[string]*api.QuotaUsage) s
net = fmt.Sprintf("%d / %s", *used.RegionLimit.Networks[0].MBits, formatQuotaLimitInt(&specBits))
}
vars := fmt.Sprintf("%d / %s", orZero(used.SecureVariablesLimit), formatQuotaLimitInt(specLimit.SecureVariablesLimit))
vars := fmt.Sprintf("%d / %s", orZero(used.VariablesLimit), formatQuotaLimitInt(specLimit.VariablesLimit))
limits[i] = fmt.Sprintf("%s|%s|%s|%s|%s|%s", specLimit.Region, cpu, memory, memoryMax, net, vars)
}

View File

@@ -16,28 +16,28 @@ func (f *VarCommand) Help() string {
helpText := `
Usage: nomad var <subcommand> [options] [args]
This command groups subcommands for interacting with secure variables. Secure
variables allow operators to provide credentials and otherwise sensitive
material to Nomad jobs at runtime via the template stanza or directly through
This command groups subcommands for interacting with variables. Variables
allow operators to provide credentials and otherwise sensitive material to
Nomad jobs at runtime via the template stanza or directly through
the Nomad API and CLI.
Users can create new secure variables; list, inspect, and delete existing
secure variables, and more. For a full guide on secure variables see:
Users can create new variables; list, inspect, and delete existing
variables, and more. For a full guide on variables see:
https://www.nomadproject.io/guides/vars.html
Create a secure variable specification file:
Create a variable specification file:
$ nomad var init
Upsert a secure variable:
Upsert a variable:
$ nomad var put <path>
Examine a secure variable:
Examine a variable:
$ nomad var get <path>
List existing secure variables:
List existing variables:
$ nomad var list <prefix>
@@ -48,7 +48,7 @@ Usage: nomad var <subcommand> [options] [args]
}
func (f *VarCommand) Synopsis() string {
return "Interact with secure variables"
return "Interact with variables"
}
func (f *VarCommand) Name() string { return "var" }
@@ -57,18 +57,18 @@ func (f *VarCommand) Run(args []string) int {
return cli.RunResultHelp
}
// SecureVariablePathPredictor returns a var predictor
func SecureVariablePathPredictor(factory ApiClientFactory) complete.Predictor {
// VariablePathPredictor returns a var predictor
func VariablePathPredictor(factory ApiClientFactory) complete.Predictor {
return complete.PredictFunc(func(a complete.Args) []string {
client, err := factory()
if err != nil {
return nil
}
resp, _, err := client.Search().PrefixSearch(a.Last, contexts.SecureVariables, nil)
resp, _, err := client.Search().PrefixSearch(a.Last, contexts.Variables, nil)
if err != nil {
return []string{}
}
return resp.Matches[contexts.SecureVariables]
return resp.Matches[contexts.Variables]
})
}

View File

@@ -21,7 +21,7 @@ const (
DefaultJsonVarInitName = "spec.nsv.json"
)
// VarInitCommand generates a new secure variable specification
// VarInitCommand generates a new variable specification
type VarInitCommand struct {
Meta
}
@@ -30,14 +30,14 @@ func (c *VarInitCommand) Help() string {
helpText := `
Usage: nomad var init <filename>
Creates an example secure variable specification file that can be used as a
Creates an example variable specification file that can be used as a
starting point to customize further. If no filename is given, the default of
"spec.nsv.hcl" or "spec.nsv.json" will be used.
Init Options:
-json
Create an example JSON secure variable specification.
Create an example JSON variable specification.
-q
Suppress non-error output
@@ -46,7 +46,7 @@ Init Options:
}
func (c *VarInitCommand) Synopsis() string {
return "Create an example secure variable specification file"
return "Create an example variable specification file"
}
func (c *VarInitCommand) AutocompleteFlags() complete.Flags {
@@ -113,7 +113,7 @@ func (c *VarInitCommand) Run(args []string) int {
// Success
if !quiet {
c.Ui.Warn(WrapAndPrepend(TidyRawString(msgWarnKeys), 70, ""))
c.Ui.Output(fmt.Sprintf("Example secure variable specification written to %s", fileName))
c.Ui.Output(fmt.Sprintf("Example variable specification written to %s", fileName))
}
return 0
}
@@ -126,17 +126,17 @@ const (
)
var defaultHclVarSpec = strings.TrimSpace(`
# A secure variable path can be specified in the specification file
# A variable path can be specified in the specification file
# and will be used when writing the variable without specifying a
# path in the command or when writing JSON directly to the `+"`/var/`"+`
# HTTP API endpoint
# path = "path/to/variable"
# path = "path/to/variable"
# The Namespace to write the variable can be included in the specification
# and is the highest precedence way to set the namespace value.
# namespace = "default"
# The items map is the only strictly required part of a secure variable
# The items map is the only strictly required part of a variable
# specification, since path and namespace can be set via other means. It
# contains the sensitive material to encrypt and store as a Nomad secure
# variable. The entire items map is encrypted and decrypted as a single unit.

View File

@@ -11,8 +11,8 @@ import (
)
const (
msgSecureVariableNotFound = "No matching secure variables found"
msgWarnFilterPerformance = "Filter queries require a full scan of the data; use prefix searching where possible"
msgVariableNotFound = "No matching variables found"
msgWarnFilterPerformance = "Filter queries require a full scan of the data; use prefix searching where possible"
)
type VarListCommand struct {
@@ -24,10 +24,10 @@ func (c *VarListCommand) Help() string {
helpText := `
Usage: nomad var list [options] <prefix>
List is used to list available secure variables. Supplying an optional prefix,
List is used to list available variables. Supplying an optional prefix,
filters the list to variables having a path starting with the prefix.
If ACLs are enabled, this command will return only secure variables stored at
If ACLs are enabled, this command will return only variables stored at
namespaced paths where the token has the ` + "`read`" + ` capability.
General Options:
@@ -48,13 +48,13 @@ List Options:
the prefix parameter should be used whenever possible.
-json
Output the secure variables in JSON format.
Output the variables in JSON format.
-t
Format and display the secure variables using a Go template.
Format and display the variables using a Go template.
-q
Output matching secure variable paths with no additional information.
Output matching variable paths with no additional information.
This option overrides the ` + "`-t`" + ` option.
`
return strings.TrimSpace(helpText)
@@ -74,7 +74,7 @@ func (c *VarListCommand) AutocompleteArgs() complete.Predictor {
}
func (c *VarListCommand) Synopsis() string {
return "List secure variable metadata"
return "List variable metadata"
}
func (c *VarListCommand) Name() string { return "var list" }
@@ -126,7 +126,7 @@ func (c *VarListCommand) Run(args []string) int {
Params: map[string]string{},
}
vars, qm, err := client.SecureVariables().PrefixList(prefix, qo)
vars, qm, err := client.Variables().PrefixList(prefix, qo)
if err != nil {
c.Ui.Error(fmt.Sprintf("Error retrieving vars: %s", err))
return 1
@@ -203,9 +203,9 @@ func (c *VarListCommand) Run(args []string) int {
return 0
}
func formatVarStubs(vars []*api.SecureVariableMetadata) string {
func formatVarStubs(vars []*api.VariableMetadata) string {
if len(vars) == 0 {
return msgSecureVariableNotFound
return msgVariableNotFound
}
// Sort the output by variable namespace, path
@@ -228,11 +228,11 @@ func formatVarStubs(vars []*api.SecureVariableMetadata) string {
return formatList(rows)
}
func dataToQuietStringSlice(vars []*api.SecureVariableMetadata, ns string) []string {
func dataToQuietStringSlice(vars []*api.VariableMetadata, ns string) []string {
// If ns is the wildcard namespace, we have to provide namespace
// as part of the quiet output, otherwise it can be a simple list
// of paths.
toPathStr := func(v *api.SecureVariableMetadata) string {
toPathStr := func(v *api.VariableMetadata) string {
if ns == "*" {
return fmt.Sprintf("%s|%s", v.Namespace, v.Path)
}
@@ -249,7 +249,7 @@ func dataToQuietStringSlice(vars []*api.SecureVariableMetadata, ns string) []str
return pList
}
func dataToQuietJSONReadySlice(vars []*api.SecureVariableMetadata, ns string) interface{} {
func dataToQuietJSONReadySlice(vars []*api.VariableMetadata, ns string) interface{} {
// If ns is the wildcard namespace, we have to provide namespace
// as part of the quiet output, otherwise it can be a simple list
// of paths.

View File

@@ -152,7 +152,7 @@ func TestVarListCommand_Online(t *testing.T) {
{
name: "plaintext/not found",
args: []string{"does/not/exist"},
expectStdOut: msgSecureVariableNotFound,
expectStdOut: msgVariableNotFound,
},
{
name: "plaintext/single variable",
@@ -178,7 +178,7 @@ func TestVarListCommand_Online(t *testing.T) {
},
{
name: "plaintext/quiet/filter",
args: []string{"-q", "-filter", "SecureVariableMetadata.Path == \"a/b/c\""},
args: []string{"-q", "-filter", "VariableMetadata.Path == \"a/b/c\""},
expectStdOut: "a/b/c",
expectStdErrPrefix: msgWarnFilterPerformance,
},
@@ -278,7 +278,7 @@ func TestVarListCommand_Online(t *testing.T) {
},
{
name: "template/filter",
args: []string{"-t", testTmpl, "-filter", "SecureVariableMetadata.Path == \"a/b/c\""},
args: []string{"-t", testTmpl, "-filter", "VariableMetadata.Path == \"a/b/c\""},
expectStdOut: "default\ta/b/c",
expectStdErrPrefix: msgWarnFilterPerformance,
},
@@ -387,9 +387,9 @@ func setupTestVariables(c *api.Client, nsList, pathList []string) SVMSlice {
}
func setupTestVariable(c *api.Client, ns, p string, out *SVMSlice) {
testVar := &api.SecureVariable{Items: map[string]string{"k": "v"}}
testVar := &api.Variable{Items: map[string]string{"k": "v"}}
c.Raw().Write("/v1/var/"+p, testVar, nil, &api.WriteOptions{Namespace: ns})
v, _, _ := c.SecureVariables().Read(p, &api.QueryOptions{Namespace: ns})
v, _, _ := c.Variables().Read(p, &api.QueryOptions{Namespace: ns})
*out = append(*out, *v.Metadata())
}
@@ -405,7 +405,7 @@ func (ps testSVNamespacePaths) NSPaths() testSVNamespacePaths {
return ps
}
type SVMSlice []api.SecureVariableMetadata
type SVMSlice []api.VariableMetadata
func (s SVMSlice) Len() int { return len(s) }
func (s SVMSlice) NSPaths() testSVNamespacePaths {