Artifactory-Client

 view release on metacpan or  search on metacpan

lib/Artifactory/Client.pm  view on Meta::CPAN

package Artifactory::Client;

use strict;
use warnings FATAL => 'all';

use Moose;

use Data::Dumper;
use URI;
use JSON::MaybeXS;
use LWP::UserAgent;
use Path::Tiny qw();
use MooseX::StrictConstructor;
use URI::Escape qw(uri_escape);
use File::Basename qw(basename);
use HTTP::Request::StreamingUpload;

use namespace::autoclean;

=head1 NAME

Artifactory::Client - Perl client for Artifactory REST API

=head1 VERSION

Version 1.8.0

=cut

our $VERSION = 'v1.8.0';

=head1 SYNOPSIS

This is a Perl client for Artifactory REST API:
https://www.jfrog.com/confluence/display/RTF/Artifactory+REST+API Every public method provided in this module returns a
HTTP::Response object.

    use Artifactory::Client;

    my $h = HTTP::Headers->new();
    $h->authorization_basic( 'admin', 'password' );
    my $ua = LWP::UserAgent->new( default_headers => $h );

    my $args = {
        artifactory  => 'http://artifactory.server.com',
        port         => 8080,
        repository   => 'myrepository',
        context_root => '/', # Context root for artifactory. Defaults to 'artifactory'.
        ua           => $ua  # Dropping in custom UA with default_headers set.  Default is a plain LWP::UserAgent.
    };

    my $client = Artifactory::Client->new( $args );
    my $path = '/foo'; # path on artifactory

    # Properties are a hashref of key-arrayref pairs.  Note that value must be an arrayref even for a single element.
    # This is to conform with Artifactory which treats property values as a list.
    my $properties = {
        one => ['two'],
        baz => ['three'],
    };
    my $file = '/local/file.xml';

    # Name of methods are taken straight from Artifactory REST API documentation.  'Deploy Artifact' would map to
    # deploy_artifact method, like below.  The caller gets HTTP::Response object back.
    my $resp = $client->deploy_artifact( path => $path, properties => $properties, file => $file );

    # Custom requests can also be made via usual get / post / put / delete requests.
    my $resp = $client->get( 'http://artifactory.server.com/path/to/resource' );

    # Repository override for calls that have a repository in the endpoint.  The passed-in repository will not persist.
    my $resp = $client->calculate_yum_repository_metadata( repository => 'different_repo', async => 1 );

=cut

=head1 Dev Env Setup / Running Tests

lib/Artifactory/Client.pm  view on Meta::CPAN

=head2 trace_artifact_retrieval( $path )

Takes path and traces artifact retrieval

=cut

sub trace_artifact_retrieval {
    my ( $self, $path ) = @_;
    $path = $self->_merge_repo_and_path($path);
    my $url = $self->_art_url() . "/$path?trace";
    return $self->get($url);
}

=head2 archive_entry_download( $path, $archive_path )

Takes path and archive_path, retrieves an archived resource from the specified archive destination.

=cut

sub archive_entry_download {
    my ( $self, $path, $archive_path ) = @_;
    $path = $self->_merge_repo_and_path($path);
    my $url = $self->_art_url() . "/$path!$archive_path";
    return $self->get($url);
}

=head2 create_directory( path => $path, properties => { key => [ values ] } )

Takes path, properties then create a directory.  Directory needs to end with a /, such as "/some_dir/".

=cut

sub create_directory {
    my ( $self, %args ) = @_;
    return $self->deploy_artifact(%args);
}

=head2 deploy_artifact( path => $path, properties => { key => [ values ] }, file => $file )

Takes path on Artifactory, properties and filename then deploys the file.  Note that properties are a hashref with
key-arrayref pairs, such as:

    $prop = { key1 => ['a'], key2 => ['a', 'b'] }

=cut

sub deploy_artifact {
    my ( $self, %args ) = @_;

    my $path       = $args{path};
    my $properties = $args{properties};
    my $file       = $args{file};
    my $header     = $args{header};

    $path = $self->_merge_repo_and_path($path);
    my @joiners = ( $self->_art_url() . "/$path" );
    my $props = $self->_attach_properties( properties => $properties, matrix => 1 );
    push @joiners, $props if ($props);    # if properties aren't passed in, the function returns empty string

    my $url = join( ";", @joiners );
    my $req = HTTP::Request::StreamingUpload->new(
        PUT     => $url,
        headers => HTTP::Headers->new( %{$header} ),
        ( $file ? ( fh => Path::Tiny::path($file)->openr_raw() ) : () ),
    );
    return $self->request($req);
}

=head2 deploy_artifact_by_checksum( path => $path, properties => { key => [ values ] }, file => $file, sha1 => $sha1 )

Takes path, properties, filename and sha1 then deploys the file.  Note that properties are a hashref with key-arrayref
pairs, such as:

    $prop = { key1 => ['a'], key2 => ['a', 'b'] }

=cut

sub deploy_artifact_by_checksum {
    my ( $self, %args ) = @_;

    my $sha1   = $args{sha1};
    my $header = {
        'X-Checksum-Deploy' => 'true',
        'X-Checksum-Sha1'   => $sha1,
    };
    $args{header} = $header;
    return $self->deploy_artifact(%args);
}

=head2 deploy_artifacts_from_archive( path => $path, file => $file )

Path is the path on Artifactory, file is path to local archive.  Will deploy $file to $path.

=cut

sub deploy_artifacts_from_archive {
    my ( $self, %args ) = @_;

    my $header = { 'X-Explode-Archive' => 'true', };
    $args{header} = $header;
    return $self->deploy_artifact(%args);
}

=head2 push_a_set_of_artifacts_to_bintray( descriptor => 'foo', gpgPassphrase => 'top_secret', gpgSign => 'true' )

Push a set of artifacts to Bintray as a version.  Uses a descriptor file (that must have 'bintray-info' in it's filename
and a .json extension) that was deployed to artifactory, the call accepts the full path to the descriptor as a
parameter.

=cut

sub push_a_set_of_artifacts_to_bintray {
    my ( $self, %args ) = @_;

    my $url = $self->_api_url() . "/bintray/push";
    my $params = $self->_stringify_hash( '&', %args );
    $url .= "?" . $params if ($params);
    return $self->post($url);
}

=head2 push_docker_tag_to_bintray( dockerImage => 'jfrog/ubuntu:latest', async => 'true', ... )



( run in 2.430 seconds using v1.01-cache-2.11-cpan-acf6aa7dc9e )