go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/gce/api/config/v1/config.go (about) 1 // Copyright 2018 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package config 16 17 import ( 18 "time" 19 20 "google.golang.org/protobuf/proto" 21 22 "go.chromium.org/luci/config/validation" 23 "go.chromium.org/luci/gae/service/datastore" 24 ) 25 26 // Ensure Config implements datastore.PropertyConverter. 27 // This allows VMs blocks to be read from and written to the datastore. 28 var _ datastore.PropertyConverter = &Config{} 29 30 // FromProperty implements datastore.PropertyConverter. 31 func (cfg *Config) FromProperty(p datastore.Property) error { 32 if p.Value() == nil { 33 cfg = &Config{} 34 return nil 35 } 36 return proto.Unmarshal(p.Value().([]byte), cfg) 37 } 38 39 // ToProperty implements datastore.PropertyConverter. 40 func (cfg *Config) ToProperty() (datastore.Property, error) { 41 p := datastore.Property{} 42 bytes, err := proto.Marshal(cfg) 43 if err != nil { 44 return datastore.Property{}, err 45 } 46 // noindex is not respected in the tags in the model. 47 return p, p.SetValue(bytes, datastore.NoIndex) 48 } 49 50 // ComputeAmount returns the amount to use given the proposed amount and time. 51 // Assumes this config has been validated. 52 func (cfg *Config) ComputeAmount(proposed int32, now time.Time) (int32, error) { 53 return cfg.GetAmount().getAmount(proposed, now) 54 } 55 56 // Validate validates this config. 57 func (cfg *Config) Validate(c *validation.Context) { 58 c.Enter("amount") 59 cfg.GetAmount().Validate(c) 60 c.Exit() 61 c.Enter("attributes") 62 cfg.GetAttributes().Validate(c) 63 c.Exit() 64 if cfg.GetCurrentAmount() != 0 { 65 c.Errorf("current amount must not be specified") 66 } 67 c.Enter("lifetime") 68 cfg.GetLifetime().Validate(c) 69 switch n, err := cfg.Lifetime.ToSeconds(); { 70 case err != nil: 71 c.Errorf("%s", err) 72 case n == 0: 73 c.Errorf("duration or seconds is required") 74 } 75 c.Exit() 76 if cfg.GetCurrentAmount() != 0 { 77 c.Errorf("current amount must not be specified") 78 } 79 if cfg.GetPrefix() == "" { 80 c.Errorf("prefix is required") 81 } 82 if cfg.GetRevision() != "" { 83 c.Errorf("revision must not be specified") 84 } 85 c.Enter("timeout") 86 cfg.GetTimeout().Validate(c) 87 c.Exit() 88 }