github.com/olli-ai/jx/v2@v2.0.400-0.20210921045218-14731b4dd448/pkg/cmd/opts/bucket.go (about) 1 package opts 2 3 import ( 4 "context" 5 "fmt" 6 "io" 7 "net/url" 8 "time" 9 10 v1 "github.com/jenkins-x/jx-api/pkg/apis/jenkins.io/v1" 11 "github.com/olli-ai/jx/v2/pkg/cloud/gke" 12 13 "github.com/jenkins-x/jx-logging/pkg/log" 14 "github.com/olli-ai/jx/v2/pkg/cloud/buckets" 15 "github.com/olli-ai/jx/v2/pkg/kube" 16 "github.com/olli-ai/jx/v2/pkg/kube/cluster" 17 "github.com/olli-ai/jx/v2/pkg/util" 18 "github.com/pkg/errors" 19 "github.com/spf13/cobra" 20 "gocloud.dev/blob" 21 ) 22 23 // CreateBucketValues contains the values to create a Bucket on cloud storage 24 type CreateBucketValues struct { 25 Bucket string 26 BucketKind string 27 28 // GKE specific values 29 GKEProjectID string 30 GKEZone string 31 } 32 33 // AddCreateBucketFlags adds the CLI arguments to be able to specify to create a new bucket along with any cloud specific parameters 34 func (cb *CreateBucketValues) AddCreateBucketFlags(cmd *cobra.Command) { 35 cmd.Flags().StringVarP(&cb.Bucket, "bucket", "", "", "Specify the name of the bucket to use") 36 cmd.Flags().StringVarP(&cb.BucketKind, "bucket-kind", "", "", "The kind of bucket to use like 'gs, s3, azure' etc") 37 cmd.Flags().StringVarP(&cb.GKEProjectID, "gke-project-id", "", "", "Google Project ID to use for a new bucket") 38 cmd.Flags().StringVarP(&cb.GKEZone, "gke-zone", "", "", "The GKE zone (e.g. us-central1-a) where the new bucket will be created") 39 } 40 41 // IsEmpty returns true if there is no bucket name specified 42 func (cb *CreateBucketValues) IsEmpty() bool { 43 return cb.Bucket == "" 44 } 45 46 // CreateBucket creates a new bucket using the create bucket values and team settings returning the newly created bucket URL 47 func (o *CommonOptions) CreateBucket(cb *CreateBucketValues, settings *v1.TeamSettings) (string, error) { 48 bucketURL, err := buckets.CreateBucketURL(cb.Bucket, cb.BucketKind, settings) 49 if err != nil { 50 return bucketURL, errors.Wrapf(err, "failed to create the bucket URL for %s", cb.Bucket) 51 } 52 53 ctx, _ := context.WithTimeout(context.Background(), time.Second*20) 54 bucket, err := blob.Open(ctx, bucketURL) 55 if err != nil { 56 return bucketURL, errors.Wrapf(err, "failed to open the bucket for %s", bucketURL) 57 } 58 59 // lets check if the bucket exists 60 iter := bucket.List(nil) 61 obj, err := iter.Next(ctx) 62 if err != nil { 63 if err == io.EOF { 64 log.Logger().Infof("bucket %s is empty", bucketURL) 65 } else { 66 log.Logger().Infof("The bucket %s does not exist yet so lets create it...", util.ColorInfo(bucketURL)) 67 err = o.CreateBucketFromURL(bucketURL, bucket, cb) 68 if err != nil { 69 return bucketURL, errors.Wrapf(err, "failed to create the bucket for %s", bucketURL) 70 } 71 } 72 } else { 73 log.Logger().Infof("Found item in bucket %s for %s", bucketURL, obj.Key) 74 } 75 return bucketURL, nil 76 } 77 78 // CreateBucketFromURL creates a bucket if it does not already exist 79 func (o *CommonOptions) CreateBucketFromURL(bucketURL string, bucket *blob.Bucket, cb *CreateBucketValues) error { 80 u, err := url.Parse(bucketURL) 81 if err != nil { 82 return err 83 } 84 switch u.Scheme { 85 case "gs": 86 return o.createGcsBucket(u, bucket, cb) 87 default: 88 return fmt.Errorf("Cannot create a bucket for provider %s", bucketURL) 89 } 90 } 91 92 func (o *CommonOptions) createGcsBucket(u *url.URL, bucket *blob.Bucket, cb *CreateBucketValues) error { 93 var err error 94 if cb.GKEProjectID == "" { 95 if kubeClient, ns, err := o.KubeClientAndDevNamespace(); err == nil { 96 if data, err := kube.ReadInstallValues(kubeClient, ns); err == nil && data != nil { 97 cb.GKEProjectID = data[kube.ProjectID] 98 if cb.GKEZone == "" { 99 cb.GKEZone = data[kube.Zone] 100 } 101 } 102 } 103 } 104 if cb.GKEProjectID == "" { 105 cb.GKEProjectID, err = o.GetGoogleProjectID("") 106 if err != nil { 107 return err 108 } 109 } 110 111 err = o.RunCommandVerbose( 112 "gcloud", "config", "set", "project", cb.GKEProjectID) 113 if err != nil { 114 return err 115 } 116 117 if cb.GKEZone == "" { 118 defaultZone := "" 119 if cluster, err := cluster.Name(o.Kube()); err == nil && cluster != "" { 120 if clusterZone, err := o.GCloud().ClusterZone(cluster); err == nil { 121 defaultZone = clusterZone 122 } 123 } 124 125 cb.GKEZone, err = o.GetGoogleZoneWithDefault(cb.GKEProjectID, defaultZone) 126 if err != nil { 127 return err 128 } 129 } 130 131 bucketName := u.Host 132 region := gke.GetRegionFromZone(cb.GKEZone) 133 err = o.GCloud().CreateBucket(cb.GKEProjectID, bucketName, region) 134 if err != nil { 135 return errors.Wrapf(err, "creating bucket %s in project %s and region %s", bucketName, cb.GKEProjectID, region) 136 } 137 return nil 138 }