plesk_lib 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.md +89 -0
  7. data/Rakefile +1 -0
  8. data/lib/plesk_lib.rb +29 -0
  9. data/lib/plesk_lib/account.rb +14 -0
  10. data/lib/plesk_lib/actions/base.rb +61 -0
  11. data/lib/plesk_lib/actions/change_customer_password.rb +27 -0
  12. data/lib/plesk_lib/actions/create_account.rb +23 -0
  13. data/lib/plesk_lib/actions/create_customer.rb +21 -0
  14. data/lib/plesk_lib/actions/create_reseller.rb +22 -0
  15. data/lib/plesk_lib/actions/create_service_plan.rb +327 -0
  16. data/lib/plesk_lib/actions/create_subscription.rb +55 -0
  17. data/lib/plesk_lib/actions/get_statistics.rb +61 -0
  18. data/lib/plesk_lib/actions/list_customers.rb +51 -0
  19. data/lib/plesk_lib/actions/list_service_plans.rb +60 -0
  20. data/lib/plesk_lib/actions/list_subscriptions.rb +42 -0
  21. data/lib/plesk_lib/customer.rb +4 -0
  22. data/lib/plesk_lib/reseller.rb +5 -0
  23. data/lib/plesk_lib/server.rb +23 -0
  24. data/lib/plesk_lib/service_plan.rb +17 -0
  25. data/lib/plesk_lib/subscription.rb +14 -0
  26. data/lib/plesk_lib/version.rb +3 -0
  27. data/plesk_lib.gemspec +30 -0
  28. data/spec/actions/change_customer_password_spec.rb +29 -0
  29. data/spec/actions/create_customer_spec.rb +50 -0
  30. data/spec/actions/create_reseller_spec.rb +35 -0
  31. data/spec/actions/create_service_plan_spec.rb +33 -0
  32. data/spec/actions/create_subscription_spec.rb +21 -0
  33. data/spec/actions/get_statistics_spec.rb +15 -0
  34. data/spec/actions/list_customers_spec.rb +31 -0
  35. data/spec/actions/list_service_plans_spec.rb +31 -0
  36. data/spec/actions/list_subscriptions.rb +31 -0
  37. data/spec/customer_spec.rb +21 -0
  38. data/spec/reseller_spec.rb +22 -0
  39. data/spec/server_spec.rb +48 -0
  40. data/spec/spec_helper.rb +28 -0
  41. data/spec/vcr/customer/change_password_existing_user.yml +57 -0
  42. data/spec/vcr/customer/change_password_missing_user.yml +57 -0
  43. data/spec/vcr/customer/list_customers.yml +57 -0
  44. data/spec/vcr/customer/list_customers_filtered.yml +57 -0
  45. data/spec/vcr/customer/minimal.yml +112 -0
  46. data/spec/vcr/customer/minimal_exists.yml +112 -0
  47. data/spec/vcr/customer/minimal_with_owner.yml +58 -0
  48. data/spec/vcr/reseller/minimal.yml +58 -0
  49. data/spec/vcr/reseller/minimal_exists.yml +58 -0
  50. data/spec/vcr/server/get_statistics.yml +57 -0
  51. data/spec/vcr/service_plan/create_minimal.yml +58 -0
  52. data/spec/vcr/service_plan/create_minimal_with_owner.yml +58 -0
  53. data/spec/vcr/service_plan/list_admin.yml +57 -0
  54. data/spec/vcr/service_plan/list_all.yml +57 -0
  55. data/spec/vcr/subscription/create.yml +57 -0
  56. data/spec/vcr/subscription/list_subscriptions.yml +57 -0
  57. data/spec/vcr/subscription/list_subscriptions_filtered.yml +57 -0
  58. metadata +257 -0
