Repository: kubernetes-sigs/external-dns (language: go)

Issue:
Assess output of other linters to improve the codebase
Seems like they will trigger a lot of things, I'd love to go through them to see what's bad and what's not:

- revive
- statickcheck
- stylecheck
- unused
- gosimple


Discussion / hints:

Fix patch:
diff --git a/.golangci.yml b/.golangci.yml
index 637999b507..20c72e8c2e 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -7,6 +7,12 @@ linters-settings:
     suggest-new: true
   misspell:
     locale: US
+  revive:
+    confusing-naming: false
+    ignore-generated-header: true
+    rules:
+      - name: confusing-naming
+        disabled: true
 
 linters:
   # please, do not use `enable-all`: it's deprecated and will be removed soon.
@@ -25,6 +31,10 @@ linters:
     - typecheck
     - unconvert
     - whitespace
+    - revive
+    - unused
+    - gosimple
+    - staticcheck
 
 issues:
   # Excluding configuration per-path, per-linter, per-text and per-source
diff --git a/pkg/tlsutils/tlsconfig.go b/pkg/tlsutils/tlsconfig.go
index 106a21af7f..3a25334971 100644
--- a/pkg/tlsutils/tlsconfig.go
+++ b/pkg/tlsutils/tlsconfig.go
@@ -21,7 +21,6 @@ import (
 	"crypto/x509"
 	"errors"
 	"fmt"
-	"io/ioutil"
 	"os"
 	"strings"
 )
@@ -77,7 +76,7 @@ func loadRoots(caPath string) (*x509.CertPool, error) {
 	}
 
 	roots := x509.NewCertPool()
-	pem, err := ioutil.ReadFile(caPath)
+	pem, err := os.ReadFile(caPath)
 	if err != nil {
 		return nil, fmt.Errorf("error reading %s: %s", caPath, err)
 	}
