knife-google 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +15 -0
  2. data/README.md +155 -66
  3. data/knife-google.gemspec +2 -1
  4. data/lib/chef/knife/google_base.rb +1 -1
  5. data/lib/chef/knife/google_disk_create.rb +17 -9
  6. data/lib/chef/knife/google_disk_delete.rb +2 -2
  7. data/lib/chef/knife/google_disk_list.rb +8 -8
  8. data/lib/chef/knife/google_project_list.rb +178 -0
  9. data/lib/chef/knife/google_region_list.rb +125 -0
  10. data/lib/chef/knife/google_server_create.rb +174 -46
  11. data/lib/chef/knife/google_server_delete.rb +9 -13
  12. data/lib/chef/knife/google_server_list.rb +5 -6
  13. data/lib/chef/knife/google_zone_list.rb +22 -28
  14. data/lib/google/compute.rb +2 -1
  15. data/lib/google/compute/client.rb +12 -7
  16. data/lib/google/compute/creatable_resource_collection.rb +12 -1
  17. data/lib/google/compute/disk.rb +0 -2
  18. data/lib/google/compute/image.rb +1 -2
  19. data/lib/google/compute/project.rb +2 -2
  20. data/lib/google/compute/{kernel.rb → region.rb} +12 -1
  21. data/lib/google/compute/region_operation.rb +62 -0
  22. data/lib/google/compute/server.rb +3 -2
  23. data/lib/google/compute/server/attached_disk.rb +3 -3
  24. data/lib/google/compute/zone.rb +6 -4
  25. data/lib/google/compute/zone_operation.rb +11 -9
  26. data/lib/knife-google/version.rb +1 -1
  27. data/spec/chef/knife/google_base_spec.rb +4 -4
  28. data/spec/chef/knife/google_disk_create_spec.rb +8 -7
  29. data/spec/chef/knife/google_disk_delete_spec.rb +15 -16
  30. data/spec/chef/knife/google_disk_list_spec.rb +6 -6
  31. data/spec/chef/knife/google_region_list_spec.rb +32 -0
  32. data/spec/chef/knife/google_server_create_spec.rb +78 -44
  33. data/spec/chef/knife/google_server_delete_spec.rb +37 -37
  34. data/spec/chef/knife/google_server_list_spec.rb +8 -7
  35. data/spec/chef/knife/google_setup_spec.rb +1 -2
  36. data/spec/chef/knife/google_zone_list_spec.rb +4 -4
  37. data/spec/data/{compute-v1beta15.json → compute-v1.json} +700 -246
  38. data/spec/data/disk.json +3 -4
  39. data/spec/data/firewall.json +2 -2
  40. data/spec/data/global_operation.json +3 -3
  41. data/spec/data/image.json +2 -2
  42. data/spec/data/machine_type.json +1 -1
  43. data/spec/data/network.json +1 -1
  44. data/spec/data/project.json +1 -1
  45. data/spec/data/region.json +23 -0
  46. data/spec/data/serial_port_output.json +1 -1
  47. data/spec/data/server.json +7 -7
  48. data/spec/data/snapshot.json +2 -2
  49. data/spec/data/zone.json +7 -15
  50. data/spec/data/zone_operation.json +3 -3
  51. data/spec/google/compute/disk_spec.rb +32 -32
  52. data/spec/google/compute/firewall_spec.rb +37 -37
  53. data/spec/google/compute/global_operation_spec.rb +9 -9
  54. data/spec/google/compute/image_spec.rb +17 -17
  55. data/spec/google/compute/machine_type_spec.rb +7 -7
  56. data/spec/google/compute/network_spec.rb +14 -14
  57. data/spec/google/compute/project_spec.rb +17 -17
  58. data/spec/google/compute/region_spec.rb +51 -0
  59. data/spec/google/compute/server_spec.rb +35 -42
  60. data/spec/google/compute/snapshot_spec.rb +11 -11
  61. data/spec/google/compute/zone_operation_spec.rb +9 -9
  62. data/spec/google/compute/zone_spec.rb +7 -7
  63. data/spec/spec_helper.rb +1 -0
  64. data/spec/support/mocks.rb +10 -10
  65. data/spec/support/resource_examples.rb +7 -7
  66. data/spec/support/spec_google_base.rb +4 -0
  67. metadata +14 -26
  68. data/spec/data/kernel.json +0 -15
  69. data/spec/google/compute/kernel_spec.rb +0 -49
