Skip to content
This repository has been archived by the owner on Dec 11, 2023. It is now read-only.

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
msniveau committed Feb 7, 2023
0 parents commit a55ac06
Show file tree
Hide file tree
Showing 9 changed files with 1,157 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# IntelliJ
/.idea/
/*.iml

# Testing
/testing/
61 changes: 61 additions & 0 deletions .golangci.yml
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...
674 changes: 674 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

52 changes: 52 additions & 0 deletions README.md
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)
}
}
```
25 changes: 25 additions & 0 deletions go.mod
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
)
168 changes: 168 additions & 0 deletions go.sum

Large diffs are not rendered by default.

90 changes: 90 additions & 0 deletions pkg/gpcloud/client/auth.go
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
}
78 changes: 78 additions & 0 deletions pkg/gpcloud/client/client.go
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,
}
}
3 changes: 3 additions & 0 deletions pkg/gpcloud/client/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package client

const Version = "23.2.0"

0 comments on commit a55ac06

Please sign in to comment.