From e8d7e78b0bb9afc4f8d27d92a9bfef3e7039a1e6 Mon Sep 17 00:00:00 2001 From: Chris Selzo Date: Fri, 9 Feb 2024 11:55:19 -0800 Subject: [PATCH] Add `force-latest-variables` flag to `apply-changes` command OpsManager now supports a flag to the apply changes endpoint that forces BOSH to use the latest version of all variables. This is an escape hatch for the feature of automatically rotating certain certificates each time a new stemcell is deployed. [#186967065] --- acceptance/apply_changes_test.go | 5 +- api/installations_service.go | 16 ++++--- api/installations_service_test.go | 62 ++++++++++++++----------- commands/apply_changes.go | 17 +++---- commands/apply_changes_test.go | 31 ++++++++++--- commands/fakes/apply_changes_service.go | 34 +++++++------- 6 files changed, 100 insertions(+), 65 deletions(-) diff --git a/acceptance/apply_changes_test.go b/acceptance/apply_changes_test.go index ff9b477a3..b5fa3fcb9 100644 --- a/acceptance/apply_changes_test.go +++ b/acceptance/apply_changes_test.go @@ -1,10 +1,11 @@ package acceptance import ( - "github.com/onsi/gomega/ghttp" "net/http" "os/exec" + "github.com/onsi/gomega/ghttp" + "github.com/onsi/gomega/gbytes" "github.com/onsi/gomega/gexec" @@ -49,6 +50,7 @@ var _ = Describe("apply-changes command", func() { ghttp.VerifyRequest("POST", "/api/v0/installations"), ghttp.VerifyJSON(`{ "ignore_warnings": "false", + "force_latest_variables": false, "deploy_products": "all" }`), ghttp.RespondWith(http.StatusOK, `{"install": {"id": 42}}`), @@ -130,6 +132,7 @@ var _ = Describe("apply-changes command", func() { ghttp.VerifyRequest("POST", "/api/v0/installations"), ghttp.VerifyJSON(`{ "ignore_warnings": "false", + "force_latest_variables": false, "deploy_products": "all" }`), ghttp.RespondWith(http.StatusOK, `{"install": {"id": 42}}`), diff --git a/api/installations_service.go b/api/installations_service.go index 82e8c6db9..24246e96c 100644 --- a/api/installations_service.go +++ b/api/installations_service.go @@ -74,7 +74,7 @@ func (a Api) ListInstallations() ([]InstallationsServiceOutput, error) { return responseStruct.Installations, nil } -func (a Api) CreateInstallation(ignoreWarnings bool, deployProducts bool, productNames []string, errands ApplyErrandChanges) (InstallationsServiceOutput, error) { +func (a Api) CreateInstallation(ignoreWarnings bool, deployProducts bool, forceLatestVariables bool, productNames []string, errands ApplyErrandChanges) (InstallationsServiceOutput, error) { productGuidMapping, err := a.fetchProductGUID() if err != nil { return InstallationsServiceOutput{}, fmt.Errorf("failed to list staged and/or deployed products: %w", err) @@ -110,13 +110,15 @@ func (a Api) CreateInstallation(ignoreWarnings bool, deployProducts bool, produc } data, err := json.Marshal(&struct { - IgnoreWarnings string `json:"ignore_warnings"` - DeployProducts interface{} `json:"deploy_products"` - Errands map[string]ProductErrand `json:"errands,omitempty"` + IgnoreWarnings string `json:"ignore_warnings"` + ForceLatestVariables bool `json:"force_latest_variables"` + DeployProducts interface{} `json:"deploy_products"` + Errands map[string]ProductErrand `json:"errands,omitempty"` }{ - IgnoreWarnings: fmt.Sprintf("%t", ignoreWarnings), - DeployProducts: deployProductsVal, - Errands: errandsPayload, + IgnoreWarnings: fmt.Sprintf("%t", ignoreWarnings), + ForceLatestVariables: forceLatestVariables, + DeployProducts: deployProductsVal, + Errands: errandsPayload, }) if err != nil { return InstallationsServiceOutput{}, err diff --git a/api/installations_service_test.go b/api/installations_service_test.go index 1994ac965..6919fbce8 100644 --- a/api/installations_service_test.go +++ b/api/installations_service_test.go @@ -1,14 +1,16 @@ package api_test import ( - "github.com/onsi/gomega/gbytes" - "github.com/onsi/gomega/ghttp" "log" "net/http" "time" + "github.com/onsi/gomega/gbytes" + "github.com/onsi/gomega/ghttp" + . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + "github.com/pivotal-cf/om/api" ) @@ -108,12 +110,12 @@ var _ = Describe("InstallationsService", func() { ), ghttp.CombineHandlers( ghttp.VerifyRequest("POST", "/api/v0/installations"), - ghttp.VerifyJSON(`{"ignore_warnings":"false", "deploy_products":"all"}`), + ghttp.VerifyJSON(`{"ignore_warnings":"false","force_latest_variables":false, "deploy_products":"all"}`), ghttp.RespondWith(http.StatusOK, `{"install": {"id":1}}`), ), ) - output, err := service.CreateInstallation(false, true, nil, api.ApplyErrandChanges{}) + output, err := service.CreateInstallation(false, true, false, nil, api.ApplyErrandChanges{}) Expect(err).ToNot(HaveOccurred()) Expect(output.ID).To(Equal(1)) @@ -133,12 +135,12 @@ var _ = Describe("InstallationsService", func() { ), ghttp.CombineHandlers( ghttp.VerifyRequest("POST", "/api/v0/installations"), - ghttp.VerifyJSON(`{"ignore_warnings":"false", "deploy_products":"none"}`), + ghttp.VerifyJSON(`{"ignore_warnings":"false","force_latest_variables":false, "deploy_products":"none"}`), ghttp.RespondWith(http.StatusOK, `{"install": {"id":1}}`), ), ) - output, err := service.CreateInstallation(false, false, nil, api.ApplyErrandChanges{}) + output, err := service.CreateInstallation(false, false, false, nil, api.ApplyErrandChanges{}) Expect(err).ToNot(HaveOccurred()) Expect(output.ID).To(Equal(1)) @@ -158,30 +160,38 @@ var _ = Describe("InstallationsService", func() { ), ghttp.CombineHandlers( ghttp.VerifyRequest("POST", "/api/v0/installations"), - ghttp.VerifyJSON(`{"ignore_warnings":"false","deploy_products":["guid2"]}`), + ghttp.VerifyJSON(`{"ignore_warnings":"false","force_latest_variables":false,"deploy_products":["guid2"]}`), ghttp.RespondWith(http.StatusOK, `{"install": {"id":1}}`), ), ) - output, err := service.CreateInstallation(false, true, []string{"product2"}, api.ApplyErrandChanges{}) + output, err := service.CreateInstallation(false, true, false, []string{"product2"}, api.ApplyErrandChanges{}) Expect(err).ToNot(HaveOccurred()) Expect(output.ID).To(Equal(1)) }) + }) - It("errors when the product does not exist", func() { + When("forcing latest variables", func() { + It("triggers an installation on an Ops Manager, forcing latest variables", func() { client.AppendHandlers( ghttp.CombineHandlers( ghttp.VerifyRequest("GET", "/api/v0/staged/products"), - ghttp.RespondWith(http.StatusOK, `[{"guid": "guid1", "type": "product1"}]`), + ghttp.RespondWith(http.StatusOK, `[{"guid": "guid1", "type": "product1"}, {"guid": "guid2", "type": "product2"}]`), ), ghttp.CombineHandlers( ghttp.VerifyRequest("GET", "/api/v0/deployed/products"), - ghttp.RespondWith(http.StatusOK, `[{"guid": "guid1", "type": "product1"}]`), + ghttp.RespondWith(http.StatusOK, `[{"guid": "guid1", "type": "product1"}, {"guid": "guid2", "type": "product2"}]`), + ), + ghttp.CombineHandlers( + ghttp.VerifyRequest("POST", "/api/v0/installations"), + ghttp.VerifyJSON(`{"ignore_warnings":"false","force_latest_variables":true,"deploy_products":["guid2"]}`), + ghttp.RespondWith(http.StatusOK, `{"install": {"id":1}}`), ), ) - _, err := service.CreateInstallation(false, true, []string{"product2"}, api.ApplyErrandChanges{}) - Expect(err).To(HaveOccurred()) + output, err := service.CreateInstallation(false, true, true, []string{"product2"}, api.ApplyErrandChanges{}) + Expect(err).ToNot(HaveOccurred()) + Expect(output.ID).To(Equal(1)) }) }) @@ -199,12 +209,12 @@ var _ = Describe("InstallationsService", func() { ), ghttp.CombineHandlers( ghttp.VerifyRequest("POST", "/api/v0/installations"), - ghttp.VerifyJSON(`{"ignore_warnings": "false", "deploy_products": ["guid1"], "errands": {"guid1": {"run_post_deploy": {"errand1": "default"}}}}`), + ghttp.VerifyJSON(`{"ignore_warnings": "false", "force_latest_variables": false, "deploy_products": ["guid1"], "errands": {"guid1": {"run_post_deploy": {"errand1": "default"}}}}`), ghttp.RespondWith(http.StatusOK, `{"install": {"id":1}}`), ), ) - output, err := service.CreateInstallation(false, true, []string{"product1"}, api.ApplyErrandChanges{ + output, err := service.CreateInstallation(false, true, false, []string{"product1"}, api.ApplyErrandChanges{ Errands: map[string]api.ProductErrand{ "product1": { RunPostDeploy: map[string]interface{}{ @@ -229,12 +239,12 @@ var _ = Describe("InstallationsService", func() { ), ghttp.CombineHandlers( ghttp.VerifyRequest("POST", "/api/v0/installations"), - ghttp.VerifyJSON(`{"ignore_warnings": "false", "deploy_products": ["guid2"]}`), + ghttp.VerifyJSON(`{"ignore_warnings": "false", "force_latest_variables": false, "deploy_products": ["guid2"]}`), ghttp.RespondWith(http.StatusOK, `{"install": {"id":1}}`), ), ) - _, err := service.CreateInstallation(false, true, []string{"product2"}, api.ApplyErrandChanges{ + _, err := service.CreateInstallation(false, true, false, []string{"product2"}, api.ApplyErrandChanges{ Errands: map[string]api.ProductErrand{ "product3": { RunPostDeploy: map[string]interface{}{ @@ -261,12 +271,12 @@ var _ = Describe("InstallationsService", func() { ), ghttp.CombineHandlers( ghttp.VerifyRequest("POST", "/api/v0/installations"), - ghttp.VerifyJSON(`{"ignore_warnings": "false", "deploy_products": "all", "errands": {"guid1": {"run_post_deploy": {"errand1": "default"}}}}`), + ghttp.VerifyJSON(`{"ignore_warnings": "false", "force_latest_variables": false, "deploy_products": "all", "errands": {"guid1": {"run_post_deploy": {"errand1": "default"}}}}`), ghttp.RespondWith(http.StatusOK, `{"install": {"id":1}}`), ), ) - output, err := service.CreateInstallation(false, true, []string{}, api.ApplyErrandChanges{ + output, err := service.CreateInstallation(false, true, false, []string{}, api.ApplyErrandChanges{ Errands: map[string]api.ProductErrand{ "product1": { RunPostDeploy: map[string]interface{}{ @@ -291,12 +301,12 @@ var _ = Describe("InstallationsService", func() { ), ghttp.CombineHandlers( ghttp.VerifyRequest("POST", "/api/v0/installations"), - ghttp.VerifyJSON(`{"ignore_warnings": "false", "deploy_products": ["guid2"], "errands": {"guid1": {"run_post_deploy": {"errand1": "default"}}}}`), + ghttp.VerifyJSON(`{"ignore_warnings": "false", "force_latest_variables": false, "deploy_products": ["guid2"], "errands": {"guid1": {"run_post_deploy": {"errand1": "default"}}}}`), ghttp.RespondWith(http.StatusOK, `{"install": {"id":1}}`), ), ) - _, err := service.CreateInstallation(false, true, []string{}, api.ApplyErrandChanges{ + _, err := service.CreateInstallation(false, true, false, []string{}, api.ApplyErrandChanges{ Errands: map[string]api.ProductErrand{ "product1": { RunPostDeploy: map[string]interface{}{ @@ -330,7 +340,7 @@ var _ = Describe("InstallationsService", func() { ), ) - _, err := service.CreateInstallation(false, true, nil, api.ApplyErrandChanges{}) + _, err := service.CreateInstallation(false, true, false, nil, api.ApplyErrandChanges{}) Expect(err).To(MatchError(ContainSubstring("could not make api request to installations endpoint: could not send api request to POST /api/v0/installations"))) }) }) @@ -348,7 +358,7 @@ var _ = Describe("InstallationsService", func() { ), ghttp.CombineHandlers( ghttp.VerifyRequest("POST", "/api/v0/installations"), - ghttp.VerifyJSON(`{"ignore_warnings":"false","deploy_products":["guid2"]}`), + ghttp.VerifyJSON(`{"ignore_warnings":"false","force_latest_variables":false,"deploy_products":["guid2"]}`), ghttp.RespondWith(http.StatusUnprocessableEntity, `{ "errors": ["'Some IAAS Error', type: SomeVerifier""], "deployment_errors": { @@ -365,7 +375,7 @@ var _ = Describe("InstallationsService", func() { ), ) - _, err := service.CreateInstallation(false, true, []string{"product2"}, api.ApplyErrandChanges{}) + _, err := service.CreateInstallation(false, true, false, []string{"product2"}, api.ApplyErrandChanges{}) Expect(err).To(MatchError(ContainSubstring("request failed: unexpected response"))) Expect(err).To(MatchError(ContainSubstring("Tip: In Ops Manager 2.6 or newer, you can use `om pre-deploy-check` to get a complete list of failed verifiers and om commands to disable them."))) }) @@ -380,7 +390,7 @@ var _ = Describe("InstallationsService", func() { ), ) - _, err := service.CreateInstallation(false, true, nil, api.ApplyErrandChanges{}) + _, err := service.CreateInstallation(false, true, false, nil, api.ApplyErrandChanges{}) Expect(err).To(MatchError(ContainSubstring("request failed: unexpected response"))) }) }) @@ -402,7 +412,7 @@ var _ = Describe("InstallationsService", func() { ), ) - _, err := service.CreateInstallation(false, true, nil, api.ApplyErrandChanges{}) + _, err := service.CreateInstallation(false, true, false, nil, api.ApplyErrandChanges{}) Expect(err).To(MatchError(ContainSubstring("failed to decode response: invalid character"))) }) }) diff --git a/commands/apply_changes.go b/commands/apply_changes.go index 5344b7f3c..3b8a795c1 100644 --- a/commands/apply_changes.go +++ b/commands/apply_changes.go @@ -20,18 +20,19 @@ type ApplyChanges struct { logWriter logWriter waitDuration time.Duration Options struct { - Config string `short:"c" long:"config" description:"path to yml file containing errand configuration (see docs/apply-changes/README.md for format)"` - IgnoreWarnings bool `short:"i" long:"ignore-warnings" description:"For convenience. Use other commands to disable particular verifiers if they are inappropriate."` - Reattach bool `long:"reattach" description:"reattach to an already running apply changes (if available)"` - RecreateVMs bool `long:"recreate-vms" description:"recreate all vms"` - SkipDeployProducts bool `short:"s" long:"skip-deploy-products" description:"skip deploying products when applying changes - just update the director"` - ProductNames []string `short:"n" long:"product-name" description:"name of the product(s) to deploy, cannot be used in conjunction with --skip-deploy-products (OM 2.2+)"` + Config string `short:"c" long:"config" description:"path to yml file containing errand configuration (see docs/apply-changes/README.md for format)"` + IgnoreWarnings bool `short:"i" long:"ignore-warnings" description:"For convenience. Use other commands to disable particular verifiers if they are inappropriate."` + Reattach bool `long:"reattach" description:"reattach to an already running apply changes (if available)"` + RecreateVMs bool `long:"recreate-vms" description:"recreate all vms"` + SkipDeployProducts bool `short:"s" long:"skip-deploy-products" description:"skip deploying products when applying changes - just update the director"` + ForceLatestVariables bool `long:"force-latest-variables" description:"force any certificates or other BOSH variables to use their latest version even when a stemcell is not being upgraded"` + ProductNames []string `short:"n" long:"product-name" description:"name of the product(s) to deploy, cannot be used in conjunction with --skip-deploy-products (OM 2.2+)"` } } //counterfeiter:generate -o ./fakes/apply_changes_service.go --fake-name ApplyChangesService . applyChangesService type applyChangesService interface { - CreateInstallation(bool, bool, []string, api.ApplyErrandChanges) (api.InstallationsServiceOutput, error) + CreateInstallation(bool, bool, bool, []string, api.ApplyErrandChanges) (api.InstallationsServiceOutput, error) GetInstallation(id int) (api.InstallationsServiceOutput, error) GetInstallationLogs(id int) (api.InstallationsServiceOutput, error) Info() (api.Info, error) @@ -158,7 +159,7 @@ func (ac ApplyChanges) Execute(args []string) error { } ac.logger.Printf("attempting to apply changes to the targeted Ops Manager") - installation, err = ac.service.CreateInstallation(ac.Options.IgnoreWarnings, !ac.Options.SkipDeployProducts, changedProducts, errands) + installation, err = ac.service.CreateInstallation(ac.Options.IgnoreWarnings, !ac.Options.SkipDeployProducts, ac.Options.ForceLatestVariables, changedProducts, errands) if err != nil { return fmt.Errorf("installation failed to trigger: %s", err) } diff --git a/commands/apply_changes_test.go b/commands/apply_changes_test.go index 5fc95ecdb..27da14da6 100644 --- a/commands/apply_changes_test.go +++ b/commands/apply_changes_test.go @@ -3,14 +3,15 @@ package commands_test import ( "errors" "fmt" - "github.com/onsi/gomega/gbytes" - "gopkg.in/yaml.v2" "io/ioutil" "log" "os" "regexp" "time" + "github.com/onsi/gomega/gbytes" + "gopkg.in/yaml.v2" + "github.com/pivotal-cf/om/api" "github.com/pivotal-cf/om/commands" "github.com/pivotal-cf/om/commands/fakes" @@ -60,9 +61,10 @@ var _ = Describe("ApplyChanges", func() { Expect(service.CreateInstallationCallCount()).To(Equal(1)) - ignoreWarnings, deployProducts, _, _ := service.CreateInstallationArgsForCall(0) + ignoreWarnings, deployProducts, forceLatestVariables, _, _ := service.CreateInstallationArgsForCall(0) Expect(ignoreWarnings).To(Equal(false)) Expect(deployProducts).To(Equal(true)) + Expect(forceLatestVariables).To(Equal(false)) Expect(stderr).To(gbytes.Say("attempting to apply changes to the targeted Ops Manager")) @@ -116,11 +118,25 @@ var _ = Describe("ApplyChanges", func() { err := executeCommand(command, []string{"--ignore-warnings"}) Expect(err).ToNot(HaveOccurred()) - ignoreWarnings, _, _, _ := service.CreateInstallationArgsForCall(0) + ignoreWarnings, _, _, _, _ := service.CreateInstallationArgsForCall(0) Expect(ignoreWarnings).To(Equal(true)) }) }) + When("passed the force-latest-variables flag", func() { + It("applies changes while forcing the latest variable versions to be used", func() { + service.InfoReturns(api.Info{Version: "2.3-build43"}, nil) + + command := commands.NewApplyChanges(service, pendingService, writer, logger, 1) + + err := executeCommand(command, []string{"--force-latest-variables"}) + Expect(err).ToNot(HaveOccurred()) + + _, _, forceLatestVariables, _, _ := service.CreateInstallationArgsForCall(0) + Expect(forceLatestVariables).To(Equal(true)) + }) + }) + When("passed the skip-deploy-products flag", func() { It("applies changes while not deploying products", func() { command := commands.NewApplyChanges(service, pendingService, writer, logger, 1) @@ -128,7 +144,7 @@ var _ = Describe("ApplyChanges", func() { err := executeCommand(command, []string{"--skip-deploy-products"}) Expect(err).ToNot(HaveOccurred()) - _, deployProducts, _, _ := service.CreateInstallationArgsForCall(0) + _, _, deployProducts, _, _ := service.CreateInstallationArgsForCall(0) Expect(deployProducts).To(Equal(false)) }) @@ -149,7 +165,7 @@ var _ = Describe("ApplyChanges", func() { err := executeCommand(command, []string{"--product-name", "product1", "--product-name", "product2"}) Expect(err).To(HaveOccurred()) - _, _, productNames, _ := service.CreateInstallationArgsForCall(0) + _, _, _, productNames, _ := service.CreateInstallationArgsForCall(0) Expect(productNames).To(ConsistOf("product1", "product2")) }) }) @@ -382,9 +398,10 @@ errands: Expect(service.CreateInstallationCallCount()).To(Equal(1)) - ignoreWarnings, deployProducts, _, errands := service.CreateInstallationArgsForCall(0) + ignoreWarnings, deployProducts, forceLatestVariables, _, errands := service.CreateInstallationArgsForCall(0) Expect(ignoreWarnings).To(Equal(false)) Expect(deployProducts).To(Equal(true)) + Expect(forceLatestVariables).To(Equal(false)) Expect(errands).To(Equal(api.ApplyErrandChanges{ Errands: map[string]api.ProductErrand{ "product1_name": { diff --git a/commands/fakes/apply_changes_service.go b/commands/fakes/apply_changes_service.go index 04d498319..9e0a26b43 100644 --- a/commands/fakes/apply_changes_service.go +++ b/commands/fakes/apply_changes_service.go @@ -8,13 +8,14 @@ import ( ) type ApplyChangesService struct { - CreateInstallationStub func(bool, bool, []string, api.ApplyErrandChanges) (api.InstallationsServiceOutput, error) + CreateInstallationStub func(bool, bool, bool, []string, api.ApplyErrandChanges) (api.InstallationsServiceOutput, error) createInstallationMutex sync.RWMutex createInstallationArgsForCall []struct { arg1 bool arg2 bool - arg3 []string - arg4 api.ApplyErrandChanges + arg3 bool + arg4 []string + arg5 api.ApplyErrandChanges } createInstallationReturns struct { result1 api.InstallationsServiceOutput @@ -101,24 +102,25 @@ type ApplyChangesService struct { invocationsMutex sync.RWMutex } -func (fake *ApplyChangesService) CreateInstallation(arg1 bool, arg2 bool, arg3 []string, arg4 api.ApplyErrandChanges) (api.InstallationsServiceOutput, error) { - var arg3Copy []string - if arg3 != nil { - arg3Copy = make([]string, len(arg3)) - copy(arg3Copy, arg3) +func (fake *ApplyChangesService) CreateInstallation(arg1 bool, arg2 bool, arg3 bool, arg4 []string, arg5 api.ApplyErrandChanges) (api.InstallationsServiceOutput, error) { + var arg4Copy []string + if arg4 != nil { + arg4Copy = make([]string, len(arg4)) + copy(arg4Copy, arg4) } fake.createInstallationMutex.Lock() ret, specificReturn := fake.createInstallationReturnsOnCall[len(fake.createInstallationArgsForCall)] fake.createInstallationArgsForCall = append(fake.createInstallationArgsForCall, struct { arg1 bool arg2 bool - arg3 []string - arg4 api.ApplyErrandChanges - }{arg1, arg2, arg3Copy, arg4}) - fake.recordInvocation("CreateInstallation", []interface{}{arg1, arg2, arg3Copy, arg4}) + arg3 bool + arg4 []string + arg5 api.ApplyErrandChanges + }{arg1, arg2, arg3, arg4Copy, arg5}) + fake.recordInvocation("CreateInstallation", []interface{}{arg1, arg2, arg3, arg4Copy, arg5}) fake.createInstallationMutex.Unlock() if fake.CreateInstallationStub != nil { - return fake.CreateInstallationStub(arg1, arg2, arg3, arg4) + return fake.CreateInstallationStub(arg1, arg2, arg3, arg4, arg5) } if specificReturn { return ret.result1, ret.result2 @@ -133,17 +135,17 @@ func (fake *ApplyChangesService) CreateInstallationCallCount() int { return len(fake.createInstallationArgsForCall) } -func (fake *ApplyChangesService) CreateInstallationCalls(stub func(bool, bool, []string, api.ApplyErrandChanges) (api.InstallationsServiceOutput, error)) { +func (fake *ApplyChangesService) CreateInstallationCalls(stub func(bool, bool, bool, []string, api.ApplyErrandChanges) (api.InstallationsServiceOutput, error)) { fake.createInstallationMutex.Lock() defer fake.createInstallationMutex.Unlock() fake.CreateInstallationStub = stub } -func (fake *ApplyChangesService) CreateInstallationArgsForCall(i int) (bool, bool, []string, api.ApplyErrandChanges) { +func (fake *ApplyChangesService) CreateInstallationArgsForCall(i int) (bool, bool, bool, []string, api.ApplyErrandChanges) { fake.createInstallationMutex.RLock() defer fake.createInstallationMutex.RUnlock() argsForCall := fake.createInstallationArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4, argsForCall.arg5 } func (fake *ApplyChangesService) CreateInstallationReturns(result1 api.InstallationsServiceOutput, result2 error) {