@@ -25,13 +25,13 @@ class Chef
25
25
  require 'google/compute'
26
26
  end
27
27
 
28
- banner "knife google server delete SERVER [SERVER] --google-compute-zone ZONE (options)"
28
+ banner "knife google server delete SERVER [SERVER] -Z ZONE (options)"
29
29
 
30
30
  attr_reader :instances
31
31
 
32
32
  option :zone,
33
33
  :short => "-Z ZONE",
34
- :long => "--google-compute-zone ZONE",
34
+ :long => "--gce-zone ZONE",
35
35
  :description => "The Zone for this server"
36
36
 
37
37
  option :purge,
@@ -39,12 +39,12 @@ class Chef
39
39
  :long => "--purge",
40
40
  :boolean => true,
41
41
  :default => false,
42
- :description => "Destroy corresponding node and client on the Chef Server, in addition to destroying the GCE server itself. Assumes node and client have the same name as the server (if not, add the '--node-name' option)."
42
+ :description => "Destroy corresponding node and client on the Chef Server, in addition to destroying the GCE server itself. Assumes node and client have the same name as the server (if not, add the '--node-name' option)."
43
43
 
44
44
  option :chef_node_name,
45
45
  :short => "-N NAME",
46
46
  :long => "--node-name NAME",
47
- :description => "The name of the node and client to delete, if it differs from the server name. Only has meaning when used with the '--purge' option."
47
+ :description => "The name of the node and client to delete, if it differs from the server name. Only has meaning when used with the '--purge' option."
48
48
 
49
49
  # Taken from knife-ec2 plugin, for rational , check the following link
50
50
  # https://github.com/opscode/knife-ec2/blob/master/lib/chef/knife/ec2_server_delete.rb#L48
@@ -60,9 +60,9 @@ class Chef
60
60
 
61
61
  def run
62
62
  begin
63
- zone = client.zones.get(config[:zone] || Chef::Config[:knife][:google_compute_zone]).self_link
63
+ zone = client.zones.get(config[:zone] || Chef::Config[:knife][:gce_zone]).self_link
64
64
  rescue Google::Compute::ResourceNotFound
65
- ui.error("Zone '#{config[:zone] || Chef::Config[:knife][:google_compute_zone]}' not found")
65
+ ui.error("Zone '#{config[:zone] || Chef::Config[:knife][:gce_zone]}' not found")
66
66
  exit 1
67
67
  rescue Google::Compute::ParameterValidation
68
68
  ui.error("Must specify zone in knife config file or in command line as an option. Try --help.")
@@ -75,25 +75,21 @@ class Chef
75
75
  instance = client.instances.get(:name=>instance_name, :zone=>selflink2name(zone))
76
76
  @instances << instance
77
77
  msg_pair("Name", instance.name)
78
- msg_pair("MachineType", selflink2name(instance.machine_type))
79
- msg_pair("Image", selflink2name(instance.image))
78
+ msg_pair("Machine Type", selflink2name(instance.machine_type))
80
79
  msg_pair("Zone", selflink2name(instance.zone))
81
80
  msg_pair("Tags", instance.tags.has_key?("items") ? instance.tags["items"].join(',') : "None")
82
81
  msg_pair("Public IP Address", public_ips(instance).join(','))
83
82
  msg_pair("Private IP Address", private_ips(instance).join(','))
84
-
85
83
  puts "\n"
84
+ ui.warn("Persistent disks attached to this instance are not deleted with this operation")
86
85
  ui.confirm("Do you really want to delete server '#{selflink2name(zone)}:#{instance.name}'")
87
-
88
86
  client.instances.delete(:instance=>instance.name, :zone=>selflink2name(zone))
89
-
90
87
  ui.warn("Deleted server '#{selflink2name(zone)}:#{instance.name}'")
91
-
92
88
  if config[:purge]
93
89
  destroy_item(Chef::Node, instance.name, "node")
94
90
  destroy_item(Chef::ApiClient, instance.name, "client")
