//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//

// Code generated by MockGen. DO NOT EDIT.
// Source: ./cloudstack/ZoneService.go
//
// Generated by this command:
//
//	mockgen -destination=./cloudstack/ZoneService_mock.go -package=cloudstack -copyright_file=header.txt -source=./cloudstack/ZoneService.go
//

// Package cloudstack is a generated GoMock package.
package cloudstack

import (
	reflect "reflect"

	gomock "go.uber.org/mock/gomock"
)

// MockZoneServiceIface is a mock of ZoneServiceIface interface.
type MockZoneServiceIface struct {
	ctrl     *gomock.Controller
	recorder *MockZoneServiceIfaceMockRecorder
	isgomock struct{}
}

// MockZoneServiceIfaceMockRecorder is the mock recorder for MockZoneServiceIface.
type MockZoneServiceIfaceMockRecorder struct {
	mock *MockZoneServiceIface
}

// NewMockZoneServiceIface creates a new mock instance.
func NewMockZoneServiceIface(ctrl *gomock.Controller) *MockZoneServiceIface {
	mock := &MockZoneServiceIface{ctrl: ctrl}
	mock.recorder = &MockZoneServiceIfaceMockRecorder{mock}
	return mock
}

// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockZoneServiceIface) EXPECT() *MockZoneServiceIfaceMockRecorder {
	return m.recorder
}

