Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
pragkent committed Aug 23, 2019
0 parents commit 0256c3b
Show file tree
Hide file tree
Showing 18 changed files with 1,174 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
vendor/
kubebuilder/
14 changes: 14 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
sudo: false

language: go

services:
- docker

go:
- 1.12

script:
- set -e
- docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
- make release
25 changes: 25 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
FROM golang:1.12.4-alpine AS build_deps

RUN apk add --no-cache git

WORKDIR /workspace
ENV GO111MODULE=on

COPY go.mod .
COPY go.sum .

RUN go mod download

FROM build_deps AS build

COPY . .

RUN CGO_ENABLED=0 go build -o webhook -ldflags '-w -extldflags "-static"' .

FROM alpine:3.9

RUN apk add --no-cache ca-certificates

COPY --from=build /workspace/webhook /usr/local/bin/webhook

ENTRYPOINT ["webhook"]
12 changes: 12 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
IMAGE_NAME := pragkent/alidns-webhook
IMAGE_TAG := $(shell cat VERSION)

test:
go test -v .

docker:
docker build -t $(IMAGE_NAME):$(IMAGE_TAG) .

release:
docker build -t $(IMAGE_NAME):$(IMAGE_TAG) .
docker push $(IMAGE_NAME):$(IMAGE_TAG)
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
alidns-webhook
=================

Cert-manager ACME DNS webhook provider for alidns.

## Running the test suite

All DNS providers **must** run the DNS01 provider conformance testing suite,
else they will have undetermined behaviour when used with cert-manager.

**It is essential that you configure and run the test suite when creating a
DNS01 webhook.**

An example Go test file has been provided in [main_test.go]().

You can run the test suite with:

```bash
$ TEST_ZONE_NAME=example.com go test .
```

1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.1.0
88 changes: 88 additions & 0 deletions alidns/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package alidns

import (
"fmt"

"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth"
"github.com/aliyun/alibaba-cloud-sdk-go/services/alidns"
"github.com/jetstack/cert-manager/pkg/issuer/acme/dns/util"
)

type Client struct {
dnsc *alidns.Client
}

func newClient(region string, cred auth.Credential) (*Client, error) {
cfg := sdk.NewConfig()
client, err := alidns.NewClientWithOptions(region, cfg, cred)
if err != nil {
return nil, err
}

return &Client{dnsc: client}, nil
}

func (c *Client) getHostedZone(zone string) (string, error) {
request := alidns.CreateDescribeDomainsRequest()
request.KeyWord = util.UnFqdn(zone)
request.SearchMode = "EXACT"

response, err := c.dnsc.DescribeDomains(request)
if err != nil {
return "", err
}

zones := response.Domains.Domain
if len(zones) == 0 {
return "", fmt.Errorf("zone %s does not exist", zone)
}

return zones[0].DomainName, nil
}

func (c *Client) addTxtRecord(zone, rr, value string) error {
record := c.newTxtRecord(zone, rr, value)
_, err := c.dnsc.AddDomainRecord(record)
return err
}

const recordTypeTxt = "TXT"

func (c *Client) newTxtRecord(zone, rr, value string) *alidns.AddDomainRecordRequest {
request := alidns.CreateAddDomainRecordRequest()
request.Type = recordTypeTxt
request.DomainName = zone
request.RR = rr
request.Value = value
return request
}

func (c *Client) getTxtRecord(zone, rr string) (*alidns.Record, error) {
request := alidns.CreateDescribeDomainRecordsRequest()
request.Type = recordTypeTxt
request.DomainName = zone
request.RRKeyWord = rr

response, err := c.dnsc.DescribeDomainRecords(request)
if err != nil {
return nil, err
}

records := response.DomainRecords.Record
for _, r := range records {
if r.RR == rr {
return &r, nil
}
}

return nil, fmt.Errorf("txt record does not exist: %v.%v", rr, zone)
}

func (c *Client) deleteDomainRecord(id string) error {
request := alidns.CreateDeleteDomainRecordRequest()
request.RecordId = id

_, err := c.dnsc.DeleteDomainRecord(request)
return err
}
50 changes: 50 additions & 0 deletions alidns/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package alidns

import (
"encoding/json"
"fmt"

apis "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1alpha1"
extapi "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
)

// Config is a structure that is used to decode into when
// solving a DNS01 challenge.
//
// This information is provided by cert-manager, and may be a reference to
// additional configuration that's needed to solve the challenge for this
// particular certificate or issuer.
//
// This typically includes references to Secret resources containing DNS
// provider credentials, in cases where a 'multi-tenant' DNS solver is being
// created.
//
// If you do *not* require per-issuer or per-certificate configuration to be
// provided to your webhook, you can skip decoding altogether in favour of
// using CLI flags or similar to provide configuration.
//
// You should not include sensitive information here. If credentials need to
// be used by your provider here, you should reference a Kubernetes Secret
// resource and fetch these credentials using a Kubernetes clientset.
type Config struct {
Region string `json:"region"`
AccessKeySecretRef apis.SecretKeySelector `json:"accessKeySecretRef"`
SecretKeySecretRef apis.SecretKeySelector `json:"secretKeySecretRef"`
}

// loadConfig is a small helper function that decodes JSON configuration into
// the typed config struct.
func loadConfig(cfgJSON *extapi.JSON) (Config, error) {
cfg := Config{}

// handle the 'base case' where no configuration has been provided
if cfgJSON == nil {
return cfg, nil
}

if err := json.Unmarshal(cfgJSON.Raw, &cfg); err != nil {
return cfg, fmt.Errorf("error decoding solver config: %v", err)
}

return cfg, nil
}
Loading

0 comments on commit 0256c3b

Please sign in to comment.