95
91
  else
96
- ui.warn("Corresponding node and client for the #{instance.name} server were not deleted and remain registered with the Chef Server")
92
+ ui.warn("Corresponding node and client for the #{instance.name} server were not deleted and remain registered with the Chef Server")
97
93
  end
98
94
  rescue
99
95
  ui.error("Could not locate server '#{selflink2name(zone)}:#{instance_name}'.")
@@ -20,27 +20,27 @@ class Chef
20
20
 
21
21
  include Knife::GoogleBase
22
22
 
23
- banner "knife google server list --google-compute-zone ZONE (options)"
23
+ banner "knife google server list -Z ZONE (options)"
24
24
 
25
25
  option :zone,
26
26
  :short => "-Z ZONE",
27
- :long => "--google-compute-zone ZONE",
27
+ :long => "--gce-zone ZONE",
28
28
  :description => "The Zone for this server"
29
29
 
30
30
  def run
31
31
  $stdout.sync = true
32
32
 
33
33
  begin
34
- zone = client.zones.get(config[:zone] || Chef::Config[:knife][:google_compute_zone])
34
+ zone = client.zones.get(config[:zone] || Chef::Config[:knife][:gce_zone])
35
35
  rescue Google::Compute::ResourceNotFound
36
- ui.error("Zone '#{config[:zone] || Chef::Config[:knife][:google_compute_zone] }' not found.")
36
+ ui.error("Zone '#{config[:zone] || Chef::Config[:knife][:gce_zone] }' not found.")
37
37
  exit 1
38
38
  rescue Google::Compute::ParameterValidation
39
39
  ui.error("Must specify zone in knife config file or in command line as an option. Try --help.")
40
40
  exit 1
41
41
  end
42
42
 
43
- instance_label = ['Name', 'Type', 'Image', 'Public IP', 'Private IP', 'Disks', 'Zone', 'Status']
43
+ instance_label = ['name', 'type', 'public ip', 'private ip', 'disks', 'zone', 'status']
44
44
  instance_list = (instance_label.map {|label| ui.color(label, :bold)}).flatten.compact
45
45
 
46
46
  output_column_count = instance_list.length
@@ -48,7 +48,6 @@ class Chef
48
48
  client.instances.list(:zone=>zone.name).each do |instance|
49
49
  instance_list << instance.name
50
50
  instance_list << selflink2name(instance.machine_type.to_s)
51
- instance_list << selflink2name(instance.image.to_s)
52
51
  instance_list << public_ips(instance).join(',')
53
52
  instance_list << private_ips(instance).join(',')
54
53
  instance_list << disks(instance).join(',')
@@ -27,11 +27,10 @@ class Chef
27
27
  $stdout.sync = true
28
28
 
29
29
  zone_list = [
30
- ui.color("Name", :bold),
31
- ui.color('Status', :bold),
32
- ui.color('Servers', :bold),
33
- ui.color('Disks', :bold),
34
- ui.color('Maintainance Window',:bold)].flatten.compact
30
+ ui.color("name", :bold),
31
+ ui.color('status', :bold),
32
+ ui.color('deprecation', :bold),
33
+ ui.color('maintainance window', :bold)].flatten.compact
35
34
 
36
35
  output_column_count = zone_list.length
37
36
 
@@ -46,30 +45,25 @@ class Chef
46
45
  ui.color(status, :red)
47
46
  end
48
47
  end
49
- instance_quota = "0"
50
- zone.quotas.each do |quota|
51
- if quota["metric"] == "INSTANCES"
52
- instance_quota = "#{quota["usage"].to_i}"
53
- end
54
- end
55
- zone_list << instance_quota
56
- disk_quota = "0"
57
- zone.quotas.each do |quota|
58
- if quota["metric"] == "DISKS"
59
- disk_quota = "#{quota["usage"].to_i}"
60
- end
48
+ deprecation_state = "-"
49
+ if zone.deprecated.respond_to?('state')
50
+ deprecation_state = zone.deprecated.state
51
+ end
52
+ zone_list << deprecation_state
53
+ unless zone.maintenance_windows.nil?
54
+ maintenance_window = zone.maintenance_windows.map do |mw|
55
+ begin_time = Time.parse(mw["beginTime"])
56
+ end_time = Time.parse(mw["endTime"])
57
+ if (Time.now >= begin_time) and (Time.now <= end_time)
58
+ ui.color("#{begin_time} to #{end_time}",:red)
59
+ else
60
+ ui.color("#{begin_time} to #{end_time}",:green)
61
+ end
62
+ end.join(",")
63
+ zone_list << maintenance_window
64
+ else
65
+ zone_list << "-"
61
66
  end
