From f0186ff2651e83c8097d79b96ee9cc71c2dbaf38 Mon Sep 17 00:00:00 2001
From: Eng Zer Jun <engzerjun@gmail.com>
Date: Fri, 17 Sep 2021 14:12:39 +0800
Subject: [PATCH] refactor: move from io/ioutil to io and os package

The io/ioutil package has been deprecated as of Go 1.16, see
https://golang.org/doc/go1.16#ioutil. This commit replaces the existing
io/ioutil functions with their new definitions in io and os packages.

Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
---
 cmd/dex/serve.go                                |  5 ++---
 connector/atlassiancrowd/atlassiancrowd.go      |  3 +--
 connector/atlassiancrowd/atlassiancrowd_test.go |  4 ++--
 connector/bitbucketcloud/bitbucketcloud.go      |  4 ++--
 connector/gitea/gitea.go                        |  4 ++--
 connector/github/github.go                      |  7 ++++---
 connector/gitlab/gitlab.go                      |  6 +++---
 connector/google/google.go                      |  4 ++--
 connector/keystone/keystone.go                  |  8 ++++----
 connector/keystone/keystone_test.go             |  8 ++++----
 connector/ldap/ldap.go                          |  4 ++--
 connector/ldap/ldap_test.go                     |  4 ++--
 connector/linkedin/linkedin.go                  |  6 +++---
 connector/openshift/openshift.go                |  7 ++++---
 connector/saml/saml.go                          |  4 ++--
 connector/saml/saml_test.go                     | 12 ++++++------
 examples/example-app/main.go                    |  3 +--
 examples/grpc-client/client.go                  |  4 ++--
 server/deviceflowhandlers_test.go               |  6 +++---
 server/server_test.go                           |  8 ++++----
 storage/conformance/gen_jwks.go                 |  4 ++--
 storage/kubernetes/client.go                    | 13 ++++++-------
 storage/kubernetes/client_test.go               |  5 ++---
 storage/kubernetes/transport.go                 |  4 ++--
 storage/sql/config.go                           |  4 ++--
 25 files changed, 69 insertions(+), 72 deletions(-)

