diff --git a/README.md b/README.md index 939d569..cabe896 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,22 @@ $jenkins = new \PhpPkg\JenkinsClient\Jenkins('http://host.org:8080'); If your Jenkins needs authentication, you need to pass a URL like this : `'http://user:token@host.org:8080'`. +Simple example - sending "String Parameters": + +```shell +curl JENKINS_URL/job/JOB_NAME/buildWithParameters \ +--user USER:TOKEN \ +--data id=123 --data verbosity=high +``` + +Another example - sending a "File Parameter": + +```shell +curl JENKINS_URL/job/JOB_NAME/buildWithParameters \ +--user USER:PASSWORD \ +--form FILE_LOCATION_AS_SET_IN_JENKINS=@PATH_TO_FILE +``` + Here are some examples of how to use it: ### Get the color of the job diff --git a/src/Jenkins.php b/src/Jenkins.php index 8014f9e..4277645 100755 --- a/src/Jenkins.php +++ b/src/Jenkins.php @@ -13,10 +13,14 @@ use PhpPkg\Http\Client\Client; use PhpPkg\JenkinsClient\Jenkins\Job; use RuntimeException; -use stdClass; use Throwable; +use Toolkit\FsUtil\File; use Toolkit\Stdlib\Helper\Assert; +use Toolkit\Stdlib\Obj; +use Toolkit\Stdlib\Obj\DataObject; use function explode; +use function is_file; +use function md5; use function sprintf; /** @@ -27,7 +31,11 @@ */ class Jenkins // extends AbstractObj { + use JenkinsCrumbTrait; + /** + * Jenkins server host URL + * * @var string */ private string $baseUrl; @@ -37,121 +45,63 @@ class Jenkins // extends AbstractObj * * @var string */ - private string $username = ''; + public string $username = ''; /** * Jenkins user password * - * @var string - */ - private string $password = ''; - - /** - * @var string - */ - private string $apiToken = ''; - - /** - * @var null all jenkins info by /api/json - */ - private $jenkins = null; - - /** - * @var AbstractClient|null - */ - private ?AbstractClient $httpClient; - - /** - * Whether or not to retrieve and send anti-CSRF crumb tokens - * with each request - * - * Defaults to false for backwards compatibility + * - usage: https://USER:PASSWORD@some.com/api/json * - * @var boolean + * @var string */ - private bool $crumbsEnabled = false; + public string $password = ''; /** - * The anti-CSRF crumb to use for each request + * Jenkins user token. * - * Set when crumbs are enabled, by requesting a new crumb from Jenkins + * - usage: https://USER:TOKEN@some.com/api/json * * @var string */ - private string $crumb = ''; + public string $apiToken = ''; /** - * The header to use for sending anti-CSRF crumbs - * - * Set when crumbs are enabled, by requesting a new crumb from Jenkins - * - * @var string + * @var bool cache jenkins info */ - private string $crumbRequestField = ''; + public bool $enableCache = false; /** - * @param string $baseUrl + * @var string cache dir */ - public function __construct(string $baseUrl) - { - $this->baseUrl = $baseUrl; - } + public string $cacheDir = ''; /** - * Enable the use of anti-CSRF crumbs on requests - * - * @return void + * @var DataObject|null all jenkins info by /api/json */ - public function enableCrumbs(): void - { - $this->crumbsEnabled = true; - - $crumbResult = $this->requestCrumb(); - - if (!$crumbResult || !is_object($crumbResult)) { - $this->crumbsEnabled = false; - return; - } - - $this->crumb = $crumbResult->crumb; - $this->crumbRequestField = $crumbResult->crumbRequestField; - } + private DataObject|null $jenkins = null; /** - * Disable the use of anti-CSRF crumbs on requests - * - * @return void + * @var AbstractClient|null */ - public function disableCrumbs(): void - { - $this->crumbsEnabled = false; - } + private ?AbstractClient $httpClient = null; /** - * Get the status of anti-CSRF crumbs - * - * @return boolean Whether or not crumbs have been enabled + * @param string $baseUrl Jenkins server host URL + * @param array $config = [ + * 'enableCache' => false, + * 'cacheDir' => '', + * 'username' => '', + * 'apiToken' => '', + * 'password' => '', + * ] */ - public function areCrumbsEnabled(): bool - { - return $this->crumbsEnabled; - } - - public function requestCrumb(): stdClass + public function __construct(string $baseUrl, array $config = []) { - $url = sprintf('%s/crumbIssuer/api/json', $this->baseUrl); - $cli = $this->getHttpClient()->get($url); + $this->baseUrl = $baseUrl; - if (!$cli->isSuccess()) { - throw new RuntimeException('Error on get csrf crumb'); + if ($config) { + Obj::init($this, $config); } - - return $cli->getJsonObject(); - } - - public function getCrumbHeaders(): array - { - return [$this->crumbRequestField => $this->crumb]; } /** @@ -168,6 +118,14 @@ public function isAvailable(): bool return true; } + /** + * @return void + */ + public function refreshCache(): void + { + $this->loadJenkinsInfo(); + } + /** * @return void */ @@ -177,17 +135,45 @@ private function initialize(): void return; } - $url = $this->baseUrl . '/api/json'; + if ($this->enableCache && $this->cacheDir) { + $cacheFile = $this->getCacheFile(); + + if (is_file($cacheFile)) { + $this->jenkins = DataObject::fromJson(File::readAll($cacheFile)); + return; + } + } + + $this->loadJenkinsInfo(); + } + + private function loadJenkinsInfo(): void + { + $url = $this->buildUrl('/api/json'); $cli = $this->getHttpClient()->get($url); if (!$cli->isSuccess()) { - throw new RuntimeException(sprintf('Error on get list of jobs on %s', $this->baseUrl)); + throw new RuntimeException('Error on get list of jobs'); } - $this->jenkins = $cli->getJsonObject(); - if (!$this->jenkins instanceof stdClass) { + $this->jenkins = $cli->getDataObject(); + if ($this->jenkins->isEmpty()) { throw new RuntimeException('Error during json_decode the /api/json data'); } + + if ($this->enableCache && $this->cacheDir) { + File::mkdirSave($this->getCacheFile(), $this->jenkins->toString()); + } + } + + /** + * @return string + */ + public function getCacheFile(): string + { + $filename = md5($this->baseUrl . $this->username) . '.json'; + + return File::join($this->cacheDir, $filename); } /** @@ -197,10 +183,14 @@ public function getAllJobs(): array { $this->initialize(); + // vdump(json_encode($this->jenkins)); + $jobs = []; foreach ($this->jenkins->jobs as $job) { - $jobs[$job->name] = [ - 'name' => $job->name + $jobName = $job['name']; + // add + $jobs[$jobName] = [ + 'name' => $jobName, ]; } @@ -216,7 +206,9 @@ public function getJobs(): array $jobs = []; foreach ($this->jenkins->jobs as $job) { - $jobs[$job->name] = $this->getJob($job->name); + $jobName = $job['name']; + + $jobs[$jobName] = $this->getJob($jobName); } return $jobs; @@ -233,11 +225,11 @@ public function getExecutors(string $computer = '(master)'): array $executors = []; for ($i = 0; $i < $this->jenkins->numExecutors; $i++) { - $url = sprintf('%s/computer/%s/executors/%s/api/json', $this->baseUrl, $computer, $i); + $url = $this->buildUrl('/computer/%s/executors/%s/api/json', $computer, $i); $cli = $this->getHttpClient()->get($url); if (!$cli->isSuccess()) { - throw new RuntimeException(sprintf('Error on get information for executors[%s@%s] on %s', $i, $computer, $this->baseUrl)); + throw new RuntimeException(sprintf('Error on get information for executors[%s@%s]', $i, $computer)); } $infos = $cli->getJsonObject(); @@ -257,13 +249,13 @@ public function getExecutors(string $computer = '(master)'): array public function launchJob(string $jobName, array $parameters = []): bool { if (0 === count($parameters)) { - $url = sprintf('%s/job/%s/build', $this->baseUrl, $jobName); + $url = $this->buildUrl('/job/%s/build', $jobName); } else { - $url = sprintf('%s/job/%s/buildWithParameters', $this->baseUrl, $jobName); + $url = $this->buildUrl('/job/%s/buildWithParameters', $jobName); } $headers = []; - if ($this->areCrumbsEnabled()) { + if ($this->isCrumbsEnabled()) { $headers = $this->getCrumbHeaders(); } @@ -283,11 +275,34 @@ public function launchJob(string $jobName, array $parameters = []): bool */ public function getJob(string $jobName): Job { - $url = sprintf('%s/job/%s/api/json', $this->baseUrl, $jobName); + $url = $this->buildUrl('/job/%s/api/json', $jobName); $cli = $this->getHttpClient()->get($url); if (!$cli->isSuccess()) { - throw new RuntimeException(sprintf('Error on get information for job %s on %s', $jobName, $this->baseUrl)); + throw new RuntimeException(sprintf('Error on get information for job %s', $jobName)); + } + + $infos = $cli->getJsonObject(); + + return new Jenkins\Job($infos, $this); + } + + /** + * Get job build params definitions + * + * @param string $jobName + * @param string $tree + * + * @return Job + */ + public function getJobParams(string $jobName, string $tree = ''): Job + { + $tree = $tree ?: 'property[parameterDefinitions[description,name,type,choices]]'; + $url = $this->buildUrl('/job/%s/api/json?tree=%s', $jobName, $tree); + $cli = $this->getHttpClient()->get($url); + + if (!$cli->isSuccess()) { + throw new RuntimeException(sprintf('Error on get information for job %s', $jobName)); } $infos = $cli->getJsonObject(); @@ -303,15 +318,15 @@ public function getJob(string $jobName): Job public function deleteJob(string $jobName): void { $headers = []; - if ($this->areCrumbsEnabled()) { + if ($this->isCrumbsEnabled()) { $headers = $this->getCrumbHeaders(); } - $url = sprintf('%s/job/%s/doDelete', $this->baseUrl, $jobName); + $url = $this->buildUrl('/job/%s/doDelete', $jobName); $cli = $this->getHttpClient()->post($url, null, $headers); if (!$cli->isSuccess()) { - throw new RuntimeException(sprintf('Error deleting job %s on %s', $jobName, $this->baseUrl)); + throw new RuntimeException(sprintf('Error deleting job %s', $jobName)); } } @@ -320,11 +335,11 @@ public function deleteJob(string $jobName): void */ public function getQueue(): Jenkins\Queue { - $url = sprintf('%s/queue/api/json', $this->baseUrl); + $url = $this->buildUrl('/queue/api/json'); $cli = $this->getHttpClient()->get($url); if (!$cli->isSuccess()) { - throw new RuntimeException(sprintf('Error on get information for queue on %s', $this->baseUrl)); + throw new RuntimeException('Error on get information for queues'); } $infos = $cli->getJsonObject(); @@ -369,11 +384,11 @@ public function getPrimaryView(): ?Jenkins\View */ public function getView(string $viewName): Jenkins\View { - $url = sprintf('%s/view/%s/api/json', $this->baseUrl, rawurlencode($viewName)); + $url = $this->buildUrl('/view/%s/api/json', rawurlencode($viewName)); $cli = $this->getHttpClient()->get($url); if (!$cli->isSuccess()) { - throw new RuntimeException(sprintf('Error on get information for view %s on %s', $viewName, $this->baseUrl)); + throw new RuntimeException(sprintf('Error on get information for view %s', $viewName)); } $infos = $cli->getJsonObject(); @@ -397,11 +412,11 @@ public function getBuild( $tree = sprintf('?tree=%s', $tree); } - $url = sprintf('%s/job/%s/%d/api/json%s', $this->baseUrl, $job, $buildId, $tree); + $url = $this->buildUrl('/job/%s/%d/api/json%s', $job, $buildId, $tree); $cli = $this->getHttpClient()->get($url); if (!$cli->isSuccess()) { - throw new RuntimeException(sprintf('Error on get information for build %s#%d on %s', $job, $buildId, $this->baseUrl)); + throw new RuntimeException(sprintf('Error on get information for build %s#%d', $job, $buildId)); } $infos = $cli->getJsonObject(); @@ -419,7 +434,7 @@ public function getBuildUrl(string $job, int $buildId): string { return $buildId < 1 ? $this->getJobUrl($job) - : sprintf('%s/job/%s/%d', $this->baseUrl, $job, $buildId); + : $this->buildUrl('/job/%s/%d', $job, $buildId); } /** @@ -429,7 +444,7 @@ public function getBuildUrl(string $job, int $buildId): string */ public function getComputer(string $computerName): Jenkins\Computer { - $url = sprintf('%s/computer/%s/api/json', $this->baseUrl, $computerName); + $url = $this->buildUrl('/computer/%s/api/json', $computerName); $cli = $this->getHttpClient()->get($url); if (!$cli->isSuccess()) { @@ -443,7 +458,7 @@ public function getComputer(string $computerName): Jenkins\Computer /** * @return string */ - public function getUrl(): string + public function getBaseUrl(): string { return $this->baseUrl; } @@ -455,7 +470,7 @@ public function getUrl(): string */ public function getJobUrl(string $jobName): string { - return sprintf('%s/job/%s', $this->baseUrl, $jobName); + return $this->buildUrl('/job/%s', $jobName); } /** @@ -467,7 +482,7 @@ public function getJobUrl(string $jobName): string */ public function getViewUrl(string $view): string { - return sprintf('%s/view/%s', $this->baseUrl, $view); + return $this->buildUrl('/view/%s', $view); } /** @@ -477,11 +492,11 @@ public function getViewUrl(string $view): string public function createJob(string $jobName, string $xmlConfiguration): void { $headers = ['Content-Type' => 'text/xml']; - if ($this->areCrumbsEnabled()) { + if ($this->isCrumbsEnabled()) { $headers = $this->getCrumbHeaders(); } - $url = sprintf('%s/createItem?name=%s', $this->baseUrl, $jobName); + $url = $this->buildUrl('/createItem?name=%s', $jobName); $cli = $this->getHttpClient()->post($url, $xmlConfiguration, $headers); if (!$cli->isSuccess()) { @@ -500,7 +515,7 @@ public function createJob(string $jobName, string $xmlConfiguration): void */ public function createJobByCopy(string $jobName, string $fromJob): void { - $url = sprintf('%s/createItem?mode=copy&name=%s&from=%s', $this->baseUrl, $jobName, $fromJob); + $url = $this->buildUrl('/createItem?mode=copy&name=%s&from=%s', $jobName, $fromJob); $cli = $this->getHttpClient()->post($url); if (!$cli->isSuccess()) { @@ -515,11 +530,11 @@ public function createJobByCopy(string $jobName, string $fromJob): void public function setJobConfig(string $jobName, string $configuration): void { $headers = ['Content-Type' => 'text/xml']; - if ($this->areCrumbsEnabled()) { + if ($this->isCrumbsEnabled()) { $headers = $this->getCrumbHeaders(); } - $url = sprintf('%s/job/%s/config.xml', $this->baseUrl, $jobName); + $url = $this->buildUrl('/job/%s/config.xml', $jobName); $cli = $this->getHttpClient()->post($url, $configuration, $headers); if (!$cli->isSuccess()) { @@ -534,7 +549,7 @@ public function setJobConfig(string $jobName, string $configuration): void */ public function getJobConfig(string $jobName): string { - $url = sprintf('%s/job/%s/config.xml', $this->baseUrl, $jobName); + $url = $this->buildUrl('/job/%s/config.xml', $jobName); $cli = $this->getHttpClient()->get($url); if (!$cli->isSuccess()) { @@ -550,17 +565,11 @@ public function getJobConfig(string $jobName): string public function stopExecutor(Jenkins\Executor $executor): void { $headers = []; - if ($this->areCrumbsEnabled()) { + if ($this->isCrumbsEnabled()) { $headers = $this->getCrumbHeaders(); } - $url = sprintf( - '%s/computer/%s/executors/%s/stop', - $this->baseUrl, - $executor->getComputer(), - $executor->getNumber() - ); - + $url = $this->buildUrl('/computer/%s/executors/%s/stop', $executor->getComputer(), $executor->getNumber()); $cli = $this->getHttpClient()->post($url, null, $headers); if (!$cli->isSuccess()) { @@ -576,11 +585,11 @@ public function stopExecutor(Jenkins\Executor $executor): void public function cancelQueue(Jenkins\JobQueue $queue): void { $headers = []; - if ($this->areCrumbsEnabled()) { + if ($this->isCrumbsEnabled()) { $headers = $this->getCrumbHeaders(); } - $url = $this->buildUrl('%s/queue/item/%s/cancelQueue', $queue->getId()); + $url = $this->buildUrl('/queue/item/%s/cancelQueue', $queue->getId()); $cli = $this->getHttpClient()->post($url, null, $headers); if (!$cli->isSuccess()) { @@ -596,11 +605,11 @@ public function cancelQueue(Jenkins\JobQueue $queue): void public function toggleOfflineComputer(string $computerName): void { $headers = []; - if ($this->areCrumbsEnabled()) { + if ($this->isCrumbsEnabled()) { $headers = $this->getCrumbHeaders(); } - $url = $this->buildUrl('%s/computer/%s/toggleOffline', $computerName); + $url = $this->buildUrl('/computer/%s/toggleOffline', $computerName); $cli = $this->getHttpClient()->post($url, null, $headers); if (!$cli->isSuccess()) { @@ -616,11 +625,11 @@ public function toggleOfflineComputer(string $computerName): void public function deleteComputer(string $computerName): void { $headers = []; - if ($this->areCrumbsEnabled()) { + if ($this->isCrumbsEnabled()) { $headers = $this->getCrumbHeaders(); } - $url = $this->buildUrl('%s/computer/%s/doDelete', $computerName); + $url = $this->buildUrl('/computer/%s/doDelete', $computerName); $cli = $this->getHttpClient()->post($url, null, $headers); if (!$cli->isSuccess()) { @@ -636,7 +645,7 @@ public function deleteComputer(string $computerName): void */ public function getConsoleTextBuild(string $jobName, string $buildNumber): string { - $url = $this->buildUrl('%s/job/%s/%s/consoleText', $jobName, $buildNumber); + $url = $this->buildUrl('/job/%s/%s/consoleText', $jobName, $buildNumber); $cli = $this->getHttpClient()->get($url); if (!$cli->isSuccess()) { @@ -654,14 +663,11 @@ public function getConsoleTextBuild(string $jobName, string $buildNumber): strin */ public function getTestReport(string $jobName, int $buildId): Jenkins\TestReport { - $url = $this->buildUrl('%s/job/%s/%d/testReport/api/json', $jobName, $buildId); + $url = $this->buildUrl('/job/%s/%d/testReport/api/json', $jobName, $buildId); $cli = $this->getHttpClient()->get($url); if (!$cli->isSuccess()) { - throw new RuntimeException(sprintf('Error on get information for build %s#%d on %s', - $jobName, - $buildId, - $this->baseUrl)); + throw new RuntimeException(sprintf('Error on get information for build %s#%d', $jobName, $buildId)); } $infos = $cli->getJsonObject(); @@ -720,10 +726,11 @@ public function buildUrl(string $pathFmt, ...$args): string Assert::notEmpty($this->baseUrl, 'jenkins base url cannot be empty'); // with auth http://user:token@host.org:8080 - if ($this->username && $this->password) { + if ($this->username) { + $tokenOrPasswd = $this->apiToken ?: $this->password; [$prefix, $host] = explode('://', $this->baseUrl, 2); - return sprintf('%s://%s:%s@%s%s', $prefix, $this->username, $this->password, $host, $apiPath); + return sprintf('%s://%s:%s@%s%s', $prefix, $this->username, $tokenOrPasswd, $host, $apiPath); } return $this->baseUrl . $apiPath; @@ -737,7 +744,7 @@ public function getHttpClient(): AbstractClient if (!$this->httpClient) { $this->httpClient = Client::factory([ 'baseUrl' => $this->baseUrl, - 'headers' => $this->apiToken ? ['token' => $this->apiToken] : [], + // 'headers' => $this->apiToken ? ['token' => $this->apiToken] : [], ]); } @@ -752,14 +759,6 @@ public function setHttpClient(AbstractClient $httpClient): void $this->httpClient = $httpClient; } - /** - * @return string - */ - public function getApiToken(): string - { - return $this->apiToken; - } - /** * @param string $apiToken */ @@ -781,35 +780,35 @@ public function setUserAuth(string $username, string $passwd): void } /** - * @return string + * @param string $username */ - public function getUsername(): string + public function setUsername(string $username): void { - return $this->username; + $this->username = $username; } /** - * @param string $username + * @param string $password */ - public function setUsername(string $username): void + public function setPassword(string $password): void { - $this->username = $username; + $this->password = $password; } /** - * @return string + * @param bool $enableCache */ - public function getPassword(): string + public function setEnableCache(bool $enableCache): void { - return $this->password; + $this->enableCache = $enableCache; } /** - * @param string $password + * @param string $cacheDir */ - public function setPassword(string $password): void + public function setCacheDir(string $cacheDir): void { - $this->password = $password; + $this->cacheDir = $cacheDir; } } diff --git a/src/Jenkins/Job.php b/src/Jenkins/Job.php index 8b18c68..d42e9d1 100755 --- a/src/Jenkins/Job.php +++ b/src/Jenkins/Job.php @@ -12,6 +12,9 @@ use DOMDocument; use PhpPkg\JenkinsClient\Jenkins; use stdClass; +use function array_keys; +use function get_object_vars; +use function property_exists; /** * class Job @@ -33,7 +36,7 @@ class Job /** * @param stdClass $job - * @param Jenkins $jenkins + * @param Jenkins $jenkins */ public function __construct(stdClass $job, Jenkins $jenkins) { @@ -76,31 +79,35 @@ public function getName(): string /** * @return array */ - public function getParametersDefinition(): array + public function getParametersDefinitions(): array { $parameters = []; - foreach ($this->job->actions as $action) { + foreach ($this->job->property as $action) { if (!property_exists($action, 'parameterDefinitions')) { continue; } - foreach ($action->parameterDefinitions as $parameterDefinition) { - $default = property_exists($parameterDefinition, 'defaultParameterValue') - && isset($parameterDefinition->defaultParameterValue->value) - ? $parameterDefinition->defaultParameterValue->value + foreach ($action->parameterDefinitions as $paramDefinition) { + $description = property_exists($paramDefinition, 'description') + ? $paramDefinition->description : null; - $description = property_exists($parameterDefinition, 'description') - ? $parameterDefinition->description + $paramType = property_exists($paramDefinition, 'type') ? $paramDefinition->choices : ''; + + $default = property_exists($paramDefinition, 'defaultParameterValue') + && isset($paramDefinition->defaultParameterValue->value) + ? $paramDefinition->defaultParameterValue->value : null; - $choices = property_exists($parameterDefinition, 'choices') - ? $parameterDefinition->choices + $choices = property_exists($paramDefinition, 'choices') + ? $paramDefinition->choices : null; - $parameters[$parameterDefinition->name] = [ + + $parameters[$paramDefinition->name] = [ + 'description' => $description, 'default' => $default, + 'type' => $paramType, 'choices' => $choices, - 'description' => $description, ]; } } @@ -178,4 +185,29 @@ public function getLastBuild(): ?Build return $this->getJenkins()->getBuild($this->getName(), $this->job->lastBuild->number); } + + /** + * @param string $propName + * + * @return mixed + */ + public function getInfo(string $propName = ''): mixed + { + if ($propName) { + if (property_exists($this->job, $propName)) { + return $this->job->$propName; + } + return []; + } + + return $this->job; + } + + /** + * @return array + */ + public function getKeys(): array + { + return array_keys(get_object_vars($this->job)); + } } diff --git a/src/JenkinsCrumbTrait.php b/src/JenkinsCrumbTrait.php new file mode 100644 index 0000000..750405d --- /dev/null +++ b/src/JenkinsCrumbTrait.php @@ -0,0 +1,113 @@ +crumbsEnabled = true; + + $crumbResult = $this->requestCrumb(); + if (!$crumbResult || !is_object($crumbResult)) { + $this->crumbsEnabled = false; + return; + } + + $this->crumbValue = $crumbResult->crumb; + $this->crumbField = $crumbResult->crumbRequestField; + } + + /** + * @return stdClass + */ + public function requestCrumb(): stdClass + { + $url = $this->buildUrl('/crumbIssuer/api/json'); + $cli = $this->getHttpClient()->get($url); + + if (!$cli->isSuccess()) { + throw new RuntimeException('Error on get csrf crumb'); + } + + // { + // "_class":"hudson.security.csrf.DefaultCrumbIssuer", + // "crumb":"03a97f9f8d0071148f82da4d057790f9", + // "crumbRequestField":"Jenkins-Crumb" + // } + return $cli->getJsonObject(); + } + + /** + * Disable the use of anti-CSRF crumbs on requests + * + * @return void + */ + public function disableCrumbs(): void + { + $this->crumbsEnabled = false; + } + + /** + * Get the status of anti-CSRF crumbs + * + * @return boolean Whether or not crumbs have been enabled + */ + public function isCrumbsEnabled(): bool + { + return $this->crumbsEnabled; + } + + /** + * @return array + */ + public function getCrumbHeaders(): array + { + return $this->crumbsEnabled ? [$this->crumbField => $this->crumbValue] : []; + } + +} \ No newline at end of file diff --git a/src/Model/JenkinsInfo.php b/src/Model/JenkinsInfo.php new file mode 100644 index 0000000..736a323 --- /dev/null +++ b/src/Model/JenkinsInfo.php @@ -0,0 +1,16 @@ +