-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
modified: README.md new file: example/generateSignedUrl/main.go new file: example/upload/go_gcs.png new file: example/upload/main.go new file: example/upload/tes.txt new file: gcs.go new file: go.mod new file: go.sum
- Loading branch information
Showing
9 changed files
with
561 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,3 +20,7 @@ | |
# Go workspace file | ||
go.work | ||
go.work.sum | ||
|
||
cred | ||
.idea | ||
.env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,104 @@ | ||
# go-gcp-wrapper | ||
A Google Cloud Storage wrapper, to simplify go application to interact with Google Cloud Storage | ||
# go-gcs-wrapper | ||
go-gcs-wrapper is a library that makes it easy for Go applications to interact with Google Cloud Storage. | ||
It provides simple functions for tasks like uploading files and generating signed URLs for secure access. | ||
This wrapper handles the complex details of the Google Cloud Storage API, allowing developers to use storage features | ||
with less code and effort. | ||
|
||
### installation | ||
```shell | ||
go get -d github.com/michaelwp/go-gcs-wrapper | ||
``` | ||
|
||
### basic of use | ||
- Upload file | ||
```go | ||
package main | ||
|
||
import ( | ||
"context" | ||
"github.com/joho/godotenv" | ||
gogcswrapper "github.com/michaelwp/go-gcs-wrapper" | ||
"log" | ||
"os" | ||
) | ||
|
||
func init() { | ||
err := godotenv.Load(".env") | ||
if err != nil { | ||
log.Fatal("Error loading .env file", err) | ||
} | ||
} | ||
|
||
func main() { | ||
projectId := os.Getenv("GOOGLE_APPLICATION_PROJECT_ID") | ||
bucket := os.Getenv("GOOGLE_APPLICATION_BUCKET") | ||
object := "go_gcs.png" | ||
uploadObjPath := "upload_tes" | ||
localObjPath := "." | ||
|
||
ctx := context.Background() | ||
gcs := gogcswrapper.NewGCS(ctx, projectId) | ||
|
||
params := &gogcswrapper.UploadParams{ | ||
BucketAndObject: &gogcswrapper.BucketAndObject{ | ||
Bucket: bucket, | ||
Object: object, | ||
}, | ||
LocalObjPath: localObjPath, | ||
UploadObjPath: uploadObjPath, | ||
} | ||
|
||
err := gcs.Upload(ctx, params) | ||
if err != nil { | ||
log.Fatal("error uploading file", err) | ||
} | ||
} | ||
``` | ||
|
||
- Generate signed Url | ||
```go | ||
package main | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"github.com/joho/godotenv" | ||
gogcswrapper "github.com/michaelwp/go-gcs-wrapper" | ||
"log" | ||
"os" | ||
"time" | ||
) | ||
|
||
func init() { | ||
err := godotenv.Load(".env") | ||
if err != nil { | ||
log.Fatal("Error loading .env file", err) | ||
} | ||
} | ||
|
||
func main() { | ||
projectId := os.Getenv("GOOGLE_APPLICATION_PROJECT_ID") | ||
bucket := os.Getenv("GOOGLE_APPLICATION_BUCKET") | ||
object := "go_gcs.png" | ||
uploadObjPath := "upload_tes" | ||
|
||
ctx := context.Background() | ||
gcs := gogcswrapper.NewGCS(ctx, projectId) | ||
|
||
params := &gogcswrapper.GenerateSignedURLParams{ | ||
BucketAndObject: &gogcswrapper.BucketAndObject{ | ||
Bucket: bucket, | ||
Object: object, | ||
}, | ||
UploadObjPath: uploadObjPath, | ||
ExpirationTime: time.Now().Add(time.Minute * 10), | ||
} | ||
|
||
signedUrl, err := gcs.GenerateSignedURL(params) | ||
if err != nil { | ||
log.Fatal("error generating sign url", err) | ||
} | ||
|
||
fmt.Printf("Signed URL: %s\n", signedUrl) | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
author: Michael Putong @2024 | ||
This is an example on how to implement go-gcs-wrapper | ||
to generate a Google Cloud Storage's signedUrl | ||
visit the code repository in github.com/michaelwp/go-gcs-wrapper | ||
*/ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"github.com/joho/godotenv" | ||
gogcswrapper "github.com/michaelwp/go-gcs-wrapper" | ||
"log" | ||
"os" | ||
"time" | ||
) | ||
|
||
func init() { | ||
err := godotenv.Load(".env") | ||
if err != nil { | ||
log.Fatal("Error loading .env file", err) | ||
} | ||
} | ||
|
||
func main() { | ||
projectId := os.Getenv("GOOGLE_APPLICATION_PROJECT_ID") | ||
bucket := os.Getenv("GOOGLE_APPLICATION_BUCKET") | ||
object := "go_gcs.png" | ||
uploadObjPath := "upload_tes" | ||
|
||
ctx := context.Background() | ||
gcs := gogcswrapper.NewGCS(ctx, projectId) | ||
|
||
params := &gogcswrapper.GenerateSignedURLParams{ | ||
BucketAndObject: &gogcswrapper.BucketAndObject{ | ||
Bucket: bucket, | ||
Object: object, | ||
}, | ||
UploadObjPath: uploadObjPath, | ||
ExpirationTime: time.Now().Add(time.Minute * 10), | ||
} | ||
|
||
signedUrl, err := gcs.GenerateSignedURL(params) | ||
if err != nil { | ||
log.Fatal("error generating sign url", err) | ||
} | ||
|
||
fmt.Printf("Signed URL: %s\n", signedUrl) | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/* | ||
author: Michael Putong @2024 | ||
This is an example on how to implement go-gcs-wrapper | ||
to upload a file to Google Cloud Storage | ||
visit the code repository in github.com/michaelwp/go-gcs-wrapper | ||
*/ | ||
|
||
package main | ||
|
||
import ( | ||
"context" | ||
"github.com/joho/godotenv" | ||
gogcswrapper "github.com/michaelwp/go-gcs-wrapper" | ||
"log" | ||
"os" | ||
) | ||
|
||
func init() { | ||
err := godotenv.Load(".env") | ||
if err != nil { | ||
log.Fatal("Error loading .env file", err) | ||
} | ||
} | ||
|
||
func main() { | ||
projectId := os.Getenv("GOOGLE_APPLICATION_PROJECT_ID") | ||
bucket := os.Getenv("GOOGLE_APPLICATION_BUCKET") | ||
object := "go_gcs.png" | ||
uploadObjPath := "upload_tes" | ||
localObjPath := "." | ||
|
||
ctx := context.Background() | ||
gcs := gogcswrapper.NewGCS(ctx, projectId) | ||
|
||
params := &gogcswrapper.UploadParams{ | ||
BucketAndObject: &gogcswrapper.BucketAndObject{ | ||
Bucket: bucket, | ||
Object: object, | ||
}, | ||
LocalObjPath: localObjPath, | ||
UploadObjPath: uploadObjPath, | ||
} | ||
|
||
err := gcs.Upload(ctx, params) | ||
if err != nil { | ||
log.Fatal("error uploading file", err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
tes upload file to gcs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
/* | ||
author: Michael Putong @2024 | ||
----------------------------------------------------------------- | ||
This is a library that is wrapping the Google Cloud Storage Library | ||
to simplify the interaction within Go application and Google Cloud Storage. | ||
----------------------------------------------------------------- | ||
This code is free to use, modify and distribute, although | ||
the author is not responsible for any damage occurred in its use. | ||
----------------------------------------------------------------- | ||
visit the code repository in github.com/michaelwp/go-semaphore | ||
*/ | ||
|
||
package go_gcs_wrapper | ||
|
||
import ( | ||
"cloud.google.com/go/storage" | ||
"context" | ||
"fmt" | ||
"io" | ||
"log" | ||
"os" | ||
"time" | ||
) | ||
|
||
type Gcs interface { | ||
Upload(ctx context.Context, params *UploadParams) error | ||
GenerateSignedURL(params *GenerateSignedURLParams) (string, error) | ||
} | ||
|
||
type gcs struct { | ||
StorageClient *storage.Client | ||
ProjectId string | ||
} | ||
|
||
type BucketAndObject struct { | ||
Bucket string | ||
Object string | ||
} | ||
|
||
type UploadParams struct { | ||
LocalObjPath string | ||
UploadObjPath string | ||
*BucketAndObject | ||
} | ||
|
||
type GenerateSignedURLParams struct { | ||
*BucketAndObject | ||
ExpirationTime time.Time | ||
UploadObjPath string | ||
} | ||
|
||
func NewGCS(ctx context.Context, projectId string) Gcs { | ||
client, err := storage.NewClient(ctx) | ||
if err != nil { | ||
log.Fatal("failed to create GCS client") | ||
} | ||
return &gcs{ | ||
StorageClient: client, | ||
ProjectId: projectId, | ||
} | ||
} | ||
|
||
func (g gcs) Upload(ctx context.Context, params *UploadParams) error { | ||
// open the local file that is intended to be uploaded to GCS. | ||
// ensure the file is closed at the end. | ||
file, err := os.Open(params.LocalObjPath + "/" + params.Object) | ||
if err != nil { | ||
return fmt.Errorf("os.Open: %w", err) | ||
} | ||
defer func(f *os.File) { | ||
err := f.Close() | ||
if err != nil { | ||
log.Printf("failed to close file: %v", err) | ||
} | ||
}(file) | ||
|
||
// set the timeout to 1 minute | ||
ctx, cancel := context.WithTimeout(ctx, time.Minute*1) | ||
defer cancel() | ||
|
||
object := g.StorageClient. | ||
Bucket(params.Bucket). | ||
Object(params.UploadObjPath + "/" + params.Object) | ||
|
||
// set a generation-match precondition to avoid potential race | ||
// conditions and data corruptions. The request to upload is aborted if the | ||
// object's generation number does not match your precondition. | ||
object = object.If(storage.Conditions{DoesNotExist: true}) | ||
|
||
// Upload an object with storage.Writer, and close it at the end. | ||
writer := object.NewWriter(ctx) | ||
defer func(w *storage.Writer) { | ||
err := w.Close() | ||
if err != nil { | ||
log.Printf("failed to close writer: %v", err) | ||
} | ||
}(writer) | ||
|
||
_, err = io.Copy(writer, file) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
log.Printf("File %s successfully uploaded to %s/%s .\n", | ||
params.Object, params.Bucket, params.UploadObjPath) | ||
|
||
return nil | ||
} | ||
|
||
func (g gcs) GenerateSignedURL(params *GenerateSignedURLParams) (string, error) { | ||
// Set up the signed URL options. | ||
opts := &storage.SignedURLOptions{ | ||
Scheme: storage.SigningSchemeV4, | ||
Method: "GET", | ||
Expires: params.ExpirationTime, | ||
} | ||
|
||
// Signing a URL requires credentials authorized to sign a URL. You can pass | ||
// these in through SignedURLOptions with one of the following options: | ||
// a. a Google service account private key, obtainable from the Google Developers Console | ||
// b. a Google Access ID with iam.serviceAccounts.signBlob permissions | ||
// c. a SignBytes function implementing custom signing. | ||
// In this example, none of these options are used, which means the SignedURL | ||
// function attempts to use the same authentication that was used to instantiate | ||
// the Storage client. This authentication must include a private key or have | ||
// iam.serviceAccounts.signBlob permissions. | ||
signedUrl, err := g.StorageClient. | ||
Bucket(params.Bucket). | ||
SignedURL(params.UploadObjPath+"/"+params.Object, opts) | ||
if err != nil { | ||
log.Fatalf("Failed to generate signed URL: %v", err) | ||
} | ||
|
||
log.Println("SignedURL generated successfully") | ||
return signedUrl, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
module github.com/michaelwp/go-gcs-wrapper | ||
|
||
go 1.22 | ||
|
||
require cloud.google.com/go/storage v1.42.0 | ||
|
||
require ( | ||
cloud.google.com/go v0.114.0 // indirect | ||
cloud.google.com/go/auth v0.5.1 // indirect | ||
cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect | ||
cloud.google.com/go/compute/metadata v0.3.0 // indirect | ||
cloud.google.com/go/iam v1.1.8 // indirect | ||
github.com/felixge/httpsnoop v1.0.4 // indirect | ||
github.com/go-logr/logr v1.4.1 // indirect | ||
github.com/go-logr/stdr v1.2.2 // indirect | ||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect | ||
github.com/golang/protobuf v1.5.4 // indirect | ||
github.com/google/s2a-go v0.1.7 // indirect | ||
github.com/google/uuid v1.6.0 // indirect | ||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect | ||
github.com/googleapis/gax-go/v2 v2.12.4 // indirect | ||
github.com/joho/godotenv v1.5.1 // indirect | ||
go.opencensus.io v0.24.0 // indirect | ||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect | ||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect | ||
go.opentelemetry.io/otel v1.24.0 // indirect | ||
go.opentelemetry.io/otel/metric v1.24.0 // indirect | ||
go.opentelemetry.io/otel/trace v1.24.0 // indirect | ||
golang.org/x/crypto v0.23.0 // indirect | ||
golang.org/x/net v0.25.0 // indirect | ||
golang.org/x/oauth2 v0.21.0 // indirect | ||
golang.org/x/sync v0.7.0 // indirect | ||
golang.org/x/sys v0.20.0 // indirect | ||
golang.org/x/text v0.15.0 // indirect | ||
golang.org/x/time v0.5.0 // indirect | ||
google.golang.org/api v0.183.0 // indirect | ||
google.golang.org/genproto v0.0.0-20240528184218-531527333157 // indirect | ||
google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 // indirect | ||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect | ||
google.golang.org/grpc v1.64.0 // indirect | ||
google.golang.org/protobuf v1.34.1 // indirect | ||
) |
Oops, something went wrong.