//
// 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/FirewallService.go
//
// Generated by this command:
//
//	mockgen -destination=./cloudstack/FirewallService_mock.go -package=cloudstack -copyright_file=header.txt -source=./cloudstack/FirewallService.go
//

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

import (
	reflect "reflect"

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

// MockFirewallServiceIface is a mock of FirewallServiceIface interface.
type MockFirewallServiceIface struct {
	ctrl     *gomock.Controller
	recorder *MockFirewallServiceIfaceMockRecorder
	isgomock struct{}
}

// MockFirewallServiceIfaceMockRecorder is the mock recorder for MockFirewallServiceIface.
type MockFirewallServiceIfaceMockRecorder struct {
	mock *MockFirewallServiceIface
}

// NewMockFirewallServiceIface creates a new mock instance.
func NewMockFirewallServiceIface(ctrl *gomock.Controller) *MockFirewallServiceIface {
	mock := &MockFirewallServiceIface{ctrl: ctrl}
	mock.recorder = &MockFirewallServiceIfaceMockRecorder{mock}
	return mock
}

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

// AddPaloAltoFirewall mocks base method.
func (m *MockFirewallServiceIface) AddPaloAltoFirewall(p *AddPaloAltoFirewallParams) (*AddPaloAltoFirewallResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "AddPaloAltoFirewall", p)
	ret0, _ := ret[0].(*AddPaloAltoFirewallResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ConfigurePaloAltoFirewall mocks base method.
func (m *MockFirewallServiceIface) ConfigurePaloAltoFirewall(p *ConfigurePaloAltoFirewallParams) (*PaloAltoFirewallResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ConfigurePaloAltoFirewall", p)
	ret0, _ := ret[0].(*PaloAltoFirewallResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// CreateEgressFirewallRule mocks base method.
func (m *MockFirewallServiceIface) CreateEgressFirewallRule(p *CreateEgressFirewallRuleParams) (*CreateEgressFirewallRuleResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CreateEgressFirewallRule", p)
	ret0, _ := ret[0].(*CreateEgressFirewallRuleResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// CreateFirewallRule mocks base method.
func (m *MockFirewallServiceIface) CreateFirewallRule(p *CreateFirewallRuleParams) (*CreateFirewallRuleResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CreateFirewallRule", p)
	ret0, _ := ret[0].(*CreateFirewallRuleResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// CreateIpv6FirewallRule mocks base method.
func (m *MockFirewallServiceIface) CreateIpv6FirewallRule(p *CreateIpv6FirewallRuleParams) (*CreateIpv6FirewallRuleResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CreateIpv6FirewallRule", p)
	ret0, _ := ret[0].(*CreateIpv6FirewallRuleResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// CreatePortForwardingRule mocks base method.
func (m *MockFirewallServiceIface) CreatePortForwardingRule(p *CreatePortForwardingRuleParams) (*CreatePortForwardingRuleResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CreatePortForwardingRule", p)
	ret0, _ := ret[0].(*CreatePortForwardingRuleResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// CreateRoutingFirewallRule mocks base method.
func (m *MockFirewallServiceIface) CreateRoutingFirewallRule(p *CreateRoutingFirewallRuleParams) (*CreateRoutingFirewallRuleResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CreateRoutingFirewallRule", p)
	ret0, _ := ret[0].(*CreateRoutingFirewallRuleResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// DeleteEgressFirewallRule mocks base method.
func (m *MockFirewallServiceIface) DeleteEgressFirewallRule(p *DeleteEgressFirewallRuleParams) (*DeleteEgressFirewallRuleResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteEgressFirewallRule", p)
	ret0, _ := ret[0].(*DeleteEgressFirewallRuleResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// DeleteFirewallRule mocks base method.
func (m *MockFirewallServiceIface) DeleteFirewallRule(p *DeleteFirewallRuleParams) (*DeleteFirewallRuleResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteFirewallRule", p)
	ret0, _ := ret[0].(*DeleteFirewallRuleResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// DeleteIpv6FirewallRule mocks base method.
func (m *MockFirewallServiceIface) DeleteIpv6FirewallRule(p *DeleteIpv6FirewallRuleParams) (*DeleteIpv6FirewallRuleResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteIpv6FirewallRule", p)
	ret0, _ := ret[0].(*DeleteIpv6FirewallRuleResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// DeletePaloAltoFirewall mocks base method.
func (m *MockFirewallServiceIface) DeletePaloAltoFirewall(p *DeletePaloAltoFirewallParams) (*DeletePaloAltoFirewallResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeletePaloAltoFirewall", p)
	ret0, _ := ret[0].(*DeletePaloAltoFirewallResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// DeletePortForwardingRule mocks base method.
func (m *MockFirewallServiceIface) DeletePortForwardingRule(p *DeletePortForwardingRuleParams) (*DeletePortForwardingRuleResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeletePortForwardingRule", p)
	ret0, _ := ret[0].(*DeletePortForwardingRuleResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// DeleteRoutingFirewallRule mocks base method.
func (m *MockFirewallServiceIface) DeleteRoutingFirewallRule(p *DeleteRoutingFirewallRuleParams) (*DeleteRoutingFirewallRuleResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteRoutingFirewallRule", p)
	ret0, _ := ret[0].(*DeleteRoutingFirewallRuleResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

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

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

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

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

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

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

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

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

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

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

// ListEgressFirewallRules mocks base method.
func (m *MockFirewallServiceIface) ListEgressFirewallRules(p *ListEgressFirewallRulesParams) (*ListEgressFirewallRulesResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListEgressFirewallRules", p)
	ret0, _ := ret[0].(*ListEgressFirewallRulesResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ListFirewallRules mocks base method.
func (m *MockFirewallServiceIface) ListFirewallRules(p *ListFirewallRulesParams) (*ListFirewallRulesResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListFirewallRules", p)
	ret0, _ := ret[0].(*ListFirewallRulesResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ListIpv6FirewallRules mocks base method.
func (m *MockFirewallServiceIface) ListIpv6FirewallRules(p *ListIpv6FirewallRulesParams) (*ListIpv6FirewallRulesResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListIpv6FirewallRules", p)
	ret0, _ := ret[0].(*ListIpv6FirewallRulesResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ListPaloAltoFirewalls mocks base method.
func (m *MockFirewallServiceIface) ListPaloAltoFirewalls(p *ListPaloAltoFirewallsParams) (*ListPaloAltoFirewallsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListPaloAltoFirewalls", p)
	ret0, _ := ret[0].(*ListPaloAltoFirewallsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ListPortForwardingRules mocks base method.
func (m *MockFirewallServiceIface) ListPortForwardingRules(p *ListPortForwardingRulesParams) (*ListPortForwardingRulesResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListPortForwardingRules", p)
	ret0, _ := ret[0].(*ListPortForwardingRulesResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ListRoutingFirewallRules mocks base method.
func (m *MockFirewallServiceIface) ListRoutingFirewallRules(p *ListRoutingFirewallRulesParams) (*ListRoutingFirewallRulesResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListRoutingFirewallRules", p)
	ret0, _ := ret[0].(*ListRoutingFirewallRulesResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// NewAddPaloAltoFirewallParams mocks base method.
func (m *MockFirewallServiceIface) NewAddPaloAltoFirewallParams(networkdevicetype, password, physicalnetworkid, url, username string) *AddPaloAltoFirewallParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewAddPaloAltoFirewallParams", networkdevicetype, password, physicalnetworkid, url, username)
	ret0, _ := ret[0].(*AddPaloAltoFirewallParams)
	return ret0
}

// NewAddPaloAltoFirewallParams indicates an expected call of NewAddPaloAltoFirewallParams.
func (mr *MockFirewallServiceIfaceMockRecorder) NewAddPaloAltoFirewallParams(networkdevicetype, password, physicalnetworkid, url, username any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAddPaloAltoFirewallParams", reflect.TypeOf((*MockFirewallServiceIface)(nil).NewAddPaloAltoFirewallParams), networkdevicetype, password, physicalnetworkid, url, username)
}

// NewConfigurePaloAltoFirewallParams mocks base method.
func (m *MockFirewallServiceIface) NewConfigurePaloAltoFirewallParams(fwdeviceid string) *ConfigurePaloAltoFirewallParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewConfigurePaloAltoFirewallParams", fwdeviceid)
	ret0, _ := ret[0].(*ConfigurePaloAltoFirewallParams)
	return ret0
}

// NewConfigurePaloAltoFirewallParams indicates an expected call of NewConfigurePaloAltoFirewallParams.
func (mr *MockFirewallServiceIfaceMockRecorder) NewConfigurePaloAltoFirewallParams(fwdeviceid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewConfigurePaloAltoFirewallParams", reflect.TypeOf((*MockFirewallServiceIface)(nil).NewConfigurePaloAltoFirewallParams), fwdeviceid)
}

// NewCreateEgressFirewallRuleParams mocks base method.
func (m *MockFirewallServiceIface) NewCreateEgressFirewallRuleParams(networkid, protocol string) *CreateEgressFirewallRuleParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewCreateEgressFirewallRuleParams", networkid, protocol)
	ret0, _ := ret[0].(*CreateEgressFirewallRuleParams)
	return ret0
}

// NewCreateEgressFirewallRuleParams indicates an expected call of NewCreateEgressFirewallRuleParams.
func (mr *MockFirewallServiceIfaceMockRecorder) NewCreateEgressFirewallRuleParams(networkid, protocol any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewCreateEgressFirewallRuleParams", reflect.TypeOf((*MockFirewallServiceIface)(nil).NewCreateEgressFirewallRuleParams), networkid, protocol)
}

// NewCreateFirewallRuleParams mocks base method.
func (m *MockFirewallServiceIface) NewCreateFirewallRuleParams(ipaddressid, protocol string) *CreateFirewallRuleParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewCreateFirewallRuleParams", ipaddressid, protocol)
	ret0, _ := ret[0].(*CreateFirewallRuleParams)
	return ret0
}

// NewCreateFirewallRuleParams indicates an expected call of NewCreateFirewallRuleParams.
func (mr *MockFirewallServiceIfaceMockRecorder) NewCreateFirewallRuleParams(ipaddressid, protocol any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewCreateFirewallRuleParams", reflect.TypeOf((*MockFirewallServiceIface)(nil).NewCreateFirewallRuleParams), ipaddressid, protocol)
}

// NewCreateIpv6FirewallRuleParams mocks base method.
func (m *MockFirewallServiceIface) NewCreateIpv6FirewallRuleParams(networkid, protocol string) *CreateIpv6FirewallRuleParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewCreateIpv6FirewallRuleParams", networkid, protocol)
	ret0, _ := ret[0].(*CreateIpv6FirewallRuleParams)
	return ret0
}

// NewCreateIpv6FirewallRuleParams indicates an expected call of NewCreateIpv6FirewallRuleParams.
func (mr *MockFirewallServiceIfaceMockRecorder) NewCreateIpv6FirewallRuleParams(networkid, protocol any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewCreateIpv6FirewallRuleParams", reflect.TypeOf((*MockFirewallServiceIface)(nil).NewCreateIpv6FirewallRuleParams), networkid, protocol)
}

// NewCreatePortForwardingRuleParams mocks base method.
func (m *MockFirewallServiceIface) NewCreatePortForwardingRuleParams(ipaddressid string, privateport int, protocol string, publicport int, virtualmachineid string) *CreatePortForwardingRuleParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewCreatePortForwardingRuleParams", ipaddressid, privateport, protocol, publicport, virtualmachineid)
	ret0, _ := ret[0].(*CreatePortForwardingRuleParams)
	return ret0
}

// NewCreatePortForwardingRuleParams indicates an expected call of NewCreatePortForwardingRuleParams.
func (mr *MockFirewallServiceIfaceMockRecorder) NewCreatePortForwardingRuleParams(ipaddressid, privateport, protocol, publicport, virtualmachineid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewCreatePortForwardingRuleParams", reflect.TypeOf((*MockFirewallServiceIface)(nil).NewCreatePortForwardingRuleParams), ipaddressid, privateport, protocol, publicport, virtualmachineid)
}

// NewCreateRoutingFirewallRuleParams mocks base method.
func (m *MockFirewallServiceIface) NewCreateRoutingFirewallRuleParams(networkid, protocol string) *CreateRoutingFirewallRuleParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewCreateRoutingFirewallRuleParams", networkid, protocol)
	ret0, _ := ret[0].(*CreateRoutingFirewallRuleParams)
	return ret0
}

// NewCreateRoutingFirewallRuleParams indicates an expected call of NewCreateRoutingFirewallRuleParams.
func (mr *MockFirewallServiceIfaceMockRecorder) NewCreateRoutingFirewallRuleParams(networkid, protocol any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewCreateRoutingFirewallRuleParams", reflect.TypeOf((*MockFirewallServiceIface)(nil).NewCreateRoutingFirewallRuleParams), networkid, protocol)
}

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

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

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

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

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

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

// NewDeletePaloAltoFirewallParams mocks base method.
func (m *MockFirewallServiceIface) NewDeletePaloAltoFirewallParams(fwdeviceid string) *DeletePaloAltoFirewallParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewDeletePaloAltoFirewallParams", fwdeviceid)
	ret0, _ := ret[0].(*DeletePaloAltoFirewallParams)
	return ret0
}

// NewDeletePaloAltoFirewallParams indicates an expected call of NewDeletePaloAltoFirewallParams.
func (mr *MockFirewallServiceIfaceMockRecorder) NewDeletePaloAltoFirewallParams(fwdeviceid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDeletePaloAltoFirewallParams", reflect.TypeOf((*MockFirewallServiceIface)(nil).NewDeletePaloAltoFirewallParams), fwdeviceid)
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// UpdateEgressFirewallRule mocks base method.
func (m *MockFirewallServiceIface) UpdateEgressFirewallRule(p *UpdateEgressFirewallRuleParams) (*UpdateEgressFirewallRuleResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdateEgressFirewallRule", p)
	ret0, _ := ret[0].(*UpdateEgressFirewallRuleResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// UpdateFirewallRule mocks base method.
func (m *MockFirewallServiceIface) UpdateFirewallRule(p *UpdateFirewallRuleParams) (*UpdateFirewallRuleResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdateFirewallRule", p)
	ret0, _ := ret[0].(*UpdateFirewallRuleResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// UpdateIpv6FirewallRule mocks base method.
func (m *MockFirewallServiceIface) UpdateIpv6FirewallRule(p *UpdateIpv6FirewallRuleParams) (*UpdateIpv6FirewallRuleResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdateIpv6FirewallRule", p)
	ret0, _ := ret[0].(*UpdateIpv6FirewallRuleResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// UpdatePortForwardingRule mocks base method.
func (m *MockFirewallServiceIface) UpdatePortForwardingRule(p *UpdatePortForwardingRuleParams) (*UpdatePortForwardingRuleResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdatePortForwardingRule", p)
	ret0, _ := ret[0].(*UpdatePortForwardingRuleResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// UpdateRoutingFirewallRule mocks base method.
func (m *MockFirewallServiceIface) UpdateRoutingFirewallRule(p *UpdateRoutingFirewallRuleParams) (*UpdateRoutingFirewallRuleResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdateRoutingFirewallRule", p)
	ret0, _ := ret[0].(*UpdateRoutingFirewallRuleResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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