// AddVmwareDc mocks base method.
func (m *MockZoneServiceIface) AddVmwareDc(p *AddVmwareDcParams) (*AddVmwareDcResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "AddVmwareDc", p)
	ret0, _ := ret[0].(*AddVmwareDcResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// AddVmwareDc indicates an expected call of AddVmwareDc.
func (mr *MockZoneServiceIfaceMockRecorder) AddVmwareDc(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddVmwareDc", reflect.TypeOf((*MockZoneServiceIface)(nil).AddVmwareDc), p)
}

// CreateIpv4SubnetForZone mocks base method.
func (m *MockZoneServiceIface) CreateIpv4SubnetForZone(p *CreateIpv4SubnetForZoneParams) (*CreateIpv4SubnetForZoneResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CreateIpv4SubnetForZone", p)
	ret0, _ := ret[0].(*CreateIpv4SubnetForZoneResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// CreateIpv4SubnetForZone indicates an expected call of CreateIpv4SubnetForZone.
func (mr *MockZoneServiceIfaceMockRecorder) CreateIpv4SubnetForZone(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateIpv4SubnetForZone", reflect.TypeOf((*MockZoneServiceIface)(nil).CreateIpv4SubnetForZone), p)
}

// CreateZone mocks base method.
func (m *MockZoneServiceIface) CreateZone(p *CreateZoneParams) (*CreateZoneResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CreateZone", p)
	ret0, _ := ret[0].(*CreateZoneResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// CreateZone indicates an expected call of CreateZone.
func (mr *MockZoneServiceIfaceMockRecorder) CreateZone(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateZone", reflect.TypeOf((*MockZoneServiceIface)(nil).CreateZone), p)
}

// DedicateIpv4SubnetForZone mocks base method.
func (m *MockZoneServiceIface) DedicateIpv4SubnetForZone(p *DedicateIpv4SubnetForZoneParams) (*DedicateIpv4SubnetForZoneResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DedicateIpv4SubnetForZone", p)
	ret0, _ := ret[0].(*DedicateIpv4SubnetForZoneResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DedicateIpv4SubnetForZone indicates an expected call of DedicateIpv4SubnetForZone.
func (mr *MockZoneServiceIfaceMockRecorder) DedicateIpv4SubnetForZone(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DedicateIpv4SubnetForZone", reflect.TypeOf((*MockZoneServiceIface)(nil).DedicateIpv4SubnetForZone), p)
}

// DedicateZone mocks base method.
func (m *MockZoneServiceIface) DedicateZone(p *DedicateZoneParams) (*DedicateZoneResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DedicateZone", p)
	ret0, _ := ret[0].(*DedicateZoneResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DedicateZone indicates an expected call of DedicateZone.
func (mr *MockZoneServiceIfaceMockRecorder) DedicateZone(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DedicateZone", reflect.TypeOf((*MockZoneServiceIface)(nil).DedicateZone), p)
}

// DeleteIpv4SubnetForZone mocks base method.
func (m *MockZoneServiceIface) DeleteIpv4SubnetForZone(p *DeleteIpv4SubnetForZoneParams) (*DeleteIpv4SubnetForZoneResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteIpv4SubnetForZone", p)
	ret0, _ := ret[0].(*DeleteIpv4SubnetForZoneResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DeleteIpv4SubnetForZone indicates an expected call of DeleteIpv4SubnetForZone.
func (mr *MockZoneServiceIfaceMockRecorder) DeleteIpv4SubnetForZone(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteIpv4SubnetForZone", reflect.TypeOf((*MockZoneServiceIface)(nil).DeleteIpv4SubnetForZone), p)
}

// DeleteZone mocks base method.
func (m *MockZoneServiceIface) DeleteZone(p *DeleteZoneParams) (*DeleteZoneResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteZone", p)
	ret0, _ := ret[0].(*DeleteZoneResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DeleteZone indicates an expected call of DeleteZone.
func (mr *MockZoneServiceIfaceMockRecorder) DeleteZone(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteZone", reflect.TypeOf((*MockZoneServiceIface)(nil).DeleteZone), p)
}

// DisableHAForZone mocks base method.
func (m *MockZoneServiceIface) DisableHAForZone(p *DisableHAForZoneParams) (*DisableHAForZoneResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DisableHAForZone", p)
	ret0, _ := ret[0].(*DisableHAForZoneResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DisableHAForZone indicates an expected call of DisableHAForZone.
func (mr *MockZoneServiceIfaceMockRecorder) DisableHAForZone(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisableHAForZone", reflect.TypeOf((*MockZoneServiceIface)(nil).DisableHAForZone), p)
}

// DisableOutOfBandManagementForZone mocks base method.
func (m *MockZoneServiceIface) DisableOutOfBandManagementForZone(p *DisableOutOfBandManagementForZoneParams) (*DisableOutOfBandManagementForZoneResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DisableOutOfBandManagementForZone", p)
	ret0, _ := ret[0].(*DisableOutOfBandManagementForZoneResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DisableOutOfBandManagementForZone indicates an expected call of DisableOutOfBandManagementForZone.
func (mr *MockZoneServiceIfaceMockRecorder) DisableOutOfBandManagementForZone(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisableOutOfBandManagementForZone", reflect.TypeOf((*MockZoneServiceIface)(nil).DisableOutOfBandManagementForZone), p)
}

// EnableHAForZone mocks base method.
func (m *MockZoneServiceIface) EnableHAForZone(p *EnableHAForZoneParams) (*EnableHAForZoneResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "EnableHAForZone", p)
	ret0, _ := ret[0].(*EnableHAForZoneResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// EnableHAForZone indicates an expected call of EnableHAForZone.
func (mr *MockZoneServiceIfaceMockRecorder) EnableHAForZone(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableHAForZone", reflect.TypeOf((*MockZoneServiceIface)(nil).EnableHAForZone), p)
}

// EnableOutOfBandManagementForZone mocks base method.
func (m *MockZoneServiceIface) EnableOutOfBandManagementForZone(p *EnableOutOfBandManagementForZoneParams) (*EnableOutOfBandManagementForZoneResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "EnableOutOfBandManagementForZone", p)
	ret0, _ := ret[0].(*EnableOutOfBandManagementForZoneResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// EnableOutOfBandManagementForZone indicates an expected call of EnableOutOfBandManagementForZone.
func (mr *MockZoneServiceIfaceMockRecorder) EnableOutOfBandManagementForZone(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableOutOfBandManagementForZone", reflect.TypeOf((*MockZoneServiceIface)(nil).EnableOutOfBandManagementForZone), p)
}

// GetIpv4SubnetsForZoneByID mocks base method.
func (m *MockZoneServiceIface) GetIpv4SubnetsForZoneByID(id string, opts ...OptionFunc) (*Ipv4SubnetsForZone, int, error) {
	m.ctrl.T.Helper()
	varargs := []any{id}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetIpv4SubnetsForZoneByID", varargs...)
	ret0, _ := ret[0].(*Ipv4SubnetsForZone)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetIpv4SubnetsForZoneByID indicates an expected call of GetIpv4SubnetsForZoneByID.
func (mr *MockZoneServiceIfaceMockRecorder) GetIpv4SubnetsForZoneByID(id any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{id}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetIpv4SubnetsForZoneByID", reflect.TypeOf((*MockZoneServiceIface)(nil).GetIpv4SubnetsForZoneByID), varargs...)
}

// GetVmwareDcID mocks base method.
func (m *MockZoneServiceIface) GetVmwareDcID(keyword, zoneid string, opts ...OptionFunc) (string, int, error) {
	m.ctrl.T.Helper()
	varargs := []any{keyword, zoneid}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetVmwareDcID", varargs...)
	ret0, _ := ret[0].(string)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetVmwareDcID indicates an expected call of GetVmwareDcID.
func (mr *MockZoneServiceIfaceMockRecorder) GetVmwareDcID(keyword, zoneid any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{keyword, zoneid}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVmwareDcID", reflect.TypeOf((*MockZoneServiceIface)(nil).GetVmwareDcID), varargs...)
}

// GetZoneByID mocks base method.
func (m *MockZoneServiceIface) GetZoneByID(id string, opts ...OptionFunc) (*Zone, int, error) {
	m.ctrl.T.Helper()
	varargs := []any{id}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetZoneByID", varargs...)
	ret0, _ := ret[0].(*Zone)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetZoneByID indicates an expected call of GetZoneByID.
func (mr *MockZoneServiceIfaceMockRecorder) GetZoneByID(id any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{id}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetZoneByID", reflect.TypeOf((*MockZoneServiceIface)(nil).GetZoneByID), varargs...)
}

// GetZoneByName mocks base method.
func (m *MockZoneServiceIface) GetZoneByName(name string, opts ...OptionFunc) (*Zone, int, error) {
	m.ctrl.T.Helper()
	varargs := []any{name}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetZoneByName", varargs...)
	ret0, _ := ret[0].(*Zone)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetZoneByName indicates an expected call of GetZoneByName.
func (mr *MockZoneServiceIfaceMockRecorder) GetZoneByName(name any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{name}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetZoneByName", reflect.TypeOf((*MockZoneServiceIface)(nil).GetZoneByName), varargs...)
}

// GetZoneID mocks base method.
func (m *MockZoneServiceIface) GetZoneID(name string, opts ...OptionFunc) (string, int, error) {
	m.ctrl.T.Helper()
	varargs := []any{name}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetZoneID", varargs...)
	ret0, _ := ret[0].(string)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetZoneID indicates an expected call of GetZoneID.
func (mr *MockZoneServiceIfaceMockRecorder) GetZoneID(name any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{name}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetZoneID", reflect.TypeOf((*MockZoneServiceIface)(nil).GetZoneID), varargs...)
}

// GetZonesMetricByID mocks base method.
func (m *MockZoneServiceIface) GetZonesMetricByID(id string, opts ...OptionFunc) (*ZonesMetric, int, error) {
	m.ctrl.T.Helper()
	varargs := []any{id}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetZonesMetricByID", varargs...)
	ret0, _ := ret[0].(*ZonesMetric)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetZonesMetricByID indicates an expected call of GetZonesMetricByID.
func (mr *MockZoneServiceIfaceMockRecorder) GetZonesMetricByID(id any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{id}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetZonesMetricByID", reflect.TypeOf((*MockZoneServiceIface)(nil).GetZonesMetricByID), varargs...)
}

// GetZonesMetricByName mocks base method.
func (m *MockZoneServiceIface) GetZonesMetricByName(name string, opts ...OptionFunc) (*ZonesMetric, int, error) {
	m.ctrl.T.Helper()
	varargs := []any{name}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetZonesMetricByName", varargs...)
	ret0, _ := ret[0].(*ZonesMetric)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetZonesMetricByName indicates an expected call of GetZonesMetricByName.
func (mr *MockZoneServiceIfaceMockRecorder) GetZonesMetricByName(name any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{name}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetZonesMetricByName", reflect.TypeOf((*MockZoneServiceIface)(nil).GetZonesMetricByName), varargs...)
}

// GetZonesMetricID mocks base method.
func (m *MockZoneServiceIface) GetZonesMetricID(name string, opts ...OptionFunc) (string, int, error) {
	m.ctrl.T.Helper()
	varargs := []any{name}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetZonesMetricID", varargs...)
	ret0, _ := ret[0].(string)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetZonesMetricID indicates an expected call of GetZonesMetricID.
func (mr *MockZoneServiceIfaceMockRecorder) GetZonesMetricID(name any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{name}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetZonesMetricID", reflect.TypeOf((*MockZoneServiceIface)(nil).GetZonesMetricID), varargs...)
}

// ListDedicatedZones mocks base method.
func (m *MockZoneServiceIface) ListDedicatedZones(p *ListDedicatedZonesParams) (*ListDedicatedZonesResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListDedicatedZones", p)
	ret0, _ := ret[0].(*ListDedicatedZonesResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListDedicatedZones indicates an expected call of ListDedicatedZones.
func (mr *MockZoneServiceIfaceMockRecorder) ListDedicatedZones(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDedicatedZones", reflect.TypeOf((*MockZoneServiceIface)(nil).ListDedicatedZones), p)
}

// ListIpv4SubnetsForZone mocks base method.
func (m *MockZoneServiceIface) ListIpv4SubnetsForZone(p *ListIpv4SubnetsForZoneParams) (*ListIpv4SubnetsForZoneResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListIpv4SubnetsForZone", p)
	ret0, _ := ret[0].(*ListIpv4SubnetsForZoneResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListIpv4SubnetsForZone indicates an expected call of ListIpv4SubnetsForZone.
func (mr *MockZoneServiceIfaceMockRecorder) ListIpv4SubnetsForZone(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListIpv4SubnetsForZone", reflect.TypeOf((*MockZoneServiceIface)(nil).ListIpv4SubnetsForZone), p)
}

// ListVmwareDcVms mocks base method.
func (m *MockZoneServiceIface) ListVmwareDcVms(p *ListVmwareDcVmsParams) (*ListVmwareDcVmsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListVmwareDcVms", p)
	ret0, _ := ret[0].(*ListVmwareDcVmsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListVmwareDcVms indicates an expected call of ListVmwareDcVms.
func (mr *MockZoneServiceIfaceMockRecorder) ListVmwareDcVms(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListVmwareDcVms", reflect.TypeOf((*MockZoneServiceIface)(nil).ListVmwareDcVms), p)
}

// ListVmwareDcs mocks base method.
func (m *MockZoneServiceIface) ListVmwareDcs(p *ListVmwareDcsParams) (*ListVmwareDcsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListVmwareDcs", p)
	ret0, _ := ret[0].(*ListVmwareDcsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListVmwareDcs indicates an expected call of ListVmwareDcs.
func (mr *MockZoneServiceIfaceMockRecorder) ListVmwareDcs(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListVmwareDcs", reflect.TypeOf((*MockZoneServiceIface)(nil).ListVmwareDcs), p)
}

// ListZones mocks base method.
func (m *MockZoneServiceIface) ListZones(p *ListZonesParams) (*ListZonesResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListZones", p)
	ret0, _ := ret[0].(*ListZonesResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListZones indicates an expected call of ListZones.
func (mr *MockZoneServiceIfaceMockRecorder) ListZones(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListZones", reflect.TypeOf((*MockZoneServiceIface)(nil).ListZones), p)
}

// ListZonesMetrics mocks base method.
func (m *MockZoneServiceIface) ListZonesMetrics(p *ListZonesMetricsParams) (*ListZonesMetricsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListZonesMetrics", p)
	ret0, _ := ret[0].(*ListZonesMetricsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListZonesMetrics indicates an expected call of ListZonesMetrics.
func (mr *MockZoneServiceIfaceMockRecorder) ListZonesMetrics(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListZonesMetrics", reflect.TypeOf((*MockZoneServiceIface)(nil).ListZonesMetrics), p)
}

// NewAddVmwareDcParams mocks base method.
func (m *MockZoneServiceIface) NewAddVmwareDcParams(name, vcenter, zoneid string) *AddVmwareDcParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewAddVmwareDcParams", name, vcenter, zoneid)
	ret0, _ := ret[0].(*AddVmwareDcParams)
	return ret0
}

// NewAddVmwareDcParams indicates an expected call of NewAddVmwareDcParams.
func (mr *MockZoneServiceIfaceMockRecorder) NewAddVmwareDcParams(name, vcenter, zoneid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAddVmwareDcParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewAddVmwareDcParams), name, vcenter, zoneid)
}

// NewCreateIpv4SubnetForZoneParams mocks base method.
func (m *MockZoneServiceIface) NewCreateIpv4SubnetForZoneParams(subnet, zoneid string) *CreateIpv4SubnetForZoneParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewCreateIpv4SubnetForZoneParams", subnet, zoneid)
	ret0, _ := ret[0].(*CreateIpv4SubnetForZoneParams)
	return ret0
}

// NewCreateIpv4SubnetForZoneParams indicates an expected call of NewCreateIpv4SubnetForZoneParams.
func (mr *MockZoneServiceIfaceMockRecorder) NewCreateIpv4SubnetForZoneParams(subnet, zoneid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewCreateIpv4SubnetForZoneParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewCreateIpv4SubnetForZoneParams), subnet, zoneid)
}

// NewCreateZoneParams mocks base method.
func (m *MockZoneServiceIface) NewCreateZoneParams(dns1, internaldns1, name, networktype string) *CreateZoneParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewCreateZoneParams", dns1, internaldns1, name, networktype)
	ret0, _ := ret[0].(*CreateZoneParams)
	return ret0
}

// NewCreateZoneParams indicates an expected call of NewCreateZoneParams.
func (mr *MockZoneServiceIfaceMockRecorder) NewCreateZoneParams(dns1, internaldns1, name, networktype any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewCreateZoneParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewCreateZoneParams), dns1, internaldns1, name, networktype)
}

// NewDedicateIpv4SubnetForZoneParams mocks base method.
func (m *MockZoneServiceIface) NewDedicateIpv4SubnetForZoneParams(id string) *DedicateIpv4SubnetForZoneParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewDedicateIpv4SubnetForZoneParams", id)
	ret0, _ := ret[0].(*DedicateIpv4SubnetForZoneParams)
	return ret0
}

// NewDedicateIpv4SubnetForZoneParams indicates an expected call of NewDedicateIpv4SubnetForZoneParams.
func (mr *MockZoneServiceIfaceMockRecorder) NewDedicateIpv4SubnetForZoneParams(id any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDedicateIpv4SubnetForZoneParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewDedicateIpv4SubnetForZoneParams), id)
}

// NewDedicateZoneParams mocks base method.
func (m *MockZoneServiceIface) NewDedicateZoneParams(domainid, zoneid string) *DedicateZoneParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewDedicateZoneParams", domainid, zoneid)
	ret0, _ := ret[0].(*DedicateZoneParams)
	return ret0
}

// NewDedicateZoneParams indicates an expected call of NewDedicateZoneParams.
func (mr *MockZoneServiceIfaceMockRecorder) NewDedicateZoneParams(domainid, zoneid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDedicateZoneParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewDedicateZoneParams), domainid, zoneid)
}

// NewDeleteIpv4SubnetForZoneParams mocks base method.
func (m *MockZoneServiceIface) NewDeleteIpv4SubnetForZoneParams(id string) *DeleteIpv4SubnetForZoneParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewDeleteIpv4SubnetForZoneParams", id)
	ret0, _ := ret[0].(*DeleteIpv4SubnetForZoneParams)
	return ret0
}

// NewDeleteIpv4SubnetForZoneParams indicates an expected call of NewDeleteIpv4SubnetForZoneParams.
func (mr *MockZoneServiceIfaceMockRecorder) NewDeleteIpv4SubnetForZoneParams(id any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDeleteIpv4SubnetForZoneParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewDeleteIpv4SubnetForZoneParams), id)
}

// NewDeleteZoneParams mocks base method.
func (m *MockZoneServiceIface) NewDeleteZoneParams(id string) *DeleteZoneParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewDeleteZoneParams", id)
	ret0, _ := ret[0].(*DeleteZoneParams)
	return ret0
}

// NewDeleteZoneParams indicates an expected call of NewDeleteZoneParams.
func (mr *MockZoneServiceIfaceMockRecorder) NewDeleteZoneParams(id any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDeleteZoneParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewDeleteZoneParams), id)
}

// NewDisableHAForZoneParams mocks base method.
func (m *MockZoneServiceIface) NewDisableHAForZoneParams(zoneid string) *DisableHAForZoneParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewDisableHAForZoneParams", zoneid)
	ret0, _ := ret[0].(*DisableHAForZoneParams)
	return ret0
}

// NewDisableHAForZoneParams indicates an expected call of NewDisableHAForZoneParams.
func (mr *MockZoneServiceIfaceMockRecorder) NewDisableHAForZoneParams(zoneid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDisableHAForZoneParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewDisableHAForZoneParams), zoneid)
}

// NewDisableOutOfBandManagementForZoneParams mocks base method.
func (m *MockZoneServiceIface) NewDisableOutOfBandManagementForZoneParams(zoneid string) *DisableOutOfBandManagementForZoneParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewDisableOutOfBandManagementForZoneParams", zoneid)
	ret0, _ := ret[0].(*DisableOutOfBandManagementForZoneParams)
	return ret0
}

// NewDisableOutOfBandManagementForZoneParams indicates an expected call of NewDisableOutOfBandManagementForZoneParams.
func (mr *MockZoneServiceIfaceMockRecorder) NewDisableOutOfBandManagementForZoneParams(zoneid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDisableOutOfBandManagementForZoneParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewDisableOutOfBandManagementForZoneParams), zoneid)
}

// NewEnableHAForZoneParams mocks base method.
func (m *MockZoneServiceIface) NewEnableHAForZoneParams(zoneid string) *EnableHAForZoneParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewEnableHAForZoneParams", zoneid)
	ret0, _ := ret[0].(*EnableHAForZoneParams)
	return ret0
}

// NewEnableHAForZoneParams indicates an expected call of NewEnableHAForZoneParams.
func (mr *MockZoneServiceIfaceMockRecorder) NewEnableHAForZoneParams(zoneid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewEnableHAForZoneParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewEnableHAForZoneParams), zoneid)
}

// NewEnableOutOfBandManagementForZoneParams mocks base method.
func (m *MockZoneServiceIface) NewEnableOutOfBandManagementForZoneParams(zoneid string) *EnableOutOfBandManagementForZoneParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewEnableOutOfBandManagementForZoneParams", zoneid)
	ret0, _ := ret[0].(*EnableOutOfBandManagementForZoneParams)
	return ret0
}

// NewEnableOutOfBandManagementForZoneParams indicates an expected call of NewEnableOutOfBandManagementForZoneParams.
func (mr *MockZoneServiceIfaceMockRecorder) NewEnableOutOfBandManagementForZoneParams(zoneid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewEnableOutOfBandManagementForZoneParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewEnableOutOfBandManagementForZoneParams), zoneid)
}

// NewListDedicatedZonesParams mocks base method.
func (m *MockZoneServiceIface) NewListDedicatedZonesParams() *ListDedicatedZonesParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewListDedicatedZonesParams")
	ret0, _ := ret[0].(*ListDedicatedZonesParams)
	return ret0
}

// NewListDedicatedZonesParams indicates an expected call of NewListDedicatedZonesParams.
func (mr *MockZoneServiceIfaceMockRecorder) NewListDedicatedZonesParams() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListDedicatedZonesParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewListDedicatedZonesParams))
}

// NewListIpv4SubnetsForZoneParams mocks base method.
func (m *MockZoneServiceIface) NewListIpv4SubnetsForZoneParams() *ListIpv4SubnetsForZoneParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewListIpv4SubnetsForZoneParams")
	ret0, _ := ret[0].(*ListIpv4SubnetsForZoneParams)
	return ret0
}

// NewListIpv4SubnetsForZoneParams indicates an expected call of NewListIpv4SubnetsForZoneParams.
func (mr *MockZoneServiceIfaceMockRecorder) NewListIpv4SubnetsForZoneParams() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListIpv4SubnetsForZoneParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewListIpv4SubnetsForZoneParams))
}

