github.com/adityamillind98/nomad@v0.11.8/command/agent/consul/acl_testing.go (about)

     1  package consul
     2  
     3  import (
     4  	"errors"
     5  	"sync"
     6  	"time"
     7  
     8  	"github.com/hashicorp/consul/api"
     9  	"github.com/hashicorp/go-hclog"
    10  	"github.com/hashicorp/nomad/helper/uuid"
    11  )
    12  
    13  var _ ACLsAPI = (*MockACLsAPI)(nil)
    14  
    15  // MockACLsAPI is a mock of consul.ACLsAPI
    16  type MockACLsAPI struct {
    17  	logger hclog.Logger
    18  
    19  	lock  sync.Mutex
    20  	state struct {
    21  		index  uint64
    22  		error  error
    23  		tokens map[string]*api.ACLToken
    24  	}
    25  }
    26  
    27  func NewMockACLsAPI(l hclog.Logger) *MockACLsAPI {
    28  	return &MockACLsAPI{
    29  		logger: l.Named("mock_consul"),
    30  		state: struct {
    31  			index  uint64
    32  			error  error
    33  			tokens map[string]*api.ACLToken
    34  		}{tokens: make(map[string]*api.ACLToken)},
    35  	}
    36  }
    37  
    38  // Example Consul policies for use in tests.
    39  const (
    40  	ExamplePolicyID1 = "a7c86856-0af5-4ab5-8834-03f4517e5564"
    41  	ExamplePolicyID2 = "ffa1b66c-967d-4468-8775-c687b5cfc16e"
    42  	ExamplePolicyID3 = "f68f0c36-51f8-4343-97dd-f0d4816c915f"
    43  )
    44  
    45  func (m *MockACLsAPI) PolicyRead(policyID string, _ *api.QueryOptions) (*api.ACLPolicy, *api.QueryMeta, error) {
    46  	switch policyID {
    47  
    48  	case ExamplePolicyID1:
    49  		return &api.ACLPolicy{
    50  			ID:    ExamplePolicyID1,
    51  			Name:  "example-policy-1",
    52  			Rules: `service "service1" { policy = "write" }`,
    53  		}, nil, nil
    54  
    55  	case ExamplePolicyID2:
    56  		return &api.ACLPolicy{
    57  			ID:    ExamplePolicyID2,
    58  			Rules: `service_prefix "foo-" { policy = "write" }`,
    59  		}, nil, nil
    60  
    61  	case ExamplePolicyID3:
    62  		return &api.ACLPolicy{
    63  			ID: ExamplePolicyID3,
    64  			Rules: `
    65  service "service1" { policy = "read" }
    66  service "service2" { policy = "write" }`,
    67  		}, nil, nil
    68  
    69  	default:
    70  		return nil, nil, errors.New("no such policy")
    71  	}
    72  }
    73  
    74  // Example Consul roles for use in tests.
    75  const (
    76  	ExampleRoleID1 = "e569a3a8-7dfb-b024-e492-e790fe3c4183"
    77  	ExampleRoleID2 = "88c825f4-d0da-1c2b-0c1c-cc9fe84c4468"
    78  	ExampleRoleID3 = "b19b2058-6205-6dff-d2b0-470f29b8e627"
    79  )
    80  
    81  func (m *MockACLsAPI) RoleRead(roleID string, _ *api.QueryOptions) (*api.ACLRole, *api.QueryMeta, error) {
    82  	switch roleID {
    83  	case ExampleRoleID1:
    84  		return &api.ACLRole{
    85  			ID:   ExampleRoleID1,
    86  			Name: "example-role-1",
    87  			Policies: []*api.ACLRolePolicyLink{{
    88  				ID:   ExamplePolicyID1,
    89  				Name: "example-policy-1",
    90  			}},
    91  			ServiceIdentities: nil,
    92  		}, nil, nil
    93  	case ExampleRoleID2:
    94  		return &api.ACLRole{
    95  			ID:   ExampleRoleID2,
    96  			Name: "example-role-2",
    97  			Policies: []*api.ACLRolePolicyLink{{
    98  				ID:   ExamplePolicyID2,
    99  				Name: "example-policy-2",
   100  			}},
   101  			ServiceIdentities: nil,
   102  		}, nil, nil
   103  	case ExampleRoleID3:
   104  		return &api.ACLRole{
   105  			ID:                ExampleRoleID3,
   106  			Name:              "example-role-3",
   107  			Policies:          nil, // todo add more if needed
   108  			ServiceIdentities: nil, // todo add more if needed
   109  		}, nil, nil
   110  	default:
   111  		return nil, nil, nil
   112  	}
   113  }
   114  
   115  // Example Consul "operator" tokens for use in tests.
   116  
   117  const (
   118  	ExampleOperatorTokenID0 = "de591604-86eb-1e6f-8b44-d4db752921ae"
   119  	ExampleOperatorTokenID1 = "59c219c2-47e4-43f3-bb45-258fd13f59d5"
   120  	ExampleOperatorTokenID2 = "868cc216-e123-4c2b-b362-f4d4c087de8e"
   121  	ExampleOperatorTokenID3 = "6177d1b9-c0f6-4118-b891-d818a3cb80b1"
   122  	ExampleOperatorTokenID4 = "754ae26c-f3cc-e088-d486-9c0d20f5eaea"
   123  )
   124  
   125  var (
   126  	ExampleOperatorToken0 = &api.ACLToken{
   127  		SecretID:    ExampleOperatorTokenID0,
   128  		AccessorID:  "228865c6-3bf6-6683-df03-06dea2779088 ",
   129  		Description: "Operator Token 0",
   130  	}
   131  
   132  	ExampleOperatorToken1 = &api.ACLToken{
   133  		SecretID:    ExampleOperatorTokenID1,
   134  		AccessorID:  "e341bacd-535e-417c-8f45-f88d7faffcaf",
   135  		Description: "Operator Token 1",
   136  		Policies: []*api.ACLTokenPolicyLink{{
   137  			ID: ExamplePolicyID1,
   138  		}},
   139  	}
   140  
   141  	ExampleOperatorToken2 = &api.ACLToken{
   142  		SecretID:    ExampleOperatorTokenID2,
   143  		AccessorID:  "615b4d77-5164-4ec6-b616-24c0b24ac9cb",
   144  		Description: "Operator Token 2",
   145  		Policies: []*api.ACLTokenPolicyLink{{
   146  			ID: ExamplePolicyID2,
   147  		}},
   148  	}
   149  
   150  	ExampleOperatorToken3 = &api.ACLToken{
   151  		SecretID:    ExampleOperatorTokenID3,
   152  		AccessorID:  "6b7de0d7-15f7-45b4-95eb-fb775bfe3fdc",
   153  		Description: "Operator Token 3",
   154  		Policies: []*api.ACLTokenPolicyLink{{
   155  			ID: ExamplePolicyID3,
   156  		}},
   157  	}
   158  
   159  	ExampleOperatorToken4 = &api.ACLToken{
   160  		SecretID:    ExampleOperatorTokenID4,
   161  		AccessorID:  "7b5fdb1a-71e5-f3d8-2cfe-448d973f327d",
   162  		Description: "Operator Token 4",
   163  		Policies:    nil, // no direct policy, only roles
   164  		Roles: []*api.ACLTokenRoleLink{{
   165  			ID:   ExampleRoleID1,
   166  			Name: "example-role-1",
   167  		}},
   168  	}
   169  )
   170  
   171  func (m *MockACLsAPI) TokenReadSelf(q *api.QueryOptions) (*api.ACLToken, *api.QueryMeta, error) {
   172  	switch q.Token {
   173  
   174  	case ExampleOperatorTokenID1:
   175  		return ExampleOperatorToken1, nil, nil
   176  
   177  	case ExampleOperatorTokenID2:
   178  		return ExampleOperatorToken2, nil, nil
   179  
   180  	case ExampleOperatorTokenID3:
   181  		return ExampleOperatorToken3, nil, nil
   182  
   183  	case ExampleOperatorTokenID4:
   184  		return ExampleOperatorToken4, nil, nil
   185  
   186  	default:
   187  		return nil, nil, errors.New("no such token")
   188  	}
   189  }
   190  
   191  // SetError is a helper method for configuring an error that will be returned
   192  // on future calls to mocked methods.
   193  func (m *MockACLsAPI) SetError(err error) {
   194  	m.lock.Lock()
   195  	defer m.lock.Unlock()
   196  	m.state.error = err
   197  }
   198  
   199  // TokenCreate is a mock of ACLsAPI.TokenCreate
   200  func (m *MockACLsAPI) TokenCreate(token *api.ACLToken, opts *api.WriteOptions) (*api.ACLToken, *api.WriteMeta, error) {
   201  	index, created, meta, err := m.tokenCreate(token, opts)
   202  
   203  	services := func(token *api.ACLToken) []string {
   204  		if token == nil {
   205  			return nil
   206  		}
   207  		var names []string
   208  		for _, id := range token.ServiceIdentities {
   209  			names = append(names, id.ServiceName)
   210  		}
   211  		return names
   212  	}(created)
   213  
   214  	description := func(token *api.ACLToken) string {
   215  		if token == nil {
   216  			return "<nil>"
   217  		}
   218  		return token.Description
   219  	}(created)
   220  
   221  	accessor := func(token *api.ACLToken) string {
   222  		if token == nil {
   223  			return "<nil>"
   224  		}
   225  		return token.AccessorID
   226  	}(created)
   227  
   228  	secret := func(token *api.ACLToken) string {
   229  		if token == nil {
   230  			return "<nil>"
   231  		}
   232  		return token.SecretID
   233  	}(created)
   234  
   235  	m.logger.Trace("TokenCreate()", "description", description, "service_identities", services, "accessor", accessor, "secret", secret, "index", index, "error", err)
   236  	return created, meta, err
   237  }
   238  
   239  func (m *MockACLsAPI) tokenCreate(token *api.ACLToken, _ *api.WriteOptions) (uint64, *api.ACLToken, *api.WriteMeta, error) {
   240  	m.lock.Lock()
   241  	defer m.lock.Unlock()
   242  
   243  	m.state.index++
   244  
   245  	if m.state.error != nil {
   246  		return m.state.index, nil, nil, m.state.error
   247  	}
   248  
   249  	secret := &api.ACLToken{
   250  		CreateIndex:       m.state.index,
   251  		ModifyIndex:       m.state.index,
   252  		AccessorID:        uuid.Generate(),
   253  		SecretID:          uuid.Generate(),
   254  		Description:       token.Description,
   255  		ServiceIdentities: token.ServiceIdentities,
   256  		CreateTime:        time.Now(),
   257  	}
   258  
   259  	m.state.tokens[secret.AccessorID] = secret
   260  
   261  	w := &api.WriteMeta{
   262  		RequestTime: 1 * time.Millisecond,
   263  	}
   264  
   265  	return m.state.index, secret, w, nil
   266  }
   267  
   268  // TokenDelete is a mock of ACLsAPI.TokenDelete
   269  func (m *MockACLsAPI) TokenDelete(accessorID string, opts *api.WriteOptions) (*api.WriteMeta, error) {
   270  	meta, err := m.tokenDelete(accessorID, opts)
   271  	m.logger.Trace("TokenDelete()", "accessor", accessorID, "error", err)
   272  	return meta, err
   273  }
   274  
   275  func (m *MockACLsAPI) tokenDelete(tokenID string, _ *api.WriteOptions) (*api.WriteMeta, error) {
   276  	m.lock.Lock()
   277  	defer m.lock.Unlock()
   278  
   279  	m.state.index++
   280  
   281  	if m.state.error != nil {
   282  		return nil, m.state.error
   283  	}
   284  
   285  	if _, exists := m.state.tokens[tokenID]; !exists {
   286  		return nil, nil // consul no-ops delete of non-existent token
   287  	}
   288  
   289  	delete(m.state.tokens, tokenID)
   290  
   291  	m.logger.Trace("TokenDelete()")
   292  
   293  	return nil, nil
   294  }
   295  
   296  // TokenList is a mock of ACLsAPI.TokenList
   297  func (m *MockACLsAPI) TokenList(_ *api.QueryOptions) ([]*api.ACLTokenListEntry, *api.QueryMeta, error) {
   298  	m.lock.Lock()
   299  	defer m.lock.Unlock()
   300  
   301  	//todo(shoenig): will need this for background token reconciliation
   302  	// coming in another issue
   303  
   304  	return nil, nil, nil
   305  }