diff --git a/provider/alibabacloud/alibaba_cloud.go b/provider/alibabacloud/alibaba_cloud.go
index e2d14b05c0..ccd9c7caa0 100644
--- a/provider/alibabacloud/alibaba_cloud.go
+++ b/provider/alibabacloud/alibaba_cloud.go
@@ -19,7 +19,7 @@ package alibabacloud
 import (
 	"context"
 	"fmt"
-	"io/ioutil"
+	"os"
 	"strings"
 	"sync"
 	"time"
@@ -99,7 +99,7 @@ type alibabaCloudConfig struct {
 func NewAlibabaCloudProvider(configFile string, domainFilter endpoint.DomainFilter, zoneIDFileter provider.ZoneIDFilter, zoneType string, dryRun bool) (*AlibabaCloudProvider, error) {
 	cfg := alibabaCloudConfig{}
 	if configFile != "" {
-		contents, err := ioutil.ReadFile(configFile)
+		contents, err := os.ReadFile(configFile)
 		if err != nil {
 			return nil, fmt.Errorf("failed to read Alibaba Cloud config file '%s': %v", configFile, err)
 		}
diff --git a/provider/azure/azure.go b/provider/azure/azure.go
index 2b2ff29246..dfab96effa 100644
--- a/provider/azure/azure.go
+++ b/provider/azure/azure.go
@@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
+// nolint:staticcheck
 package azure
 
 import (
diff --git a/provider/azure/azure_private_dns.go b/provider/azure/azure_private_dns.go
index 320def42aa..374b5e5d6c 100644
--- a/provider/azure/azure_private_dns.go
+++ b/provider/azure/azure_private_dns.go
@@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
+// nolint:staticcheck
 package azure
 
 import (
diff --git a/provider/azure/config.go b/provider/azure/config.go
index 67baed947d..e9a071b849 100644
--- a/provider/azure/config.go
+++ b/provider/azure/config.go
@@ -18,7 +18,7 @@ package azure
 
 import (
 	"fmt"
-	"io/ioutil"
+	"os"
 	"strings"
 
 	"github.com/Azure/go-autorest/autorest/adal"
@@ -42,7 +42,7 @@ type config struct {
 }
 
 func getConfig(configFile, resourceGroup, userAssignedIdentityClientID string) (*config, error) {
-	contents, err := ioutil.ReadFile(configFile)
+	contents, err := os.ReadFile(configFile)
 	if err != nil {
 		return nil, fmt.Errorf("failed to read Azure config file '%s': %v", configFile, err)
 	}
diff --git a/provider/bluecat/gateway/api.go b/provider/bluecat/gateway/api.go
index 8cd593462d..d0d8dc5603 100644
--- a/provider/bluecat/gateway/api.go
+++ b/provider/bluecat/gateway/api.go
@@ -22,7 +22,6 @@ import (
 	"crypto/tls"
 	"encoding/json"
 	"io"
-	"io/ioutil"
 	"net/http"
 	"os"
 	"strings"
@@ -181,7 +180,7 @@ func GetBluecatGatewayToken(cfg BluecatConfig) (string, http.Cookie, error) {
 	}
 	defer response.Body.Close()
 
-	responseBody, err := ioutil.ReadAll(response.Body)
+	responseBody, err := io.ReadAll(response.Body)
 	if err != nil {
 		return "", http.Cookie{}, errors.Wrap(err, "failed to read login response from bluecat gateway")
 	}
@@ -504,7 +503,7 @@ func (c GatewayClientConfig) ServerFullDeploy() error {
 	}
 
 	if response.StatusCode != http.StatusCreated {
-		responseBody, err := ioutil.ReadAll(response.Body)
+		responseBody, err := io.ReadAll(response.Body)
 		if err != nil {
 			return errors.Wrap(err, "failed to read full deploy response body")
 		}
diff --git a/provider/coredns/coredns.go b/provider/coredns/coredns.go
index 520dc54506..356ffee732 100644
--- a/provider/coredns/coredns.go
+++ b/provider/coredns/coredns.go
@@ -23,7 +23,6 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
-	"io/ioutil"
 	"math/rand"
 	"net"
 	"os"
@@ -191,7 +190,7 @@ func loadRoots(caPath string) (*x509.CertPool, error) {
 	}
 
 	roots := x509.NewCertPool()
-	pem, err := ioutil.ReadFile(caPath)
+	pem, err := os.ReadFile(caPath)
 	if err != nil {
 		return nil, fmt.Errorf("error reading %s: %s", caPath, err)
 	}
diff --git a/provider/godaddy/client.go b/provider/godaddy/client.go
index d7e0485f27..32f4df62c3 100644
--- a/provider/godaddy/client.go
+++ b/provider/godaddy/client.go
@@ -22,7 +22,7 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
-	"io/ioutil"
+	"io"
 	"net/http"
 	"time"
 
@@ -286,7 +286,7 @@ func (c *Client) CallAPIWithContext(ctx context.Context, method, path string, re
 func (c *Client) UnmarshalResponse(response *http.Response, resType interface{}) error {
 	// Read all the response body
 	defer response.Body.Close()
-	body, err := ioutil.ReadAll(response.Body)
+	body, err := io.ReadAll(response.Body)
 	if err != nil {
 		return err
 	}
diff --git a/provider/ibmcloud/ibmcloud.go b/provider/ibmcloud/ibmcloud.go
index d6aabd3221..1340edfd2c 100644
--- a/provider/ibmcloud/ibmcloud.go
+++ b/provider/ibmcloud/ibmcloud.go
@@ -19,7 +19,7 @@ package ibmcloud
 import (
 	"context"
 	"fmt"
-	"io/ioutil"
+	"os"
 	"reflect"
 	"strconv"
 	"strings"
@@ -201,7 +201,7 @@ type ibmcloudChange struct {
 }
 
 func getConfig(configFile string) (*ibmcloudConfig, error) {
-	contents, err := ioutil.ReadFile(configFile)
+	contents, err := os.ReadFile(configFile)
 	if err != nil {
 		return nil, fmt.Errorf("failed to read IBM Cloud config file '%s': %v", configFile, err)
 	}
diff --git a/provider/oci/oci.go b/provider/oci/oci.go
index c4817b4110..f9a47a48b7 100644
--- a/provider/oci/oci.go
+++ b/provider/oci/oci.go
@@ -18,7 +18,7 @@ package oci
 
 import (
 	"context"
-	"io/ioutil"
+	"os"
 	"strings"
 
 	"github.com/oracle/oci-go-sdk/common"
@@ -72,7 +72,7 @@ type ociDNSClient interface {
 // LoadOCIConfig reads and parses the OCI ExternalDNS config file at the given
 // path.
 func LoadOCIConfig(path string) (*OCIConfig, error) {
-	contents, err := ioutil.ReadFile(path)
+	contents, err := os.ReadFile(path)
 	if err != nil {
 		return nil, errors.Wrapf(err, "reading OCI config file %q", path)
 	}
diff --git a/provider/pihole/client.go b/provider/pihole/client.go
index 2cb223ccbe..df6fb4c576 100644
--- a/provider/pihole/client.go
+++ b/provider/pihole/client.go
@@ -23,7 +23,6 @@ import (
 	"errors"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"net/http"
 	"net/http/cookiejar"
 	"net/url"
@@ -114,7 +113,7 @@ func (p *piholeClient) listRecords(ctx context.Context, rtype string) ([]*endpoi
 		return nil, err
 	}
 	defer body.Close()
-	raw, err := ioutil.ReadAll(body)
+	raw, err := io.ReadAll(body)
 	if err != nil {
 		return nil, err
 	}
@@ -207,11 +206,11 @@ func (p *piholeClient) apply(ctx context.Context, action string, ep *endpoint.En
 	}
 
 	if p.cfg.DryRun {
-		log.Infof("DRY RUN: %s %s IN %s -> %s", strings.Title(action), ep.DNSName, ep.RecordType, ep.Targets[0])
+		log.Infof("DRY RUN: %s %s IN %s -> %s", action, ep.DNSName, ep.RecordType, ep.Targets[0])
 		return nil
 	}
 
-	log.Infof("%s %s IN %s -> %s", strings.Title(action), ep.DNSName, ep.RecordType, ep.Targets[0])
+	log.Infof("%s %s IN %s -> %s", action, ep.DNSName, ep.RecordType, ep.Targets[0])
 
 	form := p.newDNSActionForm(action, ep)
 	req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, strings.NewReader(form.Encode()))
@@ -226,7 +225,7 @@ func (p *piholeClient) apply(ctx context.Context, action string, ep *endpoint.En
 	}
 	defer body.Close()
 
-	raw, err := ioutil.ReadAll(body)
+	raw, err := io.ReadAll(body)
 	if err != nil {
 		return nil
 	}
diff --git a/provider/rdns/rdns.go b/provider/rdns/rdns.go
index 4331059c33..e645be0bc0 100644
--- a/provider/rdns/rdns.go
+++ b/provider/rdns/rdns.go
@@ -22,7 +22,6 @@ import (
 	"crypto/x509"
 	"encoding/json"
 	"fmt"
-	"io/ioutil"
 	"math/rand"
 	"os"
 	"regexp"
@@ -309,7 +308,7 @@ func newEtcdv3Client() (RDNSClient, error) {
 
 		if ca != "" {
 			roots := x509.NewCertPool()
-			pem, err := ioutil.ReadFile(ca)
+			pem, err := os.ReadFile(ca)
 			if err != nil {
 				return nil, fmt.Errorf("error reading %s: %s", ca, err)
 			}
diff --git a/provider/tencentcloud/cloudapi/tencentapi.go b/provider/tencentcloud/cloudapi/tencentapi.go
index 95f119c7c9..5997cb67f6 100644
--- a/provider/tencentcloud/cloudapi/tencentapi.go
+++ b/provider/tencentcloud/cloudapi/tencentapi.go
@@ -53,7 +53,7 @@ func (api *defaultTencentAPIService) CreatePrivateZoneRecord(request *privatedns
 		client := api.ClientSetService.PrivateDnsCli(apiAction.Name)
 		if response, err = client.CreatePrivateZoneRecord(request); err != nil {
 			requestJson := JsonWrapper(request)
-			if retry := dealWithError(apiAction, requestJson, err); retry == false || times == api.RetryDefault {
+			if retry := dealWithError(apiAction, requestJson, err); retry || times == api.RetryDefault {
 				APIErrorRecord(apiAction, requestJson, JsonWrapper(response), err)
 				return nil, err
 			}
@@ -71,7 +71,7 @@ func (api *defaultTencentAPIService) DeletePrivateZoneRecord(request *privatedns
 		client := api.ClientSetService.PrivateDnsCli(apiAction.Name)
 		if response, err = client.DeletePrivateZoneRecord(request); err != nil {
 			requestJson := JsonWrapper(request)
-			if retry := dealWithError(apiAction, requestJson, err); retry == false || times == api.RetryDefault {
+			if retry := dealWithError(apiAction, requestJson, err); retry || times == api.RetryDefault {
 				APIErrorRecord(apiAction, requestJson, JsonWrapper(response), err)
 				return nil, err
 			}
@@ -89,7 +89,7 @@ func (api *defaultTencentAPIService) ModifyPrivateZoneRecord(request *privatedns
 		client := api.ClientSetService.PrivateDnsCli(apiAction.Name)
 		if response, err = client.ModifyPrivateZoneRecord(request); err != nil {
 			requestJson := JsonWrapper(request)
-			if retry := dealWithError(apiAction, requestJson, err); retry == false || times == api.RetryDefault {
+			if retry := dealWithError(apiAction, requestJson, err); retry || times == api.RetryDefault {
 				APIErrorRecord(apiAction, requestJson, JsonWrapper(response), err)
 				return nil, err
 			}
@@ -107,7 +107,7 @@ func (api *defaultTencentAPIService) DescribePrivateZoneList(request *privatedns
 		client := api.ClientSetService.PrivateDnsCli(apiAction.Name)
 		if response, err = client.DescribePrivateZoneList(request); err != nil {
 			requestJson := JsonWrapper(request)
-			if retry := dealWithError(apiAction, requestJson, err); retry == false || times == api.RetryDefault {
+			if retry := dealWithError(apiAction, requestJson, err); retry || times == api.RetryDefault {
 				APIErrorRecord(apiAction, requestJson, JsonWrapper(response), err)
 				return nil, err
 			}
@@ -125,7 +125,7 @@ func (api *defaultTencentAPIService) DescribePrivateZoneRecordList(request *priv
 		client := api.ClientSetService.PrivateDnsCli(apiAction.Name)
 		if response, err = client.DescribePrivateZoneRecordList(request); err != nil {
 			requestJson := JsonWrapper(request)
-			if retry := dealWithError(apiAction, requestJson, err); retry == false || times == api.RetryDefault {
+			if retry := dealWithError(apiAction, requestJson, err); retry || times == api.RetryDefault {
 				APIErrorRecord(apiAction, requestJson, JsonWrapper(response), err)
 				return nil, err
 			}
@@ -147,7 +147,7 @@ func (api *defaultTencentAPIService) DescribeDomainList(request *dnspod.Describe
 		client := api.ClientSetService.DnsPodCli(apiAction.Name)
 		if response, err = client.DescribeDomainList(request); err != nil {
 			requestJson := JsonWrapper(request)
-			if retry := dealWithError(apiAction, requestJson, err); retry == false || times == api.RetryDefault {
+			if retry := dealWithError(apiAction, requestJson, err); retry || times == api.RetryDefault {
 				APIErrorRecord(apiAction, requestJson, JsonWrapper(response), err)
 				return nil, err
 			}
@@ -165,7 +165,7 @@ func (api *defaultTencentAPIService) DescribeRecordList(request *dnspod.Describe
 		client := api.ClientSetService.DnsPodCli(apiAction.Name)
 		if response, err = client.DescribeRecordList(request); err != nil {
 			requestJson := JsonWrapper(request)
-			if retry := dealWithError(apiAction, requestJson, err); retry == false || times == api.RetryDefault {
+			if retry := dealWithError(apiAction, requestJson, err); retry || times == api.RetryDefault {
 				APIErrorRecord(apiAction, requestJson, JsonWrapper(response), err)
 				return nil, err
 			}
@@ -183,7 +183,7 @@ func (api *defaultTencentAPIService) CreateRecord(request *dnspod.CreateRecordRe
 		client := api.ClientSetService.DnsPodCli(apiAction.Name)
 		if response, err = client.CreateRecord(request); err != nil {
 			requestJson := JsonWrapper(request)
-			if retry := dealWithError(apiAction, requestJson, err); retry == false || times == api.RetryDefault {
+			if retry := dealWithError(apiAction, requestJson, err); retry || times == api.RetryDefault {
 				APIErrorRecord(apiAction, requestJson, JsonWrapper(response), err)
 				return nil, err
 			}
@@ -201,7 +201,7 @@ func (api *defaultTencentAPIService) DeleteRecord(request *dnspod.DeleteRecordRe
 		client := api.ClientSetService.DnsPodCli(apiAction.Name)
 		if response, err = client.DeleteRecord(request); err != nil {
 			requestJson := JsonWrapper(request)
-			if retry := dealWithError(apiAction, requestJson, err); retry == false || times == api.RetryDefault {
+			if retry := dealWithError(apiAction, requestJson, err); retry || times == api.RetryDefault {
 				APIErrorRecord(apiAction, requestJson, JsonWrapper(response), err)
 				return nil, err
 			}
@@ -219,7 +219,7 @@ func (api *defaultTencentAPIService) ModifyRecord(request *dnspod.ModifyRecordRe
 		client := api.ClientSetService.DnsPodCli(apiAction.Name)
 		if response, err = client.ModifyRecord(request); err != nil {
 			requestJson := JsonWrapper(request)
-			if retry := dealWithError(apiAction, requestJson, err); retry == false || times == api.RetryDefault {
+			if retry := dealWithError(apiAction, requestJson, err); retry || times == api.RetryDefault {
 				APIErrorRecord(apiAction, requestJson, JsonWrapper(response), err)
 				return nil, err
 			}
diff --git a/provider/tencentcloud/tencent_cloud.go b/provider/tencentcloud/tencent_cloud.go
index e551af6634..e52a4df844 100644
--- a/provider/tencentcloud/tencent_cloud.go
+++ b/provider/tencentcloud/tencent_cloud.go
@@ -67,7 +67,6 @@ func NewTencentCloudProvider(domainFilter endpoint.DomainFilter, zoneIDFilter pr
 
 type TencentCloudProvider struct {
 	provider.BaseProvider
-	logger       *log.Logger
 	apiService   cloudapi.TencentAPIService
 	domainFilter endpoint.DomainFilter
 	zoneIDFilter provider.ZoneIDFilter // Private Zone only
diff --git a/source/skipper_routegroup.go b/source/skipper_routegroup.go
index 1cf0f8ce53..252f0b8eb9 100644
--- a/source/skipper_routegroup.go
+++ b/source/skipper_routegroup.go
@@ -23,10 +23,10 @@ import (
 	"crypto/x509"
 	"encoding/json"
 	"fmt"
-	"io/ioutil"
 	"net"
 	"net/http"
 	"net/url"
+	"os"
 	"sort"
 	"strings"
 	"sync"
@@ -116,7 +116,7 @@ func newRouteGroupClient(token, tokenPath string, timeout time.Duration) *routeG
 	cli.updateToken()
 
 	// cluster internal use custom CA to reach TLS endpoint
-	rootCA, err := ioutil.ReadFile(rootCAFile)
+	rootCA, err := os.ReadFile(rootCAFile)
 	if err != nil {
 		return cli
 	}
@@ -138,7 +138,7 @@ func (cli *routeGroupClient) updateToken() {
 		return
 	}
 
-	token, err := ioutil.ReadFile(cli.tokenFile)
+	token, err := os.ReadFile(cli.tokenFile)
 	if err != nil {
 		log.Errorf("Failed to read token from file (%s): %v", cli.tokenFile, err)
 		return


Test patch:
diff --git a/internal/testutils/init.go b/internal/testutils/init.go
index a2c1bce5d0..27143cf23a 100644
--- a/internal/testutils/init.go
+++ b/internal/testutils/init.go
@@ -17,7 +17,7 @@ limitations under the License.
 package testutils
 
 import (
-	"io/ioutil"
+	"io"
 	"log"
 	"os"
 
@@ -29,8 +29,8 @@ import (
 func init() {
 	config.FastPoll = true
 	if os.Getenv("DEBUG") == "" {
-		logrus.SetOutput(ioutil.Discard)
-		log.SetOutput(ioutil.Discard)
+		logrus.SetOutput(io.Discard)
+		log.SetOutput(io.Discard)
 	} else {
 		if level, err := logrus.ParseLevel(os.Getenv("DEBUG")); err == nil {
 			logrus.SetLevel(level)
diff --git a/provider/azure/config_test.go b/provider/azure/config_test.go
index a2129113a3..580b664c75 100644
--- a/provider/azure/config_test.go
+++ b/provider/azure/config_test.go
@@ -18,7 +18,6 @@ package azure
 
 import (
 	"fmt"
-	"io/ioutil"
 	"os"
 	"reflect"
 	"testing"
@@ -27,7 +26,7 @@ import (
 )
 
 func TestGetAzureEnvironmentConfig(t *testing.T) {
-	tmp, err := ioutil.TempFile("", "azureconf")
+	tmp, err := os.CreateTemp("", "azureconf")
 	if err != nil {
 		t.Errorf("couldn't write temp file %v", err)
 	}
diff --git a/provider/bluecat/gateway/api_test.go b/provider/bluecat/gateway/api_test.go
index 88aad8326d..10ebd51b5f 100644
--- a/provider/bluecat/gateway/api_test.go
+++ b/provider/bluecat/gateway/api_test.go
@@ -15,7 +15,7 @@ package api
 
 import (
 	"encoding/json"
-	"io/ioutil"
+	"io"
 	"net/http"
 	"net/http/httptest"
 	"strings"
@@ -100,7 +100,7 @@ func TestBluecatSplitProperties(t *testing.T) {
 func TestCreateTXTRecord(t *testing.T) {
 	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		req := BluecatCreateTXTRecordRequest{}
-		requestBodyBytes, _ := ioutil.ReadAll(r.Body)
+		requestBodyBytes, _ := io.ReadAll(r.Body)
 		err := json.Unmarshal(requestBodyBytes, &req)
 		if err != nil {
 			t.Fatalf("failed to unmarshal body for server full deploy")
@@ -196,7 +196,7 @@ func TestDeleteTXTRecord(t *testing.T) {
 func TestServerFullDeploy(t *testing.T) {
 	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		req := BluecatServerFullDeployRequest{}
-		requestBodyBytes, _ := ioutil.ReadAll(r.Body)
+		requestBodyBytes, _ := io.ReadAll(r.Body)
 		err := json.Unmarshal(requestBodyBytes, &req)
 		if err != nil {
 			t.Fatalf("failed to unmarshal body for server full deploy")
diff --git a/provider/designate/designate_test.go b/provider/designate/designate_test.go
index 0afc72fa6b..d0790cf6f8 100644
--- a/provider/designate/designate_test.go
+++ b/provider/designate/designate_test.go
@@ -20,7 +20,6 @@ import (
 	"context"
 	"encoding/pem"
 	"fmt"
-	"io/ioutil"
 	"net/http"
 	"net/http/httptest"
 	"os"
@@ -174,7 +173,7 @@ func TestNewDesignateProvider(t *testing.T) {
 		Type:  "CERTIFICATE",
 		Bytes: ts.Certificate().Raw,
 	}
-	tmpfile, err := ioutil.TempFile("", "os-test.crt")
+	tmpfile, err := os.CreateTemp("", "os-test.crt")
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/provider/provider_test.go b/provider/provider_test.go
index 0e24ca4f01..ae389e9207 100644
--- a/provider/provider_test.go
+++ b/provider/provider_test.go
@@ -17,7 +17,7 @@ limitations under the License.
 package provider
 
 import (
-	"io/ioutil"
+	"io"
 	"os"
 	"testing"
 
@@ -26,7 +26,7 @@ import (
 )
 
 func TestMain(m *testing.M) {
-	log.SetOutput(ioutil.Discard)
+	log.SetOutput(io.Discard)
 	os.Exit(m.Run())
 }
 
diff --git a/source/crd_test.go b/source/crd_test.go
index fe9d4e6606..aaada1802b 100644
--- a/source/crd_test.go
+++ b/source/crd_test.go
@@ -22,7 +22,6 @@ import (
 	"encoding/json"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"net/http"
 	"strings"
 	"testing"
@@ -54,7 +53,7 @@ func defaultHeader() http.Header {
 }
 
 func objBody(codec runtime.Encoder, obj runtime.Object) io.ReadCloser {
-	return ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(codec, obj))))
+	return io.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(codec, obj))))
 }
 
 func fakeRESTClient(endpoints []*endpoint.Endpoint, apiVersion, kind, namespace, name string, annotations map[string]string, labels map[string]string, t *testing.T) rest.Interface {