From 409b3c9959e25d5fe9713d28bb3b18232951089f Mon Sep 17 00:00:00 2001
From: Ludovic Fernandez <ldez@users.noreply.github.com>
Date: Mon, 22 Aug 2022 17:05:31 +0200
Subject: [PATCH] feat: update to go1.18 (#1700)

---
 .github/workflows/documentation.yml           |  2 +-
 .github/workflows/go-cross.yml                |  2 +-
 .github/workflows/pr.yml                      |  4 +-
 .github/workflows/release.yml                 |  2 +-
 .golangci.toml                                | 12 +++++-
 certcrypto/crypto_test.go                     |  5 ++-
 challenge/dns01/dns_challenge_manual_test.go  |  3 +-
 challenge/http01/domain_matcher.go            |  9 ++--
 cmd/accounts_storage.go                       | 41 +++++++++----------
 cmd/certs_storage.go                          | 15 ++++---
 e2e/loader/loader.go                          |  3 +-
 go.mod                                        |  2 +-
 go.sum                                        |  9 ----
 platform/config/env/env.go                    |  1 -
 platform/config/env/env_test.go               | 38 +++++------------
 providers/dns/acmedns/acmedns.go              |  4 +-
 providers/dns/bluecat/bluecat.go              | 12 +++---
 providers/dns/cloudflare/cloudflare.go        |  4 +-
 providers/dns/cloudns/internal/client.go      | 27 ++++++------
 providers/dns/designate/designate_test.go     |  5 +--
 providers/dns/hurricane/internal/client.go    |  8 ++--
 providers/dns/joker/internal/dmapi/client.go  | 19 ++++-----
 providers/dns/joker/provider_dmapi.go         |  2 +-
 providers/dns/lightsail/lightsail.go          |  6 +--
 providers/dns/oraclecloud/oraclecloud_test.go |  3 +-
 providers/dns/route53/route53.go              |  8 ++--
 26 files changed, 112 insertions(+), 134 deletions(-)

diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml
index 6e11c747..ad62eb4a 100644
--- a/.github/workflows/documentation.yml
+++ b/.github/workflows/documentation.yml
@@ -11,7 +11,7 @@ jobs:
     name: Build and deploy documentation
     runs-on: ubuntu-latest
     env:
-      GO_VERSION: 1.18
+      GO_VERSION: 1.19
       HUGO_VERSION: 0.101.0
       CGO_ENABLED: 0
 
diff --git a/.github/workflows/go-cross.yml b/.github/workflows/go-cross.yml
index 5b0cfaec..c9f0cc10 100644
--- a/.github/workflows/go-cross.yml
+++ b/.github/workflows/go-cross.yml
@@ -16,7 +16,7 @@ jobs:
 
     strategy:
       matrix:
-        go-version: [ 1.17, 1.18, 1.x ]
+        go-version: [ 1.18, 1.19, 1.x ]
         os: [ubuntu-latest, macos-latest, windows-latest]
 
     steps:
diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
index cef5689f..e1aaa4ab 100644
--- a/.github/workflows/pr.yml
+++ b/.github/workflows/pr.yml
@@ -12,8 +12,8 @@ jobs:
     name: Main Process
     runs-on: ubuntu-latest
     env:
-      GO_VERSION: 1.18
-      GOLANGCI_LINT_VERSION: v1.46.2
+      GO_VERSION: 1.19
+      GOLANGCI_LINT_VERSION: v1.48.0
       HUGO_VERSION: 0.54.0
       CGO_ENABLED: 0
       LEGO_E2E_TESTS: CI
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 4b545963..2d6854b8 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -11,7 +11,7 @@ jobs:
     name: Release version
     runs-on: ubuntu-latest
     env:
-      GO_VERSION: 1.18
+      GO_VERSION: 1.19
       SEIHON_VERSION: v0.8.3
       CGO_ENABLED: 0
 
diff --git a/.golangci.toml b/.golangci.toml
index 8930971a..82d1883e 100644
--- a/.golangci.toml
+++ b/.golangci.toml
@@ -57,6 +57,8 @@
     "maligned", # deprecated
     "scopelint", # deprecated
     "golint", # deprecated
+    "nosnakecase", # deprecated
+    "ifshort", # deprecated
     "exhaustivestruct", # deprecated
     "cyclop", # duplicate of gocyclo
     "sqlclosecheck", # not relevant (SQL)
@@ -79,7 +81,6 @@
     "exhaustive", # not relevant
     "exhaustruct", # not relevant
     "makezero", # not relevant
-    "ifshort", # not relevant
     "forbidigo", # not relevant
     "varnamelen", # not relevant
     "nilnil", # not relevant
@@ -196,3 +197,12 @@
   [[issues.exclude-rules]]
     path = "providers/dns/sakuracloud/client.go"
     text = "mu is a global variable"
+  [[issues.exclude-rules]]
+    path = "providers/dns/tencentcloud/client.go"
+    text = "RESOURCENOTFOUND_NODATAOFRECORD contains underscore."
+  [[issues.exclude-rules]]
+    path = "providers/dns/ibmcloud/internal/wrapper.go"
+    text = "Dns_Domain(_ResourceRecord)? contains underscore."
+  [[issues.exclude-rules]]
+    path = "providers/dns/rfc2136/"
+    text = "RR_Header contains underscore."
diff --git a/certcrypto/crypto_test.go b/certcrypto/crypto_test.go
index c56441b5..f2abc04c 100644
--- a/certcrypto/crypto_test.go
+++ b/certcrypto/crypto_test.go
@@ -6,6 +6,7 @@ import (
 	"crypto/rand"
 	"crypto/rsa"
 	"encoding/pem"
+	"regexp"
 	"testing"
 	"time"
 
@@ -112,7 +113,9 @@ func TestPEMEncode(t *testing.T) {
 
 	data := PEMEncode(key)
 	require.NotNil(t, data)
-	assert.Len(t, data, 127)
+
+	exp := regexp.MustCompile(`^-----BEGIN RSA PRIVATE KEY-----\s+\S{60,}\s+-----END RSA PRIVATE KEY-----\s+`)
+	assert.Regexp(t, exp, string(data))
 }
 
 func TestParsePEMCertificate(t *testing.T) {
diff --git a/challenge/dns01/dns_challenge_manual_test.go b/challenge/dns01/dns_challenge_manual_test.go
index 1360aec2..1cd5b54a 100644
--- a/challenge/dns01/dns_challenge_manual_test.go
+++ b/challenge/dns01/dns_challenge_manual_test.go
@@ -2,7 +2,6 @@ package dns01
 
 import (
 	"io"
-	"io/ioutil"
 	"os"
 	"testing"
 
@@ -32,7 +31,7 @@ func TestDNSProviderManual(t *testing.T) {
 
 	for _, test := range testCases {
 		t.Run(test.desc, func(t *testing.T) {
-			file, err := ioutil.TempFile("", "lego_test")
+			file, err := os.CreateTemp("", "lego_test")
 			assert.NoError(t, err)
 			defer func() { _ = os.Remove(file.Name()) }()
 
diff --git a/challenge/http01/domain_matcher.go b/challenge/http01/domain_matcher.go
index 231f02d7..ae681c64 100644
--- a/challenge/http01/domain_matcher.go
+++ b/challenge/http01/domain_matcher.go
@@ -27,10 +27,13 @@ import (
 //
 // Note: RFC7239 also reminds us, "that an HTTP list [...] may be split over multiple header fields" (section 7.1),
 // meaning that
-//   X-Header: a
-//   X-Header: b
+//
+//	X-Header: a
+//	X-Header: b
+//
 // is equal to
-//   X-Header: a, b
+//
+//	X-Header: a, b
 //
 // All matcher implementations (explicitly not excluding arbitraryMatcher!)
 // have in common that they only match against the first value in such lists.
diff --git a/cmd/accounts_storage.go b/cmd/accounts_storage.go
index 1b4014eb..05cd2372 100644
--- a/cmd/accounts_storage.go
+++ b/cmd/accounts_storage.go
@@ -28,36 +28,35 @@ const (
 //
 // rootPath:
 //
-//     ./.lego/accounts/
-//          │      └── root accounts directory
-//          └── "path" option
+//	./.lego/accounts/
+//	     │      └── root accounts directory
+//	     └── "path" option
 //
 // rootUserPath:
 //
-//     ./.lego/accounts/localhost_14000/hubert@hubert.com/
-//          │      │             │             └── userID ("email" option)
-//          │      │             └── CA server ("server" option)
-//          │      └── root accounts directory
-//          └── "path" option
+//	./.lego/accounts/localhost_14000/hubert@hubert.com/
+//	     │      │             │             └── userID ("email" option)
+//	     │      │             └── CA server ("server" option)
+//	     │      └── root accounts directory
+//	     └── "path" option
 //
 // keysPath:
 //
-//     ./.lego/accounts/localhost_14000/hubert@hubert.com/keys/
-//          │      │             │             │           └── root keys directory
-//          │      │             │             └── userID ("email" option)
-//          │      │             └── CA server ("server" option)
-//          │      └── root accounts directory
-//          └── "path" option
+//	./.lego/accounts/localhost_14000/hubert@hubert.com/keys/
+//	     │      │             │             │           └── root keys directory
+//	     │      │             │             └── userID ("email" option)
+//	     │      │             └── CA server ("server" option)
+//	     │      └── root accounts directory
+//	     └── "path" option
 //
 // accountFilePath:
 //
-//     ./.lego/accounts/localhost_14000/hubert@hubert.com/account.json
-//          │      │             │             │             └── account file
-//          │      │             │             └── userID ("email" option)
-//          │      │             └── CA server ("server" option)
-//          │      └── root accounts directory
-//          └── "path" option
-//
+//	./.lego/accounts/localhost_14000/hubert@hubert.com/account.json
+//	     │      │             │             │             └── account file
+//	     │      │             │             └── userID ("email" option)
+//	     │      │             └── CA server ("server" option)
+//	     │      └── root accounts directory
+//	     └── "path" option
 type AccountsStorage struct {
 	userID          string
 	rootPath        string
diff --git a/cmd/certs_storage.go b/cmd/certs_storage.go
index 3d7e46f4..5709f1a8 100644
--- a/cmd/certs_storage.go
+++ b/cmd/certs_storage.go
@@ -27,20 +27,19 @@ const (
 	baseArchivesFolderName     = "archives"
 )
 
-// CertificatesStorage a certificates storage.
+// CertificatesStorage a certificates' storage.
 //
 // rootPath:
 //
-//     ./.lego/certificates/
-//          │      └── root certificates directory
-//          └── "path" option
+//	./.lego/certificates/
+//	     │      └── root certificates directory
+//	     └── "path" option
 //
 // archivePath:
 //
-//     ./.lego/archives/
-//          │      └── archived certificates directory
-//          └── "path" option
-//
+//	./.lego/archives/
+//	     │      └── archived certificates directory
+//	     └── "path" option
 type CertificatesStorage struct {
 	rootPath    string
 	archivePath string
diff --git a/e2e/loader/loader.go b/e2e/loader/loader.go
index 1ac47003..7e8ff539 100644
--- a/e2e/loader/loader.go
+++ b/e2e/loader/loader.go
@@ -5,7 +5,6 @@ import (
 	"crypto/tls"
 	"errors"
 	"fmt"
-	"io/ioutil"
 	"net/http"
 	"os"
 	"os/exec"
@@ -198,7 +197,7 @@ func buildLego() (string, func(), error) {
 	}
 	defer func() { _ = os.Chdir(here) }()
 
-	buildPath, err := ioutil.TempDir("", "lego_test")
+	buildPath, err := os.MkdirTemp("", "lego_test")
 	if err != nil {
 		return "", func() {}, err
 	}
diff --git a/go.mod b/go.mod
index 87337700..ba4407dd 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
 module github.com/go-acme/lego/v4
 
-go 1.17
+go 1.18
 
 // github.com/exoscale/egoscale v1.19.0 => It is an error, please don't use it.
 // github.com/linode/linodego v1.0.0 => It is an error, please don't use it.
diff --git a/go.sum b/go.sum
index a9734835..9538e46b 100644
--- a/go.sum
+++ b/go.sum
@@ -152,16 +152,13 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+
 github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
 github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
 github.com/go-playground/validator/v10 v10.9.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
-github.com/go-playground/validator/v10 v10.10.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
 github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48 h1:JVrqSeQfdhYRFk24TvhTZWU0q8lfCojxZQFi3Ou7+uY=
 github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
 github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b h1:/vQ+oYKu+JoyaMPDsv5FzwuL2wwWBgBbtj/YLCi4LuA=
-github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b/go.mod h1:Xo4aNUOrJnVruqWQJBtW6+bTBDTniY8yZum5rF3b5jw=
 github.com/goccy/go-json v0.7.8/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
 github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
-github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
 github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
@@ -247,7 +244,6 @@ github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrj
 github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
 github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
 github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
-github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
 github.com/hashicorp/go-retryablehttp v0.7.0/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
 github.com/hashicorp/go-retryablehttp v0.7.1 h1:sUiuQAnLlbvmExtFQs72iFW/HXeUn8Z1aJLQ4LJJbTQ=
 github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
@@ -266,7 +262,6 @@ github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0m
 github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
 github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df h1:MZf03xP9WdakyXhOWuAD5uPK3wHh96wCsqe3hCMKh8E=
@@ -487,7 +482,6 @@ github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:s
 github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/smartystreets/gunit v1.0.4 h1:tpTjnuH7MLlqhoD21vRoMZbMIi5GmBsAJDFyF67GhZA=
-github.com/smartystreets/gunit v1.0.4/go.mod h1:EH5qMBab2UclzXUcpR8b93eHsIlp9u+pDQIRp5DZNzQ=
 github.com/softlayer/softlayer-go v1.0.3 h1:9FONm5xzQ9belQtbdryR6gBg4EF6hX6lrjNKi0IvZkU=
 github.com/softlayer/softlayer-go v1.0.3/go.mod h1:6HepcfAXROz0Rf63krk5hPZyHT6qyx2MNvYyHof7ik4=
 github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e h1:3OgWYFw7jxCZPcvAg+4R8A50GZ+CCkARF10lxu2qDsQ=
@@ -508,7 +502,6 @@ github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5q
 github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
 github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
 github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
@@ -518,7 +511,6 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
 github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
 github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
@@ -578,7 +570,6 @@ golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5
 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/crypto v0.0.0-20220214200702-86341886e292 h1:f+lwQ+GtmgoY+A2YaQxlSOnDjXcQ7ZRLWOHbC6HtRqE=
 golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
diff --git a/platform/config/env/env.go b/platform/config/env/env.go
index 1839529f..9da13ea9 100644
--- a/platform/config/env/env.go
+++ b/platform/config/env/env.go
@@ -54,7 +54,6 @@ func Get(names ...string) (map[string]string, error) {
 //	// LEGO_TWO=""
 //	env.GetWithFallback([]string{"LEGO_ONE", "LEGO_TWO"})
 //	// => error
-//
 func GetWithFallback(groups ...[]string) (map[string]string, error) {
 	values := map[string]string{}
 
diff --git a/platform/config/env/env_test.go b/platform/config/env/env_test.go
index 7b3c52b2..be422f1d 100644
--- a/platform/config/env/env_test.go
+++ b/platform/config/env/env_test.go
@@ -1,7 +1,6 @@
 package env
 
 import (
-	"io/ioutil"
 	"os"
 	"testing"
 	"time"
@@ -143,9 +142,7 @@ func TestGetOrDefaultInt(t *testing.T) {
 
 	for _, test := range testCases {
 		t.Run(test.desc, func(t *testing.T) {
-			defer os.Unsetenv(key)
-			err := os.Setenv(key, test.envValue)
-			require.NoError(t, err)
+			t.Setenv(key, test.envValue)
 
 			result := GetOrDefaultInt(key, test.defaultValue)
 			assert.Equal(t, test.expected, result)
@@ -190,9 +187,7 @@ func TestGetOrDefaultSecond(t *testing.T) {
 
 	for _, test := range testCases {
 		t.Run(test.desc, func(t *testing.T) {
-			defer os.Unsetenv(key)
-			err := os.Setenv(key, test.envValue)
-			require.NoError(t, err)
+			t.Setenv(key, test.envValue)
 
 			result := GetOrDefaultSecond(key, test.defaultValue)
 			assert.Equal(t, test.expected, result)
@@ -224,9 +219,7 @@ func TestGetOrDefaultString(t *testing.T) {
 
 	for _, test := range testCases {
 		t.Run(test.desc, func(t *testing.T) {
-			defer os.Unsetenv(key)
-			err := os.Setenv(key, test.envValue)
-			require.NoError(t, err)
+			t.Setenv(key, test.envValue)
 
 			actual := GetOrDefaultString(key, test.defaultValue)
 			assert.Equal(t, test.expected, actual)
@@ -264,9 +257,7 @@ func TestGetOrDefaultBool(t *testing.T) {
 
 	for _, test := range testCases {
 		t.Run(test.desc, func(t *testing.T) {
-			defer os.Unsetenv(key)
-			err := os.Setenv(key, test.envValue)
-			require.NoError(t, err)
+			t.Setenv(key, test.envValue)
 
 			actual := GetOrDefaultBool(key, test.defaultValue)
 			assert.Equal(t, test.expected, actual)
@@ -275,9 +266,7 @@ func TestGetOrDefaultBool(t *testing.T) {
 }
 
 func TestGetOrFile_ReadsEnvVars(t *testing.T) {
-	err := os.Setenv("TEST_LEGO_ENV_VAR", "lego_env")
-	require.NoError(t, err)
-	defer os.Unsetenv("TEST_LEGO_ENV_VAR")
+	t.Setenv("TEST_LEGO_ENV_VAR", "lego_env")
 
 	value := GetOrFile("TEST_LEGO_ENV_VAR")
 
@@ -309,16 +298,14 @@ func TestGetOrFile_ReadsFiles(t *testing.T) {
 			err = os.Unsetenv(varEnvName)
 			require.NoError(t, err)
 
-			file, err := ioutil.TempFile("", "lego")
+			file, err := os.CreateTemp("", "lego")
 			require.NoError(t, err)
 			defer os.Remove(file.Name())
 
 			err = os.WriteFile(file.Name(), []byte("lego_file\n"), 0o644)
 			require.NoError(t, err)
 
-			err = os.Setenv(varEnvFileName, file.Name())
-			require.NoError(t, err)
-			defer os.Unsetenv(varEnvFileName)
+			t.Setenv(varEnvFileName, file.Name())
 
 			value := GetOrFile(varEnvName)
 
@@ -336,20 +323,15 @@ func TestGetOrFile_PrefersEnvVars(t *testing.T) {
 	err = os.Unsetenv(varEnvName)
 	require.NoError(t, err)
 
-	file, err := ioutil.TempFile("", "lego")
+	file, err := os.CreateTemp("", "lego")
 	require.NoError(t, err)
 	defer os.Remove(file.Name())
 
 	err = os.WriteFile(file.Name(), []byte("lego_file"), 0o644)
 	require.NoError(t, err)
 
-	err = os.Setenv(varEnvFileName, file.Name())
-	require.NoError(t, err)
-	defer os.Unsetenv(varEnvFileName)
-
-	err = os.Setenv(varEnvName, "lego_env")
-	require.NoError(t, err)
-	defer os.Unsetenv(varEnvName)
+	t.Setenv(varEnvFileName, file.Name())
+	t.Setenv(varEnvName, "lego_env")
 
 	value := GetOrFile(varEnvName)
 
diff --git a/providers/dns/acmedns/acmedns.go b/providers/dns/acmedns/acmedns.go
index 4b63fde5..40d6b96e 100644
--- a/providers/dns/acmedns/acmedns.go
+++ b/providers/dns/acmedns/acmedns.go
@@ -84,8 +84,8 @@ type ErrCNAMERequired struct {
 
 // Error returns a descriptive message for the ErrCNAMERequired instance telling
 // the user that a CNAME needs to be added to the DNS zone of c.Domain before
-// the ACME-DNS hook will work. The CNAME to be created should be of the form:
-//   {{ c.FQDN }} 	CNAME	{{ c.Target }}
+// the ACME-DNS hook will work.
+// The CNAME to be created should be of the form: {{ c.FQDN }} 	CNAME	{{ c.Target }}.
 func (e ErrCNAMERequired) Error() string {
 	return fmt.Sprintf("acme-dns: new account created for %q. "+
 		"To complete setup for %q you must provision the following "+
diff --git a/providers/dns/bluecat/bluecat.go b/providers/dns/bluecat/bluecat.go
index 75ee3c48..4961d578 100644
--- a/providers/dns/bluecat/bluecat.go
+++ b/providers/dns/bluecat/bluecat.go
@@ -65,12 +65,12 @@ type DNSProvider struct {
 
 // NewDNSProvider returns a DNSProvider instance configured for Bluecat DNS.
 // Credentials must be passed in the environment variables:
-//	- BLUECAT_SERVER_URL
-//	  It should have the scheme, hostname, and port (if required) of the authoritative Bluecat BAM server.
-//	  The REST endpoint will be appended.
-//	- BLUECAT_USER_NAME and BLUECAT_PASSWORD
-//	- BLUECAT_CONFIG_NAME (the Configuration name)
-//	- BLUECAT_DNS_VIEW (external DNS View Name)
+//   - BLUECAT_SERVER_URL
+//     It should have the scheme, hostname, and port (if required) of the authoritative Bluecat BAM server.
+//     The REST endpoint will be appended.
+//   - BLUECAT_USER_NAME and BLUECAT_PASSWORD
+//   - BLUECAT_CONFIG_NAME (the Configuration name)
+//   - BLUECAT_DNS_VIEW (external DNS View Name)
 func NewDNSProvider() (*DNSProvider, error) {
 	values, err := env.Get(EnvServerURL, EnvUserName, EnvPassword, EnvConfigName, EnvDNSView)
 	if err != nil {
diff --git a/providers/dns/cloudflare/cloudflare.go b/providers/dns/cloudflare/cloudflare.go
index 5e57e9b3..28b214ab 100644
--- a/providers/dns/cloudflare/cloudflare.go
+++ b/providers/dns/cloudflare/cloudflare.go
@@ -9,7 +9,7 @@ import (
 	"sync"
 	"time"
 
-	cloudflare "github.com/cloudflare/cloudflare-go"
+	"github.com/cloudflare/cloudflare-go"
 	"github.com/go-acme/lego/v4/challenge/dns01"
 	"github.com/go-acme/lego/v4/log"
 	"github.com/go-acme/lego/v4/platform/config/env"
@@ -78,7 +78,7 @@ func NewDNSProvider() (*DNSProvider, error) {
 			[]string{"CLOUDFLARE_ZONE_API_TOKEN", "CF_ZONE_API_TOKEN", "CLOUDFLARE_DNS_API_TOKEN", "CF_DNS_API_TOKEN"},
 		)
 		if errT != nil {
-			// nolint:errorlint
+			//nolint:errorlint
 			return nil, fmt.Errorf("cloudflare: %v or %v", err, errT)
 		}
 	}
diff --git a/providers/dns/cloudns/internal/client.go b/providers/dns/cloudns/internal/client.go
index 8208133e..e9f89217 100644
--- a/providers/dns/cloudns/internal/client.go
+++ b/providers/dns/cloudns/internal/client.go
@@ -317,19 +317,20 @@ func toUnreadableBodyMessage(req *http.Request, rawBody []byte) string {
 
 // Rounds the given TTL in seconds to the next accepted value.
 // Accepted TTL values are:
-//  - 60 = 1 minute
-//  - 300 = 5 minutes
-//  - 900 = 15 minutes
-//  - 1800 = 30 minutes
-//  - 3600 = 1 hour
-//  - 21600 = 6 hours
-//  - 43200 = 12 hours
-//  - 86400 = 1 day
-//  - 172800 = 2 days
-//  - 259200 = 3 days
-//  - 604800 = 1 week
-//  - 1209600 = 2 weeks
-//  - 2592000 = 1 month
+//   - 60 = 1 minute
+//   - 300 = 5 minutes
+//   - 900 = 15 minutes
+//   - 1800 = 30 minutes
+//   - 3600 = 1 hour
+//   - 21600 = 6 hours
+//   - 43200 = 12 hours
+//   - 86400 = 1 day
+//   - 172800 = 2 days
+//   - 259200 = 3 days
+//   - 604800 = 1 week
+//   - 1209600 = 2 weeks
+//   - 2592000 = 1 month
+//
 // See https://www.cloudns.net/wiki/article/58/ for details.
 func ttlRounder(ttl int) int {
 	for _, validTTL := range []int{60, 300, 900, 1800, 3600, 21600, 43200, 86400, 172800, 259200, 604800, 1209600} {
diff --git a/providers/dns/designate/designate_test.go b/providers/dns/designate/designate_test.go
index 82a7063b..f80fee1c 100644
--- a/providers/dns/designate/designate_test.go
+++ b/providers/dns/designate/designate_test.go
@@ -1,7 +1,6 @@
 package designate
 
 import (
-	"io/ioutil"
 	"net/http"
 	"net/http/httptest"
 	"os"
@@ -266,7 +265,7 @@ func TestNewDNSProviderConfig(t *testing.T) {
 func createCloudsYaml(t *testing.T, cloudName string, cloud clientconfig.Cloud) string {
 	t.Helper()
 
-	file, err := ioutil.TempFile("", "lego_test")
+	file, err := os.CreateTemp("", "lego_test")
 	require.NoError(t, err)
 
 	t.Cleanup(func() { _ = os.RemoveAll(file.Name()) })
@@ -317,7 +316,7 @@ func setupTestProvider(t *testing.T) string {
 		]
 	}
 }`))
-		w.WriteHeader(200)
+		w.WriteHeader(http.StatusOK)
 	})
 
 	server := httptest.NewServer(mux)
diff --git a/providers/dns/hurricane/internal/client.go b/providers/dns/hurricane/internal/client.go
index 5acdb4bf..81b863cc 100644
--- a/providers/dns/hurricane/internal/client.go
+++ b/providers/dns/hurricane/internal/client.go
@@ -96,9 +96,9 @@ func (c *Client) UpdateTxtRecord(ctx context.Context, domain string, txt string)
 }
 
 func evaluateBody(body string, hostname string) error {
-	words := strings.SplitN(body, " ", 2)
+	code, _, _ := strings.Cut(body, " ")
 
-	switch words[0] {
+	switch code {
 	case codeGood:
 		return nil
 	case codeNoChg:
@@ -125,8 +125,8 @@ func evaluateBody(body string, hostname string) error {
 // limit computes the rate based on burst.
 // The API rate limit per-record is 10 reqs / 2 minutes.
 //
-//     10 reqs / 2 minutes = freq 1/12 (burst = 1)
-//     6 reqs / 2 minutes = freq 1/20 (burst = 5)
+//	10 reqs / 2 minutes = freq 1/12 (burst = 1)
+//	6 reqs / 2 minutes = freq 1/20 (burst = 5)
 //
 // https://github.com/go-acme/lego/issues/1415
 func limit(burst int) rate.Limit {
diff --git a/providers/dns/joker/internal/dmapi/client.go b/providers/dns/joker/internal/dmapi/client.go
index e8e97c3a..0f0e636a 100644
--- a/providers/dns/joker/internal/dmapi/client.go
+++ b/providers/dns/joker/internal/dmapi/client.go
@@ -165,23 +165,20 @@ func (c *Client) postRequest(cmd string, data url.Values) (*Response, error) {
 func parseResponse(message string) *Response {
 	r := &Response{Headers: url.Values{}, StatusCode: -1}
 
-	parts := strings.SplitN(message, "\n\n", 2)
+	lines, body, _ := strings.Cut(message, "\n\n")
 
-	for _, line := range strings.Split(parts[0], "\n") {
+	for _, line := range strings.Split(lines, "\n") {
 		if strings.TrimSpace(line) == "" {
 			continue
 		}
 
-		kv := strings.SplitN(line, ":", 2)
+		k, v, _ := strings.Cut(line, ":")
 
-		val := ""
-		if len(kv) == 2 {
-			val = strings.TrimSpace(kv[1])
-		}
+		val := strings.TrimSpace(v)
 
-		r.Headers.Add(kv[0], val)
+		r.Headers.Add(k, val)
 
-		switch kv[0] {
+		switch k {
 		case "Status-Code":
 			i, err := strconv.Atoi(val)
 			if err == nil {
@@ -194,9 +191,7 @@ func parseResponse(message string) *Response {
 		}
 	}
 
-	if len(parts) > 1 {
-		r.Body = parts[1]
-	}
+	r.Body = body
 
 	return r
 }
diff --git a/providers/dns/joker/provider_dmapi.go b/providers/dns/joker/provider_dmapi.go
index b0940898..f0cb3185 100644
--- a/providers/dns/joker/provider_dmapi.go
+++ b/providers/dns/joker/provider_dmapi.go
@@ -26,7 +26,7 @@ func newDmapiProvider() (*dmapiProvider, error) {
 		var errU error
 		values, errU = env.Get(EnvUsername, EnvPassword)
 		if errU != nil {
-			// nolint:errorlint // false-positive
+			//nolint:errorlint // false-positive
 			return nil, fmt.Errorf("joker: %v or %v", errU, err)
 		}
 	}
diff --git a/providers/dns/lightsail/lightsail.go b/providers/dns/lightsail/lightsail.go
index 94419c23..b1dab779 100644
--- a/providers/dns/lightsail/lightsail.go
+++ b/providers/dns/lightsail/lightsail.go
@@ -80,10 +80,10 @@ type DNSProvider struct {
 //
 // AWS Credentials are automatically detected in the following locations
 // and prioritized in the following order:
-// 1. Environment variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY,
+//  1. Environment variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY,
 //     [AWS_SESSION_TOKEN], [DNS_ZONE], [LIGHTSAIL_REGION]
-// 2. Shared credentials file (defaults to ~/.aws/credentials)
-// 3. Amazon EC2 IAM role
+//  2. Shared credentials file (defaults to ~/.aws/credentials)
+//  3. Amazon EC2 IAM role
 //
 // public hosted zone via the FQDN.
 //
diff --git a/providers/dns/oraclecloud/oraclecloud_test.go b/providers/dns/oraclecloud/oraclecloud_test.go
index bcd473ae..ea76b674 100644
--- a/providers/dns/oraclecloud/oraclecloud_test.go
+++ b/providers/dns/oraclecloud/oraclecloud_test.go
@@ -6,7 +6,6 @@ import (
 	"crypto/x509"
 	"encoding/base64"
 	"encoding/pem"
-	"io/ioutil"
 	"os"
 	"testing"
 	"time"
@@ -307,7 +306,7 @@ func mustGeneratePrivateKeyFile(pwd string) string {
 		panic(err)
 	}
 
-	file, err := ioutil.TempFile("", "lego_oci_*.pem")
+	file, err := os.CreateTemp("", "lego_oci_*.pem")
 	if err != nil {
 		panic(err)
 	}
diff --git a/providers/dns/route53/route53.go b/providers/dns/route53/route53.go
index 05ac212b..daa81aeb 100644
--- a/providers/dns/route53/route53.go
+++ b/providers/dns/route53/route53.go
@@ -91,10 +91,10 @@ func (d customRetryer) RetryRules(r *request.Request) time.Duration {
 // NewDNSProvider returns a DNSProvider instance configured for the AWS Route 53 service.
 //
 // AWS Credentials are automatically detected in the following locations and prioritized in the following order:
-// 1. Environment variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY,
-//    AWS_REGION, [AWS_SESSION_TOKEN]
-// 2. Shared credentials file (defaults to ~/.aws/credentials)
-// 3. Amazon EC2 IAM role
+//  1. Environment variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY,
+//     AWS_REGION, [AWS_SESSION_TOKEN]
+//  2. Shared credentials file (defaults to ~/.aws/credentials)
+//  3. Amazon EC2 IAM role
 //
 // If AWS_HOSTED_ZONE_ID is not set, Lego tries to determine the correct public hosted zone via the FQDN.
 //