diff --git a/.bra.toml b/.bra.toml new file mode 100644 index 0000000..bc2edd8 --- /dev/null +++ b/.bra.toml @@ -0,0 +1,31 @@ +[run] +watch_all = true +watch_dirs = ["cmd", "pkg"] +watch_exts = [".go"] +ignore = [".git", "bin", "dist"] +ignore_files = [] +build_delay = 1500 +interrupt_timout = 15 +graceful_kill = false + +init_cmds = [ + ["make", "build"], + [ + "./bin/prometheus-scw-sd", + "--log.pretty", + "--log.level", + "debug", + "server" + ] +] + +cmds = [ + ["make", "build"], + [ + "./bin/prometheus-scw-sd", + "--log.pretty", + "--log.level", + "debug", + "server" + ] +] diff --git a/.codacy.yml b/.codacy.yml new file mode 100644 index 0000000..d66398f --- /dev/null +++ b/.codacy.yml @@ -0,0 +1,3 @@ +exclude_paths: + - _tools/** + - vendor/** diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..e69de29 diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..3795b8d --- /dev/null +++ b/.drone.yml @@ -0,0 +1,284 @@ +workspace: + base: /srv/app + path: src/github.com/promhippie/prometheus-scw-sd + +branches: + - master + +pipeline: + cache-restore: + image: plugins/s3-cache:1 + pull: true + secrets: [ cache_s3_endpoint, cache_s3_access_key, cache_s3_secret_key ] + restore: true + when: + local: false + + app-prepare: + image: webhippie/golang:edge + pull: true + environment: + - CGO_ENABLED=0 + - GOPATH=/srv/app + - TAGS= + commands: + - make clean + - make retool + - make sync + - make generate + + app-vet: + image: webhippie/golang:edge + pull: true + group: cli + environment: + - CGO_ENABLED=0 + - GOPATH=/srv/app + - TAGS= + commands: + - make vet + + app-check: + image: webhippie/golang:edge + pull: true + group: cli + environment: + - CGO_ENABLED=0 + - GOPATH=/srv/app + - TAGS= + commands: + - make megacheck + + app-lint: + image: webhippie/golang:edge + pull: true + group: cli + environment: + - CGO_ENABLED=0 + - GOPATH=/srv/app + - TAGS= + commands: + - make lint + + app-test: + image: webhippie/golang:edge + pull: true + group: cli + environment: + - CGO_ENABLED=0 + - GOPATH=/srv/app + - TAGS= + commands: + - make test + + app-build: + image: webhippie/golang:edge + pull: true + group: cli + environment: + - CGO_ENABLED=0 + - GOPATH=/srv/app + - TAGS= + commands: + - make build + + app-windows: + image: karalabe/xgo-latest:latest + pull: true + group: release + environment: + - CGO_ENABLED=0 + - GOPATH=/srv/app + - TAGS= + commands: + - make release-dirs release-windows + when: + event: [ push, tag ] + + app-linux: + image: karalabe/xgo-latest:latest + pull: true + group: release + environment: + - CGO_ENABLED=0 + - GOPATH=/srv/app + - TAGS= + commands: + - make release-dirs release-linux + when: + event: [ push, tag ] + + app-darwin: + image: karalabe/xgo-latest:latest + pull: true + group: release + environment: + - CGO_ENABLED=0 + - GOPATH=/srv/app + - TAGS= + commands: + - make release-dirs release-darwin + when: + event: [ push, tag ] + + app-finish: + image: webhippie/golang:edge + pull: true + environment: + - CGO_ENABLED=0 + - GOPATH=/srv/app + - TAGS= + commands: + - make release-copy release-check + when: + event: [ push, tag ] + + app-gpgsign: + image: plugins/gpgsign:1 + pull: true + secrets: [ gpgsign_key, gpgsign_passphrase ] + detach_sign: true + files: + - dist/release/* + excludes: + - dist/release/*.sha256 + when: + event: [ push, tag ] + + docker-amd64: + image: plugins/docker:17.05 + pull: true + group: docker + secrets: [ docker_username, docker_password ] + repo: promhippie/prometheus-scw-sd + dockerfile: docker/Dockerfile.linux.amd64 + auto_tag: true + auto_tag_suffix: linux-amd64 + when: + event: [ push, tag ] + + docker-i386: + image: plugins/docker:17.05 + pull: true + group: docker + secrets: [ docker_username, docker_password ] + repo: promhippie/prometheus-scw-sd + dockerfile: docker/Dockerfile.linux.i386 + auto_tag: true + auto_tag_suffix: linux-i386 + when: + event: [ push, tag ] + + docker-arm64v8: + image: plugins/docker:17.05 + pull: true + group: docker + secrets: [ docker_username, docker_password ] + repo: promhippie/prometheus-scw-sd + dockerfile: docker/Dockerfile.linux.arm64v8 + auto_tag: true + auto_tag_suffix: linux-arm64v8 + when: + event: [ push, tag ] + + docker-arm32v7: + image: plugins/docker:17.05 + pull: true + group: docker + secrets: [ docker_username, docker_password ] + repo: promhippie/prometheus-scw-sd + dockerfile: docker/Dockerfile.linux.arm32v7 + auto_tag: true + auto_tag_suffix: linux-arm32v7 + when: + event: [ push, tag ] + + docker-arm32v6: + image: plugins/docker:17.05 + pull: true + group: docker + secrets: [ docker_username, docker_password ] + repo: promhippie/prometheus-scw-sd + dockerfile: docker/Dockerfile.linux.arm32v6 + auto_tag: true + auto_tag_suffix: linux-arm32v6 + when: + event: [ push, tag ] + + docker-manifests: + image: plugins/manifest:1 + pull: true + secrets: [ docker_username, docker_password ] + spec: manifest.tmpl + auto_tag: true + ignore_missing: true + when: + event: [ push, tag ] + + docker-microbadger: + image: plugins/webhook:1 + pull: true + secrets: + - source: microbadger_token + target: plugin_urls + when: + event: [ push, tag ] + + cache-rebuild: + image: plugins/s3-cache:1 + pull: true + secrets: [ cache_s3_endpoint, cache_s3_access_key, cache_s3_secret_key ] + rebuild: true + mount: + - _tools + - vendor + when: + local: false + event: [ push ] + + cache-flush: + image: plugins/s3-cache:1 + pull: true + secrets: [ cache_s3_endpoint, cache_s3_access_key, cache_s3_secret_key ] + flush: true + flush_age: 14 + when: + local: false + event: [ push ] + + docs-build: + image: webhippie/hugo:latest + pull: true + commands: + - make docs + when: + local: false + event: [ push ] + + docs-publish: + image: plugins/gh-pages:1 + pull: true + secrets: [ github_username, github_password ] + pages_directory: docs/public/ + temporary_base: tmp/ + when: + local: false + event: [ push ] + + github-release: + image: plugins/github-release:1 + pull: true + secrets: [ github_token ] + files: + - dist/release/* + when: + event: [ tag ] + + notify-matrix: + image: plugins/matrix:1 + pull: true + secrets: [ matrix_roomid, matrix_username, matrix_password ] + when: + local: false + event: [ push, tag ] + status: [ changed, failure ] diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..e49133a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,19 @@ +# http://editorconfig.org + +root = true + +[*] +charset = utf-8 +insert_final_newline = true +trim_trailing_whitespace = true + +[Makefile] +indent_style = tab +indent_size = 4 + +[*.go] +indent_style = tab +indent_size = 4 + +[*.md] +trim_trailing_whitespace = true diff --git a/.github/issue_template.md b/.github/issue_template.md new file mode 100644 index 0000000..5d9ce10 --- /dev/null +++ b/.github/issue_template.md @@ -0,0 +1,9 @@ + diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..762bf0a --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,9 @@ + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7207cc4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof + +coverage.out + +/_tools +/vendor +/bin +/dist + +.envrc +scw.json diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..825c32f --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1 @@ +# Changelog diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..c65ddd6 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,73 @@ +# Contributing to Promhippie + +Welcome! Our community focuses on helping others and making this project the best it can be. We gladly accept contributions and encourage you to get involved! + + +## Bug reports + +Please search the issues on the issue tracker with a variety of keywords to ensure your bug is not already reported. + +If unique, [open an issue](https://github.com/promhippie/prometheus-scw-sd/issues) and answer the questions so we can understand and reproduce the problematic behavior. + +The burden is on you to convince us that it is actually a bug in our project. This is easiest to do when you write clear, concise instructions so we can reproduce the behavior (even if it seems obvious). The more detailed and specific you are, the faster we will be able to help you. Check out [How to Report Bugs Effectively](http://www.chiark.greenend.org.uk/~sgtatham/bugs.html). + +Please be kind, remember that this project comes at no cost to you, and you're getting free help. + + +## Check for assigned people + +We are using Github Issues for submitting known issues (e.g. bugs, features, etc.). Some issues will have someone assigned, meaning that there's already someone that takes responsability for fixing said issue. This is not done to discourage contributions, rather to not step in the work that has already been done by the assignee. If you want to work on a known issue with someone already assigned to it, please consider contacting the assignee first (e.g. by mentioning the assignee in a new comment on the specific issue). This way you can contribute with ideas, or even with code if the assignee decides that you can step in. + +If you plan to work on a non assigned issue, please add a comment on the issue to prevent duplicated work. + + +## Minor improvements and new tests + +Submit pull requests at any time for minor changes or new tests. Make sure to write tests to assert your change is working properly and is thoroughly covered. We'll ask most pull requests to be squashed, especially with small commits. + +Your pull request may be thoroughly reviewed. This is because if we accept the PR, we also assume responsibility for it, although we would prefer you to help maintain your code after it gets merged. + + +## Mind the Style + +We believe that in order to have a healthy codebase we need to abide to a certain code style. We use `gofmt` with Go and `eslint` with Javscript for this matter, which are tools that has proved to be useful. So, before submitting your Pull Request, make sure that `gofmt` and if viable `eslint` are passing for you. + +Finally, note that `gofmt` and if viable `eslint` are called on the CI system. This means that your Pull Request will not be merged until the changes are approved. + + +## Update the Changelog + +We keep a changelog in the `CHANGELOG.md` file. This is useful to understand what has changed between each version. When you implement a new feature, or a fix for an issue, please also update the `CHANGELOG.md` file accordingly. We don't follow a strict style for the changelog, just try to be consistent with the rest of the file. + + +## Sign your work + +The sign-off is a simple line at the end of the explanation for the patch. Your signature certifies that you wrote the patch or otherwise have the right to pass it on as an open-source patch. The rules are pretty simple: If you can certify [DCO](DCO), then you just add a line to every git commit message: + +``` +Signed-off-by: Joe Smith +``` + +Please use your real name, we really dislike pseudonyms or anonymous contributions. We are in the opensource world without secrets. If you set your `user.name` and `user.email` git configs, you can sign your commit automatically with `git commit -s`. + + +## Collaborator status + +If your pull request is merged, congratulations! You're technically a collaborator. We may also grant you "Collaborator status" which means you can push to the repository and merge other pull requests. We hope that you will stay involved by reviewing pull requests, submitting more of your own, and resolving issues as you are able to. Thanks for making this project amazing! + +We ask that collaborators will conduct thorough code reviews and be nice to new contributors. Before merging a PR, it's best to get the approval of at least one or two other collaborators and/or the project owner. We prefer squashed commits instead of many little, semantically-unimportant commits. Also, +CI and other post-commit hooks must pass before being merged except in certain unusual circumstances. + +Collaborator status may be removed for inactive users from time to time as we see fit; this is not an insult, just a basic security precaution in case the account becomes inactive or abandoned. Privileges can always be restored later. + +**Reviewing pull requests:** Please help submit and review pull requests as you are able! We would ask that every pull request be reviewed by at least one collaborator who did not open the pull request before merging. This will help ensure high code quality as new collaborators are added to the project. + + +## Vulnerabilities + +If you've found a vulnerability that is serious, please email to thomas@webhippie.de. If it's not a big deal, a pull request will probably be faster. + + +## Thank you + +Thanks for your help! This project would not be what it is today without your contributions. diff --git a/DCO b/DCO new file mode 100644 index 0000000..716561d --- /dev/null +++ b/DCO @@ -0,0 +1,36 @@ +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +660 York Street, Suite 102, +San Francisco, CA 94110 USA + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. diff --git a/Gopkg.lock b/Gopkg.lock new file mode 100644 index 0000000..a6d9539 --- /dev/null +++ b/Gopkg.lock @@ -0,0 +1,832 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + digest = "1:5c3894b2aa4d6bead0ceeea6831b305d62879c871780e7b76296ded1b004bc57" + name = "cloud.google.com/go" + packages = ["compute/metadata"] + pruneopts = "UT" + revision = "97efc2c9ffd9fe8ef47f7f3203dc60bbca547374" + version = "v0.28.0" + +[[projects]] + digest = "1:37ee238802aa0b84f701894eccfc08dc2c643dc20de62b48f42350be2d67964d" + name = "github.com/Azure/azure-sdk-for-go" + packages = [ + "arm/compute", + "arm/network", + ] + pruneopts = "UT" + revision = "e01c89c9c29b97413ae6ebe89a294d814ec7ca8b" + version = "v6.0.0-beta" + +[[projects]] + digest = "1:8fba533e7bfcbdd89b6fc8b478376052f6041083f1b732e41ad3d9d4f162c1f4" + name = "github.com/Azure/go-autorest" + packages = [ + "autorest", + "autorest/adal", + "autorest/azure", + "autorest/date", + "autorest/to", + "autorest/validation", + ] + pruneopts = "UT" + revision = "fc3b03a2d2d1f43fad3007038bd16f044f870722" + version = "v9.10.0" + +[[projects]] + digest = "1:d329f86c6fa2702e81e331f53ae90a0fe71212398fbfd733c6002367e48143eb" + name = "github.com/aws/aws-sdk-go" + packages = [ + "aws", + "aws/awserr", + "aws/awsutil", + "aws/client", + "aws/client/metadata", + "aws/corehandlers", + "aws/credentials", + "aws/credentials/ec2rolecreds", + "aws/credentials/endpointcreds", + "aws/credentials/stscreds", + "aws/csm", + "aws/defaults", + "aws/ec2metadata", + "aws/endpoints", + "aws/request", + "aws/session", + "aws/signer/v4", + "internal/sdkio", + "internal/sdkrand", + "internal/sdkuri", + "internal/shareddefaults", + "private/protocol", + "private/protocol/ec2query", + "private/protocol/query", + "private/protocol/query/queryutil", + "private/protocol/rest", + "private/protocol/xml/xmlutil", + "service/ec2", + "service/sts", + ] + pruneopts = "UT" + revision = "d8ab6d22cfd270ded73e7d59feba528ffd963edd" + version = "v1.15.40" + +[[projects]] + branch = "master" + digest = "1:d6afaeed1502aa28e80a4ed0981d570ad91b2579193404256ce672ed0a609e0d" + name = "github.com/beorn7/perks" + packages = ["quantile"] + pruneopts = "UT" + revision = "3a771d992973f24aa725d07868b467d1ddfceafb" + +[[projects]] + digest = "1:ffe9824d294da03b391f44e1ae8281281b4afc1bdaa9588c9097785e3af10cec" + name = "github.com/davecgh/go-spew" + packages = ["spew"] + pruneopts = "UT" + revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73" + version = "v1.1.1" + +[[projects]] + digest = "1:76dc72490af7174349349838f2fe118996381b31ea83243812a97e5a0fd5ed55" + name = "github.com/dgrijalva/jwt-go" + packages = ["."] + pruneopts = "UT" + revision = "06ea1031745cb8b3dab3f6a236daf2b0aa468b7e" + version = "v3.2.0" + +[[projects]] + digest = "1:2cd7915ab26ede7d95b8749e6b1f933f1c6d5398030684e6505940a10f31cfda" + name = "github.com/ghodss/yaml" + packages = ["."] + pruneopts = "UT" + revision = "0ca9ea5df5451ffdf184b4428c902747c2c11cd7" + version = "v1.0.0" + +[[projects]] + digest = "1:b9914f85d95a0968bafd1be1908ba29e2eafafd88d6fd13696be42bf5368c380" + name = "github.com/go-chi/chi" + packages = ["."] + pruneopts = "UT" + revision = "b5294d10673813fac8558e7f47242bc9e61b4c25" + version = "v3.3.3" + +[[projects]] + digest = "1:5abd6a22805b1919f6a6bca0ae58b13cef1f3412812f38569978f43ef02743d4" + name = "github.com/go-ini/ini" + packages = ["."] + pruneopts = "UT" + revision = "5cf292cae48347c2490ac1a58fe36735fb78df7e" + version = "v1.38.2" + +[[projects]] + digest = "1:b53962d15364047cf1c18369a7bdf30571760625c34bec08f217edbc3a8f9040" + name = "github.com/go-kit/kit" + packages = [ + "log", + "log/level", + ] + pruneopts = "UT" + revision = "ca4112baa34cb55091301bdc13b1420a122b1b9e" + version = "v0.7.0" + +[[projects]] + digest = "1:31a18dae27a29aa074515e43a443abfd2ba6deb6d69309d8d7ce789c45f34659" + name = "github.com/go-logfmt/logfmt" + packages = ["."] + pruneopts = "UT" + revision = "390ab7935ee28ec6b286364bba9b4dd6410cb3d5" + version = "v0.3.0" + +[[projects]] + digest = "1:586ea76dbd0374d6fb649a91d70d652b7fe0ccffb8910a77468e7702e7901f3d" + name = "github.com/go-stack/stack" + packages = ["."] + pruneopts = "UT" + revision = "2fee6af1a9795aafbe0253a0cfbdf668e1fb8a9a" + version = "v1.8.0" + +[[projects]] + digest = "1:3c5fa2da8cbfa81f2811f5164a60801f4b6fdb0160636da2b228cbbdec4da098" + name = "github.com/gogo/protobuf" + packages = [ + "proto", + "sortkeys", + ] + pruneopts = "UT" + revision = "636bf0302bc95575d69441b25a2603156ffdddf1" + version = "v1.1.1" + +[[projects]] + branch = "master" + digest = "1:1ba1d79f2810270045c328ae5d674321db34e3aae468eb4233883b473c5c0467" + name = "github.com/golang/glog" + packages = ["."] + pruneopts = "UT" + revision = "23def4e6c14b4da8ac2ed8007337bc5eb5007998" + +[[projects]] + digest = "1:ae0036fa14b41c52607c53fa072ef5045ec5f9013ed569e6a5fa19dd5e2ac89a" + name = "github.com/golang/protobuf" + packages = [ + "proto", + "ptypes", + "ptypes/any", + "ptypes/duration", + "ptypes/timestamp", + ] + pruneopts = "UT" + revision = "aa810b61a9c79d51363740d207bb46cf8e620ed5" + version = "v1.2.0" + +[[projects]] + branch = "master" + digest = "1:0bfbe13936953a98ae3cfe8ed6670d396ad81edf069a806d2f6515d7bb6950df" + name = "github.com/google/btree" + packages = ["."] + pruneopts = "UT" + revision = "4030bb1f1f0c35b30ca7009e9ebd06849dd45306" + +[[projects]] + branch = "master" + digest = "1:3ee90c0d94da31b442dde97c99635aaafec68d0b8a3c12ee2075c6bdabeec6bb" + name = "github.com/google/gofuzz" + packages = ["."] + pruneopts = "UT" + revision = "24818f796faf91cd76ec7bddd72458fbced7a6c1" + +[[projects]] + digest = "1:a6a3cf96c8f626d50c11f5ab6c6a92e3ccde777aafe091dd305224c85d3c0030" + name = "github.com/googleapis/gnostic" + packages = [ + "OpenAPIv2", + "compiler", + "extensions", + ] + pruneopts = "UT" + revision = "7c663266750e7d82587642f65e60bc4083f1f84e" + version = "v0.2.0" + +[[projects]] + branch = "master" + digest = "1:7888b4013ec2ebe86ebff8729355aefff4fb4776a669093488cd137e92c222b1" + name = "github.com/gophercloud/gophercloud" + packages = [ + ".", + "openstack", + "openstack/compute/v2/extensions/floatingips", + "openstack/compute/v2/extensions/hypervisors", + "openstack/compute/v2/flavors", + "openstack/compute/v2/images", + "openstack/compute/v2/servers", + "openstack/identity/v2/tenants", + "openstack/identity/v2/tokens", + "openstack/identity/v3/tokens", + "openstack/utils", + "pagination", + ] + pruneopts = "UT" + revision = "725b2c0b24277f24a743631f209141fce570b5b9" + +[[projects]] + branch = "master" + digest = "1:d9221e54176cdc408f6cb9cc35626743e8728fd7e69e5b0df075df15e4bec895" + name = "github.com/gregjones/httpcache" + packages = [ + ".", + "diskcache", + ] + pruneopts = "UT" + revision = "9cad4c3443a7200dd6400aef47183728de563a38" + +[[projects]] + digest = "1:3a089fb51f40b0e4fedf9970a7a722028b0e5a9200ab2e41887476771ddddafe" + name = "github.com/hashicorp/consul" + packages = ["api"] + pruneopts = "UT" + revision = "48d287ef690ada66634885640f3444dbf7b71d18" + version = "v1.2.3" + +[[projects]] + digest = "1:f47d6109c2034cb16bd62b220e18afd5aa9d5a1630fe5d937ad96a4fb7cbb277" + name = "github.com/hashicorp/go-cleanhttp" + packages = ["."] + pruneopts = "UT" + revision = "e8ab9daed8d1ddd2d3c4efba338fe2eeae2e4f18" + version = "v0.5.0" + +[[projects]] + branch = "master" + digest = "1:35e9b9d8a799b6d4d4196f19cba3b0ffabf3c96b43eaedf388263d033c066616" + name = "github.com/hashicorp/go-rootcerts" + packages = ["."] + pruneopts = "UT" + revision = "6bb64b370b90e7ef1fa532be9e591a81c3493e00" + +[[projects]] + digest = "1:8ec8d88c248041a6df5f6574b87bc00e7e0b493881dad2e7ef47b11dc69093b5" + name = "github.com/hashicorp/golang-lru" + packages = [ + ".", + "simplelru", + ] + pruneopts = "UT" + revision = "20f1fb78b0740ba8c3cb143a61e86ba5c8669768" + version = "v0.5.0" + +[[projects]] + digest = "1:8926b09bc7e669ef6aec95f6ad5abb7240f232cc217f3841f9097d5c8c482666" + name = "github.com/hashicorp/serf" + packages = ["coordinate"] + pruneopts = "UT" + revision = "d6574a5bb1226678d7010325fb6c985db20ee458" + version = "v0.8.1" + +[[projects]] + digest = "1:e22af8c7518e1eab6f2eab2b7d7558927f816262586cd6ed9f349c97a6c285c4" + name = "github.com/jmespath/go-jmespath" + packages = ["."] + pruneopts = "UT" + revision = "0b12d6b5" + +[[projects]] + digest = "1:ecd9aa82687cf31d1585d4ac61d0ba180e42e8a6182b85bd785fcca8dfeefc1b" + name = "github.com/joho/godotenv" + packages = ["."] + pruneopts = "UT" + revision = "23d116af351c84513e1946b527c88823e476be13" + version = "v1.3.0" + +[[projects]] + digest = "1:3e551bbb3a7c0ab2a2bf4660e7fcad16db089fdcfbb44b0199e62838038623ea" + name = "github.com/json-iterator/go" + packages = ["."] + pruneopts = "UT" + revision = "1624edc4454b8682399def8740d46db5e4362ba4" + version = "v1.1.5" + +[[projects]] + branch = "master" + digest = "1:a64e323dc06b73892e5bb5d040ced475c4645d456038333883f58934abbf6f72" + name = "github.com/kr/logfmt" + packages = ["."] + pruneopts = "UT" + revision = "b84e30acd515aadc4b783ad4ff83aff3299bdfe0" + +[[projects]] + digest = "1:ff5ebae34cfbf047d505ee150de27e60570e8c394b3b8fdbb720ff6ac71985fc" + name = "github.com/matttproud/golang_protobuf_extensions" + packages = ["pbutil"] + pruneopts = "UT" + revision = "c12348ce28de40eed0136aa2b644d0ee0650e56c" + version = "v1.0.1" + +[[projects]] + digest = "1:b39aee4261f1ae13fdd21a0db189e0bba0f96c0f2eba77ab278428e2d3b00052" + name = "github.com/miekg/dns" + packages = ["."] + pruneopts = "UT" + revision = "f4db2ca6edc3af0ee51bf332099cc480bcf3ef9d" + version = "v1.0.10" + +[[projects]] + digest = "1:78bbb1ba5b7c3f2ed0ea1eab57bdd3859aec7e177811563edc41198a760b06af" + name = "github.com/mitchellh/go-homedir" + packages = ["."] + pruneopts = "UT" + revision = "ae18d6b8b3205b561c79e8e5f69bff09736185f4" + version = "v1.0.0" + +[[projects]] + digest = "1:645110e089152bd0f4a011a2648fbb0e4df5977be73ca605781157ac297f50c4" + name = "github.com/mitchellh/mapstructure" + packages = ["."] + pruneopts = "UT" + revision = "fa473d140ef3c6adf42d6b391fe76707f1f243c8" + version = "v1.0.0" + +[[projects]] + digest = "1:33422d238f147d247752996a26574ac48dcf472976eda7f5134015f06bf16563" + name = "github.com/modern-go/concurrent" + packages = ["."] + pruneopts = "UT" + revision = "bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94" + version = "1.0.3" + +[[projects]] + digest = "1:e32bdbdb7c377a07a9a46378290059822efdce5c8d96fe71940d87cb4f918855" + name = "github.com/modern-go/reflect2" + packages = ["."] + pruneopts = "UT" + revision = "4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd" + version = "1.0.1" + +[[projects]] + digest = "1:a94ab444832800c89c9d5b3ba46bcab73116a23d851f6c5918ce6f005230659e" + name = "github.com/moul/anonuuid" + packages = ["."] + pruneopts = "UT" + revision = "c6987e46f8a0231504bcd402962749f8dd9970b0" + version = "v1.1.0" + +[[projects]] + branch = "master" + digest = "1:9f07f801988b225662081432361c430cad8f5293b134e80bdf1998d14969d7a6" + name = "github.com/mwitkow/go-conntrack" + packages = ["."] + pruneopts = "UT" + revision = "cc309e4a22231782e8893f3c35ced0967807a33e" + +[[projects]] + digest = "1:9ec6cf1df5ad1d55cf41a43b6b1e7e118a91bade4f68ff4303379343e40c0e25" + name = "github.com/oklog/run" + packages = ["."] + pruneopts = "UT" + revision = "4dadeb3030eda0273a12382bb2348ffc7c9d1a39" + version = "v1.0.0" + +[[projects]] + branch = "master" + digest = "1:3bf17a6e6eaa6ad24152148a631d18662f7212e21637c2699bff3369b7f00fa2" + name = "github.com/petar/GoLLRB" + packages = ["llrb"] + pruneopts = "UT" + revision = "53be0d36a84c2a886ca057d34b6aa4468df9ccb4" + +[[projects]] + digest = "1:0e7775ebbcf00d8dd28ac663614af924411c868dca3d5aa762af0fae3808d852" + name = "github.com/peterbourgon/diskv" + packages = ["."] + pruneopts = "UT" + revision = "5f041e8faa004a95c88a202771f4cc3e991971e6" + version = "v2.0.1" + +[[projects]] + digest = "1:1bd84ab43883f0ef0129fb753f9fdabba3903eff922816aaaba8e6204fb3cde9" + name = "github.com/prometheus/client_golang" + packages = [ + "prometheus", + "prometheus/promhttp", + ] + pruneopts = "UT" + revision = "c5b7fccd204277076155f10851dad72b76a49317" + version = "v0.8.0" + +[[projects]] + branch = "master" + digest = "1:0f37e09b3e92aaeda5991581311f8dbf38944b36a3edec61cc2d1991f527554a" + name = "github.com/prometheus/client_model" + packages = ["go"] + pruneopts = "UT" + revision = "5c3871d89910bfb32f5fcab2aa4b9ec68e65a99f" + +[[projects]] + branch = "master" + digest = "1:69e8ba26d37593f67d0307c5c3ecf978c8984f6862cf1dc558f7de7f8127e785" + name = "github.com/prometheus/common" + packages = [ + "config", + "expfmt", + "internal/bitbucket.org/ww/goautoneg", + "model", + ] + pruneopts = "UT" + revision = "c7de2306084e37d54b8be01f3541a8464345e9a5" + +[[projects]] + branch = "master" + digest = "1:e9c47dd9f7bd017dc11a271f2ccd93b4f29c18075ba288e0b533d048646bc1a4" + name = "github.com/prometheus/procfs" + packages = [ + ".", + "internal/util", + "nfs", + "xfs", + ] + pruneopts = "UT" + revision = "418d78d0b9a7b7de3a6bbc8a23def624cc977bb2" + +[[projects]] + digest = "1:f9c17c7eea94cf45186ffdadeab00ee1ea4c2abb41e9ce023efa9a2f6462d198" + name = "github.com/prometheus/prometheus" + packages = [ + "discovery", + "discovery/azure", + "discovery/config", + "discovery/consul", + "discovery/dns", + "discovery/ec2", + "discovery/file", + "discovery/gce", + "discovery/kubernetes", + "discovery/marathon", + "discovery/openstack", + "discovery/targetgroup", + "discovery/triton", + "discovery/zookeeper", + "util/strutil", + "util/treecache", + ] + pruneopts = "UT" + revision = "c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + version = "v2.4.2" + +[[projects]] + digest = "1:3fd3d634f6815f19ac4b2c5e16d28ec9aa4584d0bba25d1ee6c424d813cca22a" + name = "github.com/renstrom/fuzzysearch" + packages = ["fuzzy"] + pruneopts = "UT" + revision = "b18e754edff4833912ef4dce9eaca885bd3f0de1" + version = "v1.0.1" + +[[projects]] + branch = "master" + digest = "1:4d92d3bcd412de705100c10f0428a0b63b12f3d12455ebae46e9ea384c23b333" + name = "github.com/samuel/go-zookeeper" + packages = ["zk"] + pruneopts = "UT" + revision = "c4fab1ac1bec58281ad0667dc3f0907a9476ac47" + +[[projects]] + branch = "master" + digest = "1:5f3582a7b90bcea7a2197d1fd862e5dccdb3b98b0c58b9d08926237fee98098e" + name = "github.com/scaleway/go-scaleway" + packages = [ + ".", + "cache", + "logger", + "types", + ] + pruneopts = "UT" + revision = "2d7df73e80ec0ad19582b68c3eb83d759ae66bab" + +[[projects]] + branch = "master" + digest = "1:9736c0021e676b24aed7fc1a47251b6310de90ae6639f1a49086a7d37273d59f" + name = "golang.org/x/crypto" + packages = [ + "ed25519", + "ed25519/internal/edwards25519", + "ssh/terminal", + ] + pruneopts = "UT" + revision = "0e37d006457bf46f9e6692014ba72ef82c33022c" + +[[projects]] + branch = "master" + digest = "1:ae4e8075fcfa7ab604637adca2f326d4f5c0f6f545f8a968524deaf6866c28ad" + name = "golang.org/x/net" + packages = [ + "bpf", + "context", + "context/ctxhttp", + "http/httpguts", + "http2", + "http2/hpack", + "idna", + "internal/iana", + "internal/socket", + "internal/timeseries", + "ipv4", + "ipv6", + "trace", + ] + pruneopts = "UT" + revision = "2f5d2388922f370f4355f327fcf4cfe9f5583908" + +[[projects]] + branch = "master" + digest = "1:9589e9418b22f97c582c50c65f6b195c72ab5b0797f3423de80548034b25879a" + name = "golang.org/x/oauth2" + packages = [ + ".", + "google", + "internal", + "jws", + "jwt", + ] + pruneopts = "UT" + revision = "d2e6202438beef2727060aa7cabdd924d92ebfd9" + +[[projects]] + branch = "master" + digest = "1:39ebcc2b11457b703ae9ee2e8cca0f68df21969c6102cb3b705f76cca0ea0239" + name = "golang.org/x/sync" + packages = ["errgroup"] + pruneopts = "UT" + revision = "1d60e4601c6fd243af51cc01ddf169918a5407ca" + +[[projects]] + branch = "master" + digest = "1:53820bb3512ce75fe3592c13ab1ff3e5601f44917de558022c3295ed1e0cde61" + name = "golang.org/x/sys" + packages = [ + "unix", + "windows", + ] + pruneopts = "UT" + revision = "d47a0f3392421c5624713c9a19fe781f651f8a50" + +[[projects]] + digest = "1:7509ba4347d1f8de6ae9be8818b0cd1abc3deeffe28aeaf4be6d4b6b5178d9ca" + name = "golang.org/x/text" + packages = [ + "collate", + "collate/build", + "internal/colltab", + "internal/gen", + "internal/tag", + "internal/triegen", + "internal/ucd", + "language", + "secure/bidirule", + "transform", + "unicode/bidi", + "unicode/cldr", + "unicode/norm", + "unicode/rangetable", + ] + pruneopts = "UT" + revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0" + version = "v0.3.0" + +[[projects]] + branch = "master" + digest = "1:c9e7a4b4d47c0ed205d257648b0e5b0440880cb728506e318f8ac7cd36270bc4" + name = "golang.org/x/time" + packages = ["rate"] + pruneopts = "UT" + revision = "fbb02b2291d28baffd63558aa44b4b56f178d650" + +[[projects]] + branch = "master" + digest = "1:e785020744afdc6bc4272320835f25039d14f2d0d65adc2eccdbe22d080f2cbb" + name = "google.golang.org/api" + packages = [ + "compute/v1", + "gensupport", + "googleapi", + "googleapi/internal/uritemplates", + ] + pruneopts = "UT" + revision = "920bb1beccf73147754c5567fce5b1f32cd3030f" + +[[projects]] + digest = "1:eae32afe33186dac5d4fb59f13decaee41a5ab1cc2768e9bb361a2fbe476927c" + name = "google.golang.org/appengine" + packages = [ + ".", + "internal", + "internal/app_identity", + "internal/base", + "internal/datastore", + "internal/log", + "internal/modules", + "internal/remote_api", + "internal/urlfetch", + "urlfetch", + ] + pruneopts = "UT" + revision = "ae0ab99deb4dc413a2b4bd6c8bdd0eb67f1e4d06" + version = "v1.2.0" + +[[projects]] + digest = "1:abeb38ade3f32a92943e5be54f55ed6d6e3b6602761d74b4aab4c9dd45c18abd" + name = "gopkg.in/fsnotify/fsnotify.v1" + packages = ["."] + pruneopts = "UT" + revision = "c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9" + version = "v1.4.7" + +[[projects]] + digest = "1:2d1fbdc6777e5408cabeb02bf336305e724b925ff4546ded0fa8715a7267922a" + name = "gopkg.in/inf.v0" + packages = ["."] + pruneopts = "UT" + revision = "d2d2541c53f18d2a059457998ce2876cc8e67cbf" + version = "v0.9.1" + +[[projects]] + branch = "v2" + digest = "1:927bc5076aef9916f1920f2a07e3723e9da1dcd52baa84d29893a3f417c867b4" + name = "gopkg.in/urfave/cli.v2" + packages = ["."] + pruneopts = "UT" + revision = "d3ae77c26ac8db90639677e4831a728d33c36111" + +[[projects]] + digest = "1:342378ac4dcb378a5448dd723f0784ae519383532f5e70ade24132c4c8693202" + name = "gopkg.in/yaml.v2" + packages = ["."] + pruneopts = "UT" + revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183" + version = "v2.2.1" + +[[projects]] + branch = "release-1.11" + digest = "1:e10afaf4c563b3e96f3e100f92e9b3a0e293710e281eed14a1004a77fc796648" + name = "k8s.io/api" + packages = [ + "admissionregistration/v1alpha1", + "admissionregistration/v1beta1", + "apps/v1", + "apps/v1beta1", + "apps/v1beta2", + "authentication/v1", + "authentication/v1beta1", + "authorization/v1", + "authorization/v1beta1", + "autoscaling/v1", + "autoscaling/v2beta1", + "batch/v1", + "batch/v1beta1", + "batch/v2alpha1", + "certificates/v1beta1", + "core/v1", + "events/v1beta1", + "extensions/v1beta1", + "networking/v1", + "policy/v1beta1", + "rbac/v1", + "rbac/v1alpha1", + "rbac/v1beta1", + "scheduling/v1alpha1", + "scheduling/v1beta1", + "settings/v1alpha1", + "storage/v1", + "storage/v1alpha1", + "storage/v1beta1", + ] + pruneopts = "UT" + revision = "4e7be11eab3ffcfc1876898b8272df53785a9504" + +[[projects]] + branch = "release-1.11" + digest = "1:9b510b99d82b8cb7e5d29deadb05b66ffe1f1df75c4e656d39d843b5a70a3c8d" + name = "k8s.io/apimachinery" + packages = [ + "pkg/api/errors", + "pkg/api/meta", + "pkg/api/resource", + "pkg/apis/meta/internalversion", + "pkg/apis/meta/v1", + "pkg/apis/meta/v1/unstructured", + "pkg/apis/meta/v1beta1", + "pkg/conversion", + "pkg/conversion/queryparams", + "pkg/fields", + "pkg/labels", + "pkg/runtime", + "pkg/runtime/schema", + "pkg/runtime/serializer", + "pkg/runtime/serializer/json", + "pkg/runtime/serializer/protobuf", + "pkg/runtime/serializer/recognizer", + "pkg/runtime/serializer/streaming", + "pkg/runtime/serializer/versioning", + "pkg/selection", + "pkg/types", + "pkg/util/cache", + "pkg/util/clock", + "pkg/util/diff", + "pkg/util/errors", + "pkg/util/framer", + "pkg/util/intstr", + "pkg/util/json", + "pkg/util/net", + "pkg/util/runtime", + "pkg/util/sets", + "pkg/util/validation", + "pkg/util/validation/field", + "pkg/util/wait", + "pkg/util/yaml", + "pkg/version", + "pkg/watch", + "third_party/forked/golang/reflect", + ] + pruneopts = "UT" + revision = "def12e63c512da17043b4f0293f52d1006603d9f" + +[[projects]] + digest = "1:98db1b136b75df7042a0e8c4d2c6fce5a6efa6a9ce0f53ec38bf278ad7d17fe7" + name = "k8s.io/client-go" + packages = [ + "discovery", + "kubernetes", + "kubernetes/scheme", + "kubernetes/typed/admissionregistration/v1alpha1", + "kubernetes/typed/admissionregistration/v1beta1", + "kubernetes/typed/apps/v1", + "kubernetes/typed/apps/v1beta1", + "kubernetes/typed/apps/v1beta2", + "kubernetes/typed/authentication/v1", + "kubernetes/typed/authentication/v1beta1", + "kubernetes/typed/authorization/v1", + "kubernetes/typed/authorization/v1beta1", + "kubernetes/typed/autoscaling/v1", + "kubernetes/typed/autoscaling/v2beta1", + "kubernetes/typed/batch/v1", + "kubernetes/typed/batch/v1beta1", + "kubernetes/typed/batch/v2alpha1", + "kubernetes/typed/certificates/v1beta1", + "kubernetes/typed/core/v1", + "kubernetes/typed/events/v1beta1", + "kubernetes/typed/extensions/v1beta1", + "kubernetes/typed/networking/v1", + "kubernetes/typed/policy/v1beta1", + "kubernetes/typed/rbac/v1", + "kubernetes/typed/rbac/v1alpha1", + "kubernetes/typed/rbac/v1beta1", + "kubernetes/typed/scheduling/v1alpha1", + "kubernetes/typed/scheduling/v1beta1", + "kubernetes/typed/settings/v1alpha1", + "kubernetes/typed/storage/v1", + "kubernetes/typed/storage/v1alpha1", + "kubernetes/typed/storage/v1beta1", + "pkg/apis/clientauthentication", + "pkg/apis/clientauthentication/v1alpha1", + "pkg/apis/clientauthentication/v1beta1", + "pkg/version", + "plugin/pkg/client/auth/exec", + "rest", + "rest/watch", + "tools/cache", + "tools/clientcmd/api", + "tools/metrics", + "tools/pager", + "tools/reference", + "transport", + "util/buffer", + "util/cert", + "util/connrotation", + "util/flowcontrol", + "util/integer", + "util/retry", + "util/workqueue", + ] + pruneopts = "UT" + revision = "7d04d0e2a0a1a4d4a1cd6baa432a2301492e4e65" + version = "v8.0.0" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + input-imports = [ + "github.com/go-chi/chi", + "github.com/go-kit/kit/log", + "github.com/go-kit/kit/log/level", + "github.com/joho/godotenv", + "github.com/oklog/run", + "github.com/prometheus/client_golang/prometheus", + "github.com/prometheus/client_golang/prometheus/promhttp", + "github.com/prometheus/common/model", + "github.com/prometheus/prometheus/discovery", + "github.com/prometheus/prometheus/discovery/targetgroup", + "github.com/scaleway/go-scaleway", + "github.com/scaleway/go-scaleway/logger", + "gopkg.in/urfave/cli.v2", + ] + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml new file mode 100644 index 0000000..994121d --- /dev/null +++ b/Gopkg.toml @@ -0,0 +1,55 @@ +[[constraint]] + name = "github.com/go-chi/chi" + version = "3.3.3" + +[[constraint]] + name = "github.com/go-kit/kit" + version = "0.7.0" + +[[constraint]] + name = "github.com/joho/godotenv" + version = "1.3.0" + +[[constraint]] + name = "github.com/oklog/run" + version = "1.0.0" + +[[constraint]] + name = "github.com/prometheus/client_golang" + version = "0.8.0" + +[[constraint]] + branch = "master" + name = "github.com/prometheus/common" + +[[constraint]] + name = "github.com/prometheus/prometheus" + version = "2.4.2" + +[[constraint]] + branch = "master" + name = "github.com/scaleway/go-scaleway" + +[[constraint]] + branch = "v2" + name = "gopkg.in/urfave/cli.v2" + +[[override]] + branch = "release-1.11" + name = "k8s.io/api" + +[[override]] + branch = "release-1.11" + name = "k8s.io/apimachinery" + +[[override]] + name = "k8s.io/client-go" + version = "8.0.0" + +[[override]] + name = "github.com/Azure/azure-sdk-for-go" + version = "6.0.0-beta" + +[prune] + go-tests = true + unused-packages = true diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8f71f43 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6935d43 --- /dev/null +++ b/Makefile @@ -0,0 +1,145 @@ +NAME := prometheus-scw-sd +IMPORT := github.com/promhippie/$(NAME) +DIST := dist + +ifeq ($(OS), Windows_NT) + EXECUTABLE := $(NAME).exe + HAS_RETOOL := $(shell where retool) +else + EXECUTABLE := $(NAME) + HAS_RETOOL := $(shell command -v retool) +endif + +PACKAGES ?= $(shell go list ./... | grep -v /vendor/ | grep -v /_tools/) +SOURCES ?= $(shell find . -name "*.go" -type f -not -path "./vendor/*" -not -path "./_tools/*") + +TAGS ?= + +ifndef VERSION + ifneq ($(DRONE_TAG),) + VERSION ?= $(subst v,,$(DRONE_TAG)) + else + ifneq ($(DRONE_BRANCH),) + VERSION ?= 0.0.0-$(subst /,,$(DRONE_BRANCH)) + else + VERSION ?= 0.0.0-master + endif + endif +endif + +ifndef SHA + SHA := $(shell git rev-parse --short HEAD) +endif + +ifndef DATE + DATE := $(shell date -u '+%Y%m%d') +endif + +LDFLAGS += -s -w -X "$(IMPORT)/pkg/version.Version=$(VERSION)" -X "$(IMPORT)/pkg/version.Revision=$(SHA)" -X "$(IMPORT)/pkg/version.BuildDate=$(DATE)" + +.PHONY: all +all: build + +.PHONY: update +update: + retool do dep ensure -update + +.PHONY: sync +sync: + retool do dep ensure + +.PHONY: clean +clean: + go clean -i ./... + rm -rf bin/ $(DIST)/ + +.PHONY: fmt +fmt: + gofmt -s -w $(SOURCES) + +.PHONY: vet +vet: + go vet $(PACKAGES) + +.PHONY: megacheck +megacheck: + retool do megacheck $(PACKAGES) + +.PHONY: lint +lint: + for PKG in $(PACKAGES); do retool do golint -set_exit_status $$PKG || exit 1; done; + +.PHONY: generate +generate: + retool do go generate $(PACKAGES) + +.PHONY: test +test: + retool do goverage -v -coverprofile coverage.out $(PACKAGES) + +.PHONY: install +install: $(SOURCES) + go install -v -tags '$(TAGS)' -ldflags '$(LDFLAGS)' ./cmd/$(NAME) + +.PHONY: build +build: bin/$(EXECUTABLE) + +bin/$(EXECUTABLE): $(SOURCES) + go build -i -v -tags '$(TAGS)' -ldflags '$(LDFLAGS)' -o $@ ./cmd/$(NAME) + +.PHONY: release +release: release-dirs release-windows release-linux release-darwin release-copy release-check + +.PHONY: release-dirs +release-dirs: + mkdir -p $(DIST)/binaries $(DIST)/release + +.PHONY: release-windows +release-windows: +ifeq ($(CI),drone) + xgo -dest $(DIST)/binaries -tags 'netgo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out $(EXECUTABLE)-$(VERSION) ./cmd/$(NAME) + mv /build/* $(DIST)/binaries +else + retool do xgo -dest $(DIST)/binaries -tags 'netgo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out $(EXECUTABLE)-$(VERSION) ./cmd/$(NAME) +endif + +.PHONY: release-linux +release-linux: +ifeq ($(CI),drone) + xgo -dest $(DIST)/binaries -tags 'netgo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'linux/*' -out $(EXECUTABLE)-$(VERSION) ./cmd/$(NAME) + mv /build/* $(DIST)/binaries +else + retool do xgo -dest $(DIST)/binaries -tags 'netgo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'linux/*' -out $(EXECUTABLE)-$(VERSION) ./cmd/$(NAME) +endif + +.PHONY: release-darwin +release-darwin: +ifeq ($(CI),drone) + xgo -dest $(DIST)/binaries -tags 'netgo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'darwin/*' -out $(EXECUTABLE)-$(VERSION) ./cmd/$(NAME) + mv /build/* $(DIST)/binaries +else + retool do xgo -dest $(DIST)/binaries -tags 'netgo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'darwin/*' -out $(EXECUTABLE)-$(VERSION) ./cmd/$(NAME) +endif + +.PHONY: release-copy +release-copy: + $(foreach file,$(wildcard $(DIST)/binaries/$(EXECUTABLE)-*),cp $(file) $(DIST)/release/$(notdir $(file));) + +.PHONY: release-check +release-check: + cd $(DIST)/release; $(foreach file,$(wildcard $(DIST)/release/$(EXECUTABLE)-*),sha256sum $(notdir $(file)) > $(notdir $(file)).sha256;) + +.PHONY: publish +publish: release + +.PHONY: docs +docs: + hugo -s docs/ + +.PHONY: retool +retool: +ifndef HAS_RETOOL + go get -u github.com/twitchtv/retool +endif + retool sync + retool build diff --git a/README.md b/README.md index 0c67047..4fbd184 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,68 @@ -# prometheus-scw-sd -Prometheus Service Discovery for Scaleway +# Prometheus Scaleway SD + +[![Build Status](http://github.dronehippie.de/api/badges/promhippie/prometheus-scw-sd/status.svg)](http://github.dronehippie.de/promhippie/prometheus-scw-sd) +[![Build status](https://ci.appveyor.com/api/projects/status/fa3msf0ldrw60gsy?svg=true)](https://ci.appveyor.com/project/tboerger/prometheus-scw-sd) +[![Stories in Ready](https://badge.waffle.io/promhippie/prometheus-scw-sd.svg?label=ready&title=Ready)](http://waffle.io/promhippie/prometheus-scw-sd) +[![Join the Matrix chat at https://matrix.to/#/#webhippie:matrix.org](https://img.shields.io/badge/matrix-%23webhippie-7bc9a4.svg)](https://matrix.to/#/#webhippie:matrix.org) +[![Codacy Badge](https://api.codacy.com/project/badge/Grade/4671e4dac861415db19d41c7959a530a)](https://www.codacy.com/app/promhippie/prometheus-scw-sd?utm_source=github.com&utm_medium=referral&utm_content=promhippie/prometheus-scw-sd&utm_campaign=Badge_Grade) +[![Go Doc](https://godoc.org/github.com/promhippie/prometheus-scw-sd?status.svg)](http://godoc.org/github.com/promhippie/prometheus-scw-sd) +[![Go Report](http://goreportcard.com/badge/github.com/promhippie/prometheus-scw-sd)](http://goreportcard.com/report/github.com/promhippie/prometheus-scw-sd) +[![](https://images.microbadger.com/badges/image/promhippie/prometheus-scw-sd.svg)](http://microbadger.com/images/promhippie/prometheus-scw-sd "Get your own image badge on microbadger.com") + +This project provides a server to automatically discover nodes within your Scaleway account in a Prometheus SD compatible format. + + +## Install + +You can download prebuilt binaries from our [GitHub releases](https://github.com/promhippie/prometheus-scw-sd/releases), or you can use our Docker images published on [Docker Hub](https://hub.docker.com/r/promhippie/prometheus-scw-sd/tags/). + + +## Development + +Make sure you have a working Go environment, for further reference or a guide take a look at the [install instructions](http://golang.org/doc/install.html). This project requires Go >= v1.8. + +```bash +go get -d github.com/promhippie/prometheus-scw-sd +cd $GOPATH/src/github.com/promhippie/prometheus-scw-sd + +# install retool +make retool + +# sync dependencies +make sync + +# generate code +make generate + +# build binary +make build + +./bin/prometheus-scw-sd -h +``` + + +## Security + +If you find a security issue please contact thomas@webhippie.de first. + + +## Contributing + +Fork -> Patch -> Push -> Pull Request + + +## Authors + +* [Thomas Boerger](https://github.com/tboerger) + + +## License + +Apache-2.0 + + +## Copyright + +``` +Copyright (c) 2018 Thomas Boerger +``` diff --git a/cmd/prometheus-scw-sd/main.go b/cmd/prometheus-scw-sd/main.go new file mode 100644 index 0000000..0efb41e --- /dev/null +++ b/cmd/prometheus-scw-sd/main.go @@ -0,0 +1,173 @@ +package main + +import ( + "errors" + "os" + + "github.com/go-kit/kit/log/level" + "github.com/joho/godotenv" + "github.com/promhippie/prometheus-scw-sd/pkg/action" + "github.com/promhippie/prometheus-scw-sd/pkg/config" + "github.com/promhippie/prometheus-scw-sd/pkg/version" + "gopkg.in/urfave/cli.v2" +) + +var ( + // ErrMissingOutputFile defines the error if output.file is empty. + ErrMissingOutputFile = errors.New("Missing path for output.file") + + // ErrMissingScwToken defines the error if scw.token is empty. + ErrMissingScwToken = errors.New("Missing required scw.token") + + // ErrMissingScwOrg defines the error if scw.org is empty. + ErrMissingScwOrg = errors.New("Missing required scw.org") + + // ErrMissingScwRegion defines the error if scw.region is empty. + ErrMissingScwRegion = errors.New("Missing required scw.region") +) + +func main() { + cfg := config.Load() + + if env := os.Getenv("PROMETHEUS_SCW_ENV_FILE"); env != "" { + godotenv.Load(env) + } + + app := &cli.App{ + Name: "prometheus-scw-sd", + Version: version.Version, + Usage: "Prometheus Scaleway SD", + Authors: []*cli.Author{ + { + Name: "Thomas Boerger", + Email: "thomas@webhippie.de", + }, + }, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "log.level", + Value: "info", + Usage: "Only log messages with given severity", + EnvVars: []string{"PROMETHEUS_SCW_LOG_LEVEL"}, + Destination: &cfg.Logs.Level, + }, + &cli.BoolFlag{ + Name: "log.pretty", + Value: false, + Usage: "Enable pretty messages for logging", + EnvVars: []string{"PROMETHEUS_SCW_LOG_PRETTY"}, + Destination: &cfg.Logs.Pretty, + }, + }, + Commands: []*cli.Command{ + { + Name: "server", + Usage: "start integrated server", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "web.address", + Value: "0.0.0.0:9000", + Usage: "Address to bind the metrics server", + EnvVars: []string{"PROMETHEUS_SCW_WEB_ADDRESS"}, + Destination: &cfg.Server.Addr, + }, + &cli.StringFlag{ + Name: "web.path", + Value: "/metrics", + Usage: "Path to bind the metrics server", + EnvVars: []string{"PROMETHEUS_SCW_WEB_PATH"}, + Destination: &cfg.Server.Path, + }, + &cli.StringFlag{ + Name: "output.file", + Value: "/etc/prometheus/scw.json", + Usage: "Path to write the file_sd config", + EnvVars: []string{"PROMETHEUS_SCW_OUTPUT_FILE"}, + Destination: &cfg.Target.File, + }, + &cli.IntFlag{ + Name: "output.refresh", + Value: 30, + Usage: "Discovery refresh interval in seconds", + EnvVars: []string{"PROMETHEUS_SCW_OUTPUT_REFRESH"}, + Destination: &cfg.Target.Refresh, + }, + &cli.StringFlag{ + Name: "scw.token", + Value: "", + Usage: "Access token for the Scaleway API", + EnvVars: []string{"PROMETHEUS_SCW_TOKEN"}, + Destination: &cfg.Target.Token, + }, + &cli.StringFlag{ + Name: "scw.org", + Value: "", + Usage: "Organization for the Scaleway API", + EnvVars: []string{"PROMETHEUS_SCW_ORG"}, + Destination: &cfg.Target.Org, + }, + &cli.StringFlag{ + Name: "scw.region", + Value: "", + Usage: "Region for the Scaleway API", + EnvVars: []string{"PROMETHEUS_SCW_REGION"}, + Destination: &cfg.Target.Region, + }, + }, + Action: func(c *cli.Context) error { + logger := setupLogger(cfg) + + if cfg.Target.File == "" { + level.Error(logger).Log( + "msg", ErrMissingOutputFile, + ) + + return ErrMissingOutputFile + } + + if cfg.Target.Token == "" { + level.Error(logger).Log( + "msg", ErrMissingScwToken, + ) + + return ErrMissingScwToken + } + + if cfg.Target.Org == "" { + level.Error(logger).Log( + "msg", ErrMissingScwOrg, + ) + + return ErrMissingScwOrg + } + + if cfg.Target.Region == "" { + level.Error(logger).Log( + "msg", ErrMissingScwRegion, + ) + + return ErrMissingScwRegion + } + + return action.Server(cfg, logger) + }, + }, + }, + } + + cli.HelpFlag = &cli.BoolFlag{ + Name: "help", + Aliases: []string{"h"}, + Usage: "Show the help, so what you see now", + } + + cli.VersionFlag = &cli.BoolFlag{ + Name: "version", + Aliases: []string{"v"}, + Usage: "Print the current version of that tool", + } + + if err := app.Run(os.Args); err != nil { + os.Exit(1) + } +} diff --git a/cmd/prometheus-scw-sd/setup.go b/cmd/prometheus-scw-sd/setup.go new file mode 100644 index 0000000..06faeb9 --- /dev/null +++ b/cmd/prometheus-scw-sd/setup.go @@ -0,0 +1,42 @@ +package main + +import ( + "os" + "strings" + + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" + "github.com/promhippie/prometheus-scw-sd/pkg/config" +) + +func setupLogger(cfg *config.Config) log.Logger { + var logger log.Logger + + if cfg.Logs.Pretty { + logger = log.NewSyncLogger( + log.NewLogfmtLogger(os.Stdout), + ) + } else { + logger = log.NewSyncLogger( + log.NewJSONLogger(os.Stdout), + ) + } + + switch strings.ToLower(cfg.Logs.Level) { + case "error": + logger = level.NewFilter(logger, level.AllowError()) + case "warn": + logger = level.NewFilter(logger, level.AllowWarn()) + case "info": + logger = level.NewFilter(logger, level.AllowInfo()) + case "debug": + logger = level.NewFilter(logger, level.AllowDebug()) + default: + logger = level.NewFilter(logger, level.AllowInfo()) + } + + return log.With( + logger, + "ts", log.DefaultTimestampUTC, + ) +} diff --git a/docker/Dockerfile.linux.amd64 b/docker/Dockerfile.linux.amd64 new file mode 100644 index 0000000..31c2e2b --- /dev/null +++ b/docker/Dockerfile.linux.amd64 @@ -0,0 +1,17 @@ +FROM webhippie/alpine:latest AS build +RUN apk add --no-cache ca-certificates mailcap + +FROM scratch + +LABEL maintainer="Thomas Boerger " \ + org.label-schema.name="Prometheus Scaleway SD" \ + org.label-schema.vendor="Thomas Boerger" \ + org.label-schema.schema-version="1.0" + +ENTRYPOINT ["/usr/bin/prometheus-scw-sd"] +CMD ["server"] + +COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ +COPY --from=build /etc/mime.types /etc/ + +COPY dist/binaries/prometheus-scw-sd-*-linux-amd64 /usr/bin/prometheus-scw-sd diff --git a/docker/Dockerfile.linux.arm32v6 b/docker/Dockerfile.linux.arm32v6 new file mode 100644 index 0000000..ac3df91 --- /dev/null +++ b/docker/Dockerfile.linux.arm32v6 @@ -0,0 +1,17 @@ +FROM webhippie/alpine:latest AS build +RUN apk add --no-cache ca-certificates mailcap + +FROM scratch + +LABEL maintainer="Thomas Boerger " \ + org.label-schema.name="Prometheus Scaleway SD" \ + org.label-schema.vendor="Thomas Boerger" \ + org.label-schema.schema-version="1.0" + +ENTRYPOINT ["/usr/bin/prometheus-scw-sd"] +CMD ["server"] + +COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ +COPY --from=build /etc/mime.types /etc/ + +COPY dist/binaries/prometheus-scw-sd-*-linux-arm-6 /usr/bin/prometheus-scw-sd diff --git a/docker/Dockerfile.linux.arm32v7 b/docker/Dockerfile.linux.arm32v7 new file mode 100644 index 0000000..ad2d480 --- /dev/null +++ b/docker/Dockerfile.linux.arm32v7 @@ -0,0 +1,17 @@ +FROM webhippie/alpine:latest AS build +RUN apk add --no-cache ca-certificates mailcap + +FROM scratch + +LABEL maintainer="Thomas Boerger " \ + org.label-schema.name="Prometheus Scaleway SD" \ + org.label-schema.vendor="Thomas Boerger" \ + org.label-schema.schema-version="1.0" + +ENTRYPOINT ["/usr/bin/prometheus-scw-sd"] +CMD ["server"] + +COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ +COPY --from=build /etc/mime.types /etc/ + +COPY dist/binaries/prometheus-scw-sd-*-linux-arm-7 /usr/bin/prometheus-scw-sd diff --git a/docker/Dockerfile.linux.arm64v8 b/docker/Dockerfile.linux.arm64v8 new file mode 100644 index 0000000..140a07b --- /dev/null +++ b/docker/Dockerfile.linux.arm64v8 @@ -0,0 +1,17 @@ +FROM webhippie/alpine:latest AS build +RUN apk add --no-cache ca-certificates mailcap + +FROM scratch + +LABEL maintainer="Thomas Boerger " \ + org.label-schema.name="Prometheus Scaleway SD" \ + org.label-schema.vendor="Thomas Boerger" \ + org.label-schema.schema-version="1.0" + +ENTRYPOINT ["/usr/bin/prometheus-scw-sd"] +CMD ["server"] + +COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ +COPY --from=build /etc/mime.types /etc/ + +COPY dist/binaries/prometheus-scw-sd-*-linux-arm64 /usr/bin/prometheus-scw-sd diff --git a/docker/Dockerfile.linux.i386 b/docker/Dockerfile.linux.i386 new file mode 100644 index 0000000..6b550d5 --- /dev/null +++ b/docker/Dockerfile.linux.i386 @@ -0,0 +1,17 @@ +FROM webhippie/alpine:latest AS build +RUN apk add --no-cache ca-certificates mailcap + +FROM scratch + +LABEL maintainer="Thomas Boerger " \ + org.label-schema.name="Prometheus Scaleway SD" \ + org.label-schema.vendor="Thomas Boerger" \ + org.label-schema.schema-version="1.0" + +ENTRYPOINT ["/usr/bin/prometheus-scw-sd"] +CMD ["server"] + +COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ +COPY --from=build /etc/mime.types /etc/ + +COPY dist/binaries/prometheus-scw-sd-*-linux-386 /usr/bin/prometheus-scw-sd diff --git a/docker/Dockerfile.windows.amd64 b/docker/Dockerfile.windows.amd64 new file mode 100644 index 0000000..aa278a5 --- /dev/null +++ b/docker/Dockerfile.windows.amd64 @@ -0,0 +1,12 @@ +# escape=` +FROM microsoft/nanoserver:10.0.14393.2430 + +LABEL maintainer="Thomas Boerger " ` + org.label-schema.name="Prometheus Scaleway SD" ` + org.label-schema.vendor="Thomas Boerger" ` + org.label-schema.schema-version="1.0" + +ENTRYPOINT ["c:\\prometheus-scw-sd.exe"] +CMD ["server"] + +COPY bin/prometheus-scw-sd.exe c:\prometheus-scw-sd.exe diff --git a/docs/archetypes/default.md b/docs/archetypes/default.md new file mode 100644 index 0000000..4e777be --- /dev/null +++ b/docs/archetypes/default.md @@ -0,0 +1,6 @@ +--- +title: "{{ replace .TranslationBaseName "-" " " | title }}" +date: {{ .Date }} +anchor: "{{ replace .TranslationBaseName "-" " " | title | urlize }}" +weight: +--- diff --git a/docs/config.toml b/docs/config.toml new file mode 100644 index 0000000..db92ac2 --- /dev/null +++ b/docs/config.toml @@ -0,0 +1,15 @@ +baseURL = "https://promhippie.github.io/prometheus-scw-sd/" +languageCode = "en-us" +title = "Prometheus Scaleway SD" + +[blackfriday] + angledQuotes = true + fractions = false + plainIDAnchors = true + smartlists = true + extensions = ["hardLineBreak"] + +[params] + author = "Thomas Boerger" + description = "Prometheus service discovery for Scaleway" + keywords = "prometheus, sd, service, discovery, scaleway, scw" diff --git a/docs/content/building.md b/docs/content/building.md new file mode 100644 index 0000000..a487356 --- /dev/null +++ b/docs/content/building.md @@ -0,0 +1,6 @@ +--- +title: "Building" +date: 2018-05-02T00:00:00+00:00 +anchor: "building" +weight: 30 +--- diff --git a/docs/content/getting-started.md b/docs/content/getting-started.md new file mode 100644 index 0000000..4583eb8 --- /dev/null +++ b/docs/content/getting-started.md @@ -0,0 +1,10 @@ +--- +title: "Getting Started" +date: 2018-05-02T00:00:00+00:00 +anchor: "getting-started" +weight: 10 +--- + +## Installation + +## Configuration diff --git a/docs/content/license.md b/docs/content/license.md new file mode 100644 index 0000000..4230f08 --- /dev/null +++ b/docs/content/license.md @@ -0,0 +1,8 @@ +--- +title: "License" +date: 2018-05-02T00:00:00+00:00 +anchor: "license" +weight: 40 +--- + +This project is licensed under the [Apache 2.0](https://github.com/promhippie/prometheus-scw-sd/blob/master/LICENSE) license. For the license of the used libraries you have to check the respective sources. diff --git a/docs/content/usage.md b/docs/content/usage.md new file mode 100644 index 0000000..c8be824 --- /dev/null +++ b/docs/content/usage.md @@ -0,0 +1,6 @@ +--- +title: "Usage" +date: 2018-05-02T00:00:00+00:00 +anchor: "usage" +weight: 20 +--- diff --git a/docs/layouts/index.html b/docs/layouts/index.html new file mode 100644 index 0000000..f3dca91 --- /dev/null +++ b/docs/layouts/index.html @@ -0,0 +1,57 @@ + + + + + + + + + {{ .Site.Title }} + + + + + + {{ partial "style.html" . }} + + + + + + {{ range .Data.Pages.ByWeight }} +
+

+ + {{ .Title }} + + + + + Back to Top + + +

+ + {{ .Content | markdownify }} +
+ {{ end }} + + diff --git a/docs/layouts/partials/style.html b/docs/layouts/partials/style.html new file mode 100644 index 0000000..e884d91 --- /dev/null +++ b/docs/layouts/partials/style.html @@ -0,0 +1,328 @@ + diff --git a/manifest.tmpl b/manifest.tmpl new file mode 100644 index 0000000..f1034ae --- /dev/null +++ b/manifest.tmpl @@ -0,0 +1,41 @@ +image: promhippie/prometheus-scw-sd:{{#if build.tag}}{{trimPrefix build.tag "v"}}{{else}}latest{{/if}} +{{#if build.tags}} +tags: +{{#each build.tags}} + - {{this}} +{{/each}} +{{/if}} +manifests: + - + image: promhippie/prometheus-scw-sd:{{#if build.tag}}{{trimPrefix build.tag "v"}}-{{/if}}linux-amd64 + platform: + architecture: amd64 + os: linux + - + image: promhippie/prometheus-scw-sd:{{#if build.tag}}{{trimPrefix build.tag "v"}}-{{/if}}linux-i386 + platform: + architecture: 386 + os: linux + - + image: promhippie/prometheus-scw-sd:{{#if build.tag}}{{trimPrefix build.tag "v"}}-{{/if}}linux-arm64v8 + platform: + architecture: arm64 + variant: v8 + os: linux + - + image: promhippie/prometheus-scw-sd:{{#if build.tag}}{{trimPrefix build.tag "v"}}-{{/if}}linux-arm32v7 + platform: + architecture: arm + variant: v7 + os: linux + - + image: promhippie/prometheus-scw-sd:{{#if build.tag}}{{trimPrefix build.tag "v"}}-{{/if}}linux-arm32v6 + platform: + architecture: arm + variant: v6 + os: linux + - + image: promhippie/prometheus-scw-sd:{{#if build.tag}}{{trimPrefix build.tag "v"}}-{{/if}}windows-amd64 + platform: + architecture: amd64 + os: windows diff --git a/pkg/action/discoverer.go b/pkg/action/discoverer.go new file mode 100644 index 0000000..8e84217 --- /dev/null +++ b/pkg/action/discoverer.go @@ -0,0 +1,150 @@ +package action + +import ( + "context" + "errors" + "fmt" + "time" + + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" + "github.com/prometheus/common/model" + "github.com/prometheus/prometheus/discovery/targetgroup" + "github.com/scaleway/go-scaleway" +) + +const ( + scwPrefix = model.MetaLabelPrefix + "scaleway_" + nameLabel = scwPrefix + "name" + identifierLabel = scwPrefix + "id" + archLabel = scwPrefix + "arch" + imageIdentifierLabel = scwPrefix + "image_id" + imageNameLabel = scwPrefix + "image_name" + publicIPLabel = scwPrefix + "public_ipv4" + stateLabel = scwPrefix + "state" + privateIPLabel = scwPrefix + "private_ipv4" + hostnameLabel = scwPrefix + "hostname" + orgLabel = scwPrefix + "org" + commercialTypeLabel = scwPrefix + "commercial_type" + platformLabel = scwPrefix + "platform" + hypervisorLabel = scwPrefix + "hypervisor" + nodeLabel = scwPrefix + "node" + bladeLabel = scwPrefix + "blade" + chassisLabel = scwPrefix + "chassis" + clusterLabel = scwPrefix + "cluster" + zoneLabel = scwPrefix + "zone" +) + +var ( + // ErrClientFailed defines an error if the client init fails. + ErrClientFailed = errors.New("failed to initialize client") + + // ErrClientForbidden defines an error if the authentication fails. + ErrClientForbidden = errors.New("failed to authenticate client") +) + +// Discoverer implements the Prometheus discoverer interface. +type Discoverer struct { + client *api.ScalewayAPI + logger log.Logger + refresh int + lasts map[string]struct{} +} + +// Run initializes fetching the targets for service discovery. +func (d Discoverer) Run(ctx context.Context, ch chan<- []*targetgroup.Group) { + ticker := time.NewTicker(time.Duration(d.refresh) * time.Second) + + for { + targets, err := d.getTargets(ctx) + + if err == nil { + ch <- targets + } + + select { + case <-ticker.C: + continue + case <-ctx.Done(): + return + } + } +} + +func (d *Discoverer) getTargets(ctx context.Context) ([]*targetgroup.Group, error) { + now := time.Now() + servers, err := d.client.GetServers(false, 0) + requestDuration.Observe(time.Since(now).Seconds()) + + if err != nil { + requestFailures.Inc() + return nil, err + } + + level.Debug(d.logger).Log( + "msg", "Requested servers", + "count", len(*servers), + ) + + current := make(map[string]struct{}) + targets := make([]*targetgroup.Group, len(*servers)) + + for _, server := range *servers { + target := &targetgroup.Group{ + Source: fmt.Sprintf("scaleway/%s", server.Identifier), + Targets: []model.LabelSet{ + { + model.AddressLabel: model.LabelValue(server.PublicAddress.IP), + }, + }, + Labels: model.LabelSet{ + model.AddressLabel: model.LabelValue(server.PublicAddress.IP), + model.LabelName(nameLabel): model.LabelValue(server.Name), + model.LabelName(identifierLabel): model.LabelValue(server.Identifier), + model.LabelName(archLabel): model.LabelValue(server.Arch), + model.LabelName(imageIdentifierLabel): model.LabelValue(server.Image.Identifier), + model.LabelName(imageNameLabel): model.LabelValue(server.Image.Name), + model.LabelName(publicIPLabel): model.LabelValue(server.PublicAddress.IP), + model.LabelName(stateLabel): model.LabelValue(server.State), + model.LabelName(privateIPLabel): model.LabelValue(server.PrivateIP), + model.LabelName(hostnameLabel): model.LabelValue(server.Hostname), + model.LabelName(orgLabel): model.LabelValue(server.Organization), + model.LabelName(commercialTypeLabel): model.LabelValue(server.CommercialType), + model.LabelName(platformLabel): model.LabelValue(server.Location.Platform), + model.LabelName(hypervisorLabel): model.LabelValue(server.Location.Hypervisor), + model.LabelName(nodeLabel): model.LabelValue(server.Location.Node), + model.LabelName(bladeLabel): model.LabelValue(server.Location.Blade), + model.LabelName(chassisLabel): model.LabelValue(server.Location.Chassis), + model.LabelName(clusterLabel): model.LabelValue(server.Location.Cluster), + model.LabelName(zoneLabel): model.LabelValue(server.Location.ZoneID), + }, + } + + level.Debug(d.logger).Log( + "msg", "Server added", + "source", target.Source, + ) + + current[target.Source] = struct{}{} + targets = append(targets, target) + } + + for k := range d.lasts { + if _, ok := current[k]; !ok { + level.Debug(d.logger).Log( + "msg", "Server deleted", + "source", k, + ) + + targets = append( + targets, + &targetgroup.Group{ + Source: k, + }, + ) + } + } + + d.lasts = current + return targets, nil +} diff --git a/pkg/action/metrics.go b/pkg/action/metrics.go new file mode 100644 index 0000000..969beb4 --- /dev/null +++ b/pkg/action/metrics.go @@ -0,0 +1,55 @@ +package action + +import ( + "fmt" + "os" + + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" + "github.com/prometheus/client_golang/prometheus" + "github.com/promhippie/prometheus-scw-sd/pkg/version" +) + +var ( + registry = prometheus.NewRegistry() + namespace = "prometheus_scw_sd" +) + +var ( + requestDuration = prometheus.NewHistogram( + prometheus.HistogramOpts{ + Namespace: namespace, + Name: "request_duration_seconds", + Help: "Histogram of latencies for requests to the Scaleway API.", + Buckets: []float64{0.001, 0.01, 0.1, 0.5, 1.0, 2.0, 5.0, 10.0}, + }, + ) + + requestFailures = prometheus.NewCounter( + prometheus.CounterOpts{ + Namespace: namespace, + Name: "request_failures_total", + Help: "Total number of failed requests to the Scaleway API.", + }, + ) +) + +func init() { + registry.MustRegister(prometheus.NewProcessCollector(os.Getpid(), "")) + registry.MustRegister(prometheus.NewGoCollector()) + + registry.MustRegister(version.Collector(namespace)) + + registry.MustRegister(requestDuration) + registry.MustRegister(requestFailures) +} + +type promLogger struct { + logger log.Logger +} + +func (pl promLogger) Println(v ...interface{}) { + level.Error(pl.logger).Log( + "msg", fmt.Sprintln(v...), + ) +} diff --git a/pkg/action/server.go b/pkg/action/server.go new file mode 100644 index 0000000..54a089d --- /dev/null +++ b/pkg/action/server.go @@ -0,0 +1,151 @@ +package action + +import ( + "context" + "io" + "net/http" + "os" + "os/signal" + "time" + + "github.com/go-chi/chi" + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" + "github.com/oklog/run" + "github.com/prometheus/client_golang/prometheus/promhttp" + "github.com/promhippie/prometheus-scw-sd/pkg/adapter" + "github.com/promhippie/prometheus-scw-sd/pkg/config" + "github.com/promhippie/prometheus-scw-sd/pkg/version" + "github.com/scaleway/go-scaleway" + scwlog "github.com/scaleway/go-scaleway/logger" +) + +// Server handles the server sub-command. +func Server(cfg *config.Config, logger log.Logger) error { + level.Info(logger).Log( + "msg", "Launching Prometheus Scaleway SD", + "version", version.Version, + "revision", version.Revision, + "date", version.BuildDate, + "go", version.GoVersion, + ) + + var gr run.Group + + { + ctx := context.Background() + + client, err := api.NewScalewayAPI( + cfg.Target.Org, + cfg.Target.Token, + "", + cfg.Target.Region, + func(s *api.ScalewayAPI) { + s.Logger = scwlog.NewDisableLogger() + }, + ) + + if err != nil { + return ErrClientFailed + } + + if err := client.CheckCredentials(); err != nil { + return ErrClientForbidden + } + + disc := Discoverer{ + client: client, + logger: logger, + refresh: cfg.Target.Refresh, + lasts: make(map[string]struct{}), + } + + a := adapter.NewAdapter(ctx, cfg.Target.File, "scaleway-sd", disc, logger) + a.Run() + + } + + { + server := &http.Server{ + Addr: cfg.Server.Addr, + Handler: handler(cfg, logger), + ReadTimeout: 5 * time.Second, + WriteTimeout: 10 * time.Second, + } + + gr.Add(func() error { + level.Info(logger).Log( + "msg", "Starting metrics server", + "addr", cfg.Server.Addr, + ) + + return server.ListenAndServe() + }, func(reason error) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + if err := server.Shutdown(ctx); err != nil { + level.Error(logger).Log( + "msg", "Failed to shutdown metrics gracefully", + "err", err, + ) + + return + } + + level.Info(logger).Log( + "msg", "Metrics shutdown gracefully", + "reason", reason, + ) + }) + } + + { + stop := make(chan os.Signal, 1) + + gr.Add(func() error { + signal.Notify(stop, os.Interrupt) + + <-stop + + return nil + }, func(err error) { + close(stop) + }) + } + + return gr.Run() +} + +func handler(cfg *config.Config, logger log.Logger) *chi.Mux { + mux := chi.NewRouter() + + prom := promhttp.HandlerFor( + registry, + promhttp.HandlerOpts{ + ErrorLog: promLogger{logger}, + }, + ) + + mux.Route("/", func(root chi.Router) { + root.Get(cfg.Server.Path, func(w http.ResponseWriter, r *http.Request) { + prom.ServeHTTP(w, r) + }) + + root.Get("/healthz", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/plain") + w.WriteHeader(http.StatusOK) + + io.WriteString(w, http.StatusText(http.StatusOK)) + }) + + root.Get("/readyz", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/plain") + w.WriteHeader(http.StatusOK) + + io.WriteString(w, http.StatusText(http.StatusOK)) + }) + }) + + return mux +} diff --git a/pkg/adapter/adapter.go b/pkg/adapter/adapter.go new file mode 100644 index 0000000..411b4cd --- /dev/null +++ b/pkg/adapter/adapter.go @@ -0,0 +1,152 @@ +// Copyright 2018 The Prometheus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package adapter + +// NOTE: you do not need to edit this file when implementing a custom sd. +import ( + "context" + "encoding/json" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "reflect" + + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" + "github.com/prometheus/prometheus/discovery" + "github.com/prometheus/prometheus/discovery/targetgroup" +) + +type customSD struct { + Targets []string `json:"targets"` + Labels map[string]string `json:"labels"` +} + +// Adapter runs an unknown service discovery implementation and converts its target groups +// to JSON and writes to a file for file_sd. +type Adapter struct { + ctx context.Context + disc discovery.Discoverer + groups map[string]*customSD + manager *discovery.Manager + output string + name string + logger log.Logger +} + +func mapToArray(m map[string]*customSD) []customSD { + arr := make([]customSD, 0, len(m)) + for _, v := range m { + arr = append(arr, *v) + } + return arr +} + +// Parses incoming target groups updates. If the update contains changes to the target groups +// Adapter already knows about, or new target groups, we Marshal to JSON and write to file. +func (a *Adapter) generateTargetGroups(allTargetGroups map[string][]*targetgroup.Group) { + tempGroups := make(map[string]*customSD) + for k, sdTargetGroups := range allTargetGroups { + for i, group := range sdTargetGroups { + newTargets := make([]string, 0) + newLabels := make(map[string]string) + + for _, targets := range group.Targets { + for _, target := range targets { + newTargets = append(newTargets, string(target)) + } + } + + for name, value := range group.Labels { + newLabels[string(name)] = string(value) + } + // Make a unique key, including the current index, in case the sd_type (map key) and group.Source is not unique. + key := fmt.Sprintf("%s:%s:%d", k, group.Source, i) + tempGroups[key] = &customSD{ + Targets: newTargets, + Labels: newLabels, + } + } + } + if !reflect.DeepEqual(a.groups, tempGroups) { + a.groups = tempGroups + err := a.writeOutput() + if err != nil { + level.Error(log.With(a.logger, "component", "sd-adapter")).Log("err", err) + } + } + +} + +// Writes JSON formatted targets to output file. +func (a *Adapter) writeOutput() error { + arr := mapToArray(a.groups) + b, _ := json.MarshalIndent(arr, "", " ") + + dir, _ := filepath.Split(a.output) + tmpfile, err := ioutil.TempFile(dir, "sd-adapter") + if err != nil { + return err + } + defer tmpfile.Close() + + _, err = tmpfile.Write(b) + if err != nil { + return err + } + + err = os.Rename(tmpfile.Name(), a.output) + if err != nil { + return err + } + return nil +} + +func (a *Adapter) runCustomSD(ctx context.Context) { + updates := a.manager.SyncCh() + for { + select { + case <-ctx.Done(): + case allTargetGroups, ok := <-updates: + // Handle the case that a target provider exits and closes the channel + // before the context is done. + if !ok { + return + } + a.generateTargetGroups(allTargetGroups) + } + } +} + +// Run starts a Discovery Manager and the custom service discovery implementation. +func (a *Adapter) Run() { + go a.manager.Run() + a.manager.StartCustomProvider(a.ctx, a.name, a.disc) + go a.runCustomSD(a.ctx) +} + +// NewAdapter creates a new instance of Adapter. +func NewAdapter(ctx context.Context, file string, name string, d discovery.Discoverer, logger log.Logger) *Adapter { + return &Adapter{ + ctx: ctx, + disc: d, + groups: make(map[string]*customSD), + manager: discovery.NewManager(ctx, logger), + output: file, + name: name, + logger: logger, + } +} diff --git a/pkg/config/config.go b/pkg/config/config.go new file mode 100644 index 0000000..3f88846 --- /dev/null +++ b/pkg/config/config.go @@ -0,0 +1,34 @@ +package config + +// Server defines the general server configuration. +type Server struct { + Addr string + Path string +} + +// Logs defines the level and color for log configuration. +type Logs struct { + Level string + Pretty bool +} + +// Target defines the target specific configuration. +type Target struct { + File string + Refresh int + Token string + Org string + Region string +} + +// Config is a combination of all available configurations. +type Config struct { + Server Server + Logs Logs + Target Target +} + +// Load initializes a default configuration struct. +func Load() *Config { + return &Config{} +} diff --git a/pkg/version/collector.go b/pkg/version/collector.go new file mode 100644 index 0000000..e69d1a8 --- /dev/null +++ b/pkg/version/collector.go @@ -0,0 +1,20 @@ +package version + +import ( + "github.com/prometheus/client_golang/prometheus" +) + +// Collector simply exports the version information for Prometheus. +func Collector(ns string) *prometheus.GaugeVec { + info := prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: ns, + Name: "build_info", + Help: "A metric with a constant '1' value labeled by version, revision and goversion from which it was built.", + }, + []string{"version", "revision", "goversion"}, + ) + + info.WithLabelValues(Version, Revision, GoVersion).Set(1) + return info +} diff --git a/pkg/version/version.go b/pkg/version/version.go new file mode 100644 index 0000000..a3a22de --- /dev/null +++ b/pkg/version/version.go @@ -0,0 +1,19 @@ +package version + +import ( + "runtime" +) + +var ( + // Version gets defined by the build system. + Version = "0.0.0-dev" + + // Revision indicates the commit this binary was built from. + Revision string + + // BuildDate indicates the date this binary was built. + BuildDate string + + // GoVersion running this binary. + GoVersion = runtime.Version() +) diff --git a/tools.json b/tools.json new file mode 100644 index 0000000..1b7fd76 --- /dev/null +++ b/tools.json @@ -0,0 +1,25 @@ +{ + "Tools": [ + { + "Repository": "github.com/golang/dep/cmd/dep", + "Commit": "45be32ba4708aad5e2aa8c86f9432c4c4c1f8da2" + }, + { + "Repository": "github.com/golang/lint/golint", + "Commit": "06c8688daad7faa9da5a0c2f163a3d14aac986ca" + }, + { + "Repository": "honnef.co/go/tools/cmd/megacheck", + "Commit": "3ac6a802416d2efd6654491fe47f693e56d8eb4e" + }, + { + "Repository": "github.com/karalabe/xgo", + "Commit": "d164e4e53dfdc4e25de90a762d213f8d397e24a1" + }, + { + "Repository": "github.com/haya14busa/goverage", + "Commit": "eec3514a20b55dca311300eeb08fe5c8ab9ab781" + } + ], + "RetoolVersion": "1.3.7" +}