Skip to content

Commit

Permalink
feat(core): add addr fetch logic in gcp resolver
Browse files Browse the repository at this point in the history
  • Loading branch information
shivanshkc committed Jul 12, 2022
1 parent 090e91d commit 7ee2dff
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 26 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/gorilla/websocket v1.5.0
go.mongodb.org/mongo-driver v1.9.1
go.uber.org/zap v1.21.0
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f
)

require (
Expand All @@ -31,7 +32,6 @@ require (
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
Expand Down
22 changes: 5 additions & 17 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,13 @@ func main() {
resolver := discovery.NewResolver()
go func() {
time.Sleep(time.Second * 2)
fmt.Println("Attempting fetches...")
fmt.Println("Attempting fetch...")

pid, errP := resolver.GetProjectID(ctx)
if errP != nil {
panic("failed to get project id:" + errP.Error())
addr, err := resolver.GetAddress(ctx)
if err != nil {
panic("failed to get addr:" + err.Error())
}
fmt.Println(">>>> pid:", pid)

region, errR := resolver.GetRegion(ctx)
if errR != nil {
panic("failed to get region:" + errR.Error())
}
fmt.Println(">>>> region:", region)

token, errT := resolver.GetToken(ctx)
if errT != nil {
panic("failed to get token:" + errT.Error())
}
fmt.Println(">>>> token:", token)
fmt.Println(">>>> addr:", addr)
}()

// Setting core dependencies.
Expand Down
131 changes: 123 additions & 8 deletions src/impl/discovery/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@ package discovery

import (
"context"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"os"
"strings"

"github.com/shivanshkc/rosenbridge/src/utils/httputils"

"golang.org/x/sync/errgroup"
)

const (
Expand Down Expand Up @@ -35,7 +41,7 @@ func (r *ResolverCloudRun) Resolve() string {
return r.discoveryAddr
}

func (r *ResolverCloudRun) GetProjectID(ctx context.Context) (string, error) {
func (r *ResolverCloudRun) getProjectID(ctx context.Context) (string, error) {
endpoint := fmt.Sprintf("%s%s", gcpMetadataBaseURL, gcpProjectIDURL)
// Forming the HTTP request.
request, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
Expand Down Expand Up @@ -68,7 +74,7 @@ func (r *ResolverCloudRun) GetProjectID(ctx context.Context) (string, error) {
return string(projectIDBytes), nil
}

func (r *ResolverCloudRun) GetRegion(ctx context.Context) (string, error) {
func (r *ResolverCloudRun) getRegion(ctx context.Context) (string, error) {
endpoint := fmt.Sprintf("%s%s", gcpMetadataBaseURL, gcpRegionURL)
// Forming the HTTP request.
request, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
Expand Down Expand Up @@ -98,11 +104,15 @@ func (r *ResolverCloudRun) GetRegion(ctx context.Context) (string, error) {
return "", fmt.Errorf("error in ioutil.Readall call: %w", err)
}

fmt.Println("Region bytes:", string(regionBytes))
return string(regionBytes), nil
// Region is of the form: "projects/948115683669/regions/us-central1".
// So, we split it by "/" character and then take the last element.
regionElements := strings.Split(string(regionBytes), "/")
region := regionElements[len(regionElements)-1]

return region, nil
}

func (r *ResolverCloudRun) GetToken(ctx context.Context) (string, error) {
func (r *ResolverCloudRun) getToken(ctx context.Context) (string, error) {
endpoint := fmt.Sprintf("%s%s", gcpMetadataBaseURL, gcpTokenURL)
// Forming the HTTP request.
request, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
Expand All @@ -126,12 +136,117 @@ func (r *ResolverCloudRun) GetToken(ctx context.Context) (string, error) {
return "", fmt.Errorf("response has unsuccessful status: %d", response.StatusCode)
}

// This is the expected response body structure.
bodyStruct := &struct {
AccessToken string `json:"access_token"`
ExpiresIn int `json:"expires_in"`
TokenType string `json:"token_type"`
}{}

// Decoding the response body into the intended struct.
if err := json.NewDecoder(response.Body).Decode(bodyStruct); err != nil {
return "", fmt.Errorf("error in json.NewDecoder(...).Decode call: %w", err)
}

// Returning the access token.
return bodyStruct.AccessToken, nil
}

func (r *ResolverCloudRun) GetAddress(ctx context.Context) (string, error) {
kService := os.Getenv("K_SERVICE")
if kService == "" {
return "", errors.New("K_SERVICE env var is empty")
}

// Creating an err-group to manage multiple goroutines.
eGroup, eCtx := errgroup.WithContext(ctx)

// Creating a channel to receive the project ID.
projectIDChan := make(chan string, 1)
defer close(projectIDChan)

// Project ID goroutine.
eGroup.Go(func() error {
projectID, err := r.getProjectID(eCtx)
if err != nil {
return fmt.Errorf("error in getProjectID call: %w", err)
}

projectIDChan <- projectID
return nil
})

// Creating a channel to receive the region.
regionChan := make(chan string, 1)
defer close(regionChan)

// Region goroutine.
eGroup.Go(func() error {
region, err := r.getRegion(eCtx)
if err != nil {
return fmt.Errorf("error in getRegion call: %w", err)
}

regionChan <- region
return nil
})

// Creating a channel to receive the token.
tokenChan := make(chan string, 1)
defer close(tokenChan)

// Region goroutine.
eGroup.Go(func() error {
token, err := r.getToken(eCtx)
if err != nil {
return fmt.Errorf("error in getToken call: %w", err)
}

tokenChan <- token
return nil
})

// Awaiting goroutine completions.
if err := eGroup.Wait(); err != nil {
return "", fmt.Errorf("error in eGroup.Wait call: %w", err)
}

// Retrieving the values from channels.
projectID, region, token := <-projectIDChan, <-regionChan, <-tokenChan

// Forming the API route.
endpoint := fmt.Sprintf("https://%s-run.googleapis.com/apis/serving.knative.dev/v1/namespaces/%s/services/%s",
region, projectID, kService)

// Forming the HTTP request.
request, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
if err != nil {
return "", fmt.Errorf("error in http.NewRequestWithContext call: %w", err)
}

// Setting the auth header.
request.Header.Set("authorization", fmt.Sprintf("Bearer %s", token))

// Creating the HTTP client.
client := &http.Client{}
// Executing the request.
response, err := client.Do(request)
if err != nil {
return "", fmt.Errorf("error in client.Do call: %w", err)
}
// Closing response body upon function return.
defer func() { _ = response.Body.Close() }()
// Handling unsuccessful responses.
if httputils.Is2xx(response.StatusCode) {
return "", fmt.Errorf("response has unsuccessful status: %d", response.StatusCode)
}

// Reading the response body into a byte slice.
tokenBytes, err := ioutil.ReadAll(response.Body)
addrBytes, err := ioutil.ReadAll(response.Body)
if err != nil {
return "", fmt.Errorf("error in ioutil.Readall call: %w", err)
}

fmt.Println("token bytes:", string(tokenBytes))
return string(tokenBytes), nil
fmt.Println("Addr bytes:", string(addrBytes))
return string(addrBytes), nil
}

0 comments on commit 7ee2dff

Please sign in to comment.