// NewListVmwareDcVmsParams mocks base method.
func (m *MockZoneServiceIface) NewListVmwareDcVmsParams() *ListVmwareDcVmsParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewListVmwareDcVmsParams")
	ret0, _ := ret[0].(*ListVmwareDcVmsParams)
	return ret0
}

// NewListVmwareDcVmsParams indicates an expected call of NewListVmwareDcVmsParams.
func (mr *MockZoneServiceIfaceMockRecorder) NewListVmwareDcVmsParams() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListVmwareDcVmsParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewListVmwareDcVmsParams))
}

// NewListVmwareDcsParams mocks base method.
func (m *MockZoneServiceIface) NewListVmwareDcsParams(zoneid string) *ListVmwareDcsParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewListVmwareDcsParams", zoneid)
	ret0, _ := ret[0].(*ListVmwareDcsParams)
	return ret0
}

// NewListVmwareDcsParams indicates an expected call of NewListVmwareDcsParams.
func (mr *MockZoneServiceIfaceMockRecorder) NewListVmwareDcsParams(zoneid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListVmwareDcsParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewListVmwareDcsParams), zoneid)
}

// NewListZonesMetricsParams mocks base method.
func (m *MockZoneServiceIface) NewListZonesMetricsParams() *ListZonesMetricsParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewListZonesMetricsParams")
	ret0, _ := ret[0].(*ListZonesMetricsParams)
	return ret0
}

// NewListZonesMetricsParams indicates an expected call of NewListZonesMetricsParams.
func (mr *MockZoneServiceIfaceMockRecorder) NewListZonesMetricsParams() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListZonesMetricsParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewListZonesMetricsParams))
}

// NewListZonesParams mocks base method.
func (m *MockZoneServiceIface) NewListZonesParams() *ListZonesParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewListZonesParams")
	ret0, _ := ret[0].(*ListZonesParams)
	return ret0
}

// NewListZonesParams indicates an expected call of NewListZonesParams.
func (mr *MockZoneServiceIfaceMockRecorder) NewListZonesParams() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListZonesParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewListZonesParams))
}

// NewReleaseDedicatedZoneParams mocks base method.
func (m *MockZoneServiceIface) NewReleaseDedicatedZoneParams(zoneid string) *ReleaseDedicatedZoneParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewReleaseDedicatedZoneParams", zoneid)
	ret0, _ := ret[0].(*ReleaseDedicatedZoneParams)
	return ret0
}

// NewReleaseDedicatedZoneParams indicates an expected call of NewReleaseDedicatedZoneParams.
func (mr *MockZoneServiceIfaceMockRecorder) NewReleaseDedicatedZoneParams(zoneid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewReleaseDedicatedZoneParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewReleaseDedicatedZoneParams), zoneid)
}

// NewReleaseIpv4SubnetForZoneParams mocks base method.
func (m *MockZoneServiceIface) NewReleaseIpv4SubnetForZoneParams(id string) *ReleaseIpv4SubnetForZoneParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewReleaseIpv4SubnetForZoneParams", id)
	ret0, _ := ret[0].(*ReleaseIpv4SubnetForZoneParams)
	return ret0
}

// NewReleaseIpv4SubnetForZoneParams indicates an expected call of NewReleaseIpv4SubnetForZoneParams.
func (mr *MockZoneServiceIfaceMockRecorder) NewReleaseIpv4SubnetForZoneParams(id any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewReleaseIpv4SubnetForZoneParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewReleaseIpv4SubnetForZoneParams), id)
}

// NewRemoveVmwareDcParams mocks base method.
func (m *MockZoneServiceIface) NewRemoveVmwareDcParams(zoneid string) *RemoveVmwareDcParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewRemoveVmwareDcParams", zoneid)
	ret0, _ := ret[0].(*RemoveVmwareDcParams)
	return ret0
}

// NewRemoveVmwareDcParams indicates an expected call of NewRemoveVmwareDcParams.
func (mr *MockZoneServiceIfaceMockRecorder) NewRemoveVmwareDcParams(zoneid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewRemoveVmwareDcParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewRemoveVmwareDcParams), zoneid)
}