62
- zone_list << disk_quota
63
- maintenance_window = zone.maintenance_windows.map do |mw|
64
- begin_time = Time.parse(mw["beginTime"])
65
- end_time = Time.parse(mw["endTime"])
66
- if (Time.now >= begin_time) and (Time.now <= end_time)
67
- ui.color("#{begin_time} to #{end_time}",:red)
68
- else
69
- ui.color("#{begin_time} to #{end_time}",:green)
70
- end
71
- end.join(",")
72
- zone_list << maintenance_window
73
67
  end
74
68
  ui.info(ui.list(zone_list, :uneven_columns_across, output_column_count))
75
69
  end
@@ -32,13 +32,14 @@ require 'google/compute/disk'
32
32
  require 'google/compute/firewall'
33
33
  require 'google/compute/image'
34
34
  require 'google/compute/server'
35
- require 'google/compute/kernel'
36
35
  require 'google/compute/machine_type'
37
36
  require 'google/compute/network'
38
37
  require 'google/compute/project'
39
38
  require 'google/compute/snapshot'
39
+ require 'google/compute/region'
40
40
  require 'google/compute/zone'
41
41
  require 'google/compute/global_operation'
42
+ require 'google/compute/region_operation'
42
43
  require 'google/compute/zone_operation'
43
44
  require 'google/compute/server/attached_disk'
44
45
  require 'google/compute/server/network_interface'
@@ -17,6 +17,7 @@
17
17
  require 'google/api_client'
18
18
  require 'multi_json'
19
19
  require 'google/compute/resource_collection'
20
+ require 'knife-google/version'
20
21
 
21
22
  module Google
22
23
  module Compute
@@ -27,7 +28,7 @@ module Google
27
28
  attr_reader :dispatcher
28
29
 
29
30
  def initialize(authorization, project, credential_file)
30
- api_client = Google::APIClient.new(:application_name=>'google-compute-ruby-client')
31
+ api_client = Google::APIClient.new(:application_name => 'knife-google', :application_version => Knife::Google::VERSION)
31
32
  api_client.authorization = authorization
32
33
  api_client.auto_refresh_token = true
33
34
  @project = project
@@ -65,7 +66,7 @@ module Google
65
66
  "https://www.googleapis.com/auth/userinfo.email"]
66
67
  redirect_uri = 'urn:ietf:wg:oauth:2.0:oob'
67
68
 
68
- api_client = Google::APIClient.new(:application_name=>'google-compute-ruby-client')
69
+ api_client = Google::APIClient.new(:application_name => 'knife-google', :application_version => Knife::Google::VERSION)
69
70
 
70
71
  api_client.authorization.scope = scope
71
72
  api_client.authorization.client_id = client_id
@@ -125,10 +126,6 @@ module Google
125
126
  CreatableResourceCollection.new(:resource_class => Google::Compute::Server, :dispatcher=>@dispatcher)
126
127
  end
127
128
 
128
- def kernels
129
- ListableResourceCollection.new(:resource_class => Google::Compute::Kernel,:dispatcher=>@dispatcher)
130
- end
131
-
132
129
  def machine_types
133
130
  ListableResourceCollection.new(:resource_class => Google::Compute::MachineType,:dispatcher=>@dispatcher)
134
131
  end
@@ -141,10 +138,18 @@ module Google
141
138
  DeletableResourceCollection.new(:resource_class => Google::Compute::GlobalOperation, :dispatcher=>@dispatcher)
142
139
  end
143
140
 
141
+ def regionOperations
142
+ DeletableResourceCollection.new(:resource_class => Google::Compute::RegionOperation, :dispatcher=>@dispatcher)
143
+ end
144
+
144
145
  def zoneOperations
