1package cmd
2
3import (
4	"os"
5	"path/filepath"
6	"time"
7
8	"github.com/cppforlife/go-patch/patch"
9
10	bihttpagent "github.com/cloudfoundry/bosh-agent/agentclient/http"
11	biblobstore "github.com/cloudfoundry/bosh-cli/blobstore"
12	bicloud "github.com/cloudfoundry/bosh-cli/cloud"
13	biconfig "github.com/cloudfoundry/bosh-cli/config"
14	bicpirel "github.com/cloudfoundry/bosh-cli/cpi/release"
15	bidepl "github.com/cloudfoundry/bosh-cli/deployment"
16	bidisk "github.com/cloudfoundry/bosh-cli/deployment/disk"
17	biinstance "github.com/cloudfoundry/bosh-cli/deployment/instance"
18	biinstancestate "github.com/cloudfoundry/bosh-cli/deployment/instance/state"
19	bideplmanifest "github.com/cloudfoundry/bosh-cli/deployment/manifest"
20	bideplrel "github.com/cloudfoundry/bosh-cli/deployment/release"
21	bisshtunnel "github.com/cloudfoundry/bosh-cli/deployment/sshtunnel"
22	bidepltpl "github.com/cloudfoundry/bosh-cli/deployment/template"
23	bivm "github.com/cloudfoundry/bosh-cli/deployment/vm"
24	boshtpl "github.com/cloudfoundry/bosh-cli/director/template"
25	biindex "github.com/cloudfoundry/bosh-cli/index"
26	boshinst "github.com/cloudfoundry/bosh-cli/installation"
27	boshinstmanifest "github.com/cloudfoundry/bosh-cli/installation/manifest"
28	bitarball "github.com/cloudfoundry/bosh-cli/installation/tarball"
29	biregistry "github.com/cloudfoundry/bosh-cli/registry"
30	boshrel "github.com/cloudfoundry/bosh-cli/release"
31	birelsetmanifest "github.com/cloudfoundry/bosh-cli/release/set/manifest"
32	bistatepkg "github.com/cloudfoundry/bosh-cli/state/pkg"
33	bistemcell "github.com/cloudfoundry/bosh-cli/stemcell"
34	bitemplate "github.com/cloudfoundry/bosh-cli/templatescompiler"
35	bitemplateerb "github.com/cloudfoundry/bosh-cli/templatescompiler/erbrenderer"
36	"github.com/cloudfoundry/bosh-utils/httpclient"
37)
38
39type envFactory struct {
40	deps         BasicDeps
41	manifestPath string
42	manifestVars boshtpl.Variables
43	manifestOp   patch.Op
44
45	deploymentStateService     biconfig.DeploymentStateService
46	installationManifestParser ReleaseSetAndInstallationManifestParser
47
48	releaseManager  boshinst.ReleaseManager
49	releaseFetcher  boshinst.ReleaseFetcher
50	stemcellFetcher bistemcell.Fetcher
51
52	cpiInstaller   bicpirel.CpiInstaller
53	targetProvider boshinst.TargetProvider
54	cloudFactory   bicloud.Factory
55
56	diskManagerFactory     bidisk.ManagerFactory
57	vmManagerFactory       bivm.ManagerFactory
58	stemcellManagerFactory bistemcell.ManagerFactory
59
60	instanceManagerFactory   biinstance.ManagerFactory
61	deploymentManagerFactory bidepl.ManagerFactory
62
63	agentClientFactory bihttpagent.AgentClientFactory
64	blobstoreFactory   biblobstore.Factory
65	deploymentFactory  bidepl.Factory
66	deploymentRecord   bidepl.Record
67}
68
69func NewEnvFactory(
70	deps BasicDeps,
71	manifestPath string,
72	statePath string,
73	manifestVars boshtpl.Variables,
74	manifestOp patch.Op,
75	recreatePersistentDisks bool,
76) *envFactory {
77	f := envFactory{
78		deps:         deps,
79		manifestPath: manifestPath,
80		manifestVars: manifestVars,
81		manifestOp:   manifestOp,
82	}
83
84	f.releaseManager = boshinst.NewReleaseManager(deps.Logger)
85	releaseJobResolver := bideplrel.NewJobResolver(f.releaseManager)
86
87	// todo expand path?
88	workspaceRootPath := filepath.Join(os.Getenv("HOME"), ".bosh")
89
90	{
91		tarballCacheBasePath := filepath.Join(workspaceRootPath, "downloads")
92		tarballCache := bitarball.NewCache(tarballCacheBasePath, deps.FS, deps.Logger)
93		httpClient := httpclient.NewHTTPClient(httpclient.CreateDefaultClient(nil), deps.Logger)
94		tarballProvider := bitarball.NewProvider(
95			tarballCache, deps.FS, httpClient, 3, 500*time.Millisecond, deps.Logger)
96
97		releaseProvider := boshrel.NewProvider(
98			deps.CmdRunner, deps.Compressor, deps.DigestCalculator, deps.FS, deps.Logger)
99
100		f.releaseFetcher = boshinst.NewReleaseFetcher(
101			tarballProvider,
102			releaseProvider.NewExtractingArchiveReader(),
103			f.releaseManager,
104		)
105
106		stemcellReader := bistemcell.NewReader(deps.Compressor, deps.FS)
107		stemcellExtractor := bistemcell.NewExtractor(stemcellReader, deps.FS)
108
109		f.stemcellFetcher = bistemcell.Fetcher{
110			TarballProvider:   tarballProvider,
111			StemcellExtractor: stemcellExtractor,
112		}
113	}
114
115	f.deploymentStateService = biconfig.NewFileSystemDeploymentStateService(
116		deps.FS, deps.UUIDGen, deps.Logger, biconfig.DeploymentStatePath(manifestPath, statePath))
117
118	{
119		registryServer := biregistry.NewServerManager(deps.Logger)
120		installerFactory := boshinst.NewInstallerFactory(
121			deps.UI, deps.CmdRunner, deps.Compressor, releaseJobResolver,
122			deps.UUIDGen, registryServer, deps.Logger, deps.FS, deps.DigestCreationAlgorithms)
123
124		f.cpiInstaller = bicpirel.CpiInstaller{
125			ReleaseManager:   f.releaseManager,
126			InstallerFactory: installerFactory,
127			Validator:        bicpirel.NewValidator(),
128		}
129	}
130
131	f.targetProvider = boshinst.NewTargetProvider(
132		f.deploymentStateService, deps.UUIDGen, filepath.Join(workspaceRootPath, "installations"))
133
134	{
135		diskRepo := biconfig.NewDiskRepo(f.deploymentStateService, deps.UUIDGen)
136		stemcellRepo := biconfig.NewStemcellRepo(f.deploymentStateService, deps.UUIDGen)
137		vmRepo := biconfig.NewVMRepo(f.deploymentStateService)
138
139		f.diskManagerFactory = bidisk.NewManagerFactory(diskRepo, deps.Logger)
140		diskDeployer := bivm.NewDiskDeployer(f.diskManagerFactory, diskRepo, deps.Logger, recreatePersistentDisks)
141
142		f.stemcellManagerFactory = bistemcell.NewManagerFactory(stemcellRepo)
143		f.vmManagerFactory = bivm.NewManagerFactory(
144			vmRepo, stemcellRepo, diskDeployer, deps.UUIDGen, deps.FS, deps.Logger)
145
146		deploymentRepo := biconfig.NewDeploymentRepo(f.deploymentStateService)
147		releaseRepo := biconfig.NewReleaseRepo(f.deploymentStateService, deps.UUIDGen)
148		f.deploymentRecord = bidepl.NewRecord(deploymentRepo, releaseRepo, stemcellRepo)
149	}
150
151	{
152		f.blobstoreFactory = biblobstore.NewBlobstoreFactory(deps.UUIDGen, deps.FS, deps.Logger)
153		f.deploymentFactory = bidepl.NewFactory(10*time.Second, 500*time.Millisecond)
154		f.agentClientFactory = bihttpagent.NewAgentClientFactory(1*time.Second, deps.Logger)
155		f.cloudFactory = bicloud.NewFactory(deps.FS, deps.CmdRunner, deps.Logger)
156	}
157
158	{
159		erbRenderer := bitemplateerb.NewERBRenderer(deps.FS, deps.CmdRunner, deps.Logger)
160		jobRenderer := bitemplate.NewJobRenderer(erbRenderer, deps.FS, deps.UUIDGen, deps.Logger)
161
162		builderFactory := biinstancestate.NewBuilderFactory(
163			bistatepkg.NewCompiledPackageRepo(biindex.NewInMemoryIndex()),
164			releaseJobResolver,
165			bitemplate.NewJobListRenderer(jobRenderer, deps.Logger),
166			bitemplate.NewRenderedJobListCompressor(deps.FS, deps.Compressor, deps.DigestCalculator, deps.Logger),
167			deps.Logger,
168		)
169
170		sshTunnelFactory := bisshtunnel.NewFactory(deps.Logger)
171		instanceFactory := biinstance.NewFactory(builderFactory)
172
173		f.instanceManagerFactory = biinstance.NewManagerFactory(
174			sshTunnelFactory, instanceFactory, deps.Logger)
175	}
176
177	{
178		releaseSetValidator := birelsetmanifest.NewValidator(deps.Logger)
179		releaseSetParser := birelsetmanifest.NewParser(deps.FS, deps.Logger, releaseSetValidator)
180
181		installValidator := boshinstmanifest.NewValidator(deps.Logger)
182		installParser := boshinstmanifest.NewParser(deps.FS, deps.UUIDGen, deps.Logger, installValidator)
183
184		f.installationManifestParser = ReleaseSetAndInstallationManifestParser{
185			ReleaseSetParser:   releaseSetParser,
186			InstallationParser: installParser,
187		}
188	}
189
190	return &f
191}
192
193func (f *envFactory) Preparer() DeploymentPreparer {
194	return NewDeploymentPreparer(
195		f.deps.UI,
196		f.deps.Logger,
197		"DeploymentPreparer",
198		f.deploymentStateService,
199		biconfig.NewLegacyDeploymentStateMigrator(
200			f.deploymentStateService,
201			f.deps.FS,
202			f.deps.UUIDGen,
203			f.deps.Logger,
204		),
205		f.releaseManager,
206		f.deploymentRecord,
207		f.cloudFactory,
208		f.stemcellManagerFactory,
209		f.agentClientFactory,
210		f.vmManagerFactory,
211		f.blobstoreFactory,
212		bidepl.NewDeployer(
213			f.vmManagerFactory,
214			f.instanceManagerFactory,
215			f.deploymentFactory,
216			f.deps.Logger,
217		),
218		f.manifestPath,
219		f.manifestVars,
220		f.manifestOp,
221		f.cpiInstaller,
222		f.releaseFetcher,
223		f.stemcellFetcher,
224		f.installationManifestParser,
225		NewDeploymentManifestParser(
226			bideplmanifest.NewParser(f.deps.FS, f.deps.Logger),
227			bideplmanifest.NewValidator(f.deps.Logger),
228			f.releaseManager,
229			bidepltpl.NewDeploymentTemplateFactory(f.deps.FS),
230		),
231		NewTempRootConfigurator(f.deps.FS),
232		f.targetProvider,
233	)
234}
235
236func (f *envFactory) Deleter() DeploymentDeleter {
237	return NewDeploymentDeleter(
238		f.deps.UI,
239		"DeploymentDeleter",
240		f.deps.Logger,
241		f.deploymentStateService,
242		f.releaseManager,
243		f.cloudFactory,
244		f.agentClientFactory,
245		f.blobstoreFactory,
246		bidepl.NewManagerFactory(
247			f.vmManagerFactory,
248			f.instanceManagerFactory,
249			f.diskManagerFactory,
250			f.stemcellManagerFactory,
251			f.deploymentFactory,
252		),
253		f.manifestPath,
254		f.manifestVars,
255		f.manifestOp,
256		f.cpiInstaller,
257		boshinst.NewUninstaller(f.deps.FS, f.deps.Logger),
258		f.releaseFetcher,
259		f.installationManifestParser,
260		NewTempRootConfigurator(f.deps.FS),
261		f.targetProvider,
262	)
263}
264