-
-
Save tommed/63f4740402ecc95e794963285f2e6042 to your computer and use it in GitHub Desktop.
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
package gcp_api | |
import ( | |
"errors" | |
"fmt" | |
"google.golang.org/api/googleapi" | |
"google.golang.org/api/option" | |
"google.golang.org/api/run/v1" | |
"strings" | |
) | |
const ( | |
cloudRunAPIVersion = "serving.knative.dev/v1" | |
cloudRunServiceKind = "Service" | |
) | |
// current list: https://cloud.google.com/run/docs/reference/rest/#rest_endpoints | |
var cloudRunEndpoints = []string{ | |
"https://us-central1-run.googleapis.com", | |
"https://asia-northeast1-run.googleapis.com", | |
"https://europe-west1-run.googleapis.com", | |
"https://us-east1-run.googleapis.com", | |
} | |
func findCloudRunEndpoint(location string) (string, error) { | |
for _, ep := range cloudRunEndpoints { | |
if strings.Contains(ep, location) { | |
return ep, nil | |
} | |
} | |
return "", fmt.Errorf("Unable to find a supported CloudRun endpoint for location %s. List of supported endpoints available here, supply us with just location part: <https://cloud.google.com/run/docs/reference/rest/#rest_endpoints>", location) | |
} | |
type GCPCloudRunEndpoint struct { | |
api *GCPAPI | |
service *run.APIService | |
location string | |
} | |
func (api GCPAPI) CloudRun(location string) (*GCPCloudRunEndpoint, error) { | |
// endpoint dictates location | |
ep, err := findCloudRunEndpoint(location) | |
if err != nil { return nil, err } | |
var opts = api.clientOptions() // returns [option.WithCredentialsFile(serviceAccountFile)] | |
opts = append(opts, option.WithEndpoint(ep)) | |
// build service using the selected endpoint | |
svc, err := run.NewService(api.ctx, opts...) | |
if err != nil { | |
return nil, err | |
} | |
return &GCPCloudRunEndpoint{ | |
service: svc, | |
location: location, | |
api: &api}, nil | |
} | |
func (api GCPCloudRunEndpoint) ServiceIsUpdated(projectID string, serviceName string, imageName string, envVars map[string]string, serviceAccountEmail string) (string, error) { | |
var projectNumber = api.api.ProjectNumber | |
// convert env vars | |
var kNativeEnvVars = make([]*run.EnvVar, 0) | |
if envVars != nil { | |
for k, v := range envVars { | |
kNativeEnvVars = append(kNativeEnvVars, &run.EnvVar{ | |
Name: k, | |
Value: v, | |
}) | |
} | |
} | |
// define the service | |
var serviceDefinition = &run.Service{ | |
ApiVersion: cloudRunAPIVersion, | |
Kind: cloudRunServiceKind, | |
Metadata: &run.ObjectMeta{ | |
Name: serviceName, | |
Namespace: string(projectNumber), | |
Generation: 1, | |
Labels: map[string]string{ "cloud.googleapis.com/location": api.location }, | |
}, | |
Spec: &run.ServiceSpec{ | |
Template: &run.RevisionTemplate{ | |
Metadata: &run.ObjectMeta{ | |
Name: serviceName, | |
Annotations: map[string]string{ | |
"autoscaling.knative.dev/maxScale": "1000", | |
}, | |
}, | |
Spec: &run.RevisionSpec{ | |
ContainerConcurrency: 80, | |
// ServiceAccountName: serviceAccountEmail, | |
TimeoutSeconds: 300, | |
Containers: []*run.Container{ | |
{ | |
Image: imageName, | |
Env: kNativeEnvVars, | |
Ports: []*run.ContainerPort{ | |
{ | |
ContainerPort: 8080, | |
}, | |
}, | |
Resources: &run.ResourceRequirements{ | |
Limits: map[string]string{ | |
"memory": "256Mi", | |
"cpu": "1000m", | |
}, | |
}, | |
}, | |
}, | |
}, | |
}, | |
Traffic: []*run.TrafficTarget{ | |
{ | |
LatestRevision: true, | |
Percent: 100, | |
}, | |
}, | |
}, | |
} | |
// upsert | |
var parentUri = fmt.Sprintf("namespaces/%s", projectID) | |
var serviceUri = fmt.Sprintf("%s/services/%s", parentUri, serviceName) | |
var status = "CloudRun service was created" | |
_, err := api.service.Namespaces.Services.Get(serviceUri).Do() | |
if err == nil { | |
// service already exists | |
_, err = api.service.Namespaces.Services.ReplaceService(serviceUri, serviceDefinition).Do() | |
} else { | |
// update existing service | |
_, err = api.service.Namespaces.Services.Create(parentUri, serviceDefinition).Do() | |
status = "CloudRun service was updated" | |
} | |
if err != nil { | |
v, isGoogleError := err.(*googleapi.Error) | |
if isGoogleError { | |
return "", errors.New(v.Body) | |
} | |
return "", err | |
} | |
return status, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment