github.com/gravitational/teleport/api@v0.0.0-20240507183017-3110591cbafc/types/header/header.go (about) 1 /* 2 Copyright 2023 Gravitational, Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package header 18 19 import ( 20 "slices" 21 "time" 22 23 "github.com/gravitational/trace" 24 25 "github.com/gravitational/teleport/api/types/common" 26 "github.com/gravitational/teleport/api/types/compare" 27 "github.com/gravitational/teleport/api/utils" 28 ) 29 30 var ( 31 _ compare.IsEqual[*ResourceHeader] = (*ResourceHeader)(nil) 32 _ compare.IsEqual[*Metadata] = (*Metadata)(nil) 33 ) 34 35 func ResourceHeaderFromMetadata(metadata Metadata) ResourceHeader { 36 return ResourceHeader{ 37 Metadata: metadata, 38 } 39 } 40 41 // ResourceHeader is a common header for Teleport resources. 42 type ResourceHeader struct { 43 // Kind is a resource kind. 44 Kind string `json:"kind,omitempty"` 45 // SubKind is an optional resource sub kind, used in some resources. 46 SubKind string `json:"sub_kind,omitempty"` 47 // Version is the resource version. 48 Version string `json:"version,omitempty"` 49 // Metadata is metadata for the resource. 50 Metadata Metadata `json:"metadata,omitempty"` 51 } 52 53 // GetVersion returns the resource version. 54 func (h *ResourceHeader) GetVersion() string { 55 return h.Version 56 } 57 58 // SetVersion sets the resource version. 59 func (h *ResourceHeader) SetVersion(version string) { 60 h.Version = version 61 } 62 63 // GetResourceID returns the resource ID. 64 func (h *ResourceHeader) GetResourceID() int64 { 65 return h.Metadata.GetID() 66 } 67 68 // SetResourceID sets the resource ID. 69 func (h *ResourceHeader) SetResourceID(id int64) { 70 h.Metadata.SetID(id) 71 } 72 73 // GetRevision returns the revision. 74 func (h *ResourceHeader) GetRevision() string { 75 return h.Metadata.GetRevision() 76 } 77 78 // SetRevision sets the revision. 79 func (h *ResourceHeader) SetRevision(rev string) { 80 h.Metadata.SetRevision(rev) 81 } 82 83 // GetName returns the name of the resource. 84 func (h *ResourceHeader) GetName() string { 85 return h.Metadata.GetName() 86 } 87 88 // SetName sets the name of the resource. 89 func (h *ResourceHeader) SetName(v string) { 90 h.Metadata.SetName(v) 91 } 92 93 // Expiry returns the resource expiry setting. 94 func (h *ResourceHeader) Expiry() time.Time { 95 return h.Metadata.Expiry() 96 } 97 98 // SetExpiry sets the resource expiry. 99 func (h *ResourceHeader) SetExpiry(t time.Time) { 100 h.Metadata.SetExpiry(t) 101 } 102 103 // GetMetadata returns object metadata. 104 func (h *ResourceHeader) GetMetadata() Metadata { 105 return h.Metadata 106 } 107 108 // GetKind returns the resource kind. 109 func (h *ResourceHeader) GetKind() string { 110 return h.Kind 111 } 112 113 // SetKind sets the resource kind. 114 func (h *ResourceHeader) SetKind(kind string) { 115 h.Kind = kind 116 } 117 118 // GetSubKind returns the resource subkind. 119 func (h *ResourceHeader) GetSubKind() string { 120 return h.SubKind 121 } 122 123 // SetSubKind sets the resource subkind. 124 func (h *ResourceHeader) SetSubKind(s string) { 125 h.SubKind = s 126 } 127 128 // Origin returns the origin value of the resource. 129 func (h *ResourceHeader) Origin() string { 130 return h.Metadata.Origin() 131 } 132 133 // SetOrigin sets the origin value of the resource. 134 func (h *ResourceHeader) SetOrigin(origin string) { 135 h.Metadata.SetOrigin(origin) 136 } 137 138 // GetStaticLabels returns the static labels for the resource. 139 func (h *ResourceHeader) GetStaticLabels() map[string]string { 140 return h.Metadata.GetStaticLabels() 141 } 142 143 // SetStaticLabels sets the static labels for the resource. 144 func (h *ResourceHeader) SetStaticLabels(sl map[string]string) { 145 h.Metadata.SetStaticLabels(sl) 146 } 147 148 // GetLabel retrieves the label with the provided key. If not found 149 // value will be empty and ok will be false. 150 func (h *ResourceHeader) GetLabel(key string) (string, bool) { 151 return h.Metadata.GetLabel(key) 152 } 153 154 // GetAllLabels returns all labels from the resource. 155 func (h *ResourceHeader) GetAllLabels() map[string]string { 156 return h.Metadata.GetAllLabels() 157 } 158 159 // CheckAndSetDefaults will verify that the resource header is valid. This will additionally 160 // verify that the metadata is valid. 161 func (h *ResourceHeader) CheckAndSetDefaults() error { 162 if h.Kind == "" { 163 return trace.BadParameter("resource has an empty Kind field") 164 } 165 if h.Version == "" { 166 return trace.BadParameter("resource has an empty Version field") 167 } 168 return trace.Wrap(h.Metadata.CheckAndSetDefaults()) 169 } 170 171 // IsEqual determines if two resource headers are equivalent to one another. 172 func (h *ResourceHeader) IsEqual(i *ResourceHeader) bool { 173 return deriveTeleportEqualResourceHeader(h, i) 174 } 175 176 // Metadata is resource metadata 177 type Metadata struct { 178 // Name is an object name 179 Name string `json:"name" yaml:"name"` 180 // Description is object description 181 Description string `json:"description,omitempty" yaml:"description,omitempty"` 182 // Labels is a set of labels 183 Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` 184 // Expires is a global expiry time header can be set on any resource in the system. 185 Expires time.Time `json:"expires" yaml:"expires"` 186 // ID is a record ID 187 // Deprecated: Use revision instead. 188 ID int64 `json:"id,omitempty" yaml:"id,omitempty"` 189 // Revision is an opaque identifier which tracks the versions of a resource 190 // over time. Clients should ignore and not alter its value but must return 191 // the revision in any updates of a resource. 192 Revision string `json:"revision,omitempty" yaml:"revision,omitempty"` 193 } 194 195 // GetID returns the resource ID. 196 // Deprecated: Use GetRevision instead 197 func (m *Metadata) GetID() int64 { 198 return m.ID 199 } 200 201 // SetID sets the resource ID. 202 // Deprecated: Use SetRevision instead 203 func (m *Metadata) SetID(id int64) { 204 m.ID = id 205 } 206 207 // GetRevision returns the revision 208 func (m *Metadata) GetRevision() string { 209 return m.Revision 210 } 211 212 // SetRevision sets the revision 213 func (m *Metadata) SetRevision(rev string) { 214 m.Revision = rev 215 } 216 217 // GetName returns the name of the resource. 218 func (m *Metadata) GetName() string { 219 return m.Name 220 } 221 222 // SetName sets the name of the resource. 223 func (m *Metadata) SetName(name string) { 224 m.Name = name 225 } 226 227 // SetExpiry sets the expiry time for the object. 228 func (m *Metadata) SetExpiry(expires time.Time) { 229 m.Expires = expires 230 } 231 232 // Expiry returns the object expiry setting. 233 func (m *Metadata) Expiry() time.Time { 234 return m.Expires 235 } 236 237 // Origin returns the origin value of the resource. 238 func (m *Metadata) Origin() string { 239 if m.Labels == nil { 240 return "" 241 } 242 return m.Labels[common.OriginLabel] 243 } 244 245 // SetOrigin sets the origin value of the resource. 246 func (m *Metadata) SetOrigin(origin string) { 247 if m.Labels == nil { 248 m.Labels = map[string]string{} 249 } 250 m.Labels[common.OriginLabel] = origin 251 } 252 253 // CheckAndSetDefaults verifies that the metadata object is valid. 254 func (m *Metadata) CheckAndSetDefaults() error { 255 if m.Name == "" { 256 return trace.BadParameter("missing parameter Name") 257 } 258 259 // adjust expires time to UTC if it's set 260 if !m.Expires.IsZero() { 261 utils.UTC(&m.Expires) 262 } 263 264 for key := range m.Labels { 265 if !common.IsValidLabelKey(key) { 266 return trace.BadParameter("invalid label key: %q", key) 267 } 268 } 269 270 // Check the origin value. 271 if m.Origin() != "" { 272 if !slices.Contains(common.OriginValues, m.Origin()) { 273 return trace.BadParameter("invalid origin value %q, must be one of %v", m.Origin(), common.OriginValues) 274 } 275 } 276 277 return nil 278 } 279 280 // GetStaticLabels returns the static labels for the metadata. 281 func (m *Metadata) GetStaticLabels() map[string]string { 282 return m.Labels 283 } 284 285 // SetStaticLabels sets the static labels for the metadata. 286 func (m *Metadata) SetStaticLabels(sl map[string]string) { 287 m.Labels = sl 288 } 289 290 // GetLabel retrieves the label with the provided key. If not found 291 // value will be empty and ok will be false. 292 func (m *Metadata) GetLabel(key string) (string, bool) { 293 v, ok := m.Labels[key] 294 return v, ok 295 } 296 297 // GetAllLabels returns all labels from the resource. 298 func (m *Metadata) GetAllLabels() map[string]string { 299 return m.Labels 300 } 301 302 // IsEqual determines if two metadata resources are equivalent to one another. 303 func (m *Metadata) IsEqual(i *Metadata) bool { 304 return deriveTeleportEqualMetadata(m, i) 305 }