diff --git a/cmd/dex/serve.go b/cmd/dex/serve.go
index 47030393..92068934 100644
--- a/cmd/dex/serve.go
+++ b/cmd/dex/serve.go
@@ -6,7 +6,6 @@ import (
 	"crypto/x509"
 	"errors"
 	"fmt"
-	"io/ioutil"
 	"net"
 	"net/http"
 	"os"
@@ -76,7 +75,7 @@ func commandServe() *cobra.Command {
 
 func runServe(options serveOptions) error {
 	configFile := options.config
-	configData, err := ioutil.ReadFile(configFile)
+	configData, err := os.ReadFile(configFile)
 	if err != nil {
 		return fmt.Errorf("failed to read config file %s: %v", configFile, err)
 	}
@@ -148,7 +147,7 @@ func runServe(options serveOptions) error {
 		if c.GRPC.TLSClientCA != "" {
 			// Parse certificates from client CA file to a new CertPool.
 			cPool := x509.NewCertPool()
-			clientCert, err := ioutil.ReadFile(c.GRPC.TLSClientCA)
+			clientCert, err := os.ReadFile(c.GRPC.TLSClientCA)
 			if err != nil {
 				return fmt.Errorf("invalid config: reading from client CA file: %v", err)
 			}
diff --git a/connector/atlassiancrowd/atlassiancrowd.go b/connector/atlassiancrowd/atlassiancrowd.go
index 6f034060..e2ca94b0 100644
--- a/connector/atlassiancrowd/atlassiancrowd.go
+++ b/connector/atlassiancrowd/atlassiancrowd.go
@@ -7,7 +7,6 @@ import (
 	"encoding/json"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"net"
 	"net/http"
 	"strings"
@@ -432,7 +431,7 @@ func (c *crowdConnector) crowdUserManagementRequest(ctx context.Context, method
 
 // validateCrowdResponse validates unique not JSON responses from API
 func (c *crowdConnector) validateCrowdResponse(resp *http.Response) ([]byte, error) {
-	body, err := ioutil.ReadAll(resp.Body)
+	body, err := io.ReadAll(resp.Body)
 	if err != nil {
 		return nil, fmt.Errorf("crowd: read user body: %v", err)
 	}
diff --git a/connector/atlassiancrowd/atlassiancrowd_test.go b/connector/atlassiancrowd/atlassiancrowd_test.go
index 3559445d..36789a39 100644
--- a/connector/atlassiancrowd/atlassiancrowd_test.go
+++ b/connector/atlassiancrowd/atlassiancrowd_test.go
@@ -6,7 +6,7 @@ import (
 	"crypto/tls"
 	"encoding/json"
 	"fmt"
-	"io/ioutil"
+	"io"
 	"net/http"
 	"net/http/httptest"
 	"reflect"
@@ -152,7 +152,7 @@ func newTestCrowdConnector(baseURL string) crowdConnector {
 	connector := crowdConnector{}
 	connector.BaseURL = baseURL
 	connector.logger = &logrus.Logger{
-		Out:       ioutil.Discard,
+		Out:       io.Discard,
 		Level:     logrus.DebugLevel,
 		Formatter: &logrus.TextFormatter{DisableColors: true},
 	}
diff --git a/connector/bitbucketcloud/bitbucketcloud.go b/connector/bitbucketcloud/bitbucketcloud.go
index e81893da..b9134e91 100644
--- a/connector/bitbucketcloud/bitbucketcloud.go
+++ b/connector/bitbucketcloud/bitbucketcloud.go
@@ -6,7 +6,7 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
-	"io/ioutil"
+	"io"
 	"net/http"
 	"sync"
 	"time"
@@ -453,7 +453,7 @@ func get(ctx context.Context, client *http.Client, apiURL string, v interface{})
 	defer resp.Body.Close()
 
 	if resp.StatusCode != http.StatusOK {
-		body, err := ioutil.ReadAll(resp.Body)
+		body, err := io.ReadAll(resp.Body)
 		if err != nil {
 			return fmt.Errorf("bitbucket: read body: %s: %v", resp.Status, err)
 		}
diff --git a/connector/gitea/gitea.go b/connector/gitea/gitea.go
index 33cc3126..cd371d37 100644
--- a/connector/gitea/gitea.go
+++ b/connector/gitea/gitea.go
@@ -6,7 +6,7 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
-	"io/ioutil"
+	"io"
 	"net/http"
 	"strconv"
 	"sync"
@@ -252,7 +252,7 @@ func (c *giteaConnector) user(ctx context.Context, client *http.Client) (giteaUs
 	defer resp.Body.Close()
 
 	if resp.StatusCode != http.StatusOK {
-		body, err := ioutil.ReadAll(resp.Body)
+		body, err := io.ReadAll(resp.Body)
 		if err != nil {
 			return u, fmt.Errorf("gitea: read body: %v", err)
 		}
diff --git a/connector/github/github.go b/connector/github/github.go
index 02f2cae8..ef8d418f 100644
--- a/connector/github/github.go
+++ b/connector/github/github.go
@@ -8,9 +8,10 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
-	"io/ioutil"
+	"io"
 	"net"
 	"net/http"
+	"os"
 	"regexp"
 	"strconv"
 	"strings"
@@ -210,7 +211,7 @@ func (e *oauth2Error) Error() string {
 // newHTTPClient returns a new HTTP client that trusts the custom declared rootCA cert.
 func newHTTPClient(rootCA string) (*http.Client, error) {
 	tlsConfig := tls.Config{RootCAs: x509.NewCertPool()}
-	rootCABytes, err := ioutil.ReadFile(rootCA)
+	rootCABytes, err := os.ReadFile(rootCA)
 	if err != nil {
 		return nil, fmt.Errorf("failed to read root-ca: %v", err)
 	}
@@ -488,7 +489,7 @@ func get(ctx context.Context, client *http.Client, apiURL string, v interface{})
 	defer resp.Body.Close()
 
 	if resp.StatusCode != http.StatusOK {
-		body, err := ioutil.ReadAll(resp.Body)
+		body, err := io.ReadAll(resp.Body)
 		if err != nil {
 			return "", fmt.Errorf("github: read body: %v", err)
 		}
diff --git a/connector/gitlab/gitlab.go b/connector/gitlab/gitlab.go
index e4060140..7d8e8337 100644
--- a/connector/gitlab/gitlab.go
+++ b/connector/gitlab/gitlab.go
@@ -6,7 +6,7 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
-	"io/ioutil"
+	"io"
 	"net/http"
 	"strconv"
 
@@ -232,7 +232,7 @@ func (c *gitlabConnector) user(ctx context.Context, client *http.Client) (gitlab
 	defer resp.Body.Close()
 
 	if resp.StatusCode != http.StatusOK {
-		body, err := ioutil.ReadAll(resp.Body)
+		body, err := io.ReadAll(resp.Body)
 		if err != nil {
 			return u, fmt.Errorf("gitlab: read body: %v", err)
 		}
@@ -266,7 +266,7 @@ func (c *gitlabConnector) userGroups(ctx context.Context, client *http.Client) (
 	defer resp.Body.Close()
 
 	if resp.StatusCode != http.StatusOK {
-		body, err := ioutil.ReadAll(resp.Body)
+		body, err := io.ReadAll(resp.Body)
 		if err != nil {
 			return nil, fmt.Errorf("gitlab: read body: %v", err)
 		}
diff --git a/connector/google/google.go b/connector/google/google.go
index eccb1fc7..953cb32e 100644
--- a/connector/google/google.go
+++ b/connector/google/google.go
@@ -5,8 +5,8 @@ import (
 	"context"
 	"errors"
 	"fmt"
-	"io/ioutil"
 	"net/http"
+	"os"
 	"time"
 
 	"github.com/coreos/go-oidc/v3/oidc"
@@ -274,7 +274,7 @@ func createDirectoryService(serviceAccountFilePath string, email string) (*admin
 	if serviceAccountFilePath == "" || email == "" {
 		return nil, fmt.Errorf("directory service requires both serviceAccountFilePath and adminEmail")
 	}
-	jsonCredentials, err := ioutil.ReadFile(serviceAccountFilePath)
+	jsonCredentials, err := os.ReadFile(serviceAccountFilePath)
 	if err != nil {
 		return nil, fmt.Errorf("error reading credentials from file: %v", err)
 	}
diff --git a/connector/keystone/keystone.go b/connector/keystone/keystone.go
index 3750710e..c4e98d05 100644
--- a/connector/keystone/keystone.go
+++ b/connector/keystone/keystone.go
@@ -6,7 +6,7 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
-	"io/ioutil"
+	"io"
 	"net/http"
 
 	"github.com/dexidp/dex/connector"
@@ -133,7 +133,7 @@ func (p *conn) Login(ctx context.Context, scopes connector.Scopes, username, pas
 		return identity, false, nil
 	}
 	token := resp.Header.Get("X-Subject-Token")
-	data, err := ioutil.ReadAll(resp.Body)
+	data, err := io.ReadAll(resp.Body)
 	if err != nil {
 		return identity, false, err
 	}
@@ -260,7 +260,7 @@ func (p *conn) getUser(ctx context.Context, userID string, token string) (*userR
 		return nil, err
 	}
 
-	data, err := ioutil.ReadAll(resp.Body)
+	data, err := io.ReadAll(resp.Body)
 	if err != nil {
 		return nil, err
 	}
@@ -290,7 +290,7 @@ func (p *conn) getUserGroups(ctx context.Context, userID string, token string) (
 		return nil, err
 	}
 
-	data, err := ioutil.ReadAll(resp.Body)
+	data, err := io.ReadAll(resp.Body)
 	if err != nil {
 		return nil, err
 	}
diff --git a/connector/keystone/keystone_test.go b/connector/keystone/keystone_test.go
index b1380124..cf007f19 100644
--- a/connector/keystone/keystone_test.go
+++ b/connector/keystone/keystone_test.go
@@ -5,7 +5,7 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
-	"io/ioutil"
+	"io"
 	"net/http"
 	"os"
 	"reflect"
@@ -78,7 +78,7 @@ func getAdminToken(t *testing.T, adminName, adminPass string) (token, id string)
 
 	token = resp.Header.Get("X-Subject-Token")
 
-	data, err := ioutil.ReadAll(resp.Body)
+	data, err := io.ReadAll(resp.Body)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -122,7 +122,7 @@ func createUser(t *testing.T, token, userName, userEmail, userPass string) strin
 		t.Fatal(err)
 	}
 
-	data, err := ioutil.ReadAll(resp.Body)
+	data, err := io.ReadAll(resp.Body)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -183,7 +183,7 @@ func createGroup(t *testing.T, token, description, name string) string {
 		t.Fatal(err)
 	}
 
-	data, err := ioutil.ReadAll(resp.Body)
+	data, err := io.ReadAll(resp.Body)
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/connector/ldap/ldap.go b/connector/ldap/ldap.go
index eaee078d..c9447d47 100644
--- a/connector/ldap/ldap.go
+++ b/connector/ldap/ldap.go
@@ -7,8 +7,8 @@ import (
 	"crypto/x509"
 	"encoding/json"
 	"fmt"
-	"io/ioutil"
 	"net"
+	"os"
 
 	"github.com/go-ldap/ldap/v3"
 
@@ -257,7 +257,7 @@ func (c *Config) openConnector(logger log.Logger) (*ldapConnector, error) {
 		data := c.RootCAData
 		if len(data) == 0 {
 			var err error
-			if data, err = ioutil.ReadFile(c.RootCA); err != nil {
+			if data, err = os.ReadFile(c.RootCA); err != nil {
 				return nil, fmt.Errorf("ldap: read ca file: %v", err)
 			}
 		}
diff --git a/connector/ldap/ldap_test.go b/connector/ldap/ldap_test.go
index 9ae45674..83f9f479 100644
--- a/connector/ldap/ldap_test.go
+++ b/connector/ldap/ldap_test.go
@@ -3,7 +3,7 @@ package ldap
 import (
 	"context"
 	"fmt"
-	"io/ioutil"
+	"io"
 	"os"
 	"testing"
 
@@ -555,7 +555,7 @@ func runTests(t *testing.T, connMethod connectionMethod, config *Config, tests [
 	c.BindDN = "cn=admin,dc=example,dc=org"
 	c.BindPW = "admin"
 
-	l := &logrus.Logger{Out: ioutil.Discard, Formatter: &logrus.TextFormatter{}}
+	l := &logrus.Logger{Out: io.Discard, Formatter: &logrus.TextFormatter{}}
 
 	conn, err := c.openConnector(l)
 	if err != nil {
diff --git a/connector/linkedin/linkedin.go b/connector/linkedin/linkedin.go
index 1c8312c1..f79f1c49 100644
--- a/connector/linkedin/linkedin.go
+++ b/connector/linkedin/linkedin.go
@@ -5,7 +5,7 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
-	"io/ioutil"
+	"io"
 	"net/http"
 	"strings"
 
@@ -169,7 +169,7 @@ func (c *linkedInConnector) primaryEmail(ctx context.Context, client *http.Clien
 	}
 	defer resp.Body.Close()
 
-	body, err := ioutil.ReadAll(resp.Body)
+	body, err := io.ReadAll(resp.Body)
 	if err != nil {
 		return email, fmt.Errorf("read body: %v", err)
 	}
@@ -209,7 +209,7 @@ func (c *linkedInConnector) profile(ctx context.Context, client *http.Client) (p
 	defer resp.Body.Close()
 
 	if resp.StatusCode != http.StatusOK {
-		body, err := ioutil.ReadAll(resp.Body)
+		body, err := io.ReadAll(resp.Body)
 		if err != nil {
 			return p, fmt.Errorf("read body: %v", err)
 		}
diff --git a/connector/openshift/openshift.go b/connector/openshift/openshift.go
index f06e8f80..44a03edf 100644
--- a/connector/openshift/openshift.go
+++ b/connector/openshift/openshift.go
@@ -6,9 +6,10 @@ import (
 	"crypto/x509"
 	"encoding/json"
 	"fmt"
-	"io/ioutil"
+	"io"
 	"net"
 	"net/http"
+	"os"
 	"strings"
 	"time"
 
@@ -195,7 +196,7 @@ func (c *openshiftConnector) user(ctx context.Context, client *http.Client) (u u
 	defer resp.Body.Close()
 
 	if resp.StatusCode != http.StatusOK {
-		body, err := ioutil.ReadAll(resp.Body)
+		body, err := io.ReadAll(resp.Body)
 		if err != nil {
 			return u, fmt.Errorf("read body: %v", err)
 		}
@@ -223,7 +224,7 @@ func newHTTPClient(insecureCA bool, rootCA string) (*http.Client, error) {
 		tlsConfig = tls.Config{InsecureSkipVerify: true}
 	} else if rootCA != "" {
 		tlsConfig = tls.Config{RootCAs: x509.NewCertPool()}
-		rootCABytes, err := ioutil.ReadFile(rootCA)
+		rootCABytes, err := os.ReadFile(rootCA)
 		if err != nil {
 			return nil, fmt.Errorf("failed to read root-ca: %v", err)
 		}
diff --git a/connector/saml/saml.go b/connector/saml/saml.go
index 0d52b131..908ec703 100644
--- a/connector/saml/saml.go
+++ b/connector/saml/saml.go
@@ -8,7 +8,7 @@ import (
 	"encoding/pem"
 	"encoding/xml"
 	"fmt"
-	"io/ioutil"
+	"os"
 	"strings"
 	"sync"
 	"time"
@@ -194,7 +194,7 @@ func (c *Config) openConnector(logger log.Logger) (*provider, error) {
 
 		var caData []byte
 		if c.CA != "" {
-			data, err := ioutil.ReadFile(c.CA)
+			data, err := os.ReadFile(c.CA)
 			if err != nil {
 				return nil, fmt.Errorf("read ca file: %v", err)
 			}
diff --git a/connector/saml/saml_test.go b/connector/saml/saml_test.go
index 67d7efb1..95d513ed 100644
--- a/connector/saml/saml_test.go
+++ b/connector/saml/saml_test.go
@@ -5,7 +5,7 @@ import (
 	"encoding/base64"
 	"encoding/pem"
 	"errors"
-	"io/ioutil"
+	"os"
 	"sort"
 	"testing"
 	"time"
@@ -392,7 +392,7 @@ func TestTamperedResponseNameID(t *testing.T) {
 }
 
 func loadCert(ca string) (*x509.Certificate, error) {
-	data, err := ioutil.ReadFile(ca)
+	data, err := os.ReadFile(ca)
 	if err != nil {
 		return nil, err
 	}
@@ -426,7 +426,7 @@ func (r responseTest) run(t *testing.T) {
 		t.Fatal(err)
 	}
 	conn.now = func() time.Time { return now }
-	resp, err := ioutil.ReadFile(r.respFile)
+	resp, err := os.ReadFile(r.respFile)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -456,11 +456,11 @@ func (r responseTest) run(t *testing.T) {
 
 func TestConfigCAData(t *testing.T) {
 	logger := logrus.New()
-	validPEM, err := ioutil.ReadFile("testdata/ca.crt")
+	validPEM, err := os.ReadFile("testdata/ca.crt")
 	if err != nil {
 		t.Fatal(err)
 	}
-	valid2ndPEM, err := ioutil.ReadFile("testdata/okta-ca.pem")
+	valid2ndPEM, err := os.ReadFile("testdata/okta-ca.pem")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -551,7 +551,7 @@ func runVerify(t *testing.T, ca string, resp string, shouldSucceed bool) {
 
 	validator := dsig.NewDefaultValidationContext(s)
 
-	data, err := ioutil.ReadFile(resp)
+	data, err := os.ReadFile(resp)
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/examples/example-app/main.go b/examples/example-app/main.go
index e417c8b2..451bea5b 100644
--- a/examples/example-app/main.go
+++ b/examples/example-app/main.go
@@ -8,7 +8,6 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
-	"io/ioutil"
 	"log"
 	"net"
 	"net/http"
@@ -43,7 +42,7 @@ type app struct {
 // return an HTTP client which trusts the provided root CAs.
 func httpClientForRootCAs(rootCAs string) (*http.Client, error) {
 	tlsConfig := tls.Config{RootCAs: x509.NewCertPool()}
-	rootCABytes, err := ioutil.ReadFile(rootCAs)
+	rootCABytes, err := os.ReadFile(rootCAs)
 	if err != nil {
 		return nil, fmt.Errorf("failed to read root-ca: %v", err)
 	}
diff --git a/examples/grpc-client/client.go b/examples/grpc-client/client.go
index 7b3949a1..c3a69097 100644
--- a/examples/grpc-client/client.go
+++ b/examples/grpc-client/client.go
@@ -6,8 +6,8 @@ import (
 	"crypto/x509"
 	"flag"
 	"fmt"
-	"io/ioutil"
 	"log"
+	"os"
 
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/credentials"
@@ -17,7 +17,7 @@ import (
 
 func newDexClient(hostAndPort, caPath, clientCrt, clientKey string) (api.DexClient, error) {
 	cPool := x509.NewCertPool()
-	caCert, err := ioutil.ReadFile(caPath)
+	caCert, err := os.ReadFile(caPath)
 	if err != nil {
 		return nil, fmt.Errorf("invalid CA crt file: %s", caPath)
 	}
diff --git a/server/deviceflowhandlers_test.go b/server/deviceflowhandlers_test.go
index 3898d4fc..c387af43 100644
--- a/server/deviceflowhandlers_test.go
+++ b/server/deviceflowhandlers_test.go
@@ -4,7 +4,7 @@ import (
 	"bytes"
 	"context"
 	"encoding/json"
-	"io/ioutil"
+	"io"
 	"net/http"
 	"net/http/httptest"
 	"net/url"
@@ -101,7 +101,7 @@ func TestHandleDeviceCode(t *testing.T) {
 				t.Errorf("Unexpected Response Type.  Expected %v got %v", tc.expectedResponseCode, rr.Code)
 			}
 
-			body, err := ioutil.ReadAll(rr.Body)
+			body, err := io.ReadAll(rr.Body)
 			if err != nil {
 				t.Errorf("Could read token response %v", err)
 			}
@@ -541,7 +541,7 @@ func TestDeviceTokenResponse(t *testing.T) {
 				t.Errorf("Unexpected Response Type.  Expected %v got %v", tc.expectedResponseCode, rr.Code)
 			}
 
-			body, err := ioutil.ReadAll(rr.Body)
+			body, err := io.ReadAll(rr.Body)
 			if err != nil {
 				t.Errorf("Could read token response %v", err)
 			}
diff --git a/server/server_test.go b/server/server_test.go
index 682d16a7..6f4bcb81 100644
--- a/server/server_test.go
+++ b/server/server_test.go
@@ -8,7 +8,7 @@ import (
 	"encoding/pem"
 	"errors"
 	"fmt"
-	"io/ioutil"
+	"io"
 	"net/http"
 	"net/http/httptest"
 	"net/http/httputil"
@@ -1588,7 +1588,7 @@ func TestOAuth2DeviceFlow(t *testing.T) {
 					t.Errorf("Could not request device code: %v", err)
 				}
 				defer resp.Body.Close()
-				responseBody, err := ioutil.ReadAll(resp.Body)
+				responseBody, err := io.ReadAll(resp.Body)
 				if err != nil {
 					t.Errorf("Could read device code response %v", err)
 				}
@@ -1615,7 +1615,7 @@ func TestOAuth2DeviceFlow(t *testing.T) {
 					t.Errorf("Error Posting Form: %v", err)
 				}
 				defer resp.Body.Close()
-				responseBody, err = ioutil.ReadAll(resp.Body)
+				responseBody, err = io.ReadAll(resp.Body)
 				if err != nil {
 					t.Errorf("Could read verification response %v", err)
 				}
@@ -1634,7 +1634,7 @@ func TestOAuth2DeviceFlow(t *testing.T) {
 					t.Errorf("Could not request device token: %v", err)
 				}
 				defer resp.Body.Close()
-				responseBody, err = ioutil.ReadAll(resp.Body)
+				responseBody, err = io.ReadAll(resp.Body)
 				if err != nil {
 					t.Errorf("Could read device token response %v", err)
 				}
diff --git a/storage/conformance/gen_jwks.go b/storage/conformance/gen_jwks.go
index 8fb12789..0447e328 100644
--- a/storage/conformance/gen_jwks.go
+++ b/storage/conformance/gen_jwks.go
@@ -12,8 +12,8 @@ import (
 	"encoding/json"
 	"go/format"
 	"io"
-	"io/ioutil"
 	"log"
+	"os"
 	"text/template"
 
 	jose "gopkg.in/square/go-jose.v2"
@@ -104,7 +104,7 @@ func main() {
 	if err != nil {
 		log.Fatalf("gofmt failed: %v", err)
 	}
-	if err := ioutil.WriteFile("jwks.go", out, 0644); err != nil {
+	if err := os.WriteFile("jwks.go", out, 0644); err != nil {
 		log.Fatal(err)
 	}
 }
diff --git a/storage/kubernetes/client.go b/storage/kubernetes/client.go
index 1769bf49..a5a72afa 100644
--- a/storage/kubernetes/client.go
+++ b/storage/kubernetes/client.go
@@ -13,7 +13,6 @@ import (
 	"hash"
 	"hash/fnv"
 	"io"
-	"io/ioutil"
 	"net"
 	"net/http"
 	"os"
@@ -132,7 +131,7 @@ func checkHTTPErr(r *http.Response, validStatusCodes ...int) error {
 		}
 	}
 
-	body, err := ioutil.ReadAll(io.LimitReader(r.Body, 2<<15)) // 64 KiB
+	body, err := io.ReadAll(io.LimitReader(r.Body, 2<<15)) // 64 KiB
 	if err != nil {
 		return fmt.Errorf("read response body: %v", err)
 	}
@@ -156,7 +155,7 @@ func checkHTTPErr(r *http.Response, validStatusCodes ...int) error {
 // Close the response body. The initial request is drained so the connection can
 // be reused.
 func closeResp(r *http.Response) {
-	io.Copy(ioutil.Discard, r.Body)
+	io.Copy(io.Discard, r.Body)
 	r.Body.Close()
 }
 
@@ -312,7 +311,7 @@ func newClient(cluster k8sapi.Cluster, user k8sapi.AuthInfo, namespace string, l
 		if file == "" {
 			return nil, nil
 		}
-		return ioutil.ReadFile(file)
+		return os.ReadFile(file)
 	}
 
 	if caData, err := data(cluster.CertificateAuthorityData, cluster.CertificateAuthority); err != nil {
@@ -379,7 +378,7 @@ func newClient(cluster k8sapi.Cluster, user k8sapi.AuthInfo, namespace string, l
 }
 
 func loadKubeConfig(kubeConfigPath string) (cluster k8sapi.Cluster, user k8sapi.AuthInfo, namespace string, err error) {
-	data, err := ioutil.ReadFile(kubeConfigPath)
+	data, err := os.ReadFile(kubeConfigPath)
 	if err != nil {
 		err = fmt.Errorf("read %s: %v", kubeConfigPath, err)
 		return
@@ -425,7 +424,7 @@ func namespaceFromServiceAccountJWT(s string) (string, error) {
 }
 
 func namespaceFromFile(path string) (string, error) {
-	data, err := ioutil.ReadFile(path)
+	data, err := os.ReadFile(path)
 	if err != nil {
 		return "", err
 	}
@@ -481,7 +480,7 @@ func inClusterConfig() (k8sapi.Cluster, k8sapi.AuthInfo, string, error) {
 		CertificateAuthority: serviceAccountCAPath,
 	}
 
-	token, err := ioutil.ReadFile(serviceAccountTokenPath)
+	token, err := os.ReadFile(serviceAccountTokenPath)
 	if err != nil {
 		return cluster, k8sapi.AuthInfo{}, "", err
 	}
diff --git a/storage/kubernetes/client_test.go b/storage/kubernetes/client_test.go
index bfe2d038..cfd04857 100644
--- a/storage/kubernetes/client_test.go
+++ b/storage/kubernetes/client_test.go
@@ -3,7 +3,6 @@ package kubernetes
 import (
 	"hash"
 	"hash/fnv"
-	"io/ioutil"
 	"net/http"
 	"os"
 	"path/filepath"
@@ -72,7 +71,7 @@ func TestInClusterTransport(t *testing.T) {
 	fpath := filepath.Join(os.TempDir(), "test.in_cluster")
 	defer os.RemoveAll(fpath)
 
-	err = ioutil.WriteFile(fpath, []byte("def"), 0o644)
+	err = os.WriteFile(fpath, []byte("def"), 0o644)
 	require.NoError(t, err)
 
 	tests := []struct {
@@ -136,7 +135,7 @@ func TestGetClusterConfigNamespace(t *testing.T) {
 
 	var namespaceFile string
 	{
-		tmpfile, err := ioutil.TempFile(os.TempDir(), "test-get-cluster-config-namespace")
+		tmpfile, err := os.CreateTemp(os.TempDir(), "test-get-cluster-config-namespace")
 		require.NoError(t, err)
 
 		_, err = tmpfile.Write([]byte("namespace-from-file"))
diff --git a/storage/kubernetes/transport.go b/storage/kubernetes/transport.go
index 984184c7..5d39c27f 100644
--- a/storage/kubernetes/transport.go
+++ b/storage/kubernetes/transport.go
@@ -1,8 +1,8 @@
 package kubernetes
 
 import (
-	"io/ioutil"
 	"net/http"
+	"os"
 	"sync"
 	"time"
 
@@ -103,7 +103,7 @@ func (c *inClusterTransportHelper) UpdateToken() {
 		return
 	}
 
-	token, err := ioutil.ReadFile(c.tokenLocation)
+	token, err := os.ReadFile(c.tokenLocation)
 	if err != nil {
 		return
 	}
diff --git a/storage/sql/config.go b/storage/sql/config.go
index 97ec6cb9..1aedf04c 100644
--- a/storage/sql/config.go
+++ b/storage/sql/config.go
@@ -5,8 +5,8 @@ import (
 	"crypto/x509"
 	"database/sql"
 	"fmt"
-	"io/ioutil"
 	"net"
+	"os"
 	"regexp"
 	"strconv"
 	"strings"
@@ -320,7 +320,7 @@ func (s *MySQL) makeTLSConfig() error {
 	cfg := &tls.Config{}
 	if s.SSL.CAFile != "" {
 		rootCertPool := x509.NewCertPool()
-		pem, err := ioutil.ReadFile(s.SSL.CAFile)
+		pem, err := os.ReadFile(s.SSL.CAFile)
 		if err != nil {
 			return err
 		}
-- 
GitLab