145
146
  DeletableResourceCollection.new(:resource_class => Google::Compute::ZoneOperation, :dispatcher=>@dispatcher)
146
147
  end
147
148
 
149
+ def regions
150
+ ListableResourceCollection.new(:resource_class => Google::Compute::Region, :dispatcher=>@dispatcher)
151
+ end
152
+
148
153
  def zones
149
154
  ListableResourceCollection.new(:resource_class => Google::Compute::Zone, :dispatcher=>@dispatcher)
150
155
  end
@@ -162,7 +167,7 @@ module Google
162
167
  end
163
168
 
164
169
  def compute
165
- @compute ||= @api_client.discovered_api('compute','v1beta15')
170
+ @compute ||= @api_client.discovered_api('compute','v1')
166
171
  end
167
172
 
168
173
  def dispatch(opts)
@@ -17,11 +17,22 @@ module Google
17
17
  class CreatableResourceCollection < DeletableResourceCollection
18
18
 
19
19
  def create(options={})
20
- if ["Server", "Disk"].include? self.resource_class_name
20
+ if ["Server"].include? self.resource_class_name
21
21
  data = @dispatcher.dispatch(:api_method => api_resource.insert,
22
22
  :parameters=>{:project=>project, :zone=>options[:zone]},
23
23
  :body_object => options )
24
24
  ZoneOperation.new(data.merge!(:dispatcher=>@dispatcher))
25
+ elsif ["Disk"].include? self.resource_class_name
26
+ if options[:sourceImage].nil?
27
+ data = @dispatcher.dispatch(:api_method => api_resource.insert,
28
+ :parameters=>{:project=>project, :zone=>options[:zone]},
29
+ :body_object => options)
30
+ else
31
+ data = @dispatcher.dispatch(:api_method => api_resource.insert,
32
+ :parameters=>{:project=>project, :zone=>options[:zone], :sourceImage=>options[:sourceImage]},
33
+ :body_object => options)
34
+ end
35
+ ZoneOperation.new(data.merge!(:dispatcher=>@dispatcher))
25
36
  else
