This repository has been archived by the owner on Dec 11, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit a55ac06
Showing
9 changed files
with
1,157 additions
and
0 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 |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# IntelliJ | ||
/.idea/ | ||
/*.iml | ||
|
||
# Testing | ||
/testing/ |
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,61 @@ | ||
--- | ||
|
||
run: | ||
timeout: 30m | ||
|
||
concurrency: 2 | ||
|
||
issue-exit-code: 1 | ||
|
||
tests: true | ||
|
||
allow-parallel-runners: true | ||
|
||
output: | ||
path-prefix: "backend" | ||
|
||
linters: | ||
disable-all: true | ||
enable: | ||
- deadcode | ||
- depguard | ||
- errcheck | ||
- exportloopref | ||
- goconst | ||
- gofmt | ||
- goimports | ||
- goprintffuncname | ||
- gosec | ||
- gosimple | ||
- govet | ||
- ineffassign | ||
# - lll - TODO: enable later | ||
- misspell | ||
- nakedret | ||
- nolintlint | ||
- rowserrcheck | ||
- staticcheck | ||
- structcheck | ||
- stylecheck | ||
- typecheck | ||
- unconvert | ||
- unparam | ||
- unused | ||
- varcheck | ||
- whitespace | ||
|
||
linters-settings: | ||
gosec: | ||
excludes: | ||
- G109 # Integer overflow | ||
- G204 # Subprocess arguments | ||
- G203 # Escape HTML | ||
- G402 # Insecure skip verify | ||
- G505 # Allow sha1 | ||
- G401 # Allow sha1 | ||
config: | ||
G306: "0660" | ||
|
||
misspell: | ||
ignore-words: | ||
- payed # Requires alter table... |
Large diffs are not rendered by default.
Oops, something went wrong.
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,52 @@ | ||
# GPCloud Golang Client | ||
|
||
This is the official GPCloud Golang client. Please raise an issue if you have found any problems or having questions. | ||
|
||
### Recommendations | ||
|
||
- Golang 1.18 or higher | ||
|
||
### Example usage | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"context" | ||
"log" | ||
|
||
authv1 "buf.build/gen/go/gportal/gportal-cloud/protocolbuffers/go/gpcloud/api/auth/v1" | ||
cloudv1 "buf.build/gen/go/gportal/gportal-cloud/protocolbuffers/go/gpcloud/api/cloud/v1" | ||
"github.com/G-PORTAL/gpcloud-go/pkg/gpcloud/client" | ||
) | ||
|
||
func main() { | ||
conn, err := client.NewClient( | ||
// For getting your own client ID and client Secret please ask support | ||
client.AuthOptions{ | ||
ClientID: "my-custom-client-id", | ||
ClientSecret: "my-custom-client-secret", | ||
Username: "example@gpcloud.customer", | ||
Password: "password123", | ||
}, | ||
) | ||
if err != nil { | ||
log.Fatal("failed to create client:\n", err) | ||
} | ||
|
||
ctx := context.Background() | ||
user, err := conn.AuthClient().GetUser(ctx, &authv1.GetUserRequest{}) | ||
if err != nil { | ||
log.Fatal("failed to fetch user information:\n", err) | ||
} | ||
log.Println("User ID: ", user.User.Id) | ||
|
||
projects, err := conn.CloudClient().ListProjects(ctx, &cloudv1.ListProjectsRequest{}) | ||
if err != nil { | ||
log.Fatal("failed to fetch project list: \n", err) | ||
} | ||
for _, project := range projects.Projects { | ||
log.Println("Project ID: ", project.Id) | ||
} | ||
} | ||
``` |
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,25 @@ | ||
module github.com/G-PORTAL/gpcloud-go | ||
|
||
go 1.18 | ||
|
||
require ( | ||
buf.build/gen/go/gportal/gportal-cloud/grpc/go v1.2.0-20230207110106-cd61926e15d5.4 | ||
buf.build/gen/go/gportal/gportal-cloud/protocolbuffers/go v1.28.1-20230207110106-cd61926e15d5.4 | ||
github.com/Nerzal/gocloak/v12 v12.0.0 | ||
google.golang.org/grpc v1.43.0 | ||
) | ||
|
||
require ( | ||
github.com/go-resty/resty/v2 v2.7.0 // indirect | ||
github.com/golang-jwt/jwt/v4 v4.4.2 // indirect | ||
github.com/golang/protobuf v1.5.2 // indirect | ||
github.com/google/go-cmp v0.5.6 // indirect | ||
github.com/opentracing/opentracing-go v1.2.0 // indirect | ||
github.com/pkg/errors v0.9.1 // indirect | ||
github.com/segmentio/ksuid v1.0.4 // indirect | ||
golang.org/x/net v0.0.0-20221019024206-cb67ada4b0ad // indirect | ||
golang.org/x/sys v0.0.0-20221010170243-090e33056c14 // indirect | ||
golang.org/x/text v0.3.7 // indirect | ||
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect | ||
google.golang.org/protobuf v1.28.1 // indirect | ||
) |
Large diffs are not rendered by default.
Oops, something went wrong.
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,90 @@ | ||
package client | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"time" | ||
|
||
"github.com/Nerzal/gocloak/v12" | ||
) | ||
|
||
const defaultKeycloakHostname = "https://auth.g-portal.com/auth" | ||
const defaultKeycloakRealm = "master" | ||
|
||
type GPCloudAuth struct { | ||
jwtToken *gocloak.JWT | ||
gocloakClient *gocloak.GoCloak | ||
expires time.Time | ||
authOpts *AuthOptions | ||
} | ||
|
||
type AuthOptions struct { | ||
ClientID string | ||
ClientSecret string | ||
Username string | ||
Password string | ||
Realm *string | ||
Hostname *string | ||
} | ||
|
||
func (authOptions *AuthOptions) GetRealm() string { | ||
if authOptions.Realm == nil { | ||
return defaultKeycloakRealm | ||
} | ||
return *authOptions.Realm | ||
} | ||
func (authOptions *AuthOptions) GetHostname() string { | ||
if authOptions.Hostname == nil { | ||
return defaultKeycloakHostname | ||
} | ||
return *authOptions.Hostname | ||
} | ||
|
||
func (a *GPCloudAuth) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { | ||
if a.expires.Before(time.Now()) { | ||
if err := a.refresh(); err != nil { | ||
if err2 := a.login(); err2 != nil { | ||
return nil, err2 | ||
} | ||
return nil, err | ||
} | ||
} | ||
return map[string]string{ | ||
"authorization": fmt.Sprintf("Bearer %s", a.jwtToken.AccessToken), | ||
}, nil | ||
} | ||
|
||
func (a *GPCloudAuth) RequireTransportSecurity() bool { | ||
return true | ||
} | ||
|
||
func NewAuth(opts *AuthOptions) (*GPCloudAuth, error) { | ||
auth := &GPCloudAuth{ | ||
authOpts: opts, | ||
} | ||
auth.gocloakClient = gocloak.NewClient(opts.GetHostname()) | ||
if err := auth.login(); err != nil { | ||
return nil, err | ||
} | ||
return auth, nil | ||
} | ||
|
||
func (a *GPCloudAuth) login() error { | ||
token, err := a.gocloakClient.Login(context.Background(), a.authOpts.ClientID, a.authOpts.ClientSecret, a.authOpts.GetRealm(), a.authOpts.Username, a.authOpts.Password) | ||
if err != nil { | ||
return err | ||
} | ||
a.jwtToken = token | ||
a.expires = time.Now().Add(time.Duration(token.ExpiresIn-10) * time.Second) | ||
return nil | ||
} | ||
|
||
func (a *GPCloudAuth) refresh() error { | ||
token, err := a.gocloakClient.RefreshToken(context.Background(), a.jwtToken.RefreshToken, a.authOpts.ClientID, a.authOpts.ClientSecret, a.authOpts.GetRealm()) | ||
if err != nil { | ||
return err | ||
} | ||
a.jwtToken = token | ||
a.expires = time.Now().Add(time.Duration(token.ExpiresIn-10) * time.Second) | ||
return 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,78 @@ | ||
package client | ||
|
||
import ( | ||
"crypto/tls" | ||
"fmt" | ||
|
||
"buf.build/gen/go/gportal/gportal-cloud/grpc/go/gpcloud/api/auth/v1/authv1grpc" | ||
"buf.build/gen/go/gportal/gportal-cloud/grpc/go/gpcloud/api/cloud/v1/cloudv1grpc" | ||
"buf.build/gen/go/gportal/gportal-cloud/grpc/go/gpcloud/api/metadata/v1/metadatav1grpc" | ||
"buf.build/gen/go/gportal/gportal-cloud/grpc/go/gpcloud/api/network/v1/networkv1grpc" | ||
"buf.build/gen/go/gportal/gportal-cloud/grpc/go/gpcloud/api/payment/v1/paymentv1grpc" | ||
"google.golang.org/grpc/credentials" | ||
|
||
"google.golang.org/grpc" | ||
) | ||
|
||
const DefaultEndpoint = "grpc.gpcloud.space:443" | ||
|
||
type Client struct { | ||
grpcClient *grpc.ClientConn | ||
} | ||
|
||
// CloudClient Returns the CloudServiceClient | ||
func (c *Client) CloudClient() cloudv1grpc.CloudServiceClient { | ||
return cloudv1grpc.NewCloudServiceClient(c.grpcClient) | ||
} | ||
|
||
// AuthClient Returns the CloudServiceClient | ||
func (c *Client) AuthClient() authv1grpc.AuthServiceClient { | ||
return authv1grpc.NewAuthServiceClient(c.grpcClient) | ||
} | ||
|
||
// MetadataClient Returns the MetadataServiceClient | ||
func (c *Client) MetadataClient() metadatav1grpc.MetadataServiceClient { | ||
return metadatav1grpc.NewMetadataServiceClient(c.grpcClient) | ||
} | ||
|
||
// NetworkClient Returns the NetworkServiceClient | ||
func (c *Client) NetworkClient() networkv1grpc.NetworkServiceClient { | ||
return networkv1grpc.NewNetworkServiceClient(c.grpcClient) | ||
} | ||
|
||
// PaymentClient Returns the PaymentServiceClient | ||
func (c *Client) PaymentClient() paymentv1grpc.PaymentServiceClient { | ||
return paymentv1grpc.NewPaymentServiceClient(c.grpcClient) | ||
} | ||
|
||
// NewClient Returns a new GRPC client | ||
func NewClient(authOptions AuthOptions, options ...grpc.DialOption) (*Client, error) { | ||
cl := &Client{} | ||
|
||
// Certificate pinning | ||
options = append(options, grpc.WithTransportCredentials(credentials.NewTLS(getTLSOptions()))) | ||
|
||
// User Agent | ||
options = append(options, grpc.WithUserAgent(fmt.Sprintf("GPCloud Golang Client [%s]", Version))) | ||
|
||
auth, err := NewAuth(&authOptions) | ||
if err != nil { | ||
return nil, err | ||
} | ||
// Access Token | ||
options = append(options, grpc.WithPerRPCCredentials(auth)) | ||
|
||
clientConn, err := grpc.Dial(DefaultEndpoint, options...) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
cl.grpcClient = clientConn | ||
return cl, nil | ||
} | ||
|
||
func getTLSOptions() *tls.Config { | ||
return &tls.Config{ | ||
MinVersion: tls.VersionTLS12, | ||
} | ||
} |
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,3 @@ | ||
package client | ||
|
||
const Version = "23.2.0" |