This repository has been archived by the owner on Mar 14, 2022. It is now read-only.
forked from istio/istio
-
Notifications
You must be signed in to change notification settings - Fork 0
/
store.go
187 lines (162 loc) · 6.24 KB
/
store.go
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
// Copyright 2017 Istio Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package config
import (
"fmt"
brokerconfig "istio.io/api/broker/dev"
"istio.io/istio/pkg/log"
)
// Store describes a set of platform agnostic APIs that must be supported
// by the underlying platform to store and retrieve Istio configuration.
//
// Configuration key is defined to be a combination of the type, name, and
// namespace of the configuration object. The configuration key is guaranteed
// to be unique in the store.
//
// The storage interface presented here assumes that the underlying storage
// layer supports _Get_ (list), _Update_ (update), _Create_ (create) and
// _Delete_ semantics but does not guarantee any transactional semantics.
//
// _Update_, _Create_, and _Delete_ are mutator operations. These operations
// are asynchronous, and you might not see the effect immediately (e.g. _Get_
// might not return the object by key immediately after you mutate the store.)
// Intermittent errors might occur even though the operation succeeds, so you
// should always check if the object store has been modified even if the
// mutating operation returns an error. Objects should be created with
// _Create_ operation and updated with _Update_ operation.
//
// Resource versions record the last mutation operation on each object. If a
// mutation is applied to a different revision of an object than what the
// underlying storage expects as defined by pure equality, the operation is
// blocked. The client of this interface should not make assumptions about the
// structure or ordering of the revision identifier.
//
// Object references supplied and returned from this interface should be
// treated as read-only. Modifying them violates thread-safety.
type Store interface {
// ConfigDescriptor exposes the configuration type schema known by the config store.
// The type schema defines the bidrectional mapping between configuration
// types and the protobuf encoding schema.
Descriptor() Descriptor
// Get retrieves a configuration element by a type and a key
Get(typ, name, namespace string) (entry *Entry, exists bool)
// List returns objects by type and namespace.
// Use "" for the namespace to list across namespaces.
List(typ, namespace string) ([]Entry, error)
// Create adds a new configuration object to the store. If an object with the
// same name and namespace for the type already exists, the operation fails
// with no side effects.
Create(entry Entry) (revision string, err error)
// Update modifies an existing configuration object in the store. Update
// requires that the object has been created. Resource version prevents
// overriding a value that has been changed between prior _Get_ and _Put_
// operation to achieve optimistic concurrency. This method returns a new
// revision if the operation succeeds.
Update(entry Entry) (newRevision string, err error)
// Delete removes an object from the store by key
Delete(typ, name, namespace string) error
}
// Key function for the configuration objects
func Key(typ, name, namespace string) string {
return fmt.Sprintf("%s/%s/%s", typ, namespace, name)
}
// Key is the unique identifier for a configuration object
func (entry *Entry) Key() string {
return Key(entry.Type, entry.Name, entry.Namespace)
}
// BrokerConfigStore is a specialized interface to access config store using
// Broker configuration types.
type BrokerConfigStore interface {
// ServiceClasses lists all service classes.
ServiceClasses() map[string]*brokerconfig.ServiceClass
// ServicePlans lists all service plans.
ServicePlans() map[string]*brokerconfig.ServicePlan
// ServicePlansByService lists all service plans contains the specified service class
ServicePlansByService(service string) map[string]*brokerconfig.ServicePlan
}
const (
// IstioAPIGroup defines API group name for Istio configuration resources
IstioAPIGroup = "broker.istio.io"
// IstioAPIVersion defines API group version
IstioAPIVersion = "dev"
)
var (
// ServiceClass describes service class
ServiceClass = Schema{
Type: "service-class",
Plural: "service-classes",
MessageName: "istio.broker.dev.ServiceClass",
}
// ServicePlan describes service plan
ServicePlan = Schema{
Type: "service-plan",
Plural: "service-plans",
MessageName: "istio.broker.dev.ServicePlan",
}
// BrokerConfigTypes lists all types with schemas and validation
BrokerConfigTypes = Descriptor{
ServiceClass,
ServicePlan,
}
)
// brokerConfigStore provides a simple adapter for Broker configuration types
// from the generic config registry
type brokerConfigStore struct {
Store
}
// MakeBrokerConfigStore creates a wrapper around a store
func MakeBrokerConfigStore(store Store) BrokerConfigStore {
return &brokerConfigStore{store}
}
func (i brokerConfigStore) ServiceClasses() map[string]*brokerconfig.ServiceClass {
out := make(map[string]*brokerconfig.ServiceClass)
rs, err := i.List(ServiceClass.Type, "")
if err != nil {
log.Infof("ServiceClasses => %v", err)
return out
}
for _, r := range rs {
if c, ok := r.Spec.(*brokerconfig.ServiceClass); ok {
out[r.Key()] = c
}
}
return out
}
func (i brokerConfigStore) ServicePlans() map[string]*brokerconfig.ServicePlan {
out := make(map[string]*brokerconfig.ServicePlan)
rs, err := i.List(ServicePlan.Type, "")
if err != nil {
log.Infof("ServicePlans => %v", err)
return out
}
for _, r := range rs {
if c, ok := r.Spec.(*brokerconfig.ServicePlan); ok {
out[r.Key()] = c
}
}
return out
}
func (i brokerConfigStore) ServicePlansByService(service string) map[string]*brokerconfig.ServicePlan {
out := make(map[string]*brokerconfig.ServicePlan)
rs := i.ServicePlans()
for k, v := range rs {
for _, s := range v.GetServices() {
if s == service {
out[k] = v
break
}
}
}
return out
}