// NewUpdateIpv4SubnetForZoneParams mocks base method.
func (m *MockZoneServiceIface) NewUpdateIpv4SubnetForZoneParams(id, subnet string) *UpdateIpv4SubnetForZoneParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewUpdateIpv4SubnetForZoneParams", id, subnet)
	ret0, _ := ret[0].(*UpdateIpv4SubnetForZoneParams)
	return ret0
}

// NewUpdateIpv4SubnetForZoneParams indicates an expected call of NewUpdateIpv4SubnetForZoneParams.
func (mr *MockZoneServiceIfaceMockRecorder) NewUpdateIpv4SubnetForZoneParams(id, subnet any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewUpdateIpv4SubnetForZoneParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewUpdateIpv4SubnetForZoneParams), id, subnet)
}

// NewUpdateVmwareDcParams mocks base method.
func (m *MockZoneServiceIface) NewUpdateVmwareDcParams(zoneid string) *UpdateVmwareDcParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewUpdateVmwareDcParams", zoneid)
	ret0, _ := ret[0].(*UpdateVmwareDcParams)
	return ret0
}

// NewUpdateVmwareDcParams indicates an expected call of NewUpdateVmwareDcParams.
func (mr *MockZoneServiceIfaceMockRecorder) NewUpdateVmwareDcParams(zoneid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewUpdateVmwareDcParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewUpdateVmwareDcParams), zoneid)
}

