|
|
# NAME
|
|
|
|
|
|
`GitLab::API` - lightweight GitLab API client.
|
|
|
Also implements **Session** API to obtain authentication token if needed.
|
|
|
Other modules are needed for additional methods.
|
|
|
|
|
|
See [GitLab API](http://doc.gitlab.com/ce/api/) for details.
|
|
|
|
|
|
# SYNOPSIS
|
|
|
|
|
|
```{.pl}
|
|
|
use GitLab::API;
|
|
|
use GitLab::Users;
|
|
|
use GitLab::Groups;
|
|
|
use GitLab::Projects;
|
|
|
|
|
|
my $gitlab = GitLab::API->new(AuthToken => $token);
|
|
|
|
|
|
# simple result
|
|
|
my $groups = $gitlab->groups(search => "awesome-group");
|
|
|
|
|
|
die("Failed to get groups") unless defined $groups;
|
|
|
|
|
|
# result with response
|
|
|
my ($users, $response) = $gitlab->users(-response => 1);
|
|
|
|
|
|
die("Request failed: " . $response->message) unless $response->is_success;
|
|
|
|
|
|
# iterator for paginated responses
|
|
|
my $projects = $gitlab->projects(-iterator => 1);
|
|
|
|
|
|
while (my $project = $projects->next) {
|
|
|
# ...
|
|
|
}
|
|
|
```
|
|
|
|
|
|
# DESCRIPTION
|
|
|
|
|
|
- `new()`
|
|
|
|
|
|
```{.pl}
|
|
|
$gitlab = GitLab::API->new(arg => value, ...);
|
|
|
```
|
|
|
|
|
|
Creates a new instance of `GitLab::API`. Takes a hash of arguments:
|
|
|
|
|
|
| argument | description |
|
|
|
| ------------- | --------------------------------------------------------- |
|
|
|
| Login | user login |
|
|
|
| Email | user e-mail, required only if Login is not provided, |
|
|
|
| Password | user password |
|
|
|
| AuthToken | authentication token |
|
|
|
| URL | url to connect to, usually `https://gitlab.domain/api/v3` |
|
|
|
| DieOnError | see `die_on_error()` method |
|
|
|
|
|
|
`URL` is always required.
|
|
|
The method also requires __either__ `AuthToken` __or__ ((`Login` or `Email`) and `Password`).
|
|
|
That is, the only meaningful combinations are
|
|
|
|
|
|
```{.pl}
|
|
|
GitLab::API->new(URL => $URL, AuthToken => $TOKEN);
|
|
|
GitLab::API->new(URL => $URL, Login => $LOGIN, Password => $PASSWD);
|
|
|
GitLab::API->new(URL => $URL, Email => $EMAIL, Password => $PASSWD);
|
|
|
```
|
|
|
|
|
|
- `sudo()`
|
|
|
|
|
|
```{.pl}
|
|
|
$gitlab->sudo($username);
|
|
|
$gitlab->sudo();
|
|
|
```
|
|
|
|
|
|
Similar to [sudo(8)](https://linux.die.net/man/8/sudo), changes identity to the user with the `$username`.
|
|
|
If the `$username` argument is not defined, changes the identity back to the original user.
|
|
|
|
|
|
__This feature is available only to the admins.__
|
|
|
You can test for that with the [`whoami`](#whoami) method this way:
|
|
|
|
|
|
```{.pl}
|
|
|
if ($gitlab->whoami()->{is_admin}) {
|
|
|
# Booyah!
|
|
|
}
|
|
|
```
|
|
|
|
|
|
- `whoami()`
|
|
|
|
|
|
Returns the user whose authentication key is used for the request (or impersonated user if [`sudo`](#sudo) is in effect).
|
|
|
See [REQUEST METHODS](#request-methods) below.
|
|
|
|
|
|
- `is_admin()`
|
|
|
|
|
|
```{.pl}
|
|
|
$gitlab->is_admin()
|
|
|
```
|
|
|
|
|
|
Returns `true` if the logged in user has administrator permissions.
|
|
|
The result is not affected by [`sudo()`](#sudo).
|
|
|
|
|
|
- `die_on_error()`
|
|
|
|
|
|
```{.pl}
|
|
|
my $value = $gitlab->die_on_error();
|
|
|
$gitlab->die_on_error($value);
|
|
|
```
|
|
|
|
|
|
When called without an argument, returns the current value of the settings.
|
|
|
Otherwise sets the first argument as the value.
|
|
|
|
|
|
If enabled, any call that returns an unsuccessful (!= 2\*\*) HTTP code will call `Carp::croak` with the status code.
|
|
|
If disabled, unsuccessful calls will simply return `undef`.
|
|
|
|
|
|
The setting can be 'overriden' temporarily with the `-immortal => 1` option passed to the method.
|
|
|
See [`exec_request`](#exec_request) below.
|
|
|
|
|
|
## Internal Methods
|
|
|
|
|
|
The following methods are intended to be called from additional methods implemented by `GitLab::*` modules.
|
|
|
**It is not recommended to use these methods directly.**
|
|
|
|
|
|
- `http()`
|
|
|
|
|
|
Returns the HTTP User Agent.
|
|
|
|
|
|
- `json()`
|
|
|
|
|
|
Returns the JSON decoder.
|
|
|
|
|
|
- `response()`
|
|
|
|
|
|
Returns the HTTP response of the last method.
|
|
|
|
|
|
- `login()`
|
|
|
|
|
|
```{.pl}
|
|
|
$gitlab->login(arg => value, ...);
|
|
|
```
|
|
|
|
|
|
With provided login information (`Email`, `Login`, `Password`), this method attempts to obtain user's private token.
|
|
|
Under the hood it simply calls the [session](http://docs.gitlab.com/ce/api/session.html) API method.
|
|
|
|
|
|
- `create_uri()`
|
|
|
|
|
|
```{.pl}
|
|
|
$uri = $gitlab->create_uri($template, $arguments);
|
|
|
```
|
|
|
|
|
|
Constructs an [URI](https://metacpan.org/pod/URI) instance for the template using given arguments.
|
|
|
|
|
|
- `decode_data()`
|
|
|
|
|
|
```{.pl}
|
|
|
$data = $gitlab->decode_data($response);
|
|
|
```
|
|
|
|
|
|
Decodes the JSON content from the `$response` and converts it to Perl data.
|
|
|
|
|
|
- `exec_request()`
|
|
|
|
|
|
```{.pl}
|
|
|
$data = $gitlab->exec_request($template, $arguments);
|
|
|
|
|
|
# if arguments contain {-response => 1}
|
|
|
($data, $response) = $gitlab->exec_request($template, $arguments);
|
|
|
```
|
|
|
|
|
|
Sends a request constructed from the given `$template` and `$arguments` hashref.
|
|
|
Arguments that start with `-` (minus) are reserved to modify the client's behaviour and are **never** forwarded to GitLab.
|
|
|
|
|
|
Returns data received from GitLab API, either as hashref or arrayref (this depends on the request) or `undef` if the request failed (and `die_on_error` is disabled).
|
|
|
Additionally it saves the last [HTTP::Response](https://metacpan.org/pod/HTTP::Response) object as the `response` attribute of `$self`.
|
|
|
|
|
|
The following arguments can be used to modify [`exec_request`](#exec_request)'s behaviour:
|
|
|
|
|
|
- `-response => [0|1]`
|
|
|
|
|
|
Return both data and the [HTTP::Response](https://metacpan.org/pod/HTTP::Response) object as a list of two elements if set to true value.
|
|
|
|
|
|
```{.pl}
|
|
|
my ($data, $response) = $gitlab->$method(..., -response => 1);
|
|
|
```
|
|
|
|
|
|
- `-immortal => [0|1]`
|
|
|
|
|
|
When enabled, calls will not not carp on error even when `die_on_error` is enabled.
|
|
|
Recommended with `-response` option so that the status code can be inspected directly.
|
|
|
|
|
|
```{.pl}
|
|
|
my ($data, $response) = $gitlab->$method(..., -response => 1, -immortal => 1);
|
|
|
if (!$response->is_success) {
|
|
|
# handle the error
|
|
|
}
|
|
|
```
|
|
|
|
|
|
- `-page => N`
|
|
|
|
|
|
When used with paginated requests, returns only entries from the given page.
|
|
|
The number of entities in each page is by default _50_ except (of course) the last one.
|
|
|
It is possible to change the default page size with the `-per_page` option.
|
|
|
The API returns an empty response for invalid page numbers.
|
|
|
|
|
|
The method _croaks_ if used with a template without `$tmpl->{paginated}` attribute or if combined with `-iterator`.
|
|
|
|
|
|
- `-per_page => N`
|
|
|
|
|
|
Change the page size for `-page` or `-iterator` options.
|
|
|
The maximum allowed value by GitLab is currently `100`.
|
|
|
|
|
|
- `-iterator`
|
|
|
|
|
|
When non-zero, return an instance of [`GitLab::API::Iterator`](GitLab-API-Iterator.md) that will sequentially request pages when needed.
|
|
|
|
|
|
# Package methods
|
|
|
|
|
|
- `methods()`
|
|
|
|
|
|
```{.pl}
|
|
|
$methods = GitLab::API::methods();
|
|
|
```
|
|
|
|
|
|
Returns an arrayref of method names registered with the API.
|
|
|
This method __cannot__ be exported, use
|
|
|
|
|
|
```{.pl}
|
|
|
GitLab::API::methods()
|
|
|
```
|
|
|
|
|
|
to obtain the result.
|
|
|
|
|
|
# REQUEST METHODS
|
|
|
|
|
|
Request methods are methods that create requests and call GitLab API.
|
|
|
This package provides an easy data-driven way to create such methods with
|
|
|
request templates (see ["REQUEST TEMPLATES"](#request-templates) section and [`register`](#register)
|
|
|
method below).
|
|
|
|
|
|
Unless specified otherwise, these methods take a hash of options, e.g.
|
|
|
|
|
|
```{.pl}
|
|
|
$gitlab->$method(key => value, ...);
|
|
|
```
|
|
|
|
|
|
Generally, keys starting with the `-` (minus) characters are intended to modify the underlying `exec_request`'s behaviour and are not forwarded to GitLab.
|
|
|
|
|
|
This module contains only the [`whoami`](#whoami) API method, other methods are provided
|
|
|
by additional `GitLab::*` modules.
|
|
|
|
|
|
# REQUEST TEMPLATES
|
|
|
|
|
|
This section contains instruction on how to implement API request methods.
|
|
|
See [`GitLab::Users`](pod-GitLab-Users.md) and [`GitLab::Groups`](pod-GitLab-Groups.md) for examples.
|
|
|
|
|
|
The requests are made by calling the [`exec_request`](#exec_request) method with the following parameters:
|
|
|
|
|
|
| parameter | description |
|
|
|
| ---------- | ------------------------------------- |
|
|
|
| `$tmpl` | request template |
|
|
|
| `$args` | hashref of request arguments |
|
|
|
|
|
|
The _request template_ is a hashref with the following keys:
|
|
|
|
|
|
| key | description |
|
|
|
| ----------- | -------------------------------------------------------------------------------|
|
|
|
| `method` | **[required]** `GET`, `POST`, `PUT` or `DELETE` |
|
|
|
| `path` | **[required]** URL relative to the URL parameter given to constructor |
|
|
|
| `paginated` | if set to `true`, the request will be repeated and results concatented until all items are obtained` |
|
|
|
| `query` | arrayref of paramters that should be passed as query string in the URL |
|
|
|
| `required` | arrayref of required arguments |
|
|
|
| `optional` | optional arguments |
|
|
|
| `ret` | hashref of HTTP codes whose values will be used as status messages |
|
|
|
| `encode` | arrayref of path components that should be URI-encoded |
|
|
|
|
|
|
The `path` value can contain placeholders in the format `<name>`, e.g. `/groups/<gid>/projects/<projid>` is a path that contains placeholders `gid` and `projid`.
|
|
|
When processing the template, these placeholders will automatically become __required arguments__.
|
|
|
|
|
|
Arguments specified in the `query` are _not_ required by default, hence, if missing, they will not be included in the final URL.
|
|
|
|
|
|
Additional arguments (those not mentioned in `query`) will be passed as the request content, that is, `arg=value&arg=value...`, since the request's `Content-Type` is `application/x-www-form-urlencoded` by default.
|
|
|
|
|
|
Optional arguments can be specified by the `optional` key.
|
|
|
The value of this key is an arrayref with strings.
|
|
|
|
|
|
As the name suggests, _required arguments_ must be provided, otherwise the [`exec_request`](#exec_request) will croak.
|
|
|
|
|
|
All values for `path` placeholders are encoded before replacement.
|
|
|
However, if the value can contain reserved URI characters (e.g. `'/'`), the encoding must be forced.
|
|
|
This can be done by specifying this placeholder in the `encode` arrayref.
|
|
|
|
|
|
## Examples
|
|
|
|
|
|
### Simple
|
|
|
|
|
|
Consider the following template hashref:
|
|
|
|
|
|
```{.pl}
|
|
|
my $user_by_id = {
|
|
|
name => "user_by_id",
|
|
|
method => "GET",
|
|
|
path => "/users/<uid>",
|
|
|
ret => { 404 => "User not found" },
|
|
|
};
|
|
|
```
|
|
|
|
|
|
Called as `$gitlab->exec_request($user_by_id, { uid => 10 })`, the method will replace `<uid>` placeholder with `10` and then it will call
|
|
|
|
|
|
```
|
|
|
GET .../api/v3/users/10
|
|
|
```
|
|
|
|
|
|
with empty content.
|
|
|
The `uid` argument is required; the method will croak if it is not present.
|
|
|
|
|
|
If the given user is not found, the method will return status `404` with reason `User not found`.
|
|
|
For other status codes it will return the reason provided either by GitLab or underlying HTTP client.
|
|
|
|
|
|
### Required arguments
|
|
|
|
|
|
```{.pl}
|
|
|
my $user_add_ssh_key = {
|
|
|
name => "user_add_ssh_key",
|
|
|
method => "POST",
|
|
|
path => "/users/<uid>/keys",
|
|
|
required => [ qw!title key! ],
|
|
|
};
|
|
|
```
|
|
|
|
|
|
This request requires arguments `title`, `key` and `uid` (since it appears in the `path`).
|
|
|
The latter argument will be substituted in the path, the former two will be passed in the body of the request.
|
|
|
|
|
|
### Encoding
|
|
|
|
|
|
```{.pl}
|
|
|
my $project_by_id = {
|
|
|
method => "GET",
|
|
|
path => "/projects/<id>",
|
|
|
encode => [ qw(id) ],
|
|
|
};
|
|
|
```
|
|
|
|
|
|
From API documentation, this operation returns a project with the given `id`, which can be a numerical value or a string `"NAMESPACE/PROJECT_NAME"`.
|
|
|
|
|
|
Without the `encode` parameter in the template, the following request
|
|
|
|
|
|
```{.pl}
|
|
|
$gitlab->project_by_id("user/project");
|
|
|
```
|
|
|
|
|
|
would result in the path `gitlab_url/projects/user/project` which is invalid.
|
|
|
The slash, as a reserved character, needs to be encoded using `encode_required` parameter for [`URI::Encode`](https://metacpan.org/pod/URI::Encode).
|
|
|
This option is enabled by specifying `id` in the `encode` parameter in the template.
|
|
|
Final URL in this case would be `gitlab_url/projects/user%2Fproject`.
|
|
|
|
|
|
### Pagination and optional arguments
|
|
|
|
|
|
```{.pl}
|
|
|
my $groups = {
|
|
|
name => "groups",
|
|
|
method => "GET",
|
|
|
path => "/groups",
|
|
|
query => [ qw!search! ],
|
|
|
paginated => 1,
|
|
|
};
|
|
|
```
|
|
|
|
|
|
When called, the request will be repeated with increasing `page` query value until all pages are returned.
|
|
|
These responses will be concatenated to a single one.
|
|
|
The method will croak if any of the returned pages is not an array.
|
|
|
|
|
|
In addition, the request __can__ have (but does not require) an argument `search` that will be passed in the query string (`...?search=$search`).
|
|
|
In order to make this argument required, the template would have to contain the following key:
|
|
|
|
|
|
```{.pl}
|
|
|
# ...
|
|
|
required => [ qw!search! ],
|
|
|
```
|
|
|
|
|
|
as well.
|
|
|
|
|
|
## Registering methods
|
|
|
|
|
|
- `register()`
|
|
|
|
|
|
```{.pl}
|
|
|
GitLab::API->register($template, ...);
|
|
|
```
|
|
|
|
|
|
Instead of modifying `GitLab::API` source to add a new method, or writing wrapper subs like this:
|
|
|
|
|
|
```{.pl}
|
|
|
sub my_method {
|
|
|
my ($api, $args) = @_;
|
|
|
return $api->exec_request($my_method_template, $args);
|
|
|
}
|
|
|
```
|
|
|
|
|
|
for each request, the `register` method creates a convenience wrapper method in this package.
|
|
|
The above example can be written as the following:
|
|
|
|
|
|
```{.pl}
|
|
|
GitLab::API->register($my_method_template);
|
|
|
# ...
|
|
|
$api->my_method($args);
|
|
|
```
|
|
|
|
|
|
The method name is the same as `$my_method_template->{name}` attribute.
|
|
|
|
|
|
The call will fail if a template does not containt the `name` attribute or a method with the same name already exists.
|
|
|
|
|
|
# AUTHOR
|
|
|
|
|
|
Roman Lacko <[`xlacko1@fi.muni.cz`](mailto:xlacko1@fi.muni.cz)>
|
|
|
|
|
|
# SEE ALSO
|
|
|
|
|
|
- [GitLab::API::v3](https://metacpan.org/pod/GitLab::API::v3)
|
|
|
|
|
|
Complete GitLab API v3 implementation with CLI support.
|
|
|
|
|
|
- [GitLab](pod-GitLab.md)
|
|
|
|
|
|
Wrapper around `GitLab::API`. |