Compare commits
4 Commits
088a79a334
...
6869fdc80f
| Author | SHA1 | Date | |
|---|---|---|---|
| 6869fdc80f | |||
| 439e7989b0 | |||
| 3a3eab56ed | |||
| 8374d8b3ad |
@ -47,9 +47,3 @@ Create chart name and version as used by the chart label.
|
|||||||
{{ printf "%s-webhook-tls" (include "sthome-webhook.fullname" .) }}
|
{{ printf "%s-webhook-tls" (include "sthome-webhook.fullname" .) }}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create base64 imagePullSecret using username and password.
|
|
||||||
*/}}
|
|
||||||
{{- define "imagePullSecret" }}
|
|
||||||
{{- printf "{\"auths\": {\"%s\": {\"auth\": \"%s\"}}}" .Values.imageCredentials.registry (printf "%s:%s" .Values.imageCredentials.username .Values.imageCredentials.password | b64enc) | b64enc }}
|
|
||||||
{{- end }}
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
# The GroupName here is used to identify your company or business unit that
|
# The GroupName here is used to identify your company or business unit that
|
||||||
# created this webhook.
|
# created this webhook.
|
||||||
# For sthome, this may be "webhook.acme.cert-manager.io".
|
# For sthome, this may be "acme.sthome.net".
|
||||||
# This name will need to be referenced in each Issuer's `webhook` stanza to
|
# This name will need to be referenced in each Issuer's `webhook` stanza to
|
||||||
# inform cert-manager of where to send ChallengePayload resources in order to
|
# inform cert-manager of where to send ChallengePayload resources in order to
|
||||||
# solve the DNS01 challenge.
|
# solve the DNS01 challenge.
|
||||||
@ -16,7 +16,7 @@ image:
|
|||||||
repository: stuurmcp/cert-manager-webhook-sthome
|
repository: stuurmcp/cert-manager-webhook-sthome
|
||||||
tag: 0.0.1
|
tag: 0.0.1
|
||||||
#pullPolicy should be IfNotPresent. Set to Always for testing purposes
|
#pullPolicy should be IfNotPresent. Set to Always for testing purposes
|
||||||
pullPolicy: Always
|
pullPolicy: IfNotPresent
|
||||||
|
|
||||||
imageCredentials:
|
imageCredentials:
|
||||||
name: docker-registry-credentials
|
name: docker-registry-credentials
|
||||||
|
|||||||
3
go.mod
3
go.mod
@ -15,6 +15,8 @@ require (
|
|||||||
k8s.io/client-go v0.29.0
|
k8s.io/client-go v0.29.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
require k8s.io/klog/v2 v2.110.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/NYTimes/gziphandler v1.1.1 // indirect
|
github.com/NYTimes/gziphandler v1.1.1 // indirect
|
||||||
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect
|
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect
|
||||||
@ -103,7 +105,6 @@ require (
|
|||||||
k8s.io/apimachinery v0.29.0 // indirect
|
k8s.io/apimachinery v0.29.0 // indirect
|
||||||
k8s.io/apiserver v0.29.0 // indirect
|
k8s.io/apiserver v0.29.0 // indirect
|
||||||
k8s.io/component-base v0.29.0 // indirect
|
k8s.io/component-base v0.29.0 // indirect
|
||||||
k8s.io/klog/v2 v2.110.1 // indirect
|
|
||||||
k8s.io/kms v0.29.0 // indirect
|
k8s.io/kms v0.29.0 // indirect
|
||||||
k8s.io/kube-openapi v0.0.0-20240103051144-eec4567ac022 // indirect
|
k8s.io/kube-openapi v0.0.0-20240103051144-eec4567ac022 // indirect
|
||||||
k8s.io/utils v0.0.0-20240102154912-e7106e64919e // indirect
|
k8s.io/utils v0.0.0-20240102154912-e7106e64919e // indirect
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
package sthome
|
package sthome
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -25,5 +27,66 @@ type localDNSProviderConfig struct {
|
|||||||
// `issuer.spec.acme.dns01.providers.webhook.config` field.
|
// `issuer.spec.acme.dns01.providers.webhook.config` field.
|
||||||
|
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
|
// APIKeySecretRef contains the reference information for the Kubernetes
|
||||||
|
// secret which contains the sthome API Key.
|
||||||
APIKeySecretRef v1.SecretKeySelector `json:"apiKeySecretRef"`
|
APIKeySecretRef v1.SecretKeySelector `json:"apiKeySecretRef"`
|
||||||
|
// Host is the Base URL (e.g. https://dns.example.ca) of the sthome API.
|
||||||
|
Host string `json:"host"`
|
||||||
|
|
||||||
|
// Scheme supports HTTP AuthSchemes
|
||||||
|
// https://www.iana.org/assignments/http-authschemes/http-authschemes.xhtml
|
||||||
|
//
|
||||||
|
// +optional default ""
|
||||||
|
APIKeyScheme string `json:"apiKeyScheme"`
|
||||||
|
|
||||||
|
// APIKeyHeaderName is the header name where apiKey will be set
|
||||||
|
//
|
||||||
|
// +optional default "X-API-Key"
|
||||||
|
APIKeyHeaderName string `json:"apiKeyHeaderName"`
|
||||||
|
|
||||||
|
// ServerID is the server ID in the sthome API.
|
||||||
|
// When unset, defaults to "localhost".
|
||||||
|
ServerID string `json:"serverID"`
|
||||||
|
|
||||||
|
// Headers are additional headers added to requests to the
|
||||||
|
// sthome API server.
|
||||||
|
Headers map[string]string `json:"headers"`
|
||||||
|
|
||||||
|
// CABundle is a PEM encoded CA bundle which will be used in
|
||||||
|
// certificate validation when connecting to the sthome server.
|
||||||
|
//
|
||||||
|
// When left blank, the default system store will be used.
|
||||||
|
//
|
||||||
|
// +optional
|
||||||
|
CABundle []byte `json:"caBundle"`
|
||||||
|
|
||||||
|
// TTL is the time-to-live value of the inserted DNS records.
|
||||||
|
//
|
||||||
|
// +optional
|
||||||
|
TTL int `json:"ttl"`
|
||||||
|
|
||||||
|
// Timeout is the timeout value for requests to the sthome API.
|
||||||
|
// The value is specified in seconds.
|
||||||
|
//
|
||||||
|
// +optional
|
||||||
|
Timeout int `json:"timeout"`
|
||||||
|
|
||||||
|
// AllowedZones is the list of zones that may be edited. If the list is
|
||||||
|
// empty, all zones are permitted.
|
||||||
|
AllowedZones []string `json:"allowed-zones"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsAllowedZone checks if the webhook is allowed to edit the given zone, per
|
||||||
|
// AllowedZones setting. All zones allowed if AllowedZones is empty (the default setting)
|
||||||
|
func (cfg localDNSProviderConfig) IsAllowedZone(zone string) bool {
|
||||||
|
if len(cfg.AllowedZones) == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, allowed := range cfg.AllowedZones {
|
||||||
|
if zone == allowed || strings.HasSuffix(zone, "."+allowed) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/client-go/rest"
|
"k8s.io/client-go/rest"
|
||||||
|
"k8s.io/klog/v2"
|
||||||
|
|
||||||
"github.com/cert-manager/cert-manager/pkg/acme/webhook/apis/acme/v1alpha1"
|
"github.com/cert-manager/cert-manager/pkg/acme/webhook/apis/acme/v1alpha1"
|
||||||
"github.com/cert-manager/cert-manager/pkg/issuer/acme/dns/util"
|
"github.com/cert-manager/cert-manager/pkg/issuer/acme/dns/util"
|
||||||
@ -46,9 +47,34 @@ func (loc *LocalDNSProviderSolver) Present(ch *v1alpha1.ChallengeRequest) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
klog.InfoS("Presenting challenge", "dnsName", ch.DNSName, "resolvedZone", ch.ResolvedZone, "resolvedFQDN", ch.ResolvedFQDN)
|
||||||
|
|
||||||
|
/*
|
||||||
|
provider, cfg, err := loc.init(ch.Config, ch.ResourceNamespace)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed initializing sthome provider: %v", err)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
if !cfg.IsAllowedZone(ch.ResolvedZone) {
|
||||||
|
return fmt.Errorf("zone %s may not be edited per config (allowed zones are %v)", ch.ResolvedZone, cfg.AllowedZones)
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
ctx := context.Background()
|
||||||
|
records, err := loc.getExistingRecords(ctx, provider, ch.ResolvedZone, ch.ResolvedFQDN)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed loading existing records for %s in domain %s: %v", ch.ResolvedFQDN, ch.ResolvedZone, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the record, only if it doesn't exist already
|
||||||
|
content := quote(ch.Key)
|
||||||
|
if _, ok := findRecord(records, content); !ok {
|
||||||
|
disabled := false
|
||||||
|
records = append(records, sthome.Record{Disabled: &disabled, Content: &content})
|
||||||
|
}
|
||||||
|
*/
|
||||||
// TODO: do something more useful with the decoded configuration
|
// TODO: do something more useful with the decoded configuration
|
||||||
fmt.Printf("Decoded configuration %v", cfg)
|
klog.InfoS("Decoded configuration %v", cfg)
|
||||||
fmt.Printf("presenting record for %s (%s)\n", ch.ResolvedFQDN, domainName)
|
klog.InfoS("presenting record for %s (%s)\n", ch.ResolvedFQDN, domainName)
|
||||||
// TODO: add code that sets a record in the DNS provider's console
|
// TODO: add code that sets a record in the DNS provider's console
|
||||||
|
|
||||||
// shell command
|
// shell command
|
||||||
@ -71,7 +97,7 @@ func (loc *LocalDNSProviderSolver) Present(ch *v1alpha1.ChallengeRequest) error
|
|||||||
// value provided on the ChallengeRequest should be cleaned up.
|
// value provided on the ChallengeRequest should be cleaned up.
|
||||||
// This is in order to facilitate multiple DNS validations for the same domain
|
// This is in order to facilitate multiple DNS validations for the same domain
|
||||||
// concurrently.
|
// concurrently.
|
||||||
func (s *LocalDNSProviderSolver) CleanUp(ch *v1alpha1.ChallengeRequest) error {
|
func (loc *LocalDNSProviderSolver) CleanUp(ch *v1alpha1.ChallengeRequest) error {
|
||||||
// TODO: add code that deletes a record from the DNS provider's console
|
// TODO: add code that deletes a record from the DNS provider's console
|
||||||
|
|
||||||
// shell command
|
// shell command
|
||||||
@ -96,19 +122,20 @@ func (s *LocalDNSProviderSolver) CleanUp(ch *v1alpha1.ChallengeRequest) error {
|
|||||||
// provider accounts.
|
// provider accounts.
|
||||||
// The stopCh can be used to handle early termination of the webhook, in cases
|
// The stopCh can be used to handle early termination of the webhook, in cases
|
||||||
// where a SIGTERM or similar signal is sent to the webhook process.
|
// where a SIGTERM or similar signal is sent to the webhook process.
|
||||||
func (c *LocalDNSProviderSolver) Initialize(kubeClientConfig *rest.Config, stopCh <-chan struct{}) error {
|
func (loc *LocalDNSProviderSolver) Initialize(kubeClientConfig *rest.Config, stopCh <-chan struct{}) error {
|
||||||
cl, err := kubernetes.NewForConfig(kubeClientConfig)
|
cl, err := kubernetes.NewForConfig(kubeClientConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get kubernetes client: %w", err)
|
return fmt.Errorf("failed to get kubernetes client: %w", err)
|
||||||
}
|
}
|
||||||
c.client = *cl
|
loc.client = *cl
|
||||||
|
klog.InfoS("Successfully initialised kubernetes client!")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractDomainName(zone string) string {
|
func extractDomainName(zone string) string {
|
||||||
authZone, err := util.FindZoneByFqdn(zone, util.RecursiveNameservers)
|
authZone, err := util.FindZoneByFqdn(zone, util.RecursiveNameservers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("could not get zone by fqdn %v", err)
|
klog.Errorf("could not get zone by fqdn %v", err)
|
||||||
return zone
|
return zone
|
||||||
}
|
}
|
||||||
return util.UnFqdn(authZone)
|
return util.UnFqdn(authZone)
|
||||||
|
|||||||
@ -25,4 +25,33 @@ func loadConfig(cfgJSON *extapi.JSON) (localDNSProviderConfig, error) {
|
|||||||
return cfg, nil
|
return cfg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// quote quotes the provide value
|
||||||
|
func quote(value string) string {
|
||||||
|
return fmt.Sprintf("\"%s\"", value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// findRRSet searches through te list of rrsets for a matching entry
|
||||||
|
// based on type and name.
|
||||||
|
func findRRSet(rrsets []sthome.RRset, rrtype sthome.RRType, name string) *sthome.RRset {
|
||||||
|
for _, rrset := range rrsets {
|
||||||
|
if (rrset.Type != nil && *rrset.Type == sthome.RRTypeTXT) &&
|
||||||
|
(rrset.Name != nil && *rrset.Name == name) {
|
||||||
|
return &rrset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// findRecord locates the record entry with the matching content.
|
||||||
|
func findRecord(records []sthome.Record, content string) (int, bool) {
|
||||||
|
for indx, record := range records {
|
||||||
|
if record.Content != nil && *record.Content == content {
|
||||||
|
return indx, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1, false
|
||||||
|
}
|
||||||
|
*/
|
||||||
// end of private repo workaround
|
// end of private repo workaround
|
||||||
|
|||||||
35
util/version.go
Normal file
35
util/version.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
// These are set during build time via -ldflags
|
||||||
|
var (
|
||||||
|
version = "0.0.1+dev"
|
||||||
|
gitCommit string
|
||||||
|
buildDate string
|
||||||
|
)
|
||||||
|
|
||||||
|
// VersionInfo represents the current running version
|
||||||
|
type VersionInfo struct {
|
||||||
|
Version string `json:"version"`
|
||||||
|
GitCommit string `json:"gitCommit"`
|
||||||
|
BuildDate string `json:"buildDate"`
|
||||||
|
GoVersion string `json:"goVersion"`
|
||||||
|
Compiler string `json:"compiler"`
|
||||||
|
Platform string `json:"platform"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetVersion returns the current running version
|
||||||
|
func GetVersion() VersionInfo {
|
||||||
|
return VersionInfo{
|
||||||
|
Version: version,
|
||||||
|
GitCommit: gitCommit,
|
||||||
|
BuildDate: buildDate,
|
||||||
|
GoVersion: runtime.Version(),
|
||||||
|
Compiler: runtime.Compiler,
|
||||||
|
Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH),
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user