Completed
Pull Request — master (#627)
by Stig
06:52 queued 03:13
created

DeployDispatcher::start()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 30
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 30
rs 8.8571
cc 1
eloc 14
nc 1
nop 1
1
<?php
2
3
/**
4
 * This dispatcher takes care of updating and returning information about this
5
 * projects git repository
6
 */
7
class DeployDispatcher extends Dispatcher {
8
9
	const ACTION_DEPLOY = 'deploy';
10
11
	/**
12
	 * @var array
13
	 */
14
	private static $action_types = [
15
		self::ACTION_DEPLOY
16
	];
17
18
	/**
19
	 * @var array
20
	 */
21
	public static $allowed_actions = [
22
		'history',
23
		'start',
24
		'log'
25
	];
26
27
	/**
28
	 * @var \DNProject
29
	 */
30
	protected $project = null;
31
32
	/**
33
	 * @var \DNEnvironment
34
	 */
35
	protected $environment = null;
36
37 View Code Duplication
	public function init() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
38
		parent::init();
39
40
		$this->project = $this->getCurrentProject();
41
42
		if(!$this->project) {
43
			return $this->project404Response();
44
		}
45
46
		// Performs canView permission check by limiting visible projects
47
		$this->environment = $this->getCurrentEnvironment($this->project);
48
		if(!$this->environment) {
49
			return $this->environment404Response();
50
		}
51
	}
52
53
	/**
54
	 *
55
	 * @param \SS_HTTPRequest $request
56
	 *
57
	 * @return \HTMLText|\SS_HTTPResponse
58
	 */
59
	public function index(\SS_HTTPRequest $request) {
60
		return $this->redirect(\Controller::join_links($this->Link(), 'history'), 302);
61
	}
62
63
	/**
64
	 * @return SS_HTTPResponse
65
	 */
66
	public function history(SS_HTTPRequest $request) {
67
		$data = [];
68
		$list = $this->DeployHistory();
69
		$page = $request->getVar('page') ?: 1;
70
		if ($page > $list->TotalPages()) {
71
			$page = 1;
72
		}
73
		if ($page < 1) {
74
			$page = 1;
75
		}
76
		$start = ($page - 1) * $list->getPageLength();
77
		$list->setPageStart((int) $start);
78
		if (empty($list)) {
79
			return $this->getAPIResponse(['message' => 'No deploy history'], 404);
80
		}
81
82
		foreach ($list as $deployment) {
83
			$data[] = [
84
				'CreatedDate' => $deployment->Created,
85
				'Branch' => $deployment->Branch,
86
				'Tags' => $deployment->getTags()->toArray(),
87
				'Changes' => $deployment->getDeploymentStrategy()->getChanges(),
88
				'CommitMessage' => $deployment->getCommitMessage(),
89
				'Deployer' => $deployment->Deployer()->getName(),
90
				'Approver' => $deployment->Approver()->getName(),
91
				'State' => $deployment->State,
92
			];
93
		}
94
95
		return $this->getAPIResponse(
96
			[
97
				'list' => $data,
98
				'pagelength' => $list->getPageLength(),
99
				'pagestart' => $list->getPageStart(),
100
				'totalpages' => $list->TotalPages(),
101
				'currentpage' => $list->CurrentPage()
102
			],
103
			200
104
		);
105
	}
106
107
	/**
108
	 *
109
	 * @param SS_HTTPRequest $request
110
	 *
111
	 * @return SS_HTTPResponse
112
	 * @throws ValidationException
113
	 * @throws null
114
	 */
115
	public function start(SS_HTTPRequest $request) {
116
		$this->checkSecurityToken();
117
118
		// @todo permission checks?
119
120
		// Initiate the deployment
121
		// The extension point should pass in: Project, Environment, SelectRelease, buildName
122
		// @todo: compat breakage: check what extends this in DNRoot and switch it to this dispatcher
123
		$this->extend('doDeploy', $this->project, $this->environment, $buildName, $data);
124
125
		$options = [
126
			'sha' => $request->requestVar('sha'),
127
		];
128
129
		// @todo replan and check if it's changed compared since it was originally planned?
130
		$strategy = $this->environment->Backend()->planDeploy($this->environment, $options);
131
132
		$strategy->fromArray($request->requestVars());
133
		$deployment = $strategy->createDeployment();
134
		// Skip through the approval state for now.
135
		$deployment->getMachine()->apply(DNDeployment::TR_SUBMIT);
136
		$deployment->getMachine()->apply(DNDeployment::TR_QUEUE);
137
138
		$output = [
139
			'message' => 'deployed queued',
140
			'deployID' => $deployment->ID,
141
		];
142
143
		return $this->getAPIResponse($output, 201);
144
	}
145
146
	/**
147
	    * Action - Get the latest deploy log
148
	    *
149
	    * @param SS_HTTPRequest $request
150
	    *
151
	    * @return string
152
	    * @throws SS_HTTPResponse_Exception
153
	    */
154
	public function log(SS_HTTPRequest $request) {
155
		$params = $request->params();
156
		$deployment = DNDeployment::get()->byId($params['ID']);
157
		if(!$deployment || !$deployment->ID) {
158
			throw new SS_HTTPResponse_Exception('Deployment not found', 404);
159
		}
160
		if(!$deployment->canView()) {
161
			return Security::permissionFailure();
162
		}
163
		if($this->environment->Name != $params['Environment']) {
164
			throw new LogicException("Environment in URL doesn't match this deploy");
165
		}
166
		if($this->project->Name != $params['Project']) {
167
			throw new LogicException("Project in URL doesn't match this deploy");
168
		}
169
		$log = $deployment->log();
170
		if($log->exists()) {
171
			$content = $log->content();
172
		} else {
173
			$content = 'Waiting for action to start';
174
		}
175
176
		$lines = explode(PHP_EOL, $content);
177
178
		return $this->getAPIResponse(['message' => $lines, 'status' => $deployment->ResqueStatus()], 200);
179
	}
180
181
182
	/**
183
	 * @return string
184
	 */
185
	public function Link() {
186
		return \Controller::join_links($this->project->Link(), self::ACTION_DEPLOY);
187
	}
188
189
	/**
190
	 * @param string $name
191
	 *
192
	 * @return array
193
	 */
194
	public function getModel($name = '') {
195
		return [];
196
	}
197
198
}
199