github.com/opentofu/opentofu@v1.7.1/internal/encryption/registry/lockingencryptionregistry/registry.go (about)

     1  // Copyright (c) The OpenTofu Authors
     2  // SPDX-License-Identifier: MPL-2.0
     3  // Copyright (c) 2023 HashiCorp, Inc.
     4  // SPDX-License-Identifier: MPL-2.0
     5  
     6  package lockingencryptionregistry
     7  
     8  import (
     9  	"sync"
    10  
    11  	"github.com/opentofu/opentofu/internal/encryption/keyprovider"
    12  	"github.com/opentofu/opentofu/internal/encryption/method"
    13  	"github.com/opentofu/opentofu/internal/encryption/registry"
    14  )
    15  
    16  // New returns a new encryption registry that locks for parallel access.
    17  func New() registry.Registry {
    18  	return &lockingRegistry{
    19  		lock:      &sync.RWMutex{},
    20  		providers: map[keyprovider.ID]keyprovider.Descriptor{},
    21  		methods:   map[method.ID]method.Descriptor{},
    22  	}
    23  }
    24  
    25  type lockingRegistry struct {
    26  	lock      *sync.RWMutex
    27  	providers map[keyprovider.ID]keyprovider.Descriptor
    28  	methods   map[method.ID]method.Descriptor
    29  }
    30  
    31  func (l *lockingRegistry) RegisterKeyProvider(keyProvider keyprovider.Descriptor) error {
    32  	l.lock.Lock()
    33  	defer l.lock.Unlock()
    34  
    35  	id := keyProvider.ID()
    36  	if err := id.Validate(); err != nil {
    37  		return &registry.InvalidKeyProviderError{KeyProvider: keyProvider, Cause: err}
    38  	}
    39  	if _, ok := l.providers[id]; ok {
    40  		return &registry.KeyProviderAlreadyRegisteredError{ID: id}
    41  	}
    42  	l.providers[id] = keyProvider
    43  	return nil
    44  }
    45  
    46  func (l *lockingRegistry) RegisterMethod(method method.Descriptor) error {
    47  	l.lock.Lock()
    48  	defer l.lock.Unlock()
    49  
    50  	id := method.ID()
    51  	if err := id.Validate(); err != nil {
    52  		return &registry.InvalidMethodError{Method: method, Cause: err}
    53  	}
    54  	if previousMethod, ok := l.methods[id]; ok {
    55  		return &registry.MethodAlreadyRegisteredError{ID: id, CurrentMethod: method, PreviousMethod: previousMethod}
    56  	}
    57  	l.methods[id] = method
    58  	return nil
    59  }
    60  
    61  func (l *lockingRegistry) GetKeyProviderDescriptor(id keyprovider.ID) (keyprovider.Descriptor, error) {
    62  	l.lock.RLock()
    63  	defer l.lock.RUnlock()
    64  	provider, ok := l.providers[id]
    65  	if !ok {
    66  		return nil, &registry.KeyProviderNotFoundError{ID: id}
    67  	}
    68  	return provider, nil
    69  }
    70  
    71  func (l *lockingRegistry) GetMethodDescriptor(id method.ID) (method.Descriptor, error) {
    72  	l.lock.RLock()
    73  	defer l.lock.RUnlock()
    74  	foundMethod, ok := l.methods[id]
    75  	if !ok {
    76  		return nil, &registry.MethodNotFoundError{ID: id}
    77  	}
    78  	return foundMethod, nil
    79  }