diff --git a/.golangci.yaml b/.golangci.yaml
index 682abf3..cf83e85 100644
--- a/.golangci.yaml
+++ b/.golangci.yaml
@@ -130,6 +130,8 @@ issues:
         - dupl
         - gosec
         - lll
+        - goconst
+        - dogsled
 
 run:
   timeout: 5m
diff --git a/container_registry.go b/container_registry.go
new file mode 100644
index 0000000..00d7ba8
--- /dev/null
+++ b/container_registry.go
@@ -0,0 +1,425 @@
+package govultr
+
+import (
+	"context"
+	"fmt"
+	"net/http"
+
+	"github.com/google/go-querystring/query"
+)
+
+const vcrPath = "/v2/registry"
+const vcrListPath = "/v2/registries"
+
+// ContainerRegistryService is the interface to interact with the container
+// registry endpoints on the Vultr API.  Link :
+// https://www.vultr.com/api/#tag/Container-Registry
+type ContainerRegistryService interface {
+	Create(ctx context.Context, createReq *ContainerRegistryReq) (*ContainerRegistry, *http.Response, error)
+	Get(ctx context.Context, vcrID string) (*ContainerRegistry, *http.Response, error)
+	Update(ctx context.Context, vcrID string, updateReq *ContainerRegistryUpdateReq) (*ContainerRegistry, *http.Response, error)
+	Delete(ctx context.Context, vcrID string) error
+	List(ctx context.Context, options *ListOptions) ([]ContainerRegistry, *Meta, *http.Response, error)
+	ListRepositories(ctx context.Context, vcrID string, options *ListOptions) ([]ContainerRegistryRepo, *Meta, *http.Response, error)
+	GetRepository(ctx context.Context, vcrID, imageName string) (*ContainerRegistryRepo, *http.Response, error)
+	UpdateRepository(ctx context.Context, vcrID, imageName string, updateReq *ContainerRegistryRepoUpdateReq) (*ContainerRegistryRepo, *http.Response, error) //nolint:lll
+	DeleteRepository(ctx context.Context, vcrID, imageName string) error
+	CreateDockerCredentials(ctx context.Context, vcrID string, createOptions *DockerCredentialsOpt) (*ContainerRegistryDockerCredentials, *http.Response, error) //nolint:lll
+	ListRegions(ctx context.Context, options *ListOptions) ([]ContainerRegistryRegion, *Meta, *http.Response, error)
+	ListPlans(ctx context.Context) (*ContainerRegistryPlans, *http.Response, error)
+}
+
+// ContainerRegistryServiceHandler handles interaction between the container
+// registry service and the Vultr API.
+type ContainerRegistryServiceHandler struct {
+	client *Client
+}
+
+// ContainerRegistry represents a Vultr container registry subscription.
+type ContainerRegistry struct {
+	ID          string                    `json:"id"`
+	Name        string                    `json:"name"`
+	URN         string                    `json:"urn"`
+	Storage     ContainerRegistryStorage  `json:"storage"`
+	DateCreated string                    `json:"date_created"`
+	Public      bool                      `json:"public"`
+	RootUser    ContainerRegistryUser     `json:"root_user"`
+	Metadata    ContainerRegistryMetadata `json:"metadata"`
+}
+
+type containerRegistries struct {
+	ContainerRegistries []ContainerRegistry `json:"registries"`
+	Meta                *Meta               `json:"meta"`
+}
+
+// ContainerRegistryStorage represents the storage usage and limit
+type ContainerRegistryStorage struct {
+	Used    ContainerRegistryStorageCount `json:"used"`
+	Allowed ContainerRegistryStorageCount `json:"allowed"`
+}
+
+// ContainerRegistryStorageCount represents the different storage usage counts
+type ContainerRegistryStorageCount struct {
+	Bytes        float32 `json:"bytes"`
+	MegaBytes    float32 `json:"mb"`
+	GigaBytes    float32 `json:"gb"`
+	TeraBytes    float32 `json:"tb"`
+	DateModified string  `json:"updated_at"`
+}
+
+// ContainerRegistryUser contains the user data
+type ContainerRegistryUser struct {
+	ID           int    `json:"id"`
+	UserName     string `json:"username"`
+	Password     string `json:"password"`
+	Root         bool   `json:"root"`
+	DateCreated  string `json:"added_at"`
+	DateModified string `json:"updated_at"`
+}
+
+// ContainerRegistryMetadata contains the meta data for the registry
+type ContainerRegistryMetadata struct {
+	Region       ContainerRegistryRegion       `json:"region"`
+	Subscription ContainerRegistrySubscription `json:"subscription"`
+}
+
+// ContainerRegistrySubscription contains the subscription information for the
+// registry
+type ContainerRegistrySubscription struct {
+	Billing ContainerRegistrySubscriptionBilling `json:"billing"`
+}
+
+// ContainerRegistrySubscriptionBilling represents the subscription billing
+// data on the registry
+type ContainerRegistrySubscriptionBilling struct {
+	MonthlyPrice   float32 `json:"monthly_price"`
+	PendingCharges float32 `json:"pending_charges"`
+}
+
+// ContainerRegistryReq represents the data used to create a registry
+type ContainerRegistryReq struct {
+	Name   string `json:"name"`
+	Public bool   `json:"public"`
+	Region string `json:"region"`
+	Plan   string `json:"plan"`
+}
+
+// ContainerRegistryUpdateReq represents the data used to update a registry
+type ContainerRegistryUpdateReq struct {
+	Public *bool   `json:"public"`
+	Plan   *string `json:"plan"`
+}
+
+// ContainerRegistryRepo represents the data of a registry repository
+type ContainerRegistryRepo struct {
+	Name          string `json:"name"`
+	Image         string `json:"image"`
+	Description   string `json:"description"`
+	DateCreated   string `json:"added_at"`
+	DateModified  string `json:"updated_at"`
+	PullCount     int    `json:"pull_count"`
+	ArtifactCount int    `json:"artifact_count"`
+}
+
+type containerRegistryRepos struct {
+	Repositories []ContainerRegistryRepo `json:"repositories"`
+	Meta         *Meta                   `json:"meta"`
+}
+
+// ContainerRegistryRepoUpdateReq is the data to update a registry repository
+type ContainerRegistryRepoUpdateReq struct {
+	Description string `json:"description"`
+}
+
+// DockerCredentialsOpt contains the options used to create Docker credentials
+type DockerCredentialsOpt struct {
+	ExpirySeconds *int
+	WriteAccess   *bool
+}
+
+// ContainerRegistryDockerCredentials represents the byte array of character
+// data returned after creating a Docker credential
+type ContainerRegistryDockerCredentials []byte
+
+// UnmarshalJSON is a custom unmarshal function for
+// ContainerRegistryDockerCredentials
+func (c *ContainerRegistryDockerCredentials) UnmarshalJSON(b []byte) error {
+	*c = b
+	return nil
+}
+
+// String converts the ContainerRegistryDockerCredentials to a string
+func (c *ContainerRegistryDockerCredentials) String() string {
+	return string(*c)
+}
+
+// ContainerRegistryRegion represents the region data
+type ContainerRegistryRegion struct {
+	ID           int                               `json:"id"`
+	Name         string                            `json:"name"`
+	URN          string                            `json:"urn"`
+	BaseURL      string                            `json:"base_url"`
+	Public       bool                              `json:"public"`
+	DateCreated  string                            `json:"added_at"`
+	DateModified string                            `json:"updated_at"`
+	DataCenter   ContainerRegistryRegionDataCenter `json:"data_center"`
+}
+
+// ContainerRegistryRegionDataCenter is the datacenter info for a given region
+type ContainerRegistryRegionDataCenter struct {
+	ID          int    `json:"id"`
+	Name        string `json:"name"`
+	SiteCode    string `json:"site_code"`
+	Region      string `json:"region"`
+	Country     string `json:"country"`
+	Continent   string `json:"continent"`
+	Description string `json:"description"`
+	Airport     string `json:"airport"`
+}
+
+type containerRegistryRegions struct {
+	Regions []ContainerRegistryRegion `json:"regions"`
+	Meta    *Meta                     `json:"meta"`
+}
+
+// ContainerRegistryPlans contains all plan types
+type ContainerRegistryPlans struct {
+	Plans ContainerRegistryPlanTypes `json:"plans"`
+}
+
+// ContainerRegistryPlanTypes represent the different plan types
+type ContainerRegistryPlanTypes struct {
+	StartUp    ContainerRegistryPlan `json:"start_up"`
+	Business   ContainerRegistryPlan `json:"business"`
+	Premium    ContainerRegistryPlan `json:"premium"`
+	Enterprise ContainerRegistryPlan `json:"enterprise"`
+}
+
+// ContainerRegistryPlan represent the plan data
+type ContainerRegistryPlan struct {
+	VanityName   string `json:"vanity_name"`
+	MaxStorageMB int    `json:"max_storage_mb"`
+	MonthlyPrice int    `json:"monthly_price"`
+}
+
+// Get retrieves a contrainer registry by ID
+func (h *ContainerRegistryServiceHandler) Get(ctx context.Context, id string) (*ContainerRegistry, *http.Response, error) {
+	req, errReq := h.client.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s/%s", vcrPath, id), nil)
+	if errReq != nil {
+		return nil, nil, errReq
+	}
+
+	vcr := new(ContainerRegistry)
+	resp, errResp := h.client.DoWithContext(ctx, req, &vcr)
+	if errResp != nil {
+		return nil, resp, errResp
+	}
+
+	return vcr, resp, nil
+}
+
+// List retrieves the list of all container registries
+func (h *ContainerRegistryServiceHandler) List(ctx context.Context, options *ListOptions) ([]ContainerRegistry, *Meta, *http.Response, error) { //nolint:lll,dupl
+	req, errReq := h.client.NewRequest(ctx, http.MethodGet, vcrListPath, nil)
+	if errReq != nil {
+		return nil, nil, nil, errReq
+	}
+
+	qStrings, errQ := query.Values(options)
+	if errQ != nil {
+		return nil, nil, nil, errQ
+	}
+
+	req.URL.RawQuery = qStrings.Encode()
+
+	vcrs := new(containerRegistries)
+	resp, errResp := h.client.DoWithContext(ctx, req, &vcrs)
+	if errResp != nil {
+		return nil, nil, resp, errResp
+	}
+
+	return vcrs.ContainerRegistries, vcrs.Meta, resp, nil
+}
+
+// Create creates a container registry
+func (h *ContainerRegistryServiceHandler) Create(ctx context.Context, createReq *ContainerRegistryReq) (*ContainerRegistry, *http.Response, error) { //nolint:lll
+	req, errReq := h.client.NewRequest(ctx, http.MethodPost, vcrPath, createReq)
+	if errReq != nil {
+		return nil, nil, errReq
+	}
+
+	vcr := new(ContainerRegistry)
+	resp, errResp := h.client.DoWithContext(ctx, req, &vcr)
+	if errResp != nil {
+		return nil, resp, errResp
+	}
+
+	return vcr, resp, nil
+}
+
+// Update will update an existing container registry
+func (h *ContainerRegistryServiceHandler) Update(ctx context.Context, vcrID string, updateReq *ContainerRegistryUpdateReq) (*ContainerRegistry, *http.Response, error) { //nolint:lll
+	req, errReq := h.client.NewRequest(ctx, http.MethodPut, fmt.Sprintf("%s/%s", vcrPath, vcrID), updateReq)
+	if errReq != nil {
+		return nil, nil, errReq
+	}
+
+	vcr := new(ContainerRegistry)
+	resp, errResp := h.client.DoWithContext(ctx, req, &vcr)
+	if errResp != nil {
+		return nil, resp, errResp
+	}
+
+	return vcr, resp, nil
+}
+
+// Delete will delete a container registry
+func (h *ContainerRegistryServiceHandler) Delete(ctx context.Context, vcrID string) error {
+	req, errReq := h.client.NewRequest(ctx, http.MethodDelete, fmt.Sprintf("%s/%s", vcrPath, vcrID), nil)
+	if errReq != nil {
+		return errReq
+	}
+
+	_, errResp := h.client.DoWithContext(ctx, req, nil)
+	if errResp != nil {
+		return errResp
+	}
+
+	return nil
+}
+
+// ListRepositories will get a list of the repositories for a existing
+// container registry
+func (h *ContainerRegistryServiceHandler) ListRepositories(ctx context.Context, vcrID string, options *ListOptions) ([]ContainerRegistryRepo, *Meta, *http.Response, error) { //nolint:lll,dupl
+	req, errReq := h.client.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s/%s/repositories", vcrPath, vcrID), nil)
+	if errReq != nil {
+		return nil, nil, nil, errReq
+	}
+
+	qStrings, errQ := query.Values(options)
+	if errQ != nil {
+		return nil, nil, nil, errQ
+	}
+
+	req.URL.RawQuery = qStrings.Encode()
+
+	vcrRepos := new(containerRegistryRepos)
+	resp, errResp := h.client.DoWithContext(ctx, req, &vcrRepos)
+	if errResp != nil {
+		return nil, nil, resp, errResp
+	}
+
+	return vcrRepos.Repositories, vcrRepos.Meta, resp, nil
+}
+
+// GetRepository will return an existing repository of the requested registry
+// ID and image name
+func (h *ContainerRegistryServiceHandler) GetRepository(ctx context.Context, vcrID, imageName string) (*ContainerRegistryRepo, *http.Response, error) { //nolint:lll
+	req, errReq := h.client.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s/%s/repository/%s", vcrPath, vcrID, imageName), nil)
+	if errReq != nil {
+		return nil, nil, errReq
+	}
+
+	vcrRepo := new(ContainerRegistryRepo)
+	resp, errResp := h.client.DoWithContext(ctx, req, &vcrRepo)
+	if errResp != nil {
+		return nil, resp, errResp
+	}
+
+	return vcrRepo, resp, nil
+}
+
+// UpdateRepository allows updating the repository with the specified registry
+// ID and image name
+func (h *ContainerRegistryServiceHandler) UpdateRepository(ctx context.Context, vcrID, imageName string, updateReq *ContainerRegistryRepoUpdateReq) (*ContainerRegistryRepo, *http.Response, error) { //nolint: lll
+	req, errReq := h.client.NewRequest(ctx, http.MethodPut, fmt.Sprintf("%s/%s/repository/%s", vcrPath, vcrID, imageName), updateReq)
+	if errReq != nil {
+		return nil, nil, errReq
+	}
+
+	vcrRepo := new(ContainerRegistryRepo)
+	resp, errResp := h.client.DoWithContext(ctx, req, &vcrRepo)
+	if errResp != nil {
+		return nil, resp, errResp
+	}
+
+	return vcrRepo, resp, nil
+}
+
+// DeleteRepository remove a repository from the container registry
+func (h *ContainerRegistryServiceHandler) DeleteRepository(ctx context.Context, vcrID, imageName string) error {
+	req, errReq := h.client.NewRequest(ctx, http.MethodDelete, fmt.Sprintf("%s/%s/repository/%s", vcrPath, vcrID, imageName), nil)
+	if errReq != nil {
+		return errReq
+	}
+
+	_, errResp := h.client.DoWithContext(ctx, req, nil)
+	if errResp != nil {
+		return errResp
+	}
+
+	return nil
+}
+
+// CreateDockerCredentials will create new Docker credentials used by the
+// Docker CLI
+func (h *ContainerRegistryServiceHandler) CreateDockerCredentials(ctx context.Context, vcrID string, createOptions *DockerCredentialsOpt) (*ContainerRegistryDockerCredentials, *http.Response, error) { //nolint:lll
+	url := fmt.Sprintf("%s/%s/docker-credentials", vcrPath, vcrID)
+	req, errReq := h.client.NewRequest(ctx, http.MethodOptions, url, nil)
+	if errReq != nil {
+		return nil, nil, errReq
+	}
+
+	queryParam := req.URL.Query()
+	if createOptions.ExpirySeconds != nil {
+		queryParam.Add("expiry_seconds", fmt.Sprintf("%d", createOptions.ExpirySeconds))
+	}
+
+	if createOptions.WriteAccess != nil {
+		queryParam.Add("read_write", fmt.Sprintf("%t", *createOptions.WriteAccess))
+	}
+
+	req.URL.RawQuery = queryParam.Encode()
+
+	creds := new(ContainerRegistryDockerCredentials)
+	resp, errResp := h.client.DoWithContext(ctx, req, &creds)
+	if errResp != nil {
+		return nil, nil, errResp
+	}
+
+	return creds, resp, nil
+}
+
+// ListRegions will return a list of regions relevant to the container registry
+// API operations
+func (h *ContainerRegistryServiceHandler) ListRegions(ctx context.Context, options *ListOptions) ([]ContainerRegistryRegion, *Meta, *http.Response, error) { //nolint:lll
+	req, errReq := h.client.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s/region/list", vcrPath), nil)
+	if errReq != nil {
+		return nil, nil, nil, errReq
+	}
+
+	vcrRegions := new(containerRegistryRegions)
+	resp, errResp := h.client.DoWithContext(ctx, req, &vcrRegions)
+	if errResp != nil {
+		return nil, nil, resp, errResp
+	}
+
+	return vcrRegions.Regions, vcrRegions.Meta, resp, nil
+}
+
+// ListPlans returns a list of plans relevant to the container registry
+// offerings
+func (h *ContainerRegistryServiceHandler) ListPlans(ctx context.Context) (*ContainerRegistryPlans, *http.Response, error) {
+	req, errReq := h.client.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s/plan/list", vcrPath), nil)
+	if errReq != nil {
+		return nil, nil, errReq
+	}
+
+	vcrPlans := new(ContainerRegistryPlans)
+	resp, errResp := h.client.DoWithContext(ctx, req, &vcrPlans)
+	if errResp != nil {
+		return nil, resp, errResp
+	}
+
+	return vcrPlans, resp, nil
+}
diff --git a/container_registry_test.go b/container_registry_test.go
new file mode 100644
index 0000000..75d1537
--- /dev/null
+++ b/container_registry_test.go
@@ -0,0 +1,1095 @@
+package govultr
+
+import (
+	"context"
+	"fmt"
+	"net/http"
+	"reflect"
+	"testing"
+	"time"
+)
+
+func TestVCRServiceHandler_Create(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc(vcrPath, func(writer http.ResponseWriter, request *http.Request) {
+		response := `{
+    "id": "e1d6be16-2b0c-4d76-a3eb-f28bf6ea5fe0",
+    "name": "govultrtest",
+    "region": "sjc",
+    "urn": "sjc.vultrcr.com/govultrtest",
+    "storage": {
+        "used": {
+            "updated_at": "2023-11-09 13:37:12",
+            "bytes": 0,
+            "mb": 0,
+            "gb": 0,
+            "tb": 0
+        },
+        "allowed": {
+            "bytes": 21474836480,
+            "mb": 20480,
+            "gb": 20,
+            "tb": 0.02
+        }
+    },
+    "date_created": "2023-11-09 13:37:12",
+    "public": false,
+    "root_user": {
+        "id": 635,
+        "username": "e1d6be16-2b0c-4d76-a3eb-f28bf6ea5fe0",
+        "password": "5dEr33smkSYauMmRWusNFk9HpweL5CevpnFr",
+        "root": true,
+        "added_at": "2023-11-09 13:37:12",
+        "updated_at": "2023-11-09 13:37:12"
+    },
+    "metadata": {
+        "region": {
+            "id": 3,
+            "name": "sjc",
+            "urn": "sjc.vultrcr.com",
+            "base_url": "https://sjc.vultrcr.com",
+            "public": true,
+            "added_at": "2023-09-14 09:09:16",
+            "updated_at": "2023-09-14 09:09:16",
+            "data_center": {
+                "id": 12,
+                "name": "Silicon Valley",
+                "site_code": "SJC2",
+                "region": "West",
+                "country": "US",
+                "continent": "North America",
+                "description": "Silicon Valley, California",
+                "airport": "SJC"
+            }
+        },
+        "subscription": {
+            "billing": {
+                "monthly_price": 5,
+                "pending_charges": 0
+            }
+        }
+    }
+}`
+		fmt.Fprint(writer, response)
+	})
+
+	req := &ContainerRegistryReq{
+		Name:   "govultrtest",
+		Public: false,
+		Region: "sjc",
+		Plan:   "business",
+	}
+
+	vcr, _, err := client.ContainerRegistry.Create(ctx, req)
+	if err != nil {
+		t.Errorf("ContainerRegistry.Create returned %v", err)
+	}
+
+	expected := &ContainerRegistry{
+		ID:   "e1d6be16-2b0c-4d76-a3eb-f28bf6ea5fe0",
+		Name: "govultrtest",
+		URN:  "sjc.vultrcr.com/govultrtest",
+		Storage: ContainerRegistryStorage{
+			Used: ContainerRegistryStorageCount{
+				Bytes:        0,
+				MegaBytes:    0,
+				GigaBytes:    0,
+				TeraBytes:    0,
+				DateModified: "2023-11-09 13:37:12",
+			},
+			Allowed: ContainerRegistryStorageCount{
+				Bytes:        21474836480,
+				MegaBytes:    20480,
+				GigaBytes:    20,
+				TeraBytes:    0.02,
+				DateModified: "",
+			},
+		},
+		DateCreated: "2023-11-09 13:37:12",
+		Public:      false,
+		RootUser: ContainerRegistryUser{
+			ID:           635,
+			UserName:     "e1d6be16-2b0c-4d76-a3eb-f28bf6ea5fe0",
+			Password:     "5dEr33smkSYauMmRWusNFk9HpweL5CevpnFr",
+			Root:         true,
+			DateCreated:  "2023-11-09 13:37:12",
+			DateModified: "2023-11-09 13:37:12",
+		},
+		Metadata: ContainerRegistryMetadata{
+			Region: ContainerRegistryRegion{
+				ID:           3,
+				Name:         "sjc",
+				URN:          "sjc.vultrcr.com",
+				BaseURL:      "https://sjc.vultrcr.com",
+				Public:       true,
+				DateCreated:  "2023-09-14 09:09:16",
+				DateModified: "2023-09-14 09:09:16",
+				DataCenter: ContainerRegistryRegionDataCenter{
+					ID:          12,
+					Name:        "Silicon Valley",
+					SiteCode:    "SJC2",
+					Region:      "West",
+					Country:     "US",
+					Continent:   "North America",
+					Description: "Silicon Valley, California",
+					Airport:     "SJC",
+				},
+			},
+			Subscription: ContainerRegistrySubscription{
+				Billing: ContainerRegistrySubscriptionBilling{
+					MonthlyPrice:   5,
+					PendingCharges: 0,
+				},
+			},
+		},
+	}
+
+	if !reflect.DeepEqual(vcr, expected) {
+		t.Errorf("ContainerRegistry.Create returned %+v, expected %+v", vcr, expected)
+	}
+
+	c, can := context.WithTimeout(ctx, 1*time.Microsecond)
+	defer can()
+	_, _, err = client.ContainerRegistry.Create(c, req)
+	if err == nil {
+		t.Error("ContainerRegistry.Create returned nil")
+	}
+}
+
+func TestVCRServiceHandler_List(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc(vcrListPath, func(writer http.ResponseWriter, request *http.Request) {
+		response := `{
+    "registries": [
+        {
+            "id": "297cfaff-cb5a-4b7c-ac2e-407fcdbd643e",
+            "name": "govultrtest",
+            "region": "sjc",
+            "urn": "sjc.vultrcr.com/govultrtest",
+            "storage": {
+                "used": {
+                    "updated_at": "2023-11-09 23:09:24",
+                    "bytes": 0,
+                    "mb": 0,
+                    "gb": 0,
+                    "tb": 0
+                },
+                "allowed": {
+                    "bytes": 21474836480,
+                    "mb": 20480,
+                    "gb": 20,
+                    "tb": 0.02
+                }
+            },
+            "date_created": "2023-11-09 17:32:17",
+            "public": true,
+            "root_user": {
+                "id": 639,
+                "username": "297cfaff-cb5a-4b7c-ac2e-407fcdbd643e",
+                "password": "Je2S9SkjrowwMtP933SSaxZG4BPR7D8Au33P",
+                "root": true,
+                "added_at": "2023-11-09 17:32:17",
+                "updated_at": "2023-11-09 17:32:17"
+            },
+            "metadata": {
+                "region": {
+                    "id": 3,
+                    "name": "sjc",
+                    "urn": "sjc.vultrcr.com",
+                    "base_url": "https://sjc.vultrcr.com",
+                    "public": true,
+                    "added_at": "2023-09-14 09:09:16",
+                    "updated_at": "2023-09-14 09:09:16",
+                    "data_center": {
+                        "id": 12,
+                        "name": "Silicon Valley",
+                        "site_code": "SJC2",
+                        "region": "West",
+                        "country": "US",
+                        "continent": "North America",
+                        "description": "Silicon Valley, California",
+                        "airport": "SJC"
+                    }
+                },
+                "subscription": {
+                    "billing": {
+                        "monthly_price": 5,
+                        "pending_charges": 0.01
+                    }
+                }
+            }
+        },
+        {
+            "id": "c247a5d7-b3e1-468c-bcba-c23d0716ffc8",
+            "name": "govultrtest2",
+            "region": "sjc",
+            "urn": "sjc.vultrcr.com/govultrtest2",
+            "storage": {
+                "used": {
+                    "updated_at": "2023-11-09 23:09:24",
+                    "bytes": 0,
+                    "mb": 0,
+                    "gb": 0,
+                    "tb": 0
+                },
+                "allowed": {
+                    "bytes": 21474836480,
+                    "mb": 20480,
+                    "gb": 20,
+                    "tb": 0.02
+                }
+            },
+            "date_created": "2023-11-09 17:33:13",
+            "public": true,
+            "root_user": {
+                "id": 640,
+                "username": "c247a5d7-b3e1-468c-bcba-c23d0716ffc8",
+                "password": "c9NhkeH7aeF7zj3cRFHbMFizxEik4rhWYGdW",
+                "root": true,
+                "added_at": "2023-11-09 17:33:13",
+                "updated_at": "2023-11-09 17:33:13"
+            },
+            "metadata": {
+                "region": {
+                    "id": 3,
+                    "name": "sjc",
+                    "urn": "sjc.vultrcr.com",
+                    "base_url": "https://sjc.vultrcr.com",
+                    "public": true,
+                    "added_at": "2023-09-14 09:09:16",
+                    "updated_at": "2023-09-14 09:09:16",
+                    "data_center": {
+                        "id": 12,
+                        "name": "Silicon Valley",
+                        "site_code": "SJC2",
+                        "region": "West",
+                        "country": "US",
+                        "continent": "North America",
+                        "description": "Silicon Valley, California",
+                        "airport": "SJC"
+                    }
+                },
+                "subscription": {
+                    "billing": {
+                        "monthly_price": 5,
+                        "pending_charges": 0.01
+                    }
+                }
+            }
+        }
+    ],
+    "meta": {
+        "total": 2,
+        "links": {
+            "next": "",
+            "prev": ""
+        }
+    }
+}`
+		fmt.Fprint(writer, response)
+	})
+
+	vcrs, meta, _, err := client.ContainerRegistry.List(ctx, nil)
+	if err != nil {
+		t.Errorf("ContainerRegistry.List returned %+v", err)
+	}
+
+	expected := []ContainerRegistry{
+		{
+			ID:   "297cfaff-cb5a-4b7c-ac2e-407fcdbd643e",
+			Name: "govultrtest",
+			URN:  "sjc.vultrcr.com/govultrtest",
+			Storage: ContainerRegistryStorage{
+				Used: ContainerRegistryStorageCount{
+					Bytes:        0,
+					MegaBytes:    0,
+					GigaBytes:    0,
+					TeraBytes:    0,
+					DateModified: "2023-11-09 23:09:24",
+				},
+				Allowed: ContainerRegistryStorageCount{
+					Bytes:        21474836480,
+					MegaBytes:    20480,
+					GigaBytes:    20,
+					TeraBytes:    0.02,
+					DateModified: "",
+				},
+			},
+			DateCreated: "2023-11-09 17:32:17",
+			Public:      true,
+			RootUser: ContainerRegistryUser{
+				ID:           639,
+				UserName:     "297cfaff-cb5a-4b7c-ac2e-407fcdbd643e",
+				Password:     "Je2S9SkjrowwMtP933SSaxZG4BPR7D8Au33P",
+				Root:         true,
+				DateCreated:  "2023-11-09 17:32:17",
+				DateModified: "2023-11-09 17:32:17",
+			},
+			Metadata: ContainerRegistryMetadata{
+				Region: ContainerRegistryRegion{
+					ID:           3,
+					Name:         "sjc",
+					URN:          "sjc.vultrcr.com",
+					BaseURL:      "https://sjc.vultrcr.com",
+					Public:       true,
+					DateCreated:  "2023-09-14 09:09:16",
+					DateModified: "2023-09-14 09:09:16",
+					DataCenter: ContainerRegistryRegionDataCenter{
+						ID:          12,
+						Name:        "Silicon Valley",
+						SiteCode:    "SJC2",
+						Region:      "West",
+						Country:     "US",
+						Continent:   "North America",
+						Description: "Silicon Valley, California",
+						Airport:     "SJC",
+					},
+				},
+				Subscription: ContainerRegistrySubscription{
+					Billing: ContainerRegistrySubscriptionBilling{
+						MonthlyPrice:   5,
+						PendingCharges: 0.01,
+					},
+				},
+			},
+		},
+		{
+			ID:   "c247a5d7-b3e1-468c-bcba-c23d0716ffc8",
+			Name: "govultrtest2",
+			URN:  "sjc.vultrcr.com/govultrtest2",
+			Storage: ContainerRegistryStorage{
+				Used: ContainerRegistryStorageCount{
+					Bytes:        0,
+					MegaBytes:    0,
+					GigaBytes:    0,
+					TeraBytes:    0,
+					DateModified: "2023-11-09 23:09:24",
+				},
+				Allowed: ContainerRegistryStorageCount{
+					Bytes:        21474836480,
+					MegaBytes:    20480,
+					GigaBytes:    20,
+					TeraBytes:    0.02,
+					DateModified: "",
+				},
+			},
+			DateCreated: "2023-11-09 17:33:13",
+			Public:      true,
+			RootUser: ContainerRegistryUser{
+				ID:           640,
+				UserName:     "c247a5d7-b3e1-468c-bcba-c23d0716ffc8",
+				Password:     "c9NhkeH7aeF7zj3cRFHbMFizxEik4rhWYGdW",
+				Root:         true,
+				DateCreated:  "2023-11-09 17:33:13",
+				DateModified: "2023-11-09 17:33:13",
+			},
+			Metadata: ContainerRegistryMetadata{
+				Region: ContainerRegistryRegion{
+					ID:           3,
+					Name:         "sjc",
+					URN:          "sjc.vultrcr.com",
+					BaseURL:      "https://sjc.vultrcr.com",
+					Public:       true,
+					DateCreated:  "2023-09-14 09:09:16",
+					DateModified: "2023-09-14 09:09:16",
+					DataCenter: ContainerRegistryRegionDataCenter{
+						ID:          12,
+						Name:        "Silicon Valley",
+						SiteCode:    "SJC2",
+						Region:      "West",
+						Country:     "US",
+						Continent:   "North America",
+						Description: "Silicon Valley, California",
+						Airport:     "SJC",
+					},
+				},
+				Subscription: ContainerRegistrySubscription{
+					Billing: ContainerRegistrySubscriptionBilling{
+						MonthlyPrice:   5,
+						PendingCharges: 0.01,
+					},
+				},
+			},
+		},
+	}
+
+	expectedMeta := &Meta{
+		Total: 2,
+		Links: &Links{
+			Next: "",
+			Prev: "",
+		},
+	}
+
+	if !reflect.DeepEqual(vcrs, expected) {
+		t.Errorf("ContainerRegistry.List returned %+v, expected %+v", vcrs, expected)
+	}
+
+	if !reflect.DeepEqual(meta, expectedMeta) {
+		t.Errorf("ContainerRegistry.List meta returned %+v, expected %+v", meta, expectedMeta)
+	}
+
+	c, can := context.WithTimeout(ctx, 1*time.Microsecond)
+	defer can()
+	if _, _, _, err = client.ContainerRegistry.List(c, nil); err == nil {
+		t.Error("ContainerRegistry.List returned nil")
+	}
+}
+
+func TestVCRServiceHandler_Get(t *testing.T) {
+	setup()
+	defer teardown()
+
+	vcrID := "e1d6be16-2b0c-4d76-a3eb-f28bf6ea5fe0"
+
+	mux.HandleFunc(fmt.Sprintf("%s/%s", vcrPath, vcrID), func(writer http.ResponseWriter, request *http.Request) {
+		response := `{
+    "id": "e1d6be16-2b0c-4d76-a3eb-f28bf6ea5fe0",
+    "name": "govultrtest",
+    "region": "sjc",
+    "urn": "sjc.vultrcr.com/govultrtest",
+    "storage": {
+        "used": {
+            "updated_at": "2023-11-09 13:37:12",
+            "bytes": 0,
+            "mb": 0,
+            "gb": 0,
+            "tb": 0
+        },
+        "allowed": {
+            "bytes": 21474836480,
+            "mb": 20480,
+            "gb": 20,
+            "tb": 0.02
+        }
+    },
+    "date_created": "2023-11-09 13:37:12",
+    "public": false,
+    "root_user": {
+        "id": 635,
+        "username": "e1d6be16-2b0c-4d76-a3eb-f28bf6ea5fe0",
+        "password": "5dEr33smkSYauMmRWusNFk9HpweL5CevpnFr",
+        "root": true,
+        "added_at": "2023-11-09 13:37:12",
+        "updated_at": "2023-11-09 13:37:12"
+    },
+    "metadata": {
+        "region": {
+            "id": 3,
+            "name": "sjc",
+            "urn": "sjc.vultrcr.com",
+            "base_url": "https://sjc.vultrcr.com",
+            "public": true,
+            "added_at": "2023-09-14 09:09:16",
+            "updated_at": "2023-09-14 09:09:16",
+            "data_center": {
+                "id": 12,
+                "name": "Silicon Valley",
+                "site_code": "SJC2",
+                "region": "West",
+                "country": "US",
+                "continent": "North America",
+                "description": "Silicon Valley, California",
+                "airport": "SJC"
+            }
+        },
+        "subscription": {
+            "billing": {
+                "monthly_price": 5,
+                "pending_charges": 0
+            }
+        }
+    }
+}`
+		fmt.Fprint(writer, response)
+	})
+
+	vcr, _, err := client.ContainerRegistry.Get(ctx, vcrID)
+	if err != nil {
+		t.Errorf("ContainerRegistry.Get returned %v", err)
+	}
+
+	expected := &ContainerRegistry{
+		ID:   "e1d6be16-2b0c-4d76-a3eb-f28bf6ea5fe0",
+		Name: "govultrtest",
+		URN:  "sjc.vultrcr.com/govultrtest",
+		Storage: ContainerRegistryStorage{
+			Used: ContainerRegistryStorageCount{
+				Bytes:        0,
+				MegaBytes:    0,
+				GigaBytes:    0,
+				TeraBytes:    0,
+				DateModified: "2023-11-09 13:37:12",
+			},
+			Allowed: ContainerRegistryStorageCount{
+				Bytes:        21474836480,
+				MegaBytes:    20480,
+				GigaBytes:    20,
+				TeraBytes:    0.02,
+				DateModified: "",
+			},
+		},
+		DateCreated: "2023-11-09 13:37:12",
+		Public:      false,
+		RootUser: ContainerRegistryUser{
+			ID:           635,
+			UserName:     "e1d6be16-2b0c-4d76-a3eb-f28bf6ea5fe0",
+			Password:     "5dEr33smkSYauMmRWusNFk9HpweL5CevpnFr",
+			Root:         true,
+			DateCreated:  "2023-11-09 13:37:12",
+			DateModified: "2023-11-09 13:37:12",
+		},
+		Metadata: ContainerRegistryMetadata{
+			Region: ContainerRegistryRegion{
+				ID:           3,
+				Name:         "sjc",
+				URN:          "sjc.vultrcr.com",
+				BaseURL:      "https://sjc.vultrcr.com",
+				Public:       true,
+				DateCreated:  "2023-09-14 09:09:16",
+				DateModified: "2023-09-14 09:09:16",
+				DataCenter: ContainerRegistryRegionDataCenter{
+					ID:          12,
+					Name:        "Silicon Valley",
+					SiteCode:    "SJC2",
+					Region:      "West",
+					Country:     "US",
+					Continent:   "North America",
+					Description: "Silicon Valley, California",
+					Airport:     "SJC",
+				},
+			},
+			Subscription: ContainerRegistrySubscription{
+				Billing: ContainerRegistrySubscriptionBilling{
+					MonthlyPrice:   5,
+					PendingCharges: 0,
+				},
+			},
+		},
+	}
+
+	if !reflect.DeepEqual(vcr, expected) {
+		t.Errorf("ContainerRegistry.Get returned %+v, expected %+v", vcr, expected)
+	}
+
+	c, can := context.WithTimeout(ctx, 1*time.Microsecond)
+	defer can()
+	_, _, err = client.ContainerRegistry.Get(c, vcrID)
+	if err == nil {
+		t.Error("ContainerRegistry.Get returned nil")
+	}
+}
+
+func TestVCRServiceHandler_Update(t *testing.T) {
+	setup()
+	defer teardown()
+
+	vcrID := "e1d6be16-2b0c-4d76-a3eb-f28bf6ea5fe0"
+
+	mux.HandleFunc(fmt.Sprintf("%s/%s", vcrPath, vcrID), func(writer http.ResponseWriter, request *http.Request) {
+		response := `{
+    "id": "e1d6be16-2b0c-4d76-a3eb-f28bf6ea5fe0",
+    "name": "govultrtest",
+    "region": "sjc",
+    "urn": "sjc.vultrcr.com/govultrtest",
+    "storage": {
+        "used": {
+            "updated_at": "2023-11-09 13:37:12",
+            "bytes": 0,
+            "mb": 0,
+            "gb": 0,
+            "tb": 0
+        },
+        "allowed": {
+            "bytes": 21474836480,
+            "mb": 20480,
+            "gb": 20,
+            "tb": 0.02
+        }
+    },
+    "date_created": "2023-11-09 13:37:12",
+    "public": false,
+    "root_user": {
+        "id": 635,
+        "username": "e1d6be16-2b0c-4d76-a3eb-f28bf6ea5fe0",
+        "password": "5dEr33smkSYauMmRWusNFk9HpweL5CevpnFr",
+        "root": true,
+        "added_at": "2023-11-09 13:37:12",
+        "updated_at": "2023-11-09 13:37:12"
+    },
+    "metadata": {
+        "region": {
+            "id": 3,
+            "name": "sjc",
+            "urn": "sjc.vultrcr.com",
+            "base_url": "https://sjc.vultrcr.com",
+            "public": true,
+            "added_at": "2023-09-14 09:09:16",
+            "updated_at": "2023-09-14 09:09:16",
+            "data_center": {
+                "id": 12,
+                "name": "Silicon Valley",
+                "site_code": "SJC2",
+                "region": "West",
+                "country": "US",
+                "continent": "North America",
+                "description": "Silicon Valley, California",
+                "airport": "SJC"
+            }
+        },
+        "subscription": {
+            "billing": {
+                "monthly_price": 5,
+                "pending_charges": 0
+            }
+        }
+    }
+}`
+		fmt.Fprint(writer, response)
+	})
+
+	req := &ContainerRegistryUpdateReq{
+		Public: BoolToBoolPtr(true),
+	}
+
+	vcr, _, err := client.ContainerRegistry.Update(ctx, vcrID, req)
+	if err != nil {
+		t.Errorf("ContainerRegistry.Update returned %v", err)
+	}
+
+	expected := &ContainerRegistry{
+		ID:   "e1d6be16-2b0c-4d76-a3eb-f28bf6ea5fe0",
+		Name: "govultrtest",
+		URN:  "sjc.vultrcr.com/govultrtest",
+		Storage: ContainerRegistryStorage{
+			Used: ContainerRegistryStorageCount{
+				Bytes:        0,
+				MegaBytes:    0,
+				GigaBytes:    0,
+				TeraBytes:    0,
+				DateModified: "2023-11-09 13:37:12",
+			},
+			Allowed: ContainerRegistryStorageCount{
+				Bytes:        21474836480,
+				MegaBytes:    20480,
+				GigaBytes:    20,
+				TeraBytes:    0.02,
+				DateModified: "",
+			},
+		},
+		DateCreated: "2023-11-09 13:37:12",
+		Public:      false,
+		RootUser: ContainerRegistryUser{
+			ID:           635,
+			UserName:     "e1d6be16-2b0c-4d76-a3eb-f28bf6ea5fe0",
+			Password:     "5dEr33smkSYauMmRWusNFk9HpweL5CevpnFr",
+			Root:         true,
+			DateCreated:  "2023-11-09 13:37:12",
+			DateModified: "2023-11-09 13:37:12",
+		},
+		Metadata: ContainerRegistryMetadata{
+			Region: ContainerRegistryRegion{
+				ID:           3,
+				Name:         "sjc",
+				URN:          "sjc.vultrcr.com",
+				BaseURL:      "https://sjc.vultrcr.com",
+				Public:       true,
+				DateCreated:  "2023-09-14 09:09:16",
+				DateModified: "2023-09-14 09:09:16",
+				DataCenter: ContainerRegistryRegionDataCenter{
+					ID:          12,
+					Name:        "Silicon Valley",
+					SiteCode:    "SJC2",
+					Region:      "West",
+					Country:     "US",
+					Continent:   "North America",
+					Description: "Silicon Valley, California",
+					Airport:     "SJC",
+				},
+			},
+			Subscription: ContainerRegistrySubscription{
+				Billing: ContainerRegistrySubscriptionBilling{
+					MonthlyPrice:   5,
+					PendingCharges: 0,
+				},
+			},
+		},
+	}
+
+	if !reflect.DeepEqual(vcr, expected) {
+		t.Errorf("ContainerRegistry.Update returned %+v \n\n expected %+v", vcr, expected)
+	}
+
+	c, can := context.WithTimeout(ctx, 1*time.Microsecond)
+	defer can()
+	_, _, err = client.ContainerRegistry.Update(c, vcrID, req)
+	if err == nil {
+		t.Error("ContainerRegistry.Update returned nil")
+	}
+}
+
+func TestVCRServiceHandler_Delete(t *testing.T) {
+	setup()
+	defer teardown()
+
+	vcrID := "e1d6be16-2b0c-4d76-a3eb-f28bf6ea5fe0"
+
+	mux.HandleFunc(fmt.Sprintf("%s/%s", vcrPath, vcrID), func(writer http.ResponseWriter, request *http.Request) {
+		fmt.Fprint(writer)
+	})
+
+	err := client.ContainerRegistry.Delete(ctx, vcrID)
+	if err != nil {
+		t.Errorf("ContainerRegistry.Delete returned %+v", err)
+	}
+}
+
+func TestVCRServiceHandler_GetRepository(t *testing.T) {
+	setup()
+	defer teardown()
+
+	vcrID := "e1d6be16-2b0c-4d76-a3eb-f28bf6ea5fe0"
+	vcrImage := "vultr-csi"
+
+	mux.HandleFunc(fmt.Sprintf("%s/%s/repository/%s", vcrPath, vcrID, vcrImage), func(writer http.ResponseWriter, request *http.Request) {
+		response := `{
+    "name": "govultrtest/vultr-csi",
+    "image": "vultr-csi",
+    "description": "",
+    "added_at": "2023-10-05T18:22:17.041Z",
+    "updated_at": "2023-10-27T23:26:09.369Z",
+    "pull_count": 9,
+    "artifact_count": 7
+}`
+		fmt.Fprint(writer, response)
+	})
+
+	vcrRepo, _, err := client.ContainerRegistry.GetRepository(ctx, vcrID, vcrImage)
+	if err != nil {
+		t.Errorf("ContainerRegistry.GetRepository returned %+v", err)
+	}
+
+	expected := &ContainerRegistryRepo{
+		Name:          "govultrtest/vultr-csi",
+		Image:         "vultr-csi",
+		Description:   "",
+		DateCreated:   "2023-10-05T18:22:17.041Z",
+		DateModified:  "2023-10-27T23:26:09.369Z",
+		PullCount:     9,
+		ArtifactCount: 7,
+	}
+
+	if !reflect.DeepEqual(vcrRepo, expected) {
+		t.Errorf("ContainerRegistry.GetRepository returned %+v, expected %+v", vcrRepo, expected)
+	}
+
+	c, can := context.WithTimeout(ctx, 1*time.Microsecond)
+	defer can()
+	if _, _, err = client.ContainerRegistry.GetRepository(c, vcrID, vcrImage); err == nil {
+		t.Error("ContainerRegistry.GetRepository returned nil")
+	}
+}
+
+func TestVCRServiceHandler_ListRepositories(t *testing.T) {
+	setup()
+	defer teardown()
+
+	vcrID := "e1d6be16-2b0c-4d76-a3eb-f28bf6ea5fe0"
+
+	mux.HandleFunc(fmt.Sprintf("%s/%s/repositories", vcrPath, vcrID), func(writer http.ResponseWriter, request *http.Request) {
+		response := `{
+    "repositories": [
+        {
+            "name": "govultrtest/vultr-csi",
+            "image": "vultr-csi",
+            "description": "",
+            "added_at": "2023-10-05T18:22:17.041Z",
+            "updated_at": "2023-10-27T23:26:09.369Z",
+            "pull_count": 9,
+            "artifact_count": 7
+        }
+    ],
+    "meta": {
+        "total": 1,
+        "links": {
+            "next": "",
+            "prev": ""
+        }
+    }
+}`
+		fmt.Fprint(writer, response)
+	})
+
+	vcrRepos, meta, _, err := client.ContainerRegistry.ListRepositories(ctx, vcrID, nil)
+	if err != nil {
+		t.Errorf("ContainerRegistry.ListRepositories returned %+v", err)
+	}
+
+	expected := []ContainerRegistryRepo{
+		{
+			Name:          "govultrtest/vultr-csi",
+			Image:         "vultr-csi",
+			Description:   "",
+			DateCreated:   "2023-10-05T18:22:17.041Z",
+			DateModified:  "2023-10-27T23:26:09.369Z",
+			PullCount:     9,
+			ArtifactCount: 7,
+		},
+	}
+
+	expectedMeta := &Meta{
+		Total: 1,
+		Links: &Links{
+			Next: "",
+			Prev: "",
+		},
+	}
+
+	if !reflect.DeepEqual(vcrRepos, expected) {
+		t.Errorf("ContainerRegistry.ListRepositories returned %+v, expected %+v", vcrRepos, expected)
+	}
+
+	if !reflect.DeepEqual(meta, expectedMeta) {
+		t.Errorf("ContainerRegistry.ListRepositories meta returned %+v, expected %+v", meta, expectedMeta)
+	}
+
+	c, can := context.WithTimeout(ctx, 1*time.Microsecond)
+	defer can()
+	if _, _, _, err = client.ContainerRegistry.ListRepositories(c, vcrID, nil); err == nil {
+		t.Error("ContainerRegistry.ListRepositories returned nil")
+	}
+}
+
+func TestVCRServiceHandler_UpdateRepository(t *testing.T) {
+	setup()
+	defer teardown()
+
+	vcrID := "e1d6be16-2b0c-4d76-a3eb-f28bf6ea5fe0"
+	vcrImage := "vultr-csi"
+
+	mux.HandleFunc(fmt.Sprintf("%s/%s/repository/%s", vcrPath, vcrID, vcrImage), func(writer http.ResponseWriter, request *http.Request) {
+		response := `{
+    "name": "govultrtest/vultr-csi",
+    "image": "vultr-csi",
+    "description": "test",
+    "added_at": "2023-10-05T18:22:17.041Z",
+    "updated_at": "2023-10-27T23:26:09.369Z",
+    "pull_count": 9,
+    "artifact_count": 7
+}`
+		fmt.Fprint(writer, response)
+	})
+
+	req := &ContainerRegistryRepoUpdateReq{
+		Description: "test",
+	}
+
+	vcrRepo, _, err := client.ContainerRegistry.UpdateRepository(ctx, vcrID, vcrImage, req)
+	if err != nil {
+		t.Errorf("ContainerRegistry.UpdateRepository returned %+v", err)
+	}
+
+	expected := &ContainerRegistryRepo{
+		Name:          "govultrtest/vultr-csi",
+		Image:         "vultr-csi",
+		Description:   "test",
+		DateCreated:   "2023-10-05T18:22:17.041Z",
+		DateModified:  "2023-10-27T23:26:09.369Z",
+		PullCount:     9,
+		ArtifactCount: 7,
+	}
+
+	if !reflect.DeepEqual(vcrRepo, expected) {
+		t.Errorf("ContainerRegistry.UpdateRepository returned %+v, expected %+v", vcrRepo, expected)
+	}
+
+	c, can := context.WithTimeout(ctx, 1*time.Microsecond)
+	defer can()
+	if _, _, err = client.ContainerRegistry.UpdateRepository(c, vcrID, vcrImage, req); err == nil {
+		t.Error("ContainerRegistry.UpdateRepository returned nil")
+	}
+}
+
+func TestVCRServiceHandler_DeleteRepository(t *testing.T) {
+	setup()
+	defer teardown()
+
+	vcrID := "e1d6be16-2b0c-4d76-a3eb-f28bf6ea5fe0"
+	vcrImage := "vultr-csi"
+
+	mux.HandleFunc(fmt.Sprintf("%s/%s/repository/%s", vcrPath, vcrID, vcrImage), func(writer http.ResponseWriter, request *http.Request) {
+		fmt.Fprint(writer)
+	})
+
+	err := client.ContainerRegistry.DeleteRepository(ctx, vcrID, vcrImage)
+	if err != nil {
+		t.Errorf("ContainerRegistry.DeleteRepository returned %+v", err)
+	}
+}
+
+func TestVCRServiceHandler_ListRegions(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc(fmt.Sprintf("%s/region/list", vcrPath), func(writer http.ResponseWriter, request *http.Request) {
+		response := `{
+    "regions": [
+        {
+            "id": 3,
+            "name": "sjc",
+            "urn": "sjc.vultrcr.com",
+            "base_url": "https://sjc.vultrcr.com",
+            "public": true,
+            "added_at": "2023-09-14 09:09:16",
+            "updated_at": "2023-09-14 09:09:16",
+            "data_center": {
+                "id": 12,
+                "name": "Silicon Valley",
+                "site_code": "SJC2",
+                "region": "West",
+                "country": "US",
+                "continent": "North America",
+                "description": "Silicon Valley, California",
+                "airport": "SJC"
+            }
+        }
+    ],
+    "meta": {
+        "total": 1,
+        "links": {
+            "next": "",
+            "prev": ""
+        }
+    }
+}`
+		fmt.Fprint(writer, response)
+	})
+
+	vcrRegions, meta, _, err := client.ContainerRegistry.ListRegions(ctx, nil)
+	if err != nil {
+		t.Errorf("ContainerRegistry.ListRegions returned %v", err)
+	}
+
+	expected := []ContainerRegistryRegion{
+		{
+			ID:           3,
+			Name:         "sjc",
+			URN:          "sjc.vultrcr.com",
+			BaseURL:      "https://sjc.vultrcr.com",
+			Public:       true,
+			DateCreated:  "2023-09-14 09:09:16",
+			DateModified: "2023-09-14 09:09:16",
+			DataCenter: ContainerRegistryRegionDataCenter{
+				ID:          12,
+				Name:        "Silicon Valley",
+				SiteCode:    "SJC2",
+				Region:      "West",
+				Country:     "US",
+				Continent:   "North America",
+				Description: "Silicon Valley, California",
+				Airport:     "SJC",
+			},
+		},
+	}
+
+	expectedMeta := &Meta{
+		Total: 1,
+		Links: &Links{
+			Next: "",
+			Prev: "",
+		},
+	}
+
+	if !reflect.DeepEqual(vcrRegions, expected) {
+		t.Errorf("ContainerRegistry.ListRegions returned %+v, expected %+v", vcrRegions, expected)
+	}
+
+	if !reflect.DeepEqual(meta, expectedMeta) {
+		t.Errorf("ContainerRegistry.ListRegions meta returned %+v, expected %+v", meta, expectedMeta)
+	}
+
+	c, can := context.WithTimeout(ctx, 1*time.Microsecond)
+	defer can()
+	_, _, _, err = client.ContainerRegistry.ListRegions(c, nil)
+	if err == nil {
+		t.Error("ContainerRegistry.ListRegions returned nil")
+	}
+}
+
+func TestVCRServiceHandler_ListPlans(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc(fmt.Sprintf("%s/plan/list", vcrPath), func(writer http.ResponseWriter, request *http.Request) {
+		response := `{
+    "plans": {
+        "start_up": {
+            "vanity_name": "Start Up",
+            "max_storage_mb": 10240,
+            "monthly_price": 0
+        },
+        "business": {
+            "vanity_name": "Business",
+            "max_storage_mb": 20480,
+            "monthly_price": 5
+        },
+        "premium": {
+            "vanity_name": "Premium",
+            "max_storage_mb": 51200,
+            "monthly_price": 10
+        },
+        "enterprise": {
+            "vanity_name": "Enterprise",
+            "max_storage_mb": 1048576,
+            "monthly_price": 20
+        }
+    }
+}`
+		fmt.Fprint(writer, response)
+	})
+
+	vcrPlans, _, err := client.ContainerRegistry.ListPlans(ctx)
+	if err != nil {
+		t.Errorf("ContainerRegistry.ListPlans returned %v", err)
+	}
+
+	expected := &ContainerRegistryPlans{
+		Plans: ContainerRegistryPlanTypes{
+			StartUp: ContainerRegistryPlan{
+				VanityName:   "Start Up",
+				MaxStorageMB: 10240,
+				MonthlyPrice: 0,
+			},
+			Business: ContainerRegistryPlan{
+				VanityName:   "Business",
+				MaxStorageMB: 20480,
+				MonthlyPrice: 5,
+			},
+			Premium: ContainerRegistryPlan{
+				VanityName:   "Premium",
+				MaxStorageMB: 51200,
+				MonthlyPrice: 10,
+			},
+			Enterprise: ContainerRegistryPlan{
+				VanityName:   "Enterprise",
+				MaxStorageMB: 1048576,
+				MonthlyPrice: 20,
+			},
+		},
+	}
+
+	if !reflect.DeepEqual(vcrPlans, expected) {
+		t.Errorf("ContainerRegistry.ListPlans returned %+v, expected %+v", vcrPlans, expected)
+	}
+
+	c, can := context.WithTimeout(ctx, 1*time.Microsecond)
+	defer can()
+	_, _, err = client.ContainerRegistry.ListPlans(c)
+	if err == nil {
+		t.Error("ContainerRegistry.ListPlans returned nil")
+	}
+}
diff --git a/govultr.go b/govultr.go
index 9b2ac4e..97d4e0b 100644
--- a/govultr.go
+++ b/govultr.go
@@ -1,3 +1,5 @@
+// Package govultr contains the functionality to interact with the Vultr public
+// HTTP REST API.
 package govultr
 
 import (
@@ -39,21 +41,22 @@ type Client struct {
 	UserAgent string
 
 	// Services used to interact with the API
-	Account         AccountService
-	Application     ApplicationService
-	Backup          BackupService
-	BareMetalServer BareMetalServerService
-	Billing         BillingService
-	BlockStorage    BlockStorageService
-	Database        DatabaseService
-	Domain          DomainService
-	DomainRecord    DomainRecordService
-	FirewallGroup   FirewallGroupService
-	FirewallRule    FireWallRuleService
-	Instance        InstanceService
-	ISO             ISOService
-	Kubernetes      KubernetesService
-	LoadBalancer    LoadBalancerService
+	Account           AccountService
+	Application       ApplicationService
+	Backup            BackupService
+	BareMetalServer   BareMetalServerService
+	Billing           BillingService
+	BlockStorage      BlockStorageService
+	ContainerRegistry ContainerRegistryService
+	Database          DatabaseService
+	Domain            DomainService
+	DomainRecord      DomainRecordService
+	FirewallGroup     FirewallGroupService
+	FirewallRule      FireWallRuleService
+	Instance          InstanceService
+	ISO               ISOService
+	Kubernetes        KubernetesService
+	LoadBalancer      LoadBalancerService
 	// Deprecated: Network should no longer be used. Instead, use VPC.
 	Network       NetworkService
 	ObjectStorage ObjectStorageService
@@ -116,6 +119,7 @@ func NewClient(httpClient *http.Client) *Client {
 	client.BareMetalServer = &BareMetalServerServiceHandler{client}
 	client.Billing = &BillingServiceHandler{client}
 	client.BlockStorage = &BlockStorageServiceHandler{client}
+	client.ContainerRegistry = &ContainerRegistryServiceHandler{client}
 	client.Database = &DatabaseServiceHandler{client}
 	client.Domain = &DomainServiceHandler{client}
 	client.DomainRecord = &DomainRecordsServiceHandler{client}
@@ -178,14 +182,14 @@ func (c *Client) DoWithContext(ctx context.Context, r *http.Request, data interf
 
 	rreq = rreq.WithContext(ctx)
 
-	res, err := c.client.Do(rreq)
+	res, errDo := c.client.Do(rreq)
 
 	if c.onRequestCompleted != nil {
 		c.onRequestCompleted(r, res)
 	}
 
-	if err != nil {
-		return nil, err
+	if errDo != nil {
+		return nil, errDo
 	}
 
 	defer func() {
diff --git a/kubernetes.go b/kubernetes.go
index 91447ee..90ead5a 100644
--- a/kubernetes.go
+++ b/kubernetes.go
@@ -258,7 +258,7 @@ func (k *KubernetesHandler) CreateNodePool(ctx context.Context, vkeID string, no
 }
 
 // ListNodePools will return all nodepools for a given VKE cluster
-func (k *KubernetesHandler) ListNodePools(ctx context.Context, vkeID string, options *ListOptions) ([]NodePool, *Meta, *http.Response, error) { //nolint:lll
+func (k *KubernetesHandler) ListNodePools(ctx context.Context, vkeID string, options *ListOptions) ([]NodePool, *Meta, *http.Response, error) { //nolint:lll,dupl
 	req, err := k.client.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s/%s/node-pools", vkePath, vkeID), nil)
 	if err != nil {
 		return nil, nil, nil, err
diff --git a/kubernetes_test.go b/kubernetes_test.go
index 22f9620..20c4690 100644
--- a/kubernetes_test.go
+++ b/kubernetes_test.go
@@ -308,7 +308,7 @@ func TestKubernetesHandler_ListClusters(t *testing.T) {
 	}
 
 	if !reflect.DeepEqual(meta, expectedMeta) {
-		t.Errorf("Kubernetes.List meta returned %+v, expected %+v", vke, expected)
+		t.Errorf("Kubernetes.List meta returned %+v, expected %+v", meta, expectedMeta)
 	}
 
 	c, can := context.WithTimeout(ctx, 1*time.Microsecond)
diff --git a/object_storage.go b/object_storage.go
index 1597fcd..f3624da 100644
--- a/object_storage.go
+++ b/object_storage.go
@@ -21,7 +21,7 @@ type ObjectStorageService interface {
 	RegenerateKeys(ctx context.Context, id string) (*S3Keys, *http.Response, error)
 }
 
-// ObjectStorageServiceHandler handles interaction with the firewall rule methods for the Vultr API.
+// ObjectStorageServiceHandler handles interaction between the object storage service and the Vultr API.
 type ObjectStorageServiceHandler struct {
 	client *Client
 }