26
37
  data = @dispatcher.dispatch(:api_method => api_resource.insert,
27
38
  :parameters=>{:project=>project},
@@ -23,7 +23,6 @@ module Google
23
23
 
24
24
  attr_reader :zone, :size_gb, :status, :options
25
25
  attr_reader :source_snapshot, :source_snapshot_id
26
- attr_reader :source_image
27
26
 
28
27
  def from_hash(disk_data)
29
28
  super(disk_data)
@@ -33,7 +32,6 @@ module Google
33
32
  @options = disk_data["options"]
34
33
  @source_snapshot = disk_data["sourceSnapshot"]
35
34
  @source_snapshot_id = disk_data["sourceSnapshotId"]
36
- @source_image = disk_data["sourceImage"]
37
35
  end
38
36
  end
39
37
  end
@@ -16,12 +16,11 @@ module Google
16
16
  module Compute
17
17
  class Image < Resource
18
18
 
19
- attr_reader :source_type, :preferred_kernel, :raw_disk, :deprecated
19
+ attr_reader :source_type, :raw_disk, :deprecated
20
20
 
21
21
  def from_hash(data)
22
22
  super(data)
23
23
  @source_type = data["sourceType"]
24
- @preferred_kernel = data["preferredKernel"]
25
24
  @raw_disk = data["rawDisk"]
26
25
  @deprecated = data["deprecated"]
27
26
  end
@@ -16,13 +16,12 @@ module Google
16
16
  module Compute
17
17
  class Project < Resource
18
18
 
19
- attr_reader :common_instance_metadata, :quotas, :external_ip_addresses
19
+ attr_reader :common_instance_metadata, :quotas
20
20
 
21
21
  def from_hash(data)
22
22
  super(data)
23
23
  @common_instance_metadata = data["commonInstanceMetadata"]
24
24
  @quotas = data["quotas"]
25
- @external_ip_addresses = data["externalIpAddresses"]
26
25
  end
27
26
 
28
27
  def set_common_instance_metadata(metadata)
@@ -71,6 +70,7 @@ module Google
71
70
  end
72
71
  set_common_instance_metadata(temp_metadata)
73
72
  end
73
+
74
74
  end
75
75
  end
76
76
  end
@@ -14,7 +14,18 @@
14
14
 
15
15
  module Google
16
16
  module Compute
17
- class Kernel < Resource
17
+ class Region < Resource
18
+
19
+ attr_reader :status, :zones
20
+ attr_reader :quotas, :deprecated
21
+
22
+ def from_hash(region_data)
23
+ super(region_data)
24
+ @status = region_data["status"]
25
+ @zones = region_data["zones"]
26
+ @quotas = region_data["quotas"]
27
+ @deprecated = region_data["deprecated"]
28
+ end
18
29
  end
19
30
  end
20
31
  end
@@ -0,0 +1,62 @@
1
+ # Copyright 2013 Google Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ # Google compute engine, operation resource reference
16
+
17
+ require 'timeout'
18
+
19
+ module Google
20
+ module Compute
21
+ class RegionOperation < Resource
22
+
23
+ attr_reader :zone, :client_operation_id, :operation_type
24
+ attr_reader :target_link, :target_id, :status
25
+ attr_reader :status_message, :user, :progress
26
+ attr_reader :insert_time, :start_time, :end_time
27
+ attr_reader :error, :warnings, :http_error_status_code
28
+ attr_reader :http_error_message, :region
29
+
30
+ def from_hash(data)
31
+ super(data)
32
+ @zone = data["zone"]
33
+ @client_operation_id = data["clientOperationId"]
34
+ @operation_type = data["operationType"]
35
+ @target_link= data["targetLink"]
36
+ @target_id = data["targetId"]
37
+ @status = data["status"]
38
+ @status_message = data["statusMessage"]
39
+ @user = data["user"]
40
+ @progress = data["progress"]
41
+ @insert_time = Time.parse( data["insertTime"] )
42
+ @start_time = Time.parse( data["startTime"] )
43
+ @end_time = Time.parse( data["endTime"] ) if data.key?("endTime")
44
+ @error = data["error"]
45
+ @warnings = data["warnings"]
46
+ @http_error_status_code = data["httpErrorMessage"]
47
+ @http_error_message = data["httpErrorMessage"]
48
+ @region = data["region"]
49
+ end
50
+
51
+ def wait_for_completion!(options={})
52
+ timeout = options[:timeout] || 60
53
+ status = Timeout::timeout(timeout, OperationTimeout) do
54
+ until progress==100
55
+ sleep 2
56
+ progress= get_self.progress
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -20,13 +20,13 @@ module Google
20
20
  module Compute
21
21
  class Server < Resource
22
22
 
23
- attr_reader :tags, :image, :machine_type, :status, :status_message, :zone
23
+ attr_reader :tags, :machine_type, :status, :status_message, :zone
24
24
  attr_reader :network_interfaces, :disks, :metadata, :service_accounts
25
+ attr_reader :scheduling
25
26
 
26
27
  def from_hash(data)
27
28
  super(data)
28
29
  @tags = data["tags"]
29
- @image = data["image"]
30
30
  @machine_type = data["machineType"]
31
31
  @status = data["status"]
32
32
  @status_message = data["statusMessage"]
@@ -45,6 +45,7 @@ module Google
45
45
  end
46
46
  @metadata = data["metadata"]
47
47
  @service_accounts = data["service_accounts"]
48
+ @scheduling = data["scheduling"]
48
49
  end
49
50
 
50
51
  def serial_port_output
@@ -22,16 +22,16 @@ module Google
22
22
  class AttachedDisk
23
23
  include Utils
24
24
 
25
- attr_reader :kind, :type, :mode, :source
26
- attr_reader :device_name, :index, :boot
25
+ attr_reader :kind, :index, :type, :mode
26
+ attr_reader :source, :device_name, :boot
27
27
 
28
28
  def initialize(data)
29
29
  @kind = data["kind"]
30
+ @index = data["index"]
30
31
  @type = data["type"]
31
32
  @mode= data["mode"]
32
33
  @source = data["source"]
33
34
  @device_name = data["deviceName"]
34
- @index = data["index"]
35
35
  @boot = data["boot"]
36
36
  end
37
37
  end