#!/usr/local/bin/perl # WANT_JSON # yamd - client Yandex.Mail for Domain API # Run as stand-alone application or as Ansible module # # Copyright 2018 Sergey Kiselev # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # 3. Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived from this # software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. use strict; use warnings; our $VERSION = '0.1'; use File::Basename; use Encode qw/encode/; use YAML::XS qw/Load LoadFile/; use JSON::XS; use Types::Serialiser; use LWP::UserAgent; use HTTP::Request; our $api_url = "https://pddimp.yandex.ru/api2/admin"; our $query_options = Load(<); close $fh; } else { # Stand-alone running with args in the YAML-file $task = %{LoadFile($task_file)}{yamd} or die "Unable to open file '" . $task_file ."'\n"; } } foreach my $check ("domain", "token", "service", "query") { if (!defined $task->{$check}) { die "'$check' is undefined in '$task_file'\n"; } } my $request_url = ""; my $request_type = ""; my $request_content_type = ""; { my $service = $task->{service}; my $sub_service = $task->{sub_service}; my $query = $task->{query}; $request_url = $api_url . "/" . $service; $request_url .= (defined $sub_service) ? "/" . $sub_service : ""; $request_url .= "/" . $query; if ( $service eq "import" && $query eq "start_import_file" ) { $request_url .= "?domain=" . $task->{domain}; foreach my $k (keys %{$task->{options}}) { $request_url .= "&" . $k . "=" . $task->{options}->{$k}; } } if (defined $sub_service) { $request_type = $query_options->{$service}->{$sub_service}->{$query}->{query_type}; $request_content_type = $query_options->{$service}->{$sub_service}->{$query}->{content_type}; } else { $request_type = $query_options->{$service}->{$query}->{query_type}; $request_content_type = $query_options->{$service}->{$query}->{content_type}; } if (!defined $request_content_type) { $request_content_type = $query_options->{default_content_type}; } } my $ua = new LWP::UserAgent; my $request = new HTTP::Request($request_type => $request_url); if ( $task->{service} eq "domain" && $task->{sub_service} eq "logo" && $task->{query} eq "set" ) { { my $boundary = 'X'; my @rand = ('a'..'z', 'A'..'Z'); for (0..14) { $boundary .= $rand[rand(@rand)]; } $request->header( 'PddToken' => $task->{token}, 'Content-type' => $request_content_type . "; boundary=" . $boundary ); my $field = new HTTP::Message([ 'Content-Disposition' => 'form-data; name="domain"', 'Content-Type' => 'text/plain; charset=utf-8' ]); $field->add_content_utf8($task->{domain}); $request->add_part($field); open(my $fh, '<', $task->{options}->{file}); my $file_content = new HTTP::Message([ 'Content-Disposition' => 'form-data; name="file"; filename="logo"', 'Content-Type' => 'application/octet-stream' ]); $file_content->add_content($_) while <$fh>; $request->add_part($file_content); close $fh; } } elsif ( $task->{service} eq "import" && $task->{query} eq "start_import_file" ) { { my $boundary = 'X'; my @rand = ('a'..'z', 'A'..'Z'); for (0..14) { $boundary .= $rand[rand(@rand)]; } $request->header( 'PddToken' => $task->{token}, 'Content-type' => $request_content_type . "; boundary=" . $boundary ); open(my $fh, '<', $task->{options}->{file}); my $file_content = new HTTP::Message([ 'Content-Disposition' => 'form-data; name="import_list_file"; filename="import_list_file"', 'Content-Type' => 'text/plain', ]); $file_content->add_content($_) while <$fh>; $request->add_part($file_content); close $fh; } } else { { $request->header( 'PddToken' => $task->{token}, 'Content-type' => $request_content_type ); my $request_content = "domain=" . $task->{domain}; foreach my $k (keys %{$task->{options}}) { $request_content .= "&" . $k . "="; $request_content .= encode("utf8",$task->{options}->{$k}); } $request->content($request_content); } } my $response = $ua->request($request); if ($response->is_success) { print $response->content . "\n\n"; } else { print $response->status_line . "\n\n"; }