CHORE: remove unused module pkg/acme (get-certs) (#3667)

This commit is contained in:
Tom Limoncelli 2025-07-14 15:40:31 -04:00 committed by GitHub
parent f8252436c5
commit a8a3ea73ba
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 0 additions and 796 deletions

14
go.mod
View file

@ -34,7 +34,6 @@ require (
github.com/go-gandi/go-gandi v0.7.0
github.com/gobwas/glob v0.2.4-0.20181002190808-e7a84e9525fe
github.com/gopherjs/jquery v0.0.0-20191017083323-73f4c7416038
github.com/hashicorp/vault/api v1.20.0
github.com/jinzhu/copier v0.4.0
github.com/miekg/dns v1.1.67
github.com/mittwald/go-powerdns v0.6.7
@ -65,7 +64,6 @@ require (
github.com/failsafe-go/failsafe-go v0.6.9
github.com/fatih/color v1.18.0
github.com/fbiville/markdown-table-formatter v0.3.0
github.com/go-acme/lego/v4 v4.24.0
github.com/google/go-cmp v0.7.0
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.158
@ -99,16 +97,13 @@ require (
github.com/aws/aws-sdk-go-v2/service/sts v1.34.0 // indirect
github.com/aws/smithy-go v1.22.4 // indirect
github.com/boombuler/barcode v1.0.1 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/deepmap/oapi-codegen v1.9.1 // indirect
github.com/fatih/structs v1.1.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-jose/go-jose/v4 v4.0.5 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-test/deep v1.0.3 // indirect
github.com/go-viper/mapstructure/v2 v2.3.0 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/gofrs/flock v0.12.1 // indirect
@ -120,20 +115,12 @@ require (
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
github.com/googleapis/gax-go/v2 v2.14.2 // indirect
github.com/gopherjs/gopherjs v1.17.2 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 // indirect
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect
github.com/hashicorp/go-sockaddr v1.0.2 // indirect
github.com/hashicorp/hcl v1.0.1-vault-7 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
@ -141,7 +128,6 @@ require (
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
github.com/sergi/go-diff v1.2.0 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect

43
go.sum
View file

@ -5,7 +5,6 @@ cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIi
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
cloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU=
cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo=
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.1 h1:Wc1ml6QlJs2BHQ/9Bqu1jiyggbsSjramq2oUmp5WeIo=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.1/go.mod h1:Ot/6aikWnKWi4l9QB7qVSwa8iMphQNqkWALMoNT3rzM=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1 h1:B+blDbyVIG3WaikNxPnhPiJ1MThR03b3vKGtER95TP4=
@ -45,7 +44,6 @@ github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNg
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM=
github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/aws/aws-sdk-go-v2 v1.36.5 h1:0OF9RiEMEdDdZEMqF9MRjevyxAQcf6gY+E7vwBILFj0=
github.com/aws/aws-sdk-go-v2 v1.36.5/go.mod h1:EYrzvCCN9CMUTa5+6lf6MM4tq3Zjp8UhSGR/cBsjai0=
github.com/aws/aws-sdk-go-v2/config v1.29.17 h1:jSuiQ5jEe4SAMH6lLRMY9OVC+TqJLP5655pBGjmnjr0=
@ -78,7 +76,6 @@ github.com/aws/smithy-go v1.22.4 h1:uqXzVZNuNexwc/xrh6Tb56u89WDlJY6HS+KC0S4QSjw=
github.com/aws/smithy-go v1.22.4/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI=
github.com/babolivier/go-doh-client v0.0.0-20201028162107-a76cff4cb8b6 h1:4NNbNM2Iq/k57qEu7WfL67UrbPq1uFWxW4qODCohi+0=
github.com/babolivier/go-doh-client v0.0.0-20201028162107-a76cff4cb8b6/go.mod h1:J29hk+f9lJrblVIfiJOtTFk+OblBawmib4uz/VdKzlg=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/billputer/go-namecheap v0.0.0-20210108011502-994a912fb7f9 h1:2vQTbEJvFsyd1VefzZ34GUkUD6TkJleYYJh9/25WBE4=
github.com/billputer/go-namecheap v0.0.0-20210108011502-994a912fb7f9/go.mod h1:bqqNsI2akL+lLWyApkYY0cxquWPKwEBU0Wd3chi3TEg=
github.com/bits-and-blooms/bitset v1.14.3 h1:Gd2c8lSNf9pKXom5JtD7AaKO8o7fGQ2LtFj1436qilA=
@ -86,8 +83,6 @@ github.com/bits-and-blooms/bitset v1.14.3/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/centralnicgroup-opensource/rtldev-middleware-go-sdk/v4 v4.0.7 h1:Jk7uhY5q11fE5PlEupX2Lo12w82UhGC6bE1CI5jwFbc=
github.com/centralnicgroup-opensource/rtldev-middleware-go-sdk/v4 v4.0.7/go.mod h1:FnQtD0+Q/1NZxi0eEWN+3ZRyMsE9vzSB3YjyunkbKD0=
@ -130,7 +125,6 @@ github.com/exoscale/egoscale v0.102.4 h1:GBKsZMIOzwBfSu+4ZmWka3Ejf2JLiaBDHp4CQUg
github.com/exoscale/egoscale v0.102.4/go.mod h1:ROSmPtle0wvf91iLZb09++N/9BH2Jo9XxIpAEumvocA=
github.com/failsafe-go/failsafe-go v0.6.9 h1:7HWEzOlFOjNerxgWd8onWA2j/aEuqyAtuX6uWya/364=
github.com/failsafe-go/failsafe-go v0.6.9/go.mod h1:zb7xfp1/DJ7Mn4xJhVSZ9F2qmmMEGvYHxEOHYK5SIm0=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
@ -143,13 +137,9 @@ github.com/getkin/kin-openapi v0.87.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSy
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
github.com/go-acme/lego/v4 v4.24.0 h1:pe0q49JKxfSGEP3lkgkMVQrZM1KbD+e0dpJ2McYsiVw=
github.com/go-acme/lego/v4 v4.24.0/go.mod h1:hkstZY6D0jylIrZbuNmEQrWQxTIfaJH7prwaWvKDOjw=
github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs=
github.com/go-gandi/go-gandi v0.7.0 h1:gsP33dUspsN1M+ZW9HEgHchK9HiaSkYnltO73RHhSZA=
github.com/go-gandi/go-gandi v0.7.0/go.mod h1:9NoYyfWCjFosClPiWjkbbRK5UViaZ4ctpT8/pKSSFlw=
github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE=
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
@ -166,8 +156,6 @@ github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn
github.com/go-playground/validator/v10 v10.9.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/go-viper/mapstructure/v2 v2.3.0 h1:27XbWsHIqhbdR5TIC911OfYvgSaW93HM+dX7970Q7jk=
github.com/go-viper/mapstructure/v2 v2.3.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/gobwas/glob v0.2.4-0.20181002190808-e7a84e9525fe h1:zn8tqiUbec4wR94o7Qj3LZCAT6uGobhEgnDRg6isG5U=
@ -234,31 +222,12 @@ github.com/gopherjs/jquery v0.0.0-20191017083323-73f4c7416038/go.mod h1:xKR3tvLn
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU=
github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk=
github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 h1:om4Al8Oy7kCm/B86rLCLah4Dt5Aa0Fr5rYBG60OzwHQ=
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8=
github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U=
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts=
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4=
github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc=
github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=
github.com/hashicorp/hcl v1.0.1-vault-7 h1:ag5OxFVy3QYTFTJODRzTKVZ6xvdfLLCA1cy/Y6xGI0I=
github.com/hashicorp/hcl v1.0.1-vault-7/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM=
github.com/hashicorp/vault/api v1.20.0 h1:KQMHElgudOsr+IbJgmbjHnCTxEpKs9LnozA1D3nozU4=
github.com/hashicorp/vault/api v1.20.0/go.mod h1:GZ4pcjfzoOWpkJ3ijHNpEoAxKEsBJnVljyTe3jM2Sms=
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.158 h1:pRMfrWsWPE4belcRz5FtpGNyDxOCt32lDC6HpWojqGg=
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.158/go.mod h1:Y/+YLCFCJtS29i2MbYPTUlNNfwXvkzEsZKR0imY/2aY=
github.com/jarcoal/httpmock v1.3.0 h1:2RJ8GP0IIaWwcC9Fp2BmVi8Kog3v2Hn7VXM3fTd+nuc=
@ -303,11 +272,9 @@ github.com/luadns/luadns-go v0.3.0/go.mod h1:DmPXbrGMpynq1YNDpvgww3NP5Zf4wXM5raA
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
@ -317,13 +284,8 @@ github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04
github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM=
github.com/miekg/dns v1.1.67 h1:kg0EHj0G4bfT5/oOys6HhZw4vmMlnoZ+gDu8tJ/AlI0=
github.com/miekg/dns v1.1.67/go.mod h1:fujopn7TB3Pu3JM69XaawiU0wqjpL9/8xGop5UrTPps=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mittwald/go-powerdns v0.6.7 h1:r638QOYLWyJ5Wy+qynlq5nTRlhmfQMJvM9BDsbhyiro=
github.com/mittwald/go-powerdns v0.6.7/go.mod h1:zFe/i17IP6/NGFkWGGsPL0t7VrL6u14HU8Hr06X4Qmg=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@ -360,7 +322,6 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/pquerna/otp v1.5.0 h1:NMMR+WrmaqXU4EzdGJEE1aUUI0AMRzsp96fFFWNPwxs=
github.com/pquerna/otp v1.5.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@ -377,9 +338,6 @@ github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
@ -531,7 +489,6 @@ golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

View file

@ -1,327 +0,0 @@
// Package acme provides a means of performing Let's Encrypt DNS challenges via a DNSConfig
package acme
import (
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
"io"
"log"
"net/url"
"sort"
"strings"
"time"
"github.com/StackExchange/dnscontrol/v4/models"
"github.com/StackExchange/dnscontrol/v4/pkg/nameservers"
"github.com/StackExchange/dnscontrol/v4/pkg/notifications"
"github.com/StackExchange/dnscontrol/v4/pkg/zonerecs"
"github.com/go-acme/lego/v4/certcrypto"
"github.com/go-acme/lego/v4/certificate"
"github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/challenge/dns01"
"github.com/go-acme/lego/v4/lego"
acmelog "github.com/go-acme/lego/v4/log"
)
// CertConfig describes a certificate's configuration.
type CertConfig struct {
CertName string `json:"cert_name"`
Names []string `json:"names"`
UseECC bool `json:"use_ecc"`
MustStaple bool `json:"must_staple"`
}
// Client is an interface for systems that issue or renew certs.
type Client interface {
IssueOrRenewCert(config *CertConfig, renewUnder int, verbose bool) (bool, error)
}
type certManager struct {
email string
acmeDirectory string
acmeHost string
storage Storage
cfg *models.DNSConfig
domains map[string]*models.DomainConfig
originalDomains []*models.DomainConfig
notifier notifications.Notifier
account *Account
waitedOnce bool
}
const (
// LetsEncryptLive is the endpoint for updates (production).
LetsEncryptLive = "https://acme-v02.api.letsencrypt.org/directory"
// LetsEncryptStage is the endpoint for the staging area.
LetsEncryptStage = "https://acme-staging-v02.api.letsencrypt.org/directory"
)
// New is a factory for acme clients.
func New(cfg *models.DNSConfig, directory string, email string, server string, notify notifications.Notifier) (Client, error) {
return commonNew(cfg, directoryStorage(directory), email, server, notify)
}
func commonNew(cfg *models.DNSConfig, storage Storage, email string, server string, notify notifications.Notifier) (Client, error) {
u, err := url.Parse(server)
if err != nil || u.Host == "" {
return nil, fmt.Errorf("ACME directory '%s' is not a valid URL", server)
}
c := &certManager{
storage: storage,
email: email,
acmeDirectory: server,
acmeHost: u.Host,
cfg: cfg,
domains: map[string]*models.DomainConfig{},
notifier: notify,
}
acct, err := c.getOrCreateAccount()
if err != nil {
return nil, err
}
c.account = acct
return c, nil
}
// NewVault is a factory for new vaunt clients.
func NewVault(cfg *models.DNSConfig, vaultPath string, email string, server string, notify notifications.Notifier) (Client, error) {
storage, err := makeVaultStorage(vaultPath)
if err != nil {
return nil, err
}
return commonNew(cfg, storage, email, server, notify)
}
// IssueOrRenewCert will obtain a certificate with the given name if it does not exist,
// or renew it if it is close enough to the expiration date.
// It will return true if it issued or updated the certificate.
func (c *certManager) IssueOrRenewCert(cfg *CertConfig, renewUnder int, verbose bool) (bool, error) {
if !verbose {
acmelog.Logger = log.New(io.Discard, "", 0)
}
defer c.finalCleanUp() //nolint:errcheck
log.Printf("Checking certificate [%s]", cfg.CertName)
existing, err := c.storage.GetCertificate(cfg.CertName)
if err != nil {
return false, err
}
var client *lego.Client
action := func() (*certificate.Resource, error) {
return client.Certificate.Obtain(certificate.ObtainRequest{
Bundle: true,
Domains: cfg.Names,
MustStaple: cfg.MustStaple,
})
}
if existing == nil {
log.Println("No existing cert found. Issuing new...")
} else {
names, daysLeft, err := getCertInfo(existing.Certificate)
if err != nil {
return false, err
}
log.Printf("Found existing cert. %0.2f days remaining.", daysLeft)
namesOK := dnsNamesEqual(cfg.Names, names)
if daysLeft >= float64(renewUnder) && namesOK {
log.Println("Nothing to do")
// nothing to do
return false, nil
}
if !namesOK {
log.Println("DNS Names don't match expected set. Reissuing.")
} else {
log.Println("Renewing cert")
action = func() (*certificate.Resource, error) {
return client.Certificate.Renew(*existing, true, cfg.MustStaple, "")
}
}
}
kt := certcrypto.RSA2048
if cfg.UseECC {
kt = certcrypto.EC256
}
config := lego.NewConfig(c.account)
config.CADirURL = c.acmeDirectory
config.Certificate.KeyType = kt
client, err = lego.NewClient(config)
if err != nil {
return false, err
}
client.Challenge.Remove(challenge.HTTP01)
client.Challenge.Remove(challenge.TLSALPN01)
client.Challenge.SetDNS01Provider(c, dns01.WrapPreCheck(c.preCheckDNS)) //nolint:errcheck
certResource, err := action()
if err != nil {
return false, err
}
fmt.Printf("Obtained certificate for %s\n", cfg.CertName)
if err = c.storage.StoreCertificate(cfg.CertName, certResource); err != nil {
return true, err
}
return true, nil
}
func getCertInfo(pemBytes []byte) (names []string, remaining float64, err error) {
block, _ := pem.Decode(pemBytes)
if block == nil {
return nil, 0, errors.New("invalid certificate PEM data")
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, 0, err
}
daysLeft := float64(time.Until(cert.NotAfter)) / float64(time.Hour*24)
return cert.DNSNames, daysLeft, nil
}
// checks two lists of sans to make sure they have all the same names in them.
func dnsNamesEqual(a []string, b []string) bool {
if len(a) != len(b) {
return false
}
sort.Strings(a)
sort.Strings(b)
for i, s := range a {
if b[i] != s {
return false
}
}
return true
}
func (c *certManager) Present(domain, token, keyAuth string) (e error) {
d := c.cfg.DomainContainingFQDN(domain)
name := d.Name
if seen := c.domains[name]; seen != nil {
// we've already pre-processed this domain, just need to add to it.
d = seen
} else {
// one-time tasks to get this domain ready.
// if multiple validations on a single domain, we don't need to rebuild all this.
// fix NS records for this domain's DNS providers
nsList, err := nameservers.DetermineNameservers(d)
if err != nil {
return err
}
d.Nameservers = nsList
nameservers.AddNSRecords(d)
// make sure we have the latest config before we change anything.
// alternately, we could avoid a lot of this trouble if we really trusted no-purge in all cases
if err := c.ensureNoPendingCorrections(d); err != nil {
return err
}
// Copy domain and work from cpy from now on. That way original config can be used to "restore" when we are all done.
cpy, err := d.Copy()
if err != nil {
return err
}
c.originalDomains = append(c.originalDomains, d)
c.domains[name] = cpy
d = cpy
}
fqdn, val := dns01.GetRecord(domain, keyAuth)
txt := &models.RecordConfig{Type: "TXT"}
if err := txt.SetTargetTXT(val); err != nil {
return err
}
txt.SetLabelFromFQDN(fqdn, d.Name)
d.Records = append(d.Records, txt)
return c.getAndRunCorrections(d)
}
func (c *certManager) ensureNoPendingCorrections(d *models.DomainConfig) error {
corrections, err := c.getCorrections(d)
if err != nil {
return err
}
if len(corrections) != 0 {
// TODO: maybe allow forcing through this check.
for _, c := range corrections {
fmt.Println(c.Msg)
}
return fmt.Errorf("found %d pending corrections for %s. Not going to proceed issuing certificates", len(corrections), d.Name)
}
return nil
}
// IgnoredProviders is a list of provider names that should not be used to fill challenges.
var IgnoredProviders = map[string]bool{}
func (c *certManager) getCorrections(d *models.DomainConfig) ([]*models.Correction, error) {
cs := []*models.Correction{}
for _, p := range d.DNSProviderInstances {
if IgnoredProviders[p.Name] {
continue
}
dc, err := d.Copy()
if err != nil {
return nil, err
}
reports, corrections, _, err := zonerecs.CorrectZoneRecords(p.Driver, dc)
if err != nil {
return nil, err
}
for _, c := range reports {
c.Msg = fmt.Sprintf("INFO[%s] %s", p.Name, strings.TrimSpace(c.Msg))
}
for _, c := range corrections {
c.Msg = fmt.Sprintf("[%s] %s", p.Name, strings.TrimSpace(c.Msg))
}
cs = append(cs, corrections...)
}
return cs, nil
}
func (c *certManager) getAndRunCorrections(d *models.DomainConfig) error {
cs, err := c.getCorrections(d)
if err != nil {
return err
}
fmt.Printf("%d corrections\n", len(cs))
for _, corr := range cs {
fmt.Printf("Running [%s]\n", corr.Msg)
err = corr.F()
err2 := c.notifier.Notify(d.Name, "certs", corr.Msg, err, false)
if err != nil {
return err
}
if err2 != nil {
return err2
}
}
return nil
}
func (c *certManager) CleanUp(domain, token, keyAuth string) error {
// do nothing for now. We will do a final clean up step at the very end.
return nil
}
func (c *certManager) finalCleanUp() error {
log.Println("Cleaning up all records we made")
var lastError error
for _, d := range c.originalDomains {
if err := c.getAndRunCorrections(d); err != nil {
log.Printf("ERROR cleaning up: %s", err)
lastError = err
}
}
return lastError
}

View file

@ -1,31 +0,0 @@
package acme
import (
"log"
"time"
"github.com/go-acme/lego/v4/challenge/dns01"
)
func (c *certManager) preCheckDNS(domain, fqdn, value string, native dns01.PreCheckFunc) (bool, error) {
// default record verification in the client library makes sure the authoritative nameservers
// have the expected records.
// Sometimes the Let's Encrypt verification fails anyway because records have not propagated the provider's network fully.
// So we add an additional 60 second sleep just for safety.
v, err := native(fqdn, value)
if err != nil {
return v, err
}
if !c.waitedOnce {
log.Printf("DNS ok. Waiting another 60s to ensure stability.")
time.Sleep(60 * time.Second)
c.waitedOnce = true
}
log.Printf("DNS records seem to exist. Proceeding to request validation")
return v, err
}
// Timeout increases the client-side polling check time to five minutes with one second waits in-between.
func (c *certManager) Timeout() (timeout, interval time.Duration) {
return 5 * time.Minute, time.Second
}

View file

@ -1,140 +0,0 @@
package acme
import (
"crypto/x509"
"encoding/json"
"encoding/pem"
"errors"
"os"
"path/filepath"
"github.com/go-acme/lego/v4/certificate"
)
// directoryStorage implements storage in a local file directory
type directoryStorage string
// filename for certificate / key / json file
func (d directoryStorage) certFile(name, ext string) string {
return filepath.Join(d.certDir(name), name+"."+ext)
}
func (d directoryStorage) certDir(name string) string {
return filepath.Join(string(d), "certificates", name)
}
func (d directoryStorage) accountDirectory(acmeHost string) string {
return filepath.Join(string(d), ".letsencrypt", acmeHost)
}
func (d directoryStorage) accountFile(acmeHost string) string {
return filepath.Join(d.accountDirectory(acmeHost), "account.json")
}
func (d directoryStorage) accountKeyFile(acmeHost string) string {
return filepath.Join(d.accountDirectory(acmeHost), "account.key")
}
const (
perms os.FileMode = 0o600
dirPerms os.FileMode = 0o700
)
func (d directoryStorage) GetCertificate(name string) (*certificate.Resource, error) {
f, err := os.Open(d.certFile(name, "json"))
if err != nil && os.IsNotExist(err) {
// if json does not exist, nothing does
return nil, nil
}
if err != nil {
return nil, err
}
defer f.Close()
dec := json.NewDecoder(f)
cr := &certificate.Resource{}
if err = dec.Decode(cr); err != nil {
return nil, err
}
// load cert
crtBytes, err := os.ReadFile(d.certFile(name, "crt"))
if err != nil {
return nil, err
}
cr.Certificate = crtBytes
return cr, nil
}
func (d directoryStorage) StoreCertificate(name string, cert *certificate.Resource) error {
// make sure actual cert data never gets into metadata json
if err := os.MkdirAll(d.certDir(name), dirPerms); err != nil {
return err
}
pub := cert.Certificate
cert.Certificate = nil
priv := cert.PrivateKey
cert.PrivateKey = nil
combined := []byte(string(pub) + "\n" + string(priv))
jDAt, err := json.MarshalIndent(cert, "", " ")
if err != nil {
return err
}
if err = os.WriteFile(d.certFile(name, "json"), jDAt, perms); err != nil {
return err
}
if err = os.WriteFile(d.certFile(name, "crt"), pub, perms); err != nil {
return err
}
if err = os.WriteFile(d.certFile(name, "pem"), combined, perms); err != nil {
return err
}
return os.WriteFile(d.certFile(name, "key"), priv, perms)
}
func (d directoryStorage) GetAccount(acmeHost string) (*Account, error) {
f, err := os.Open(d.accountFile(acmeHost))
if err != nil && os.IsNotExist(err) {
return nil, nil
}
if err != nil {
return nil, err
}
defer f.Close()
dec := json.NewDecoder(f)
acct := &Account{}
if err = dec.Decode(acct); err != nil {
return nil, err
}
keyBytes, err := os.ReadFile(d.accountKeyFile(acmeHost))
if err != nil {
return nil, err
}
keyBlock, _ := pem.Decode(keyBytes)
if keyBlock == nil {
return nil, errors.New("error decoding account private key")
}
acct.key, err = x509.ParseECPrivateKey(keyBlock.Bytes)
if err != nil {
return nil, err
}
return acct, nil
}
func (d directoryStorage) StoreAccount(acmeHost string, account *Account) error {
if err := os.MkdirAll(d.accountDirectory(acmeHost), dirPerms); err != nil {
return err
}
acctBytes, err := json.MarshalIndent(account, "", " ")
if err != nil {
return err
}
if err = os.WriteFile(d.accountFile(acmeHost), acctBytes, perms); err != nil {
return err
}
keyBytes, err := x509.MarshalECPrivateKey(account.key)
if err != nil {
return err
}
pemKey := &pem.Block{Type: "EC PRIVATE KEY", Bytes: keyBytes}
pemBytes := pem.EncodeToMemory(pemKey)
return os.WriteFile(d.accountKeyFile(acmeHost), pemBytes, perms)
}

View file

@ -1,76 +0,0 @@
package acme
import (
"crypto"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"github.com/go-acme/lego/v4/certcrypto"
"github.com/go-acme/lego/v4/lego"
"github.com/go-acme/lego/v4/registration"
)
func (c *certManager) getOrCreateAccount() (*Account, error) {
account, err := c.storage.GetAccount(c.acmeHost)
if err != nil {
return nil, err
}
if account != nil {
return account, nil
}
// register new
account, err = c.createAccount(c.email)
if err != nil {
return nil, err
}
err = c.storage.StoreAccount(c.acmeHost, account)
return account, err
}
// func (c *certManager) createAccount(email string) (*Account, error) {
func (c *certManager) createAccount(_ string) (*Account, error) {
privateKey, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
if err != nil {
return nil, err
}
acct := &Account{
key: privateKey,
Email: c.email,
}
config := lego.NewConfig(acct)
config.CADirURL = c.acmeDirectory
config.Certificate.KeyType = certcrypto.EC384
client, err := lego.NewClient(config)
if err != nil {
return nil, err
}
reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
if err != nil {
return nil, err
}
acct.Registration = reg
return acct, nil
}
// Account stores the data related to an ACME account.
type Account struct {
Email string `json:"email"`
Registration *registration.Resource `json:"registration"`
key *ecdsa.PrivateKey
}
// GetEmail is a getter for the Email field.
func (a *Account) GetEmail() string {
return a.Email
}
// GetPrivateKey is a getter for the PrivateKey field.
func (a *Account) GetPrivateKey() crypto.PrivateKey {
return a.key
}
// GetRegistration is a getter for the registration field.
func (a *Account) GetRegistration() *registration.Resource {
return a.Registration
}

View file

@ -1,13 +0,0 @@
package acme
import "github.com/go-acme/lego/v4/certificate"
// Storage is an abstracrion around how certificates, keys, and account info are stored on disk or elsewhere.
type Storage interface {
// Get Existing certificate, or return nil if it does not exist
GetCertificate(name string) (*certificate.Resource, error)
StoreCertificate(name string, cert *certificate.Resource) error
GetAccount(acmeHost string) (*Account, error)
StoreAccount(acmeHost string, account *Account) error
}

View file

@ -1,152 +0,0 @@
package acme
import (
"crypto/ecdsa"
"crypto/x509"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
"strings"
"github.com/go-acme/lego/v4/certificate"
"github.com/hashicorp/vault/api"
)
type vaultStorage struct {
path string
client *api.Logical
}
func makeVaultStorage(vaultPath string) (Storage, error) {
if !strings.HasSuffix(vaultPath, "/") {
vaultPath += "/"
}
client, err := api.NewClient(api.DefaultConfig())
if err != nil {
return nil, err
}
storage := &vaultStorage{
path: vaultPath,
client: client.Logical(),
}
return storage, nil
}
func (v *vaultStorage) GetCertificate(name string) (*certificate.Resource, error) {
var err error
path := v.certPath(name)
secret, err := v.client.Read(path)
if err != nil {
return nil, err
}
if secret == nil {
return nil, nil
}
cert := &certificate.Resource{}
if dat, err := v.getString("meta", secret.Data, path); err != nil {
return nil, err
} else if err = json.Unmarshal(dat, cert); err != nil {
return nil, err
}
var dat []byte
if dat, err = v.getString("tls.cert", secret.Data, path); err != nil {
return nil, err
}
cert.Certificate = dat
if dat, err = v.getString("tls.key", secret.Data, path); err != nil {
return nil, err
}
cert.PrivateKey = dat
return cert, nil
}
func (v *vaultStorage) getString(key string, data map[string]interface{}, path string) ([]byte, error) {
dat, ok := data[key]
if !ok {
return nil, fmt.Errorf("secret at %s does not have key %s", path, key)
}
str, ok := dat.(string)
if !ok {
return nil, fmt.Errorf("secret at %s is not string", path)
}
return []byte(str), nil
}
func (v *vaultStorage) StoreCertificate(name string, cert *certificate.Resource) error {
jDat, err := json.MarshalIndent(cert, "", " ")
if err != nil {
return err
}
pub := string(cert.Certificate)
key := string(cert.PrivateKey)
data := map[string]interface{}{
"tls.cert": pub,
"tls.key": key,
"tls.combined": pub + "\n" + key,
"meta": string(jDat),
}
_, err = v.client.Write(v.certPath(name), data)
return err
}
func (v *vaultStorage) registrationPath(acmeHost string) string {
return v.path + ".letsencrypt/" + acmeHost
}
func (v *vaultStorage) certPath(name string) string {
return v.path + name
}
func (v *vaultStorage) GetAccount(acmeHost string) (*Account, error) {
path := v.registrationPath(acmeHost)
secret, err := v.client.Read(path)
if err != nil {
return nil, err
}
if secret == nil {
return nil, nil
}
acct := &Account{}
if dat, err := v.getString("registration", secret.Data, path); err != nil {
return nil, err
} else if err = json.Unmarshal(dat, acct); err != nil {
return nil, err
}
var key *ecdsa.PrivateKey
var dat []byte
var block *pem.Block
if dat, err = v.getString("tls.key", secret.Data, path); err != nil {
return nil, err
} else if block, _ = pem.Decode(dat); block == nil {
return nil, errors.New("error decoding account private key")
} else if key, err = x509.ParseECPrivateKey(block.Bytes); err != nil {
return nil, err
}
acct.key = key
return acct, nil
}
func (v *vaultStorage) StoreAccount(acmeHost string, account *Account) error {
acctBytes, err := json.MarshalIndent(account, "", " ")
if err != nil {
return err
}
keyBytes, err := x509.MarshalECPrivateKey(account.key)
if err != nil {
return err
}
pemKey := &pem.Block{Type: "EC PRIVATE KEY", Bytes: keyBytes}
pemBytes := pem.EncodeToMemory(pemKey)
_, err = v.client.Write(v.registrationPath(acmeHost), map[string]interface{}{
"registration": string(acctBytes),
"tls.key": string(pemBytes),
})
return err
}