diff --git a/deploy/example-webhook/Chart.yaml b/deploy/example-webhook/Chart.yaml index 77c6ead..2e7558b 100644 --- a/deploy/example-webhook/Chart.yaml +++ b/deploy/example-webhook/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v1 -appVersion: "1.0" -description: A Helm chart for Kubernetes -name: example-webhook +appVersion: "0.1.0" +description: Sotoon Cloud DNS Cert-Manager Webhook +name: cert-manager-webhook-sotoon version: 0.1.0 diff --git a/deploy/example-webhook/values.yaml b/deploy/example-webhook/values.yaml index 31eb151..e571878 100644 --- a/deploy/example-webhook/values.yaml +++ b/deploy/example-webhook/values.yaml @@ -6,14 +6,14 @@ # solve the DNS01 challenge. # This group name should be **unique**, hence using your own company's domain # here is recommended. -groupName: acme.mycompany.com +groupName: acme.sotoon.ir certManager: namespace: cert-manager serviceAccountName: cert-manager image: - repository: mycompany/webhook-image + repository: aliorouji/cert-manager-webhook-sotoon tag: latest pullPolicy: IfNotPresent diff --git a/go.mod b/go.mod index 21e7aae..6f877fa 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.13 require ( github.com/jetstack/cert-manager v0.13.1 + k8s.io/api v0.17.0 k8s.io/apiextensions-apiserver v0.17.0 k8s.io/client-go v0.17.0 ) diff --git a/main.go b/main.go index 85aeac9..50e20df 100644 --- a/main.go +++ b/main.go @@ -6,11 +6,13 @@ import ( "os" extapi "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - //"k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "github.com/jetstack/cert-manager/pkg/acme/webhook/apis/acme/v1alpha1" "github.com/jetstack/cert-manager/pkg/acme/webhook/cmd" + + corev1 "k8s.io/api/core/v1" ) var GroupName = os.Getenv("GROUP_NAME") @@ -26,25 +28,25 @@ func main() { // webhook, where the Name() method will be used to disambiguate between // the different implementations. cmd.RunWebhookServer(GroupName, - &customDNSProviderSolver{}, + &sotoonDNSProviderSolver{}, ) } -// customDNSProviderSolver implements the provider-specific logic needed to +// sotoonDNSProviderSolver implements the provider-specific logic needed to // 'present' an ACME challenge TXT record for your own DNS provider. // To do so, it must implement the `github.com/jetstack/cert-manager/pkg/acme/webhook.Solver` // interface. -type customDNSProviderSolver struct { +type sotoonDNSProviderSolver struct { // If a Kubernetes 'clientset' is needed, you must: // 1. uncomment the additional `client` field in this structure below // 2. uncomment the "k8s.io/client-go/kubernetes" import at the top of the file // 3. uncomment the relevant code in the Initialize method below // 4. ensure your webhook's service account has the required RBAC role // assigned to it for interacting with the Kubernetes APIs you need. - //client kubernetes.Clientset + client *kubernetes.Clientset } -// customDNSProviderConfig is a structure that is used to decode into when +// sotoonDNSProviderConfig 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 @@ -58,14 +60,16 @@ type customDNSProviderSolver struct { // 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 customDNSProviderConfig struct { +type sotoonDNSProviderConfig struct { // Change the two fields below according to the format of the configuration // to be decoded. // These fields will be set by users in the // `issuer.spec.acme.dns01.providers.webhook.config` field. - //Email string `json:"email"` - //APIKeySecretRef v1alpha1.SecretKeySelector `json:"apiKeySecretRef"` + Email string `json:"email"` + Endpoint string `json:"endpoint"` + Namespace string `json:"namespace"` + APITokenSecretRef corev1.SecretKeySelector `json:"apiTokenSecretRef"` } // Name is used as the name for this DNS solver when referencing it on the ACME @@ -74,8 +78,8 @@ type customDNSProviderConfig struct { // solvers configured with the same Name() **so long as they do not co-exist // within a single webhook deployment**. // For example, `cloudflare` may be used as the name of a solver. -func (c *customDNSProviderSolver) Name() string { - return "my-custom-solver" +func (c *sotoonDNSProviderSolver) Name() string { + return "sotoon" } // Present is responsible for actually presenting the DNS record with the @@ -83,7 +87,7 @@ func (c *customDNSProviderSolver) Name() string { // This method should tolerate being called multiple times with the same value. // cert-manager itself will later perform a self check to ensure that the // solver has correctly configured the DNS provider. -func (c *customDNSProviderSolver) Present(ch *v1alpha1.ChallengeRequest) error { +func (c *sotoonDNSProviderSolver) Present(ch *v1alpha1.ChallengeRequest) error { cfg, err := loadConfig(ch.Config) if err != nil { return err @@ -102,7 +106,7 @@ func (c *customDNSProviderSolver) Present(ch *v1alpha1.ChallengeRequest) error { // value provided on the ChallengeRequest should be cleaned up. // This is in order to facilitate multiple DNS validations for the same domain // concurrently. -func (c *customDNSProviderSolver) CleanUp(ch *v1alpha1.ChallengeRequest) error { +func (c *sotoonDNSProviderSolver) CleanUp(ch *v1alpha1.ChallengeRequest) error { // TODO: add code that deletes a record from the DNS provider's console return nil } @@ -116,25 +120,21 @@ func (c *customDNSProviderSolver) CleanUp(ch *v1alpha1.ChallengeRequest) error { // provider accounts. // 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. -func (c *customDNSProviderSolver) Initialize(kubeClientConfig *rest.Config, stopCh <-chan struct{}) error { - ///// UNCOMMENT THE BELOW CODE TO MAKE A KUBERNETES CLIENTSET AVAILABLE TO - ///// YOUR CUSTOM DNS PROVIDER +func (c *sotoonDNSProviderSolver) Initialize(kubeClientConfig *rest.Config, stopCh <-chan struct{}) error { + cl, err := kubernetes.NewForConfig(kubeClientConfig) + if err != nil { + return err + } - //cl, err := kubernetes.NewForConfig(kubeClientConfig) - //if err != nil { - // return err - //} - // - //c.client = cl + c.client = cl - ///// END OF CODE TO MAKE KUBERNETES CLIENTSET AVAILABLE return nil } // loadConfig is a small helper function that decodes JSON configuration into // the typed config struct. -func loadConfig(cfgJSON *extapi.JSON) (customDNSProviderConfig, error) { - cfg := customDNSProviderConfig{} +func loadConfig(cfgJSON *extapi.JSON) (sotoonDNSProviderConfig, error) { + cfg := sotoonDNSProviderConfig{} // handle the 'base case' where no configuration has been provided if cfgJSON == nil { return cfg, nil diff --git a/main_test.go b/main_test.go index 4e32419..f8fc6a2 100644 --- a/main_test.go +++ b/main_test.go @@ -16,7 +16,7 @@ func TestRunsSuite(t *testing.T) { // snippet of valid configuration that should be included on the // ChallengeRequest passed as part of the test cases. - fixture := dns.NewFixture(&customDNSProviderSolver{}, + fixture := dns.NewFixture(&sotoonDNSProviderSolver{}, dns.SetResolvedZone(zone), dns.SetAllowAmbientCredentials(false), dns.SetManifestPath("testdata/my-custom-solver"),