|
4 | 4 | "context" |
5 | 5 | "errors" |
6 | 6 | "fmt" |
| 7 | + "sort" |
7 | 8 |
|
8 | 9 | "github.com/kernel/hypeman/lib/logger" |
9 | 10 | mw "github.com/kernel/hypeman/lib/middleware" |
@@ -56,6 +57,13 @@ func (s *ApiService) CreateVolume(ctx context.Context, request oapi.CreateVolume |
56 | 57 | } |
57 | 58 | } |
58 | 59 |
|
| 60 | + if key := reservedTagKey(request.Body.Tags); key != "" { |
| 61 | + return oapi.CreateVolume400JSONResponse{ |
| 62 | + Code: "invalid_request", |
| 63 | + Message: fmt.Sprintf("tag key %q is reserved for internal use", key), |
| 64 | + }, nil |
| 65 | + } |
| 66 | + |
59 | 67 | domainReq := volumes.CreateVolumeRequest{ |
60 | 68 | Name: request.Body.Name, |
61 | 69 | SizeGb: request.Body.SizeGb, |
@@ -116,6 +124,13 @@ func (s *ApiService) CreateVolumeFromArchive(ctx context.Context, request oapi.C |
116 | 124 | } |
117 | 125 | } |
118 | 126 |
|
| 127 | + if key := reservedTagKey(request.Params.Tags); key != "" { |
| 128 | + return oapi.CreateVolumeFromArchive400JSONResponse{ |
| 129 | + Code: "invalid_request", |
| 130 | + Message: fmt.Sprintf("tag key %q is reserved for internal use", key), |
| 131 | + }, nil |
| 132 | + } |
| 133 | + |
119 | 134 | // Create the volume from archive - stream directly without buffering |
120 | 135 | domainReq := volumes.CreateVolumeFromArchiveRequest{ |
121 | 136 | Name: request.Params.Name, |
@@ -230,3 +245,22 @@ func volumeToOAPI(vol volumes.Volume) oapi.Volume { |
230 | 245 |
|
231 | 246 | return oapiVol |
232 | 247 | } |
| 248 | + |
| 249 | +// reservedTagKey returns the first caller-supplied tag key in the reserved |
| 250 | +// internal namespace, or "" when all keys are usable by API callers. |
| 251 | +func reservedTagKey(resourceTags *oapi.Tags) string { |
| 252 | + if resourceTags == nil { |
| 253 | + return "" |
| 254 | + } |
| 255 | + keys := make([]string, 0, len(*resourceTags)) |
| 256 | + for key := range *resourceTags { |
| 257 | + keys = append(keys, key) |
| 258 | + } |
| 259 | + sort.Strings(keys) |
| 260 | + for _, key := range keys { |
| 261 | + if volumes.ReservedTagNamespace(key) != "" { |
| 262 | + return key |
| 263 | + } |
| 264 | + } |
| 265 | + return "" |
| 266 | +} |
0 commit comments