Skip to content

Commit

Permalink
Merge pull request #48 from BESTSELLER/ES-1219_cloud_run
Browse files Browse the repository at this point in the history
Es 1219 cloud run
  • Loading branch information
wrighbr authored Jan 25, 2021
2 parents caf405d + ec90e13 commit 766b613
Show file tree
Hide file tree
Showing 7 changed files with 214 additions and 112 deletions.
157 changes: 78 additions & 79 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
version: 2.1
executors:
gcp_image:
docker:
- image: google/cloud-sdk:alpine
go_image:
docker:
- image: cimg/go:1.15
Expand Down Expand Up @@ -72,84 +75,74 @@ jobs:
-Dsonar.links.scm=$CIRCLE_REPOSITORY_URL \
-Dsonar.go.coverage.reportPaths=coverage.out
docker-build-n-push:
docker:
- image: docker:stable-git
auth:
username: $DOCKERHUB_USER
password: $DOCKERHUB_PASS
build-push-serverless:
executor: gcp_image
steps:
- attach_workspace:
at: /tmp
- checkout
- setup_remote_docker
- attach_workspace:
at: /tmp
- run:
name: Push and build image
name: install jq
command: |
source /tmp/secrets
docker login -u $DOCKER_username -p $DOCKER_password $K8S_CLUSTER_docker_registry_url
docker build \
-t $K8S_CLUSTER_docker_registry_url/$SHORT/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG \
-t $K8S_CLUSTER_docker_registry_url/$SHORT/$CIRCLE_PROJECT_REPONAME:latest \
--build-arg VERSION=$CIRCLE_TAG .
docker push $K8S_CLUSTER_docker_registry_url/$SHORT/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG
docker push $K8S_CLUSTER_docker_registry_url/$SHORT/$CIRCLE_PROJECT_REPONAME:latest
apk add --no-cache jq
- run:
name: Build and push image
command: |
# source /tmp/secrets
deploy:
docker:
- image: google/cloud-sdk:alpine
auth:
username: $DOCKERHUB_USER
password: $DOCKERHUB_PASS
gcloud auth activate-service-account --key-file=/tmp/cluster_secret.json
gcloud auth configure-docker europe-docker.pkg.dev --quiet
export docker_registry_url=europe-docker.pkg.dev/es-standalone-cb21
docker build -t $docker_registry_url/es-docker/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG .
docker build -t $docker_registry_url/es-docker/$CIRCLE_PROJECT_REPONAME:$latest .
docker push $docker_registry_url/es-docker/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG
docker push $docker_registry_url/es-docker/$CIRCLE_PROJECT_REPONAME:latest
deploy-serverless:
executor: gcp_image
steps:
- checkout
- attach_workspace:
at: /tmp
- run:
name: gcloud login
command: |
source /tmp/secrets
gcloud auth activate-service-account --key-file=/tmp/cluster_secret.json
- run:
name: install kubectl
name: install jq
command: |
curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl
chmod +x ./kubectl
mv ./kubectl /usr/local/bin/kubectl
apk add --no-cache jq
- run:
name: connect to the cluster
name: gcloud login
command: |
source /tmp/secrets
gcloud container clusters get-credentials $K8S_CLUSTER_cluster_name --project $K8S_CLUSTER_project_id --zone europe-west4
gcloud components install beta
cat /tmp/cloudrun_admin | jq -r .private_key_data | base64 -d > cloudrun-admin.json
gcloud auth activate-service-account --key-file=./cloudrun-admin.json
- run:
name: Install envsubt
name: creating deployment
command: |
apk update
apk add gettext
gcloud beta run deploy $CIRCLE_PROJECT_REPONAME \
--image=europe-docker.pkg.dev/es-standalone-cb21/es-docker/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG \
--allow-unauthenticated \
--min-instances=1 \
--max-instances=100 \
--port=3000 \
--platform=managed \
--region=europe-west4 \
--project=es-standalone-cb21 \
--set-env-vars VAULT_ADDR="${VAULT_ADDR}",VAULT_ROLE=dependabot-circleci,VAULT_SECRET=ES/data/dependabot-circleci/prod,DEPENDABOT_VERSION=${$CIRCLE_TAG},DEPENDABOT_CONFIG=/secrets/secrets \
--service-account=dependabot-circleci@es-standalone-cb21.iam.gserviceaccount.com
- run:
name: replace strings
name: create domain mapping
command: |
source /tmp/secrets
if [[ ${CIRCLE_BRANCH} = "master" ]] || [[ ${CIRCLE_TAG} =~ ^[0-9]+(\.[0-9]+)*(-.*)*$ ]];
then
export DEPLOY_VERSION=''
export SECRET_VERSION=prod
else
export DEPLOY_VERSION=-$CIRCLE_BRANCH
echo 'export DEPLOY_VERSION="-$CIRCLE_BRANCH"' >> $BASH_ENV
source ${BASH_ENV}
export SECRET_VERSION=$CIRCLE_BRANCH
if ! gcloud beta run domain-mappings describe --domain=bestsellerit.com --platform=managed --region=europe-west1 --project=es-standalone-cb21; then
gcloud beta run domain-mappings create \
--service=$CIRCLE_PROJECT_REPONAME \
--domain=bestsellerit.com \
--platform=managed \
--region=europe-west1 \
--project=es-standalone-cb21
fi
envsubst < ./secrets.yml > ./secrets_var.yml && mv ./secrets_var.yml ./secrets.yml
envsubst < ./deployment.yml > ./deployment_var.yml && mv ./deployment_var.yml ./deployment.yml
- secret-injector/inject:
app-name: $CIRCLE_PROJECT_REPONAME$DEPLOY_VERSION
deploy-file: ./deployment.yml
secret-file: secrets.yml
- run:
name: create kubernetes service
command: |
kubectl apply -f ./deployment.yml
workflows:
test:
Expand Down Expand Up @@ -177,55 +170,61 @@ workflows:
tags:
ignore: /^[0-9]+(\.[0-9]+)*(-.*)*$/

