go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/common/gcloud/project_id.go (about) 1 // Copyright 2021 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 gcloud 16 17 import ( 18 "errors" 19 "fmt" 20 ) 21 22 // ValidateProjectID returns an error if the supplied string is not 23 // a valid Google Cloud project ID. 24 // 25 // A valid project ID 26 // - must be 6 to 30 lowercase ASCII letters, digits, or hyphens, 27 // - must start with a letter, and 28 // - must not have a trailing hyphen. 29 // 30 // See: 31 // https://cloud.google.com/resource-manager/reference/rest/v3/projects#resource:-project 32 func ValidateProjectID(p string) error { 33 if len(p) < 6 || len(p) > 30 { 34 return errors.New("must contain 6 to 30 ASCII letters, digits, or hyphens") 35 } 36 if p[0] < 'a' || p[0] > 'z' { 37 return errors.New("must start with a lowercase ASCII letter") 38 } 39 if p[len(p)-1] == '-' { 40 return errors.New("must not have a trailing hyphen") 41 } 42 for i := 1; i < len(p)-1; i++ { 43 switch { 44 case p[i] >= 'a' && p[i] <= 'z', p[i] >= '0' && p[i] <= '9', p[i] == '-': 45 default: 46 return fmt.Errorf("invalid letter at %d (%c)", i, p[i]) 47 } 48 } 49 return nil 50 }