1 package PVE
::API2
::Subscription
;
5 use Digest
::MD5
qw(md5_hex md5_base64);
13 use PVE
::Exception
qw(raise_param_exc);
15 use PVE
::Cluster qw
(cfs_read_file cfs_write_file
);
16 use PVE
::AccessControl
;
18 use PVE
::JSONSchema
qw(get_standard_option);
21 use PVE
::Subscription
;
26 use base
qw(PVE::RESTHandler);
28 PVE
::INotify
::register_file
('subscription', "/etc/subscription",
29 \
&read_etc_pve_subscription
,
30 \
&write_etc_pve_subscription
);
32 my $subscription_pattern = 'pve([1248])([cbsp])-[0-9a-f]{10}';
35 my $info = PVE
::ProcFSTools
::read_cpuinfo
();
36 return $info->{sockets
};
40 my ($key, $noerr) = @_;
42 if ($key =~ m/^${subscription_pattern}$/) {
43 return wantarray ?
($1, $2) : $1; # number of sockets, level
45 return undef if $noerr;
47 die "Wrong subscription key format\n";
51 my ($key, $req_sockets) = @_;
53 my ($sockets, $level) = parse_key
($key);
54 if ($sockets < $req_sockets) {
55 die "wrong number of sockets ($sockets < $req_sockets)\n";
57 return ($sockets, $level);
60 sub read_etc_pve_subscription
{
61 my ($filename, $fh) = @_;
63 my $req_sockets = get_sockets
();
64 my $server_id = PVE
::API2Tools
::get_hwaddress
();
66 my $info = PVE
::Subscription
::read_subscription
($server_id, $filename, $fh);
68 return $info if $info->{status
} ne 'Active';
70 my ($sockets, $level);
71 eval { ($sockets, $level) = check_key
($info->{key
}, $req_sockets); };
74 $info->{status
} = 'Invalid';
75 $info->{message
} = $err;
77 $info->{level
} = $level;
83 sub write_etc_pve_subscription
{
84 my ($filename, $fh, $info) = @_;
86 my $server_id = PVE
::API2Tools
::get_hwaddress
();
87 PVE
::Subscription
::write_subscription
($server_id, $filename, $fh, $info);
90 __PACKAGE__-
>register_method ({
94 description
=> "Read subscription info.",
96 permissions
=> { user
=> 'all' },
98 additionalProperties
=> 0,
100 node
=> get_standard_option
('pve-node'),
103 returns
=> { type
=> 'object'},
107 my $node = $param->{node
};
109 my $rpcenv = PVE
::RPCEnvironment
::get
();
110 my $authuser = $rpcenv->get_user();
111 my $has_permission = PVE
::AccessControl
::check_permissions
($authuser, "/nodes/$node", 'Sys.Audit');
113 my $server_id = PVE
::API2Tools
::get_hwaddress
();
114 my $url = "http://www.proxmox.com/products/proxmox-ve/subscription-service-plans";
116 my $info = PVE
::INotify
::read_file
('subscription');
118 my $no_subscription_info = {
119 status
=> "NotFound",
120 message
=> "There is no subscription key",
123 $no_subscription_info->{serverid
} = $server_id if $has_permission;
124 return $no_subscription_info;
127 if (!$has_permission) {
129 status
=> $info->{status
},
130 message
=> $info->{message
},
135 $info->{serverid
} = $server_id;
136 $info->{sockets
} = get_sockets
();
142 __PACKAGE__-
>register_method ({
147 check
=> ['perm', '/nodes/{node}', [ 'Sys.Modify' ]],
149 description
=> "Update subscription info.",
153 additionalProperties
=> 0,
155 node
=> get_standard_option
('pve-node'),
157 description
=> "Always connect to server, even if we have up to date info inside local cache.",
164 returns
=> { type
=> 'null'},
168 my $info = PVE
::INotify
::read_file
('subscription');
169 return undef if !$info;
171 my $server_id = PVE
::API2Tools
::get_hwaddress
();
172 my $key = $info->{key
};
175 PVE
::Subscription
::update_apt_auth
($key, $server_id);
178 if (!$param->{force
} && $info->{status
} eq 'Active') {
179 my $age = time() - $info->{checktime
};
180 return undef if $age < $PVE::Subscription
::localkeydays
*60*60*24;
183 my $req_sockets = get_sockets
();
184 check_key
($key, $req_sockets);
186 my $dccfg = PVE
::Cluster
::cfs_read_file
('datacenter.cfg');
187 my $proxy = $dccfg->{http_proxy
};
189 $info = PVE
::Subscription
::check_subscription
($key, $server_id, $proxy);
191 PVE
::INotify
::write_file
('subscription', $info);
196 __PACKAGE__-
>register_method ({
201 check
=> ['perm', '/nodes/{node}', [ 'Sys.Modify' ]],
203 description
=> "Set subscription key.",
207 additionalProperties
=> 0,
209 node
=> get_standard_option
('pve-node'),
211 description
=> "Proxmox VE subscription key",
213 pattern
=> $subscription_pattern,
218 returns
=> { type
=> 'null'},
222 my $key = PVE
::Tools
::trim
($param->{key
});
230 my $req_sockets = get_sockets
();
231 my $server_id = PVE
::API2Tools
::get_hwaddress
();
233 check_key
($key, $req_sockets);
235 PVE
::INotify
::write_file
('subscription', $info);
237 my $dccfg = PVE
::Cluster
::cfs_read_file
('datacenter.cfg');
238 my $proxy = $dccfg->{http_proxy
};
240 $info = PVE
::Subscription
::check_subscription
($key, $server_id, $proxy);
242 PVE
::INotify
::write_file
('subscription', $info);