Skip to content

Commit

Permalink
pr test (#1)
Browse files Browse the repository at this point in the history
* starting

* cp

* cp

* I think we can use this!

* with docker

* example and action
  • Loading branch information
Jack Lindamood committed Aug 22, 2022
1 parent a093a68 commit 529fcbe
Show file tree
Hide file tree
Showing 22 changed files with 1,769 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/.env
/.git
35 changes: 35 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Build and test code

on:
push:
tags:
- v*
branches:
- master
- main
pull_request:


jobs:
build:
name: Test
runs-on: ubuntu-latest
steps:
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: 1.19.x
- name: Check out code
uses: actions/checkout@v2
- name: golangci-lint
uses: golangci/golangci-lint-action@v2
with:
version: latest
- name: Build
run: go build -mod=readonly ./cmd/atlantis-drift-detection/main.go
- name: Verify
run: go mod verify
- name: Test
run: go test -v ./...
- name: Docker build
run: docker build -t atlantis-drift-detection .
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/.env
28 changes: 28 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
FROM golang:1.19.0 as build

WORKDIR /app

COPY go.mod .
COPY go.sum .
RUN go mod download
COPY . .

RUN CGO_ENABLED=0 GOOS=linux go build -a -tags netgo -ldflags '-w' -o /atlantis-drift-detection ./cmd/atlantis-drift-detection/main.go

FROM ubuntu:22.10

RUN apt-get update \
&& apt-get install -y wget unzip git \
&& rm -rf /var/lib/apt/lists/*


ARG TERRAFORM_VERSION=1.2.3
# Download terraform for linux
RUN wget --quiet https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip \
&& unzip terraform_${TERRAFORM_VERSION}_linux_amd64.zip \
&& mv terraform /usr/bin \
&& rm terraform_${TERRAFORM_VERSION}_linux_amd64.zip

COPY --from=build /atlantis-drift-detection /atlantis-drift-detection

ENTRYPOINT ["/atlantis-drift-detection"]
26 changes: 26 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: 'Atlantis terraform drift detection'
description: 'Some automation to detect drift inside atlantis via the remote /plan endpoint'
branding:
icon: 'activity'
color: 'blue'
inputs:
atlantisHost:
description: 'Atlantis hostname with protocol. Example: "https://atlantis.company.com'
required: true
atlantisToken:
description: 'Atlantis API token'
required: true
repo:
description: 'Repository to check'
required: true
slackWebhookURL:
description: 'Slack webhook URL to send notifications to'
required: false
runs:
using: 'docker'
image: 'Dockerfile'
env:
ATLANTIS_HOST: '{{ inputs.atlantisHost }}'
ATLANTIS_TOKEN: '{{ inputs.atlantisToken }}'
REPO: '{{ inputs.repo }}'
SLACK_WEBHOOK_URL: '{{ inputs.slackWebhookURL }}'
119 changes: 119 additions & 0 deletions cmd/atlantis-drift-detection/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package main

import (
"context"
"fmt"
"github.com/cresta/atlantis-drift-detection/internal/atlantis"
"github.com/cresta/atlantis-drift-detection/internal/drifter"
"github.com/cresta/atlantis-drift-detection/internal/notification"
"github.com/cresta/atlantis-drift-detection/internal/terraform"
"github.com/cresta/gogit"
"github.com/cresta/gogithub"
"github.com/joho/godotenv"
"net/http"
"os"

// Empty import allows pinning to version atlantis uses
_ "github.com/nlopes/slack"
"go.uber.org/zap"
)
import "github.com/joeshaw/envdecode"

type config struct {
Repo string `env:"REPO,required"`
AtlantisHostname string `env:"ATLANTIS_HOST,required"`
AtlantisToken string `env:"ATLANTIS_TOKEN,required"`
DirectoryWhitelist []string `env:"DIRECTORY_WHITELIST,required"`
SlackWebhookURL string `env:"SLACK_WEBHOOK_URL"`
}

func loadEnvIfExists() error {
_, err := os.Stat(".env")
if err != nil {
if os.IsNotExist(err) {
return nil
}
return fmt.Errorf("error checking for .env file: %v", err)
}
return godotenv.Load()
}

type zapGogitLogger struct {
logger *zap.Logger
}

func (z *zapGogitLogger) build(strings map[string]string, ints map[string]int64) *zap.Logger {
l := z.logger
for k, v := range strings {
l = l.With(zap.String(k, v))
}
for k, v := range ints {
l = l.With(zap.Int64(k, v))
}
return l
}

func (z *zapGogitLogger) Debug(_ context.Context, msg string, strings map[string]string, ints map[string]int64) {
z.build(strings, ints).Debug(msg)
}

func (z *zapGogitLogger) Info(_ context.Context, msg string, strings map[string]string, ints map[string]int64) {
z.build(strings, ints).Info(msg)
}

var _ gogit.Logger = (*zapGogitLogger)(nil)

func main() {
ctx := context.Background()
zapCfg := zap.NewProductionConfig()
zapCfg.Level = zap.NewAtomicLevelAt(zap.DebugLevel)
logger, err := zapCfg.Build(zap.AddCaller())
if err != nil {
panic(err)
}
if err := loadEnvIfExists(); err != nil {
logger.Panic("Failed to load .env", zap.Error(err))
}
var cfg config
if err := envdecode.Decode(&cfg); err != nil {
logger.Panic("failed to decode config", zap.Error(err))
}
cloner := &gogit.Cloner{
Logger: &zapGogitLogger{logger},
}
notif := &notification.Multi{
Notifications: []notification.Notification{
&notification.Zap{Logger: logger.With(zap.String("notification", "true"))},
},
}
if cfg.SlackWebhookURL != "" {
notif.Notifications = append(notif.Notifications, &notification.SlackWebhook{
WebhookURL: cfg.SlackWebhookURL,
HTTPClient: http.DefaultClient,
})
}
ghClient, err := gogithub.NewGQLClient(ctx, logger, nil)
if err != nil {
logger.Panic("failed to create github client", zap.Error(err))
}
tf := terraform.Client{
Logger: logger.With(zap.String("terraform", "true")),
}
d := drifter.Drifter{
DirectoryWhitelist: cfg.DirectoryWhitelist,
Logger: logger.With(zap.String("drifter", "true")),
Repo: cfg.Repo,
AtlantisClient: &atlantis.Client{
AtlantisHostname: cfg.AtlantisHostname,
Token: cfg.AtlantisToken,
HTTPClient: http.DefaultClient,
},
Cloner: cloner,
GithubClient: ghClient,
Terraform: &tf,
Notification: notif,
}
if err := d.Drift(ctx); err != nil {
logger.Panic("failed to drift", zap.Error(err))
}
}
22 changes: 22 additions & 0 deletions example.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Just the protocol and hostname of atlantis
ATLANTIS_HOST=https://atlantis.company.com
# Your atlantis token
ATLANTIS_TOKEN=PRIVATE_TOKEN
# A plan that is ok
PLAN_SUMMARY_OK='{"Repo": "company/terraform", "Ref": "master", "Type": "Github", "Dir": "environments/aws/env1", "Workspace": "account1"}'
# A plan that you expect to have changes
PLAN_SUMMARY_CHANGES='{"Repo": "company/terraform", "Ref": "master", "Type": "Github", "Dir": "environments/aws/env1", "Workspace": "account1"}'
# A plan you expect to already be locked
PLAN_SUMMARY_LOCK='{"Repo": "company/terraform", "Ref": "master", "Type": "Github", "Dir": "environments/aws/env1", "Workspace": "account1"}'
# Local directory to terraform
TERRAFORM_DIR=/home/USER/GolandProjects/terraform
# A sub directory in TERRAFORM_DIR that has terraform files
TERRAFORM_SUBDIR=environments/aws/env1
# Optional: A directory to whitelist (will only run for this directory)
DIRECTORY_WHITELIST=environments/aws/lambda/helloworld
# Optional: A slack webhook URL to get notifications
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/X/Y/Z
# Your terraform repository
REPO=company/terraform
# Optional: (but sometimes useful)
AWS_PROFILE=extra-prfiles
96 changes: 96 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
module github.com/cresta/atlantis-drift-detection

go 1.19

require (
github.com/cresta/gogit v0.0.2
github.com/cresta/gogithub v0.1.1
github.com/cresta/pipe v0.0.1
github.com/joeshaw/envdecode v0.0.0-20200121155833-099f1fc765bd
github.com/joho/godotenv v1.4.0
github.com/nlopes/slack v0.4.0
github.com/runatlantis/atlantis v0.19.8
github.com/stretchr/testify v1.8.0
go.uber.org/zap v1.22.0
)

require (
github.com/Laisky/graphql v1.0.5 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.1.1 // indirect
github.com/Masterminds/sprig/v3 v3.2.2 // indirect
github.com/agext/levenshtein v1.2.3 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
github.com/benbjohnson/clock v1.3.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bradleyfalzon/ghinstallation v1.1.1 // indirect
github.com/bradleyfalzon/ghinstallation/v2 v2.1.0 // indirect
github.com/cactus/go-statsd-client/statsd v0.0.0-20200623234511-94959e3146b2 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect
github.com/go-ozzo/ozzo-validation v3.6.0+incompatible // indirect
github.com/go-playground/locales v0.14.0 // indirect
github.com/go-playground/universal-translator v0.18.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.8 // indirect
github.com/google/go-github/v29 v29.0.3 // indirect
github.com/google/go-github/v31 v31.0.0 // indirect
github.com/google/go-github/v45 v45.2.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.1 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/hcl/v2 v2.13.0 // indirect
github.com/hashicorp/terraform-config-inspect v0.0.0-20211115214459-90acf1ca460f // indirect
github.com/huandu/xstrings v1.3.2 // indirect
github.com/imdario/mergo v0.3.13 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/m3db/prometheus_client_golang v1.12.8 // indirect
github.com/m3db/prometheus_client_model v0.2.1 // indirect
github.com/m3db/prometheus_common v0.34.7 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/mcdafydd/go-azuredevops v0.12.1 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/moby v20.10.17+incompatible // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
github.com/remeh/sizedwaitgroup v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.8.1 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/shurcooL/githubv4 v0.0.0-20220520033151-0b4e3294ff00 // indirect
github.com/shurcooL/graphql v0.0.0-20220606043923-3cf50f8a0a29 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/twmb/murmur3 v1.1.6 // indirect
github.com/uber-go/tally v3.5.0+incompatible // indirect
github.com/xanzy/go-gitlab v0.72.0 // indirect
github.com/zclconf/go-cty v1.10.0 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 // indirect
golang.org/x/net v0.0.0-20220812174116-3211cb980234 // indirect
golang.org/x/oauth2 v0.0.0-20220808172628-8227340efae7 // indirect
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde // indirect
golang.org/x/sys v0.0.0-20220818161305-2296e01440c6 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/go-playground/validator.v9 v9.31.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading

0 comments on commit 529fcbe

Please sign in to comment.