@@ -0,0 +1,55 @@
1
+ class PleskLib::Actions::CreateSubscription < PleskLib::Actions::Base
2
+ attr_reader :subscription, :plesk_id, :guid
3
+
4
+ def initialize(subscription)
5
+ @subscription = subscription
6
+ end
7
+
8
+ # Creates Object & Packet
9
+ def build_xml
10
+ xml = Builder::XmlMarkup.new
11
+ xml.instruct!
12
+ xml.packet(:version => '1.6.3.5') {
13
+ xml.webspace {
14
+ xml.add {
15
+ xml.gen_setup{
16
+ xml.name(subscription.name)
17
+ if subscription.owner_id.present?
18
+ xml.tag!('owner-id', subscription.owner_id)
19
+ end
20
+ if subscription.owner_login.present?
21
+ xml.tag!('owner-login', subscription.owner_login)
22
+ end
23
+ xml.ip_address(subscription.ip_address)
24
+ }
25
+ xml.hosting{
26
+ xml.vrt_hst{
27
+ xml.property{
28
+ xml.name('ftp_login')
29
+ xml.value(subscription.ftp_login)
30
+ }
31
+ xml.property{
32
+ xml.name('ftp_password')
33
+ xml.value(subscription.ftp_password)
34
+ }
35
+ xml.ip_address(subscription.ip_address)
36
+ }
37
+ }
38
+ if subscription.service_plan_id.present?
39
+ xml.tag!('plan-id', subscription.service_plan_id)
40
+ end
41
+ if subscription.service_plan_name.present?
42
+ xml.tag!('plan-name', subscription.service_plan_name)
43
+ end
44
+ }
45
+ }
46
+ }
47
+ xml.target!
48
+ end
49
+
50
+ def analyse(xml_document)
51
+ add_node = xml_document.root.locate('*/result').first
52
+ @plesk_id = add_node.id.text.to_i
53
+ @guid = add_node.guid.text
54
+ end
55
+ end
@@ -0,0 +1,61 @@
1
+ class PleskLib::Actions::GetStatistics < PleskLib::Actions::Base
2
+ attr_reader :statistics
3
+
4
+ def build_xml
5
+ xml = Builder::XmlMarkup.new
6
+ xml.instruct!
7
+ xml.packet(:version => '1.6.3.5') {
8
+ xml.server{
9
+ xml.get{
10
+ xml.stat()
11
+ }
12
+ }
13
+ }
14
+ return xml.target!
15
+ end
16
+
17
+ def analyse(xml_document)
18
+ status_root = xml_document.root.server.get.result.stat
19
+ @statistics = {}
20
+ object_stats = {}
21
+ device_stats = {}
22
+
23
+ status_root.objects.nodes.each do |node|
24
+ object_stats[node.name] = node.text.to_i
25
+ end
26
+
27
+ status_root.load_avg.nodes.each do |node|
28
+ @statistics[node.name] = node.text.to_f / 100
29
+ end
30
+
31
+ status_root.mem.nodes.each do |node|
32
+ @statistics['mem_' + node.name] = BigDecimal.new(node.text)
33
+ end
34
+
35
+ status_root.swap.nodes.each do |node|
36
+ @statistics['swap_' + node.name] = BigDecimal.new(node.text)
37
+ end
38
+
39
+ status_root.diskspace.nodes.each do |device_node|
40
+ device_name = nil, device_attrs = {}
41
+ device_node.nodes.each do |attr_node|
42
+ if attr_node.name == 'name'
43
+ device_name = attr_node.text
44
+ else
45
+ device_attrs[attr_node.name] = BigDecimal.new(attr_node.text)
46
+ end
47
+ end
48
+ device_stats[device_name] = device_attrs
49
+ end
50
+
51
+ status_root.version.nodes.each do |node|
52
+ @statistics[node.name] = node.text
53
+ end
54
+
55
+ status_root.other.nodes.each do |node|
56
+ @statistics[node.name] = node.name == 'uptime' ? node.text.to_i : node.text
57
+ end
58
+
59
+ @statistics.merge!({objects: object_stats, devices: device_stats})
60
+ end
61
+ end
@@ -0,0 +1,51 @@
1
+ class PleskLib::Actions::ListCustomers < PleskLib::Actions::Base
2
+ attr_reader :customers
3
+
4
+ MAPPING = {
5
+ 'cr_date' => 'created_at', 'cname' => 'company_name', 'pname' => 'person_name',
6
+ 'login' => 'login', 'status' => 'status', 'phone' => 'phone', 'fax' => 'fax',
7
+ 'email' => 'email', 'address' => 'address', 'city' => 'city', 'state' => 'state',
8
+ 'pcode' => 'postal_code', 'country' => 'country', 'locale' => 'locale',
9
+ 'guid' => 'guid', 'owner-id' => 'owner_id', 'vendor-guid' => 'vendor_guid',
10
+ 'external-id' => 'external_id', 'password' => 'password',
11
+ 'password_type' => 'password_type'
12
+ }
13
+
14
+ def initialize(owner_id = nil)
15
+ @owner_id = owner_id
16
+ end
17
+
18
+ def build_xml
19
+ xml = Builder::XmlMarkup.new
20
+ xml.instruct!
21
+ xml.packet(:version => '1.6.3.5') {
22
+ xml.customer {
23
+ xml.get {
24
+ xml.filter {
25
+ xml.tag!('owner-id', @owner_id) if @owner_id.present?
26
+ }
27
+ xml.dataset {
28
+ xml.gen_info
29
+ xml.stat
30
+ }
31
+ }
32
+ }
33
+ }
34
+ return xml.target!
35
+ end
36
+
37
+ def analyse(xml_document)
38
+ @customers = []
39
+ xml_document.root.customer.get.nodes.each do |customer_node|
40
+ customer = PleskLib::Customer.new(nil)
41
+ customer_node.data.gen_info.nodes.each do |attribute_node|
42
+ customer_attribute = MAPPING[attribute_node.name]
43
+ next if customer_attribute.blank? || !customer.respond_to?(customer_attribute) ||
44
+ attribute_node.text.blank?
45
+ customer.send("#{customer_attribute}=", attribute_node.text)
46
+ end
47
+ customer.status = customer.status.to_i
48
+ @customers << customer
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,60 @@
1
+ class PleskLib::Actions::ListServicePlans < PleskLib::Actions::Base
2
+ attr_reader :service_plans
3
+
4
+ def initialize(owner_id = nil)
5
+ @owner_id = owner_id
6
+ end
7
+
8
+ MAPPING = {
9
+ 'cr_date' => 'created_at', 'cname' => 'company_name', 'pname' => 'person_name',
10
+ 'login' => 'login', 'status' => 'status', 'phone' => 'phone', 'fax' => 'fax',
11
+ 'email' => 'email', 'address' => 'address', 'city' => 'city', 'state' => 'state',
12
+ 'pcode' => 'postal_code', 'country' => 'country', 'locale' => 'locale',
13
+ 'guid' => 'guid', 'owner-id' => 'owner_id', 'vendor-guid' => 'vendor_guid',
14
+ 'external-id' => 'external_id', 'password' => 'password',
15
+ 'password_type' => 'password_type'
16
+ }
17
+
18
+ def build_xml
19
+ xml = Builder::XmlMarkup.new
20
+ xml.instruct!
21
+ xml.packet(:version => '1.6.3.5') {
22
+ xml.tag!('service-plan') {
23
+ xml.get {
24
+ xml.filter
25
+ if @owner_id.present?
26
+ xml.tag!('owner-id', @owner_id)
27
+ else
28
+ xml.tag!('owner-all')
29
+ end
30
+ }
31
+ }
32
+ }
33
+ return xml.target!
34
+ end
35
+
36
+ def analyse(xml_document)
37
+ @service_plans = []
38
+ xml_document.root.send('service-plan').get.nodes.each do |plan_el|
39
+ service_plan = PleskLib::ServicePlan.new(plan_el.locate('name').first.text)
40
+ # binding.pry
41
+ service_plan.id = plan_el.send('id').text.to_i
42
+ service_plan.external_id = plan_el.send('external-id').text
43
+ service_plan.guid = plan_el.send('guid').text
44
+
45
+ owner_id_nodes = plan_el.locate('owner-id')
46
+ if owner_id_nodes.first.present?
47
+ service_plan.owner_id = owner_id_nodes.first.text.to_i
48
+ end
49
+
50
+ # plan_el.elements['data//gen_info'].each_element do |attribute|
51
+ # service_plan_attribute = MAPPING[attribute.name]
52
+ # next if service_plan_attribute.blank? || !service_plan.respond_to?(service_plan_attribute) ||
53
+ # attribute.text.blank?
54
+ # service_plan.send("#{service_plan_attribute}=", attribute.text)
55
+ # end
56
+ # service_plan.status = service_plan.status.to_i
57
+ @service_plans << service_plan
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,42 @@
1
+ class PleskLib::Actions::ListSubscriptions < PleskLib::Actions::Base
2
+ attr_reader :subscriptions
3
+
4
+ def initialize(owner_id = nil)
5
+ @owner_id = owner_id
6
+ end
7
+
8
+ def build_xml
9
+ xml = Builder::XmlMarkup.new
10
+ xml.instruct!
11
+ xml.packet(:version => '1.6.3.5') {
12
+ xml.webspace {
13
+ xml.get {
14
+ xml.filter {
15
+ xml.tag!('owner-id', @owner_id) if @owner_id.present?
16
+ }
17
+ xml.dataset {
18
+ xml.gen_info
19
+ xml.hosting
20
+ }
21
+ }
22
+ }
23
+ }
24
+ return xml.target!
25
+ end
26
+
27
+ def analyse(xml_document)
28
+ @subscriptions = []
29
+ xml_document.root.webspace.get.nodes.each do |webspace_node|
30
+ subscription = PleskLib::Subscription.new
31
+ # binding.pry
32
+ webspace_node.data.gen_info.nodes.each do |attribute_node|
33
+ subscription_attribute = attribute_node.name.underscore
34
+ next if !subscription.respond_to?(subscription_attribute) ||
35
+ attribute_node.text.blank?
36
+ subscription.send("#{subscription_attribute}=", attribute_node.text)
37
+ end
38
+ subscription.id = webspace_node.id.text.to_i
39
+ @subscriptions << subscription
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,4 @@
1
+ module PleskLib
2
+ class Customer < Account
3
+ end
4
+ end
@@ -0,0 +1,5 @@
1
+ module PleskLib
2
+ class Reseller < Account
3
+ attr_accessor :service_plan_id
4
+ end
5
+ end
@@ -0,0 +1,23 @@
1
+ module PleskLib
2
+ class Server
3
+ attr_accessor :host, :password, :username
4
+
5
+ def initialize(host, username, password)
6
+ @host = host
7
+ @username = username
8
+ @password = password
9
+ end
10
+
11
+ def method_missing(method_name, *args)
12
+ begin
13
+ action_class = "PleskLib::Actions::#{method_name.to_s.camelize}".constantize
14
+ rescue NameError => e
15
+ raise NoMethodError, "The Action #{e.name} is not available. Please check the action docs."
16
+ else
17
+ action = action_class.new(*args)
18
+ action.execute_on(self)
19
+ return action
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,17 @@
1
+ module PleskLib
2
+ class ServicePlan
3
+ attr_accessor :name, :mailboxes, :domains, :traffic, :storage, :external_id,
4
+ :owner_id, :id, :guid
5
+
6
+ def initialize(name, attributes = {})
7
+ @name = name
8
+ attributes.each_pair do |key, value|
9
+ send("#{key}=", value)
10
+ end if attributes.present?
11
+ end
12
+
13
+ def to_s
14
+ "#<#{self.class}: id=#{self.id} name=#{self.name}, guid: #{self.guid}>"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ module PleskLib
2
+ class Subscription
3
+ attr_accessor :id, :ip_address, :name, :owner_id, :owner_login,
4
+ :service_plan_name, :service_plan_id, :customer_account_id,
5
+ :reseller_account_id, :external_id, :guid, :vendor_guid,
6
+ :ftp_login, :ftp_password
7
+
8
+ def initialize(attributes = {})
9
+ attributes.each_pair do |key, value|
10
+ send("#{key}=", value)
11
+ end if attributes.present?
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ module PleskLib
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'plesk_lib/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "plesk_lib"
8
+ spec.version = PleskLib::VERSION
9
+ spec.authors = ["Phillipp Röll"]
10
+ spec.email = ["phillipp.roell@trafficplex.de"]
11
+ spec.summary = %q{Plesk 11 provisioning library. Extracted out of plesk_kit}
12
+ spec.description = %q{Add customers, resellers, service plans and subscriptions to plesk via the XML RPC API}
13
+ spec.homepage = "https://github.com/phillipp/plesk_lib"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency "activesupport", ">= 3.0.0"
22
+ spec.add_runtime_dependency "ox", "~> 2.1.1"
23
+ spec.add_runtime_dependency "builder", "~> 3.2.2"
24
+ spec.add_development_dependency "bundler", "~> 1.5"
25
+ spec.add_development_dependency "rake"
26
+ spec.add_development_dependency "rspec", "~> 2.14.1"
27
+ spec.add_development_dependency "vcr", "~> 2.8.0"
28
+ spec.add_development_dependency "webmock", "~> 1.17.4"
29
+ spec.add_development_dependency "pry", "~> 0.9.12.6"
30
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe PleskLib::Actions::ChangeCustomerPassword do
4
+ let(:server) { PleskLib::Server.new('10.0.0.158', 'admin', 'ccsnDxnWy2j0') }
5
+
6
+ context 'when user exists on the server' do
7
+ let(:customer) { PleskLib::Customer.new('user91') }
8
+
9
+ it 'should reset the customers password' do
10
+ VCR.use_cassette 'customer/change_password_existing_user', match_requests_on: [:method, :uri, :body] do
11
+ action = PleskLib::Actions::ChangeCustomerPassword.new(customer, 'new_password')
12
+ action.execute_on(server)
13
+ end
14
+ end
15
+ end
16
+
17
+ context 'when user is missing' do
18
+ let(:customer) { PleskLib::Customer.new('unknownuser') }
19
+
20
+ it 'should raise a AccountNotFound exception' do
21
+ VCR.use_cassette 'customer/change_password_missing_user', match_requests_on: [:method, :uri, :body] do
22
+ action = PleskLib::Actions::ChangeCustomerPassword.new(customer, 'new_password')
23
+ expect {
24
+ action.execute_on(server)
25
+ }.to raise_error(PleskLib::AccountNotFound)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ describe PleskLib::Actions::CreateCustomer do
4
+ let(:customer_attributes) do
5
+ { password: 'customer_secret', phone: '0000000000',
6
+ email: 'noreply@ausupport.com.au', country: 'AU',
7
+ person_name: 'FirstName LastName', company_name: 'My Company' }
8
+ end
9
+
10
+ let(:server) { PleskLib::Server.new('10.0.0.158', 'admin', 'ccsnDxnWy2j0') }
11
+ let(:customer) { PleskLib::Customer.new('cust91', customer_attributes) }
12
+
13
+ context 'when login is available on the plesk server' do
14
+ it 'should create a customer' do
15
+ VCR.use_cassette 'customer/minimal', match_requests_on: [:method, :uri, :body] do
16
+ action = PleskLib::Actions::CreateCustomer.new(customer)
17
+ action.execute_on(server)
18
+ action.plesk_id.to_i.should > 0
19
+ end
20
+ end
21
+ end
22
+
23
+ context 'when an owner id is set' do
24
+ let(:customer) { PleskLib::Customer.new('cust8891', customer_attributes) }
25
+ let(:customer_attributes) do
26
+ { password: 'customer_secret', phone: '0000000000',
27
+ email: 'noreply@ausupport.com.au', country: 'AU',
28
+ person_name: 'FirstName LastName', company_name: 'My Company',
29
+ owner_id: 3 }
30
+ end
31
+ it 'should create a customer' do
32
+ VCR.use_cassette 'customer/minimal_with_owner', match_requests_on: [:method, :uri, :body] do
33
+ action = PleskLib::Actions::CreateCustomer.new(customer)
34
+ action.execute_on(server)
35
+ action.plesk_id.to_i.should > 0
36
+ end
37
+ end
38
+ end
39
+
40
+ context 'when login is already taken' do
41
+ it 'should raise a LoginAlreadyTaken exception' do
42
+ VCR.use_cassette 'customer/minimal_exists', match_requests_on: [:method, :uri, :body] do
43
+ action = PleskLib::Actions::CreateCustomer.new(customer)
44
+ expect {
45
+ action.execute_on(server)
46
+ }.to raise_error(PleskLib::LoginAlreadyTaken)
47
+ end
48
+ end
49
+ end
50
+ end