// NewUpdateZoneParams mocks base method.
func (m *MockZoneServiceIface) NewUpdateZoneParams(id string) *UpdateZoneParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewUpdateZoneParams", id)
	ret0, _ := ret[0].(*UpdateZoneParams)
	return ret0
}

// NewUpdateZoneParams indicates an expected call of NewUpdateZoneParams.
func (mr *MockZoneServiceIfaceMockRecorder) NewUpdateZoneParams(id any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewUpdateZoneParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewUpdateZoneParams), id)
}

// ReleaseDedicatedZone mocks base method.
func (m *MockZoneServiceIface) ReleaseDedicatedZone(p *ReleaseDedicatedZoneParams) (*ReleaseDedicatedZoneResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ReleaseDedicatedZone", p)
	ret0, _ := ret[0].(*ReleaseDedicatedZoneResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ReleaseDedicatedZone indicates an expected call of ReleaseDedicatedZone.
func (mr *MockZoneServiceIfaceMockRecorder) ReleaseDedicatedZone(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReleaseDedicatedZone", reflect.TypeOf((*MockZoneServiceIface)(nil).ReleaseDedicatedZone), p)
}

// ReleaseIpv4SubnetForZone mocks base method.
func (m *MockZoneServiceIface) ReleaseIpv4SubnetForZone(p *ReleaseIpv4SubnetForZoneParams) (*ReleaseIpv4SubnetForZoneResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ReleaseIpv4SubnetForZone", p)
	ret0, _ := ret[0].(*ReleaseIpv4SubnetForZoneResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ReleaseIpv4SubnetForZone indicates an expected call of ReleaseIpv4SubnetForZone.
func (mr *MockZoneServiceIfaceMockRecorder) ReleaseIpv4SubnetForZone(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReleaseIpv4SubnetForZone", reflect.TypeOf((*MockZoneServiceIface)(nil).ReleaseIpv4SubnetForZone), p)
}

// RemoveVmwareDc mocks base method.
func (m *MockZoneServiceIface) RemoveVmwareDc(p *RemoveVmwareDcParams) (*RemoveVmwareDcResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "RemoveVmwareDc", p)
	ret0, _ := ret[0].(*RemoveVmwareDcResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// RemoveVmwareDc indicates an expected call of RemoveVmwareDc.
func (mr *MockZoneServiceIfaceMockRecorder) RemoveVmwareDc(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveVmwareDc", reflect.TypeOf((*MockZoneServiceIface)(nil).RemoveVmwareDc), p)
}

// UpdateIpv4SubnetForZone mocks base method.
func (m *MockZoneServiceIface) UpdateIpv4SubnetForZone(p *UpdateIpv4SubnetForZoneParams) (*UpdateIpv4SubnetForZoneResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdateIpv4SubnetForZone", p)
	ret0, _ := ret[0].(*UpdateIpv4SubnetForZoneResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateIpv4SubnetForZone indicates an expected call of UpdateIpv4SubnetForZone.
func (mr *MockZoneServiceIfaceMockRecorder) UpdateIpv4SubnetForZone(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateIpv4SubnetForZone", reflect.TypeOf((*MockZoneServiceIface)(nil).UpdateIpv4SubnetForZone), p)
}

// UpdateVmwareDc mocks base method.
func (m *MockZoneServiceIface) UpdateVmwareDc(p *UpdateVmwareDcParams) (*UpdateVmwareDcResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdateVmwareDc", p)
	ret0, _ := ret[0].(*UpdateVmwareDcResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateVmwareDc indicates an expected call of UpdateVmwareDc.
func (mr *MockZoneServiceIfaceMockRecorder) UpdateVmwareDc(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateVmwareDc", reflect.TypeOf((*MockZoneServiceIface)(nil).UpdateVmwareDc), p)
}

// UpdateZone mocks base method.
func (m *MockZoneServiceIface) UpdateZone(p *UpdateZoneParams) (*UpdateZoneResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdateZone", p)
	ret0, _ := ret[0].(*UpdateZoneResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateZone indicates an expected call of UpdateZone.
func (mr *MockZoneServiceIfaceMockRecorder) UpdateZone(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateZone", reflect.TypeOf((*MockZoneServiceIface)(nil).UpdateZone), p)
}
