File: set.go

package info (click to toggle)
golang-github-spiffe-go-spiffe 2.5.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,116 kB
  • sloc: makefile: 157
file content (135 lines) | stat: -rw-r--r-- 3,463 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package spiffebundle

import (
	"sort"
	"sync"

	"github.com/spiffe/go-spiffe/v2/bundle/jwtbundle"
	"github.com/spiffe/go-spiffe/v2/bundle/x509bundle"
	"github.com/spiffe/go-spiffe/v2/spiffeid"
)

// Set is a set of bundles, keyed by trust domain.
type Set struct {
	mtx     sync.RWMutex
	bundles map[spiffeid.TrustDomain]*Bundle
}

// NewSet creates a new set initialized with the given bundles.
func NewSet(bundles ...*Bundle) *Set {
	bundlesMap := make(map[spiffeid.TrustDomain]*Bundle)

	for _, b := range bundles {
		if b != nil {
			bundlesMap[b.trustDomain] = b
		}
	}

	return &Set{
		bundles: bundlesMap,
	}
}

// Add adds a new bundle into the set. If a bundle already exists for the
// trust domain, the existing bundle is replaced.
func (s *Set) Add(bundle *Bundle) {
	s.mtx.Lock()
	defer s.mtx.Unlock()

	if bundle != nil {
		s.bundles[bundle.trustDomain] = bundle
	}
}

// Remove removes the bundle for the given trust domain.
func (s *Set) Remove(trustDomain spiffeid.TrustDomain) {
	s.mtx.Lock()
	defer s.mtx.Unlock()

	delete(s.bundles, trustDomain)
}

// Has returns true if there is a bundle for the given trust domain.
func (s *Set) Has(trustDomain spiffeid.TrustDomain) bool {
	s.mtx.RLock()
	defer s.mtx.RUnlock()

	_, ok := s.bundles[trustDomain]
	return ok
}

// Get returns a bundle for the given trust domain. If the bundle is in the set
// it is returned and the boolean is true. Otherwise, the returned value is
// nil and the boolean is false.
func (s *Set) Get(trustDomain spiffeid.TrustDomain) (*Bundle, bool) {
	s.mtx.RLock()
	defer s.mtx.RUnlock()

	bundle, ok := s.bundles[trustDomain]
	return bundle, ok
}

// Bundles returns the bundles in the set sorted by trust domain.
func (s *Set) Bundles() []*Bundle {
	s.mtx.RLock()
	defer s.mtx.RUnlock()

	out := make([]*Bundle, 0, len(s.bundles))
	for _, bundle := range s.bundles {
		out = append(out, bundle)
	}
	sort.Slice(out, func(a, b int) bool {
		return out[a].TrustDomain().Compare(out[b].TrustDomain()) < 0
	})
	return out
}

// Len returns the number of bundles in the set.
func (s *Set) Len() int {
	s.mtx.RLock()
	defer s.mtx.RUnlock()

	return len(s.bundles)
}

// GetBundleForTrustDomain returns the SPIFFE bundle for the given trust
// domain. It implements the Source interface.
func (s *Set) GetBundleForTrustDomain(trustDomain spiffeid.TrustDomain) (*Bundle, error) {
	s.mtx.RLock()
	defer s.mtx.RUnlock()

	bundle, ok := s.bundles[trustDomain]
	if !ok {
		return nil, spiffebundleErr.New("no SPIFFE bundle for trust domain %q", trustDomain)
	}

	return bundle, nil
}

// GetX509BundleForTrustDomain returns the X.509 bundle for the given trust
// domain. It implements the x509bundle.Source interface.
func (s *Set) GetX509BundleForTrustDomain(trustDomain spiffeid.TrustDomain) (*x509bundle.Bundle, error) {
	s.mtx.RLock()
	defer s.mtx.RUnlock()

	bundle, ok := s.bundles[trustDomain]
	if !ok {
		return nil, spiffebundleErr.New("no X.509 bundle for trust domain %q", trustDomain)
	}

	return bundle.X509Bundle(), nil
}

// GetJWTBundleForTrustDomain returns the JWT bundle for the given trust
// domain. It implements the jwtbundle.Source interface.
func (s *Set) GetJWTBundleForTrustDomain(trustDomain spiffeid.TrustDomain) (*jwtbundle.Bundle, error) {
	s.mtx.RLock()
	defer s.mtx.RUnlock()

	bundle, ok := s.bundles[trustDomain]
	if !ok {
		return nil, spiffebundleErr.New("no JWT bundle for trust domain %q", trustDomain)
	}

	return bundle.JWTBundle(), nil
}