test-build-deploy:

serverless-test-build-deploy:
jobs:
- secret-injector/dump-secrets:
context:
- es02-prod
- shared
context: es02-prod
filters:
tags:
only: /^[0-9]+(\.[0-9]+)*(-.*)*$/
branches:
ignore: /.*/
- test:
context:
- shared
requires:
- secret-injector/dump-secrets
filters:
tags:
only: /^[0-9]+(\.[0-9]+)*(-.*)*$/
branches:
ignore: /.*/
ignore: /.*/
- test-sonar:
context:
- es02-prod
- shared
requires:
- secret-injector/dump-secrets
filters:
tags:
only: /^[0-9]+(\.[0-9]+)*(-.*)*$/
branches:
ignore: /.*/
- docker-build-n-push:
context:
- es02-prod
- shared
- secret-injector/dump-secrets:
requires:
- test
- test-sonar
name: secret-injector/cloudrun
vault-path: "gcp_landingzone/key/cloudrun-admin"
output-filename: cloudrun_admin
format: json
context: es02-prod
filters:
tags:
only: /^[0-9]+(\.[0-9]+)*(-.*)*$/
branches:
ignore: /.*/
- build-push-serverless:
requires:
- secret-injector/dump-secrets
- secret-injector/cloudrun
filters:
tags:
only: /^[0-9]+(\.[0-9]+)*(-.*)*$/
branches:
ignore: /.*/
- deploy:
context:
- es02-prod
- shared
- deploy-serverless:
requires:
- docker-build-n-push
- build-push-serverless
context: es02-prod
filters:
tags:
only: /^[0-9]+(\.[0-9]+)*(-.*)*$/
branches:
ignore: /.*/
ignore: /.*/
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ RUN GOOS=linux GOARCH=amd64 go build -ldflags="-w -s -X gh.version=${VERSION}" -
FROM alpine
COPY --from=builder /tmp/dependabot-circleci /dependabot-circleci

CMD ["/dependabot-circleci"]
CMD ["/dependabot-circleci"]
EXPOSE 3000
9 changes: 7 additions & 2 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ import (
"gopkg.in/yaml.v2"
)

type DatadogConfig struct {
APIKey string `yaml:"api_key"`
}

