#
# This file is part of DNS-NIOS
#
# This software is Copyright (c) 2021 by Christian Segundo.
#
# This is free software, licensed under:
#
# The Artistic License 2.0 (GPL Compatible)
#
## no critic
package DNS::NIOS;
$DNS::NIOS::VERSION = '0.005';
# ABSTRACT: Perl binding for NIOS
# VERSION
# AUTHORITY
## use critic
use strictures 2;
use Carp qw(croak);
use JSON qw(to_json);
use LWP::UserAgent;
use MIME::Base64 qw(encode_base64);
use URI;
use URI::QueryParam;
use DNS::NIOS::Response;
use Role::Tiny::With;
use Class::Tiny qw( password username wapi_addr traits ),
{
wapi_version => 'v2.7',
scheme => 'https',
insecure => 0,
timeout => 10,
debug => $ENV{NIOS_DEBUG}
};
sub BUILD {
my ( $self, $args ) = @_;
defined( $self->$_ )
or croak("$_ is required!")
for qw(username password wapi_addr); ## no critic (ControlStructures::ProhibitPostfixControls)
( ( $self->scheme eq 'http' ) or ( $self->scheme eq 'https' ) )
or croak( "scheme not supported: " . $self->scheme );
$self->{base_url} =
$self->scheme . "://"
. $self->wapi_addr
. "/wapi/"
. $self->wapi_version . "/";
$self->{ua} = LWP::UserAgent->new( timeout => $self->timeout );
$self->{ua}->agent( 'NIOS-perl/' . $DNS::NIOS::VERSION );
$self->{ua}->ssl_opts( verify_hostname => 0, SSL_verify_mode => 0x00 )
if $self->insecure and $self->scheme eq 'https'; ## no critic (ControlStructures::ProhibitPostfixControls)
$self->{ua}->default_header( 'Accept' => 'application/json' );
$self->{ua}->default_header( 'Content-Type' => 'application/json' );
$self->{ua}->default_header( 'Authorization' => 'Basic '
. encode_base64( $self->username . ":" . $self->password ) );
if ( $self->traits ) {
foreach ( @{ $self->traits } ) {
with $_;
}
}
}
sub create {
my ( $self, %args ) = @_;
defined( $args{$_} )
or croak("$_ is required!")
for qw(path payload);
return $self->__request( 'POST', $args{path},
( payload => $args{payload}, params => $args{params} ) );
}
sub update {
my ( $self, %args ) = @_;
defined( $args{$_} )
or croak("$_ is required!")
for qw(path payload);
return $self->__request( 'PUT', $args{path},
( payload => $args{payload}, params => $args{params} ) );
}
sub get {
my ( $self, %args ) = @_;
defined( $args{path} )
or croak("path is required!");
return $self->__request( 'GET', $args{path}, ( params => $args{params} ) );
}
sub delete {
my ( $self, %args ) = @_;
defined( $args{path} )
or croak("path is required!");
return $self->__request( 'DELETE', $args{path}, ( params => $args{params} ) );
}
sub __request {
my ( $self, $op, $path, %args ) = @_;
my $payload = delete $args{payload};
my $params = delete $args{params};
my $query_params = q{};
grep( /(^\Q$op\E$)/, qw(GET POST PUT DELETE) )
or die("invalid operation: $op");
croak("invalid path") unless ( defined $path and length $path );
if ( $op eq 'PUT' or $op eq 'POST' ) {
croak("invalid payload") unless keys %{$payload};
}
if ( defined $params ) {
my $u = URI->new( q{}, 'http' );
$query_params = q{?};
foreach ( keys %{$params} ) {
$u->query_param( $_ => $params->{$_} );
}
$query_params .= $u->query;
}
my $request =
HTTP::Request->new( $op, $self->{base_url} . $path . $query_params );
if ( $op eq 'PUT' or $op eq 'POST' ) {
$request->content( to_json($payload) );
}
return DNS::NIOS::Response->new(
_http_response => $self->{ua}->request($request) );
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
DNS::NIOS - Perl binding for NIOS
=head1 VERSION
version 0.005
=head1 SYNOPSIS
# Read below for a list of options
my $n = NIOS->new(
username => "username",
password => "password",
wapi_addr => "10.0.0.1",
);
$x = $n->get(
path => 'record:a',
params => {
_paging => 1,
_max_results => 1,
_return_as_object => 1
}
);
say $x->content->{result}[0]->{_ref};
=head1 DESCRIPTION
Perl bindings for L
=head2 Normal usage
Normally, you will add some traits to the client, primarily L
since it provides methods for some endpoints.
=head2 Minimal usage
Without any traits, DNS::NIOS provides access to all API endpoints using the methods described below.
=head1 CONSTRUCTOR
=for Pod::Coverage BUILD
=head2 new
The following attributes are required at construction time:
=over 4
=item * C
Configures the username to use to authenticate the connection to the remote instance of NIOS.
=item * C
Specifies the password to use to authenticate the connection to the remote instance of NIOS.
=item * C
DNS hostname or address for connecting to the remote instance of NIOS WAPI.
=back
my $n = NIOS->new(
username => "username",
password => "password",
wapi_addr => "10.0.0.1",
);
Optional attributes:
=over 4
=item * C
Enable or disable verifying SSL certificates when C is C. Default is C.
=item * C
Default is C.
=item * C
The amount of time before to wait before receiving a response. Default is C<10>.
=item * C
Specifies the version of WAPI to use. Default is C.
=item * C
=item * C
List of traits to apply, see L.
=back
=head1 METHODS
=over
=item * All methods require a path parameter that can be either a resource type (eg: "record:a") or a WAPI Object reference.
=item * All methods return a L object.
=back
=head2 create
# Create a new A record:
my $x = $n->create(
path => "record:a",
payload => {
name => "rhds.ext.home",
ipv4addr => "10.0.0.1",
extattrs => {
"Tenant ID" => { value => "home" },
"CMP Type" => { value => "OpenStack" },
"Cloud API Owned" => { value => "True" }
}
}
);
=head2 delete
# Delete a WAPI Object Reference
$x = $n->delete(path => $object_ref);
=head2 get
# List all A records with:
# pagination
# limiting results to 1
# returning response as an object
$x = $n->get(
path => 'record:a',
params => {
_paging => 1,
_max_results => 1,
_return_as_object => 1
}
);
=head2 update
# Update a WAPI Object Reference
$x = $n->update(
path => $object_ref,
payload => {
name => "updated_name"
}
);
=head1 AUTHOR
Christian Segundo
=head1 COPYRIGHT AND LICENSE
This software is Copyright (c) 2021 by Christian Segundo.
This is free software, licensed under:
The Artistic License 2.0 (GPL Compatible)
=cut