implement call_method
[pve-client.git] / pveclient
1 #!/usr/bin/perl
2
3 package PVE::CLI::pveclient;
4
5 use strict;
6 use warnings;
7 use Cwd 'abs_path';
8 use Data::Dumper;
9
10 use PVE::APIClient::JSONSchema qw(register_standard_option get_standard_option);
11 use PVE::APIClient::CLIHandler;
12
13 use PVE::APIClient::LWP;
14 use PVE::APIClient::Helpers;
15 use PVE::APIClient::Config;
16 use PVE::APIClient::Commands::config;
17 use PVE::APIClient::Commands::remote;
18 use PVE::APIClient::Commands::list;
19 use PVE::APIClient::Commands::lxc;
20 use PVE::APIClient::Commands::GuestStatus;
21
22 use JSON;
23
24 sub call_method {
25     my ($remote, $path, $method, $param) = @_;
26
27     die "missing API path\n" if !defined($path);
28
29     my $config = PVE::APIClient::Config->load();
30
31     # test if api path exists
32     my $info = PVE::APIClient::Helpers::lookup_api_method($path, $method);
33
34     my $conn = PVE::APIClient::Config->remote_conn($config, $remote);
35
36     my $res = $conn->call($method, "api2/json/$path", $param);
37     die "undefined result" if !defined($res);
38     die "undefined result data" if !exists($res->{data});
39
40     return $res->{data};
41 }
42
43 use base qw(PVE::APIClient::CLIHandler);
44
45 my $cmd = $ARGV[0];
46
47 if ($cmd && $cmd eq 'packagedepends') {
48     # experimental code to print required perl packages
49     my $packages = {};
50     my $dir = Cwd::getcwd;
51
52     foreach my $k (keys %INC) {
53         my $file = abs_path($INC{$k});
54         next if $file =~ m/^\Q$dir\E/;
55         my $res = `dpkg -S '$file'`;
56         if ($res && $res =~ m/^(\S+): $file$/) {
57             my $debian_package = $1;
58             $debian_package =~ s/:amd64$//;
59             $packages->{$debian_package} = 1;
60         } else {
61             die "unable to find package for '$file'\n";
62         }
63     }
64     print join("\n", sort(keys %$packages)) . "\n";
65
66     exit(0);
67 }
68
69 my $path_properties = {};
70 my $path_returns = { type => 'null' };
71
72 # dynamically update schema definition for direct API call
73 # like: pveclient api <get|set|create|delete|help> <remote> <path>
74 if (my $info =  PVE::APIClient::Helpers::extract_path_info()) {
75     $path_properties = $info->{parameters}->{properties};
76     $path_returns = $info->{returns};
77 }
78
79 $path_properties->{remote} = get_standard_option('pveclient-remote-name');
80 $path_properties->{api_path} = {
81     description => "API path.",
82     type => 'string',
83     completion => sub {
84         my ($cmd, $pname, $cur, $args) = @_;
85         return PVE::APIClient::Helpers::complete_api_path($cur);
86     },
87 };
88
89 my $format_result = sub {
90     my ($data, $format) = @_;
91
92     return if $path_returns->{type} eq 'null';
93
94     # TODO: implement different output formats ($format)
95     print to_json($data, {utf8 => 1, allow_nonref => 1, canonical => 1, pretty => 1 });
96 };
97
98 __PACKAGE__->register_method ({
99     name => 'pveclient_get',
100     path => 'pveclient_get',
101     method => 'GET',
102     description => "call API GET on <path>.",
103     parameters => {
104         additionalProperties => 0,
105         properties => $path_properties,
106     },
107     returns => $path_returns,
108     code => sub {
109         my ($param) = @_;
110
111         my $path = PVE::Tools::extract_param($param, 'api_path');
112         my $remote = PVE::Tools::extract_param($param, 'remote');
113
114         return call_method($remote, $path, 'GET', $param);
115     }});
116
117 __PACKAGE__->register_method ({
118     name => 'pveclient_set',
119     path => 'pveclient_set',
120     method => 'PUT',
121     description => "call API PUT on <path>.",
122     parameters => {
123         additionalProperties => 0,
124         properties => $path_properties,
125     },
126     returns => $path_returns,
127     code => sub {
128         my ($param) = @_;
129
130         print Dumper($param);
131
132         die "implement me";
133
134     }});
135
136 __PACKAGE__->register_method ({
137     name => 'pveclient_create',
138     path => 'pveclient_create',
139     method => 'PUSH',
140     description => "call API PUSH on <path>.",
141     parameters => {
142         additionalProperties => 0,
143         properties => $path_properties,
144     },
145     returns => $path_returns,
146     code => sub {
147         my ($param) = @_;
148
149         print Dumper($param);
150
151         die "implement me";
152
153     }});
154
155 __PACKAGE__->register_method ({
156     name => 'pveclient_delete',
157     path => 'pveclient_delete',
158     method => 'DELETE',
159     description => "call API DELETE on <path>.",
160     parameters => {
161         additionalProperties => 0,
162         properties => $path_properties,
163     },
164     returns => $path_returns,
165     code => sub {
166         my ($param) = @_;
167
168         print Dumper($param);
169
170         die "implement me";
171
172     }});
173
174
175 our $cmddef = {
176     config => $PVE::APIClient::Commands::config::cmddef,
177     list => $PVE::APIClient::Commands::list::cmddef,
178     lxc => $PVE::APIClient::Commands::lxc::cmddef,
179     remote => $PVE::APIClient::Commands::remote::cmddef,
180
181     spice => [ 'PVE::APIClient::Commands::GuestStatus', 'spice', ['remote', 'vmid']],
182     start => [ 'PVE::APIClient::Commands::GuestStatus', 'start', ['remote', 'vmid']],
183     stop => [ 'PVE::APIClient::Commands::GuestStatus', 'stop', ['remote', 'vmid']],
184
185     api => {
186         get => [ __PACKAGE__, 'pveclient_get', ['remote', 'api_path'], {}, $format_result ],
187         set => [ __PACKAGE__, 'pveclient_set', ['remote', 'api_path'], {}, $format_result ],
188         create => [ __PACKAGE__, 'pveclient_create', ['remote', 'api_path'], {}, $format_result ],
189         delete => [ __PACKAGE__, 'pveclient_delete', ['remote', 'api_path'], {}, $format_result ],
190     },
191 };
192
193
194 __PACKAGE__->run_cli_handler();