// Config contains global config
type Config struct {
Github githubapp.Config `yaml:"github"`
Server baseapp.HTTPConfig `yaml:"server"`
Datadog DatadogConfig `yaml:"datadog"`
Github githubapp.Config `yaml:"github"`
Server baseapp.HTTPConfig `yaml:"server"`
}

// RepoConfig contains specific config for each repos
Expand Down
106 changes: 84 additions & 22 deletions datadog/client.go
Original file line number Diff line number Diff line change
@@ -1,47 +1,109 @@
package datadog

import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"time"

"github.com/BESTSELLER/dependabot-circleci/config"
"github.com/DataDog/datadog-go/statsd"
"github.com/rs/zerolog/log"
)

var client *statsd.Client
var metricPrefix = "dependabot_circleci"
type DataDog struct {
Series []Series `json:"series"`
}

// CreateClient creates a statsd client
func CreateClient() (err error) {
client, err = statsd.New(config.EnvVars.DDAddress)
if err != nil {
return err
}
return nil
type Series struct {
Metric string `json:"metric"`
Points [][]int64 `json:"points"`
Tags []string `json:"tags"`
Type string `json:"type"`
Host string `json:"host"`
Interval int64 `json:"interval"`
}

var metricPrefix = "dependabot_circleci"

// IncrementCount incrementes a counter based on the input
func IncrementCount(metricName string, org string) {
err := client.Incr(
fmt.Sprintf("%s.%s", metricPrefix, metricName),
[]string{
"organistation:" + org,
},
1)
metric := metricPrefix + "." + metricName
err := postDataDogMetric(metric, 1, "count", []string{"organistation:" + org})
if err != nil {
log.Debug().Err(err).Msgf("could increment datadog counter %s", metricName)
}
}

// Gauge incrementes a counter based on the input
func Gauge(metricName string, value float64, tags []string) {
err := client.Gauge(
fmt.Sprintf("%s.%s", metricPrefix, metricName),
value,
tags,
1,
)
metric := metricPrefix + "." + metricName
err := postDataDogMetric(metric, int64(value), "gauge", tags)
if err != nil {
log.Debug().Err(err).Msgf("could send gauge to datadog %s", metricName)
}

}

func postDataDogMetric(metric string, value int64, metricType string, tags []string) error {
apiKey := config.AppConfig.Datadog.APIKey

url := "https://api.datadoghq.eu/api/v1/series?api_key=" + apiKey

series := Series{
Metric: metric,
Type: metricType,
Tags: tags,
}

point := [][]int64{
{time.Now().Unix(), value},
}
series.Points = point

payload := DataDog{[]Series{series}}

_, err := postStructAsJSON(url, payload, nil)
if err != nil {
return err
}

return nil
}

func postStructAsJSON(url string, payload interface{}, target interface{}) (string, error) {
var myClient = http.Client{}
b := new(bytes.Buffer)
err := json.NewEncoder(b).Encode(payload)
if err != nil {
fmt.Printf("Unable to encode struct: %s", err)
return "", err
}
req, err := http.NewRequest("POST", url, b)
if err != nil {
return "", err
}
req.Header.Add("Accept", "application/json")
req.Header.Add("Content-Type", "application/json")
r, err := myClient.Do(req)
if err != nil {
return "", err
}
defer r.Body.Close()

// check status code
bodyBytes, _ := ioutil.ReadAll(r.Body)
bodyString := string(bodyBytes)

if r.StatusCode < 200 || r.StatusCode > 299 {
return "", fmt.Errorf("Request failed, expected status: 2xx got: %d, error message: %s", r.StatusCode, bodyString)
}
decode := json.NewDecoder(r.Body)
err = decode.Decode(&target)
if err != nil {
return "", err
}

return bodyString, nil
}
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ module github.com/BESTSELLER/dependabot-circleci
go 1.15

require (
github.com/CircleCI-Public/circleci-cli v0.1.11924
github.com/BESTSELLER/go-vault v0.1.2
github.com/CircleCI-Public/circleci-cli v0.1.11756
github.com/DataDog/datadog-go v4.2.0+incompatible
github.com/go-co-op/gocron v0.5.1
github.com/google/go-containerregistry v0.4.0
Expand Down
Loading

0 comments on commit 766b613

Please sign in to comment.