knife-cloudstack-fog 0.3.4 → 0.4.0
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.
- data/README.rdoc +3 -0
- data/lib/chef/knife/cloudstack_server_create.rb +445 -293
- data/lib/knife-cloudstack-fog/version.rb +2 -2
- metadata +4 -3
    
        data/README.rdoc
    CHANGED
    
    | @@ -1,3 +1,6 @@ | |
| 1 | 
            +
            [](http://badge.fury.io/rb/knife-cloudstack-fog)
         | 
| 2 | 
            +
            [](https://www.travis-ci.org/fifthecho/knife-cloudstack-fog)
         | 
| 3 | 
            +
             | 
| 1 4 | 
             
            = Knife Cloudstack
         | 
| 2 5 |  | 
| 3 6 | 
             
            = DESCRIPTION:
         | 
| @@ -23,298 +23,450 @@ require 'chef/json_compat' | |
| 23 23 | 
             
            require 'chef/knife/cloudstack_base'
         | 
| 24 24 |  | 
| 25 25 | 
             
            class Chef
         | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 45 | 
            -
             | 
| 46 | 
            -
             | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 52 | 
            -
             | 
| 53 | 
            -
             | 
| 54 | 
            -
             | 
| 55 | 
            -
             | 
| 56 | 
            -
             | 
| 57 | 
            -
             | 
| 58 | 
            -
             | 
| 59 | 
            -
             | 
| 60 | 
            -
             | 
| 61 | 
            -
             | 
| 62 | 
            -
             | 
| 63 | 
            -
             | 
| 64 | 
            -
             | 
| 65 | 
            -
             | 
| 66 | 
            -
             | 
| 67 | 
            -
             | 
| 68 | 
            -
             | 
| 69 | 
            -
             | 
| 70 | 
            -
             | 
| 71 | 
            -
             | 
| 72 | 
            -
             | 
| 73 | 
            -
             | 
| 74 | 
            -
             | 
| 75 | 
            -
             | 
| 76 | 
            -
             | 
| 77 | 
            -
             | 
| 78 | 
            -
             | 
| 79 | 
            -
             | 
| 80 | 
            -
             | 
| 81 | 
            -
             | 
| 82 | 
            -
             | 
| 83 | 
            -
             | 
| 84 | 
            -
             | 
| 85 | 
            -
             | 
| 86 | 
            -
             | 
| 87 | 
            -
             | 
| 88 | 
            -
             | 
| 89 | 
            -
             | 
| 90 | 
            -
             | 
| 91 | 
            -
             | 
| 92 | 
            -
             | 
| 93 | 
            -
             | 
| 94 | 
            -
             | 
| 95 | 
            -
             | 
| 96 | 
            -
             | 
| 97 | 
            -
             | 
| 98 | 
            -
             | 
| 99 | 
            -
             | 
| 100 | 
            -
             | 
| 101 | 
            -
             | 
| 102 | 
            -
             | 
| 103 | 
            -
             | 
| 104 | 
            -
             | 
| 105 | 
            -
             | 
| 106 | 
            -
             | 
| 107 | 
            -
             | 
| 108 | 
            -
             | 
| 109 | 
            -
             | 
| 110 | 
            -
             | 
| 111 | 
            -
             | 
| 112 | 
            -
             | 
| 113 | 
            -
             | 
| 114 | 
            -
             | 
| 115 | 
            -
             | 
| 116 | 
            -
             | 
| 117 | 
            -
             | 
| 118 | 
            -
             | 
| 119 | 
            -
             | 
| 120 | 
            -
             | 
| 121 | 
            -
             | 
| 122 | 
            -
             | 
| 123 | 
            -
             | 
| 124 | 
            -
             | 
| 125 | 
            -
             | 
| 126 | 
            -
             | 
| 127 | 
            -
             | 
| 128 | 
            -
             | 
| 129 | 
            -
             | 
| 130 | 
            -
             | 
| 131 | 
            -
             | 
| 132 | 
            -
             | 
| 133 | 
            -
             | 
| 134 | 
            -
             | 
| 135 | 
            -
             | 
| 136 | 
            -
             | 
| 137 | 
            -
             | 
| 138 | 
            -
             | 
| 139 | 
            -
             | 
| 140 | 
            -
             | 
| 141 | 
            -
             | 
| 142 | 
            -
             | 
| 143 | 
            -
             | 
| 144 | 
            -
             | 
| 145 | 
            -
             | 
| 146 | 
            -
             | 
| 147 | 
            -
             | 
| 148 | 
            -
             | 
| 149 | 
            -
             | 
| 150 | 
            -
             | 
| 151 | 
            -
             | 
| 152 | 
            -
             | 
| 153 | 
            -
             | 
| 154 | 
            -
             | 
| 155 | 
            -
             | 
| 156 | 
            -
             | 
| 157 | 
            -
             | 
| 158 | 
            -
             | 
| 159 | 
            -
             | 
| 160 | 
            -
             | 
| 161 | 
            -
             | 
| 162 | 
            -
             | 
| 163 | 
            -
             | 
| 164 | 
            -
             | 
| 165 | 
            -
             | 
| 166 | 
            -
             | 
| 167 | 
            -
             | 
| 168 | 
            -
             | 
| 169 | 
            -
             | 
| 170 | 
            -
             | 
| 171 | 
            -
             | 
| 172 | 
            -
             | 
| 173 | 
            -
             | 
| 174 | 
            -
             | 
| 175 | 
            -
             | 
| 176 | 
            -
             | 
| 177 | 
            -
             | 
| 178 | 
            -
             | 
| 179 | 
            -
             | 
| 180 | 
            -
             | 
| 181 | 
            -
             | 
| 182 | 
            -
             | 
| 183 | 
            -
             | 
| 184 | 
            -
             | 
| 185 | 
            -
             | 
| 186 | 
            -
             | 
| 187 | 
            -
             | 
| 188 | 
            -
             | 
| 189 | 
            -
             | 
| 190 | 
            -
             | 
| 191 | 
            -
             | 
| 192 | 
            -
             | 
| 193 | 
            -
             | 
| 194 | 
            -
             | 
| 195 | 
            -
             | 
| 196 | 
            -
             | 
| 197 | 
            -
             | 
| 198 | 
            -
             | 
| 199 | 
            -
             | 
| 200 | 
            -
             | 
| 201 | 
            -
             | 
| 202 | 
            -
             | 
| 203 | 
            -
             | 
| 204 | 
            -
             | 
| 205 | 
            -
             | 
| 206 | 
            -
             | 
| 207 | 
            -
             | 
| 208 | 
            -
             | 
| 209 | 
            -
             | 
| 210 | 
            -
             | 
| 211 | 
            -
             | 
| 212 | 
            -
             | 
| 213 | 
            -
             | 
| 214 | 
            -
             | 
| 215 | 
            -
             | 
| 216 | 
            -
             | 
| 217 | 
            -
             | 
| 218 | 
            -
             | 
| 219 | 
            -
             | 
| 220 | 
            -
             | 
| 221 | 
            -
             | 
| 222 | 
            -
             | 
| 223 | 
            -
             | 
| 224 | 
            -
             | 
| 225 | 
            -
             | 
| 226 | 
            -
             | 
| 227 | 
            -
             | 
| 228 | 
            -
             | 
| 229 | 
            -
             | 
| 230 | 
            -
             | 
| 231 | 
            -
             | 
| 232 | 
            -
             | 
| 233 | 
            -
             | 
| 234 | 
            -
             | 
| 235 | 
            -
             | 
| 236 | 
            -
             | 
| 237 | 
            -
             | 
| 238 | 
            -
             | 
| 239 | 
            -
             | 
| 240 | 
            -
             | 
| 241 | 
            -
             | 
| 242 | 
            -
             | 
| 243 | 
            -
             | 
| 244 | 
            -
             | 
| 245 | 
            -
             | 
| 246 | 
            -
             | 
| 247 | 
            -
             | 
| 248 | 
            -
             | 
| 249 | 
            -
             | 
| 250 | 
            -
             | 
| 251 | 
            -
             | 
| 252 | 
            -
             | 
| 253 | 
            -
             | 
| 254 | 
            -
             | 
| 255 | 
            -
             | 
| 256 | 
            -
             | 
| 257 | 
            -
             | 
| 258 | 
            -
             | 
| 259 | 
            -
             | 
| 260 | 
            -
             | 
| 261 | 
            -
             | 
| 262 | 
            -
             | 
| 263 | 
            -
             | 
| 264 | 
            -
             | 
| 265 | 
            -
             | 
| 266 | 
            -
             | 
| 267 | 
            -
             | 
| 268 | 
            -
             | 
| 269 | 
            -
             | 
| 270 | 
            -
             | 
| 271 | 
            -
             | 
| 272 | 
            -
             | 
| 273 | 
            -
             | 
| 274 | 
            -
             | 
| 275 | 
            -
             | 
| 276 | 
            -
             | 
| 277 | 
            -
             | 
| 278 | 
            -
             | 
| 279 | 
            -
             | 
| 280 | 
            -
             | 
| 281 | 
            -
             | 
| 282 | 
            -
             | 
| 283 | 
            -
             | 
| 284 | 
            -
             | 
| 285 | 
            -
             | 
| 286 | 
            -
             | 
| 287 | 
            -
             | 
| 288 | 
            -
             | 
| 289 | 
            -
             | 
| 290 | 
            -
             | 
| 291 | 
            -
             | 
| 292 | 
            -
             | 
| 293 | 
            -
             | 
| 294 | 
            -
             | 
| 295 | 
            -
             | 
| 296 | 
            -
             | 
| 297 | 
            -
             | 
| 298 | 
            -
             | 
| 299 | 
            -
             | 
| 300 | 
            -
             | 
| 301 | 
            -
             | 
| 302 | 
            -
             | 
| 303 | 
            -
             | 
| 304 | 
            -
             | 
| 305 | 
            -
             | 
| 306 | 
            -
             | 
| 307 | 
            -
             | 
| 308 | 
            -
             | 
| 309 | 
            -
             | 
| 310 | 
            -
             | 
| 311 | 
            -
             | 
| 312 | 
            -
             | 
| 313 | 
            -
             | 
| 314 | 
            -
             | 
| 315 | 
            -
             | 
| 316 | 
            -
             | 
| 26 | 
            +
            	class Knife
         | 
| 27 | 
            +
            		class CloudstackServerCreate < Knife
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            			include Knife::CloudstackBase
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            			banner "knife cloudstack server create -s SERVICEID -t TEMPLATEID -z ZONEID (options)"
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            			option  :cloudstack_serviceid,
         | 
| 34 | 
            +
            						:short => "-s SERVICEID",
         | 
| 35 | 
            +
            						:long => "--serviceid SERVICEID",
         | 
| 36 | 
            +
            						:description => "The CloudStack service offering ID."
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            			option  :cloudstack_templateid,
         | 
| 39 | 
            +
            						:short => "-t TEMPLATEID",
         | 
| 40 | 
            +
            						:long => "--templateid TEMPLATEID",
         | 
| 41 | 
            +
            						:description => "The CloudStack template ID for the server."
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            			option  :cloudstack_zoneid,
         | 
| 44 | 
            +
            						:short => "-z ZONEID",
         | 
| 45 | 
            +
            						:long => "--zoneid ZONE",
         | 
| 46 | 
            +
            						:description => "The CloudStack zone ID for the server."
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            			option  :cloudstack_networkids,
         | 
| 49 | 
            +
            						:short => "-w NETWORKIDS",
         | 
| 50 | 
            +
            						:long => "--networkids NETWORKIDS",
         | 
| 51 | 
            +
            						:description => "Comma separated list of CloudStack network IDs.",
         | 
| 52 | 
            +
            						:proc => lambda { |n| n.split(/[\s,]+/) },
         | 
| 53 | 
            +
            						:default => []
         | 
| 54 | 
            +
             | 
| 55 | 
            +
            			option  :cloudstack_groupids,
         | 
| 56 | 
            +
            						:short => "-g SECURITYGROUPIDS",
         | 
| 57 | 
            +
            						:long => "--groupids SECURITYGROUPIDS",
         | 
| 58 | 
            +
            						:description => "Comma separated list of CloudStack Security Group IDs.",
         | 
| 59 | 
            +
            						:proc => lambda { |n| n.split(/[\s,]+/) },
         | 
| 60 | 
            +
            						:default => []
         | 
| 61 | 
            +
             | 
| 62 | 
            +
            			option  :cloudstack_groupnames,
         | 
| 63 | 
            +
            						:short => "-G SECURITYGROUPNAMES",
         | 
| 64 | 
            +
            						:long => "--groupnames SECURITYGROUPNAMES",
         | 
| 65 | 
            +
            						:description => "Comma separated list of CloudStack Security Group names. Each group name must be encapuslated in quotes if it contains whitespace.",
         | 
| 66 | 
            +
            						:proc => lambda { |n| n.split(/[\s,]+/) },
         | 
| 67 | 
            +
            						:default => []
         | 
| 68 | 
            +
             | 
| 69 | 
            +
            			option  :distro,
         | 
| 70 | 
            +
            						:short => "-d DISTRO",
         | 
| 71 | 
            +
            						:long => "--distro DISTRO",
         | 
| 72 | 
            +
            						:description => "Bootstrap a distro using a template; default is 'chef-full'",
         | 
| 73 | 
            +
            						:proc => Proc.new { |d| Chef::Config[:knife][:distro] = d },
         | 
| 74 | 
            +
            						:default => "chef-full"
         | 
| 75 | 
            +
             | 
| 76 | 
            +
            			option  :template_file,
         | 
| 77 | 
            +
            						:long => "--template-file TEMPLATE",
         | 
| 78 | 
            +
            						:description => "Full path to location of template to use",
         | 
| 79 | 
            +
            						:proc => Proc.new { |t| Chef::Config[:knife][:template_file] = t },
         | 
| 80 | 
            +
            						:default => false
         | 
| 81 | 
            +
             | 
| 82 | 
            +
            			option  :run_list,
         | 
| 83 | 
            +
            						:short => "-r RUN_LIST",
         | 
| 84 | 
            +
            						:long => "--run-list RUN_LIST",
         | 
| 85 | 
            +
            						:description => "Comma separated list of roles/recipes to apply",
         | 
| 86 | 
            +
            						:proc => lambda { |o| o.split(/[\s,]+/) },
         | 
| 87 | 
            +
            						:default => []
         | 
| 88 | 
            +
             | 
| 89 | 
            +
            			option  :ssh_user,
         | 
| 90 | 
            +
            						:short => "-x USERNAME",
         | 
| 91 | 
            +
            						:long => "--ssh-user USERNAME",
         | 
| 92 | 
            +
            						:description => "The ssh username",
         | 
| 93 | 
            +
            						:default => 'root'
         | 
| 94 | 
            +
             | 
| 95 | 
            +
            			option  :ssh_password,
         | 
| 96 | 
            +
            						:short => "-P PASSWORD",
         | 
| 97 | 
            +
            						:long => "--ssh-password PASSWORD",
         | 
| 98 | 
            +
            						:description => "The ssh password"
         | 
| 99 | 
            +
             | 
| 100 | 
            +
            			option  :identity_file,
         | 
| 101 | 
            +
            						:short => "-i PRIVATE_KEY_FILE",
         | 
| 102 | 
            +
            						:long => "--identity-file PRIVATE_KEY_FILE",
         | 
| 103 | 
            +
            						:description => "The Private key file for authenticating SSH session. --keypair option is also needed."
         | 
| 104 | 
            +
             | 
| 105 | 
            +
            			option 	:ssh_port,
         | 
| 106 | 
            +
            						:short => "-p PORT",
         | 
| 107 | 
            +
            						:long => "--ssh-port PORT",
         | 
| 108 | 
            +
            						:description => "The port which SSH should be listening on. If unspecified, will default to 22."
         | 
| 109 | 
            +
             | 
| 110 | 
            +
            			option  :server_name,
         | 
| 111 | 
            +
            						:short => "-N NAME",
         | 
| 112 | 
            +
            						:long => "--display-name NAME",
         | 
| 113 | 
            +
            						:description => "The instance display name"
         | 
| 114 | 
            +
             | 
| 115 | 
            +
            			option  :host_name,
         | 
| 116 | 
            +
            						:short => "-H NAME",
         | 
| 117 | 
            +
            						:long => "--hostname NAME",
         | 
| 118 | 
            +
            						:description => "The instance host name"
         | 
| 119 | 
            +
             | 
| 120 | 
            +
            			option  :keypair,
         | 
| 121 | 
            +
            						:short => "-k KEYPAIR",
         | 
| 122 | 
            +
            						:long => "--keypair KEYPAIR",
         | 
| 123 | 
            +
            						:description => "The CloudStack Key Pair to use for SSH key authentication."
         | 
| 124 | 
            +
             | 
| 125 | 
            +
            			option  :diskoffering,
         | 
| 126 | 
            +
            						:short => "-D DISKOFFERINGID",
         | 
| 127 | 
            +
            						:long => "--diskoffering DISKOFFERINGID",
         | 
| 128 | 
            +
            						:description => "Specifies either the Disk Offering ID for the ROOT disk for an ISO template, or a DATA disk."
         | 
| 129 | 
            +
             | 
| 130 | 
            +
            			option  :size,
         | 
| 131 | 
            +
            						:short => "-Z SIZE",
         | 
| 132 | 
            +
            						:long => "--size SIZE",
         | 
| 133 | 
            +
            						:description => "Specifies the arbitrary Disk Size for DATADISK volume in GB. Must be passed with custom size Disk Offering ID."
         | 
| 134 | 
            +
             | 
| 135 | 
            +
            			option 	:random_ssh_port,
         | 
| 136 | 
            +
            						:long => "--random-ssh-port",
         | 
| 137 | 
            +
            						:description => "Map a random, unused high-level port to 22 for SSH and creates a port forward for this mapping. For Isolated Networking and VPC only."
         | 
| 138 | 
            +
             | 
| 139 | 
            +
            			option 	:ssh_gateway,
         | 
| 140 | 
            +
            						:short => "-W GATEWAY",
         | 
| 141 | 
            +
            						:long => "--ssh-gateway GATEWAY",
         | 
| 142 | 
            +
            						:description => "The ssh gateway server. Connection is defined as USERNAME@HOST:PORT",
         | 
| 143 | 
            +
            						:proc => Proc.new { |key| Chef::Config[:knife][:ssh_gateway] = key }
         | 
| 144 | 
            +
             | 
| 145 | 
            +
            			# def bootstrap_for_node(host, user, password)
         | 
| 146 | 
            +
            			def bootstrap_for_node(server, ssh_host)
         | 
| 147 | 
            +
            				host = server["name"]
         | 
| 148 | 
            +
            				user = config[:ssh_user]
         | 
| 149 | 
            +
            				password = server["password"]
         | 
| 150 | 
            +
            				Chef::Log.debug("Bootstrap host: #{host}")
         | 
| 151 | 
            +
            				Chef::Log.debug("Bootstrap user: #{user}")
         | 
| 152 | 
            +
            				Chef::Log.debug("Bootstrap pass: #{password}")
         | 
| 153 | 
            +
            				bootstrap = Chef::Knife::Bootstrap.new
         | 
| 154 | 
            +
            				bootstrap.name_args = [ssh_host]
         | 
| 155 | 
            +
            				bootstrap.config[:run_list] = config[:run_list]
         | 
| 156 | 
            +
            				bootstrap.config[:ssh_user] = user
         | 
| 157 | 
            +
            				bootstrap.config[:ssh_password] = password
         | 
| 158 | 
            +
            				bootstrap.config[:ssh_gateway] = config[:ssh_gateway]
         | 
| 159 | 
            +
            				bootstrap.config[:identity_file] = locate_config_value(:identity_file)
         | 
| 160 | 
            +
            				bootstrap.config[:chef_node_name] = config[:server_name] if config[:server_name]
         | 
| 161 | 
            +
            				bootstrap.config[:prerelease] = config[:prerelease]
         | 
| 162 | 
            +
            				bootstrap.config[:bootstrap_version] = locate_config_value(:bootstrap_version)
         | 
| 163 | 
            +
            				bootstrap.config[:distro] = locate_config_value(:distro)
         | 
| 164 | 
            +
            				bootstrap.config[:use_sudo] = true
         | 
| 165 | 
            +
            				bootstrap.config[:template_file] = locate_config_value(:template_file)
         | 
| 166 | 
            +
            				bootstrap.config[:environment] = config[:environment]
         | 
| 167 | 
            +
            				# may be needed for vpc_mode
         | 
| 168 | 
            +
            				bootstrap.config[:no_host_key_verify] = config[:no_host_key_verify]
         | 
| 169 | 
            +
            				begin
         | 
| 170 | 
            +
            					bootstrap
         | 
| 171 | 
            +
            				rescue
         | 
| 172 | 
            +
            					sleep @initial_sleep_delay
         | 
| 173 | 
            +
            					retry
         | 
| 174 | 
            +
            				end
         | 
| 175 | 
            +
            			end
         | 
| 176 | 
            +
             | 
| 177 | 
            +
            			def vpc_mode?
         | 
| 178 | 
            +
            				# Virtual Private Cloud / Isolated Networking requires a network id. If
         | 
| 179 | 
            +
            				# present, do a few things differently
         | 
| 180 | 
            +
            				!!locate_config_value(:cloudstack_networkids)
         | 
| 181 | 
            +
            			end
         | 
| 182 | 
            +
             | 
| 183 | 
            +
            			def wait_for_sshd(hostname)
         | 
| 184 | 
            +
            				config[:ssh_gateway] ? wait_for_tunnelled_sshd(hostname) : wait_for_direct_sshd(hostname, @sshport)
         | 
| 185 | 
            +
            			end
         | 
| 186 | 
            +
             | 
| 187 | 
            +
            			def wait_for_tunnelled_sshd(hostname)
         | 
| 188 | 
            +
            				Chef::Log.debug("Connecting to #{hostname} via wait_for_tunnelled_sshd")
         | 
| 189 | 
            +
            				print("#{ui.color(".", :magenta)}")
         | 
| 190 | 
            +
            				print("#{ui.color(".", :magenta)}") until tunnel_test_ssh(ssh_connect_host) {
         | 
| 191 | 
            +
            					sleep @initial_sleep_delay ||= (vpc_mode? ? 40 : 10)
         | 
| 192 | 
            +
            					puts("#{ui.color(". Done.", :magenta)}")
         | 
| 193 | 
            +
            				}
         | 
| 194 | 
            +
            			end
         | 
| 195 | 
            +
             | 
| 196 | 
            +
            			def tunnel_test_ssh(hostname, &block)
         | 
| 197 | 
            +
            				gw_host, gw_user = config[:ssh_gateway].split('@').reverse
         | 
| 198 | 
            +
            				gw_host, gw_port = gw_host.split(':')
         | 
| 199 | 
            +
            				Chef::Log.debug("Connecting to #{hostname} via #{gw_host} over port #{gw_port}.")
         | 
| 200 | 
            +
            				gateway = Net::SSH::Gateway.new(gw_host, gw_user, :port => gw_port || 22)
         | 
| 201 | 
            +
            				status = false
         | 
| 202 | 
            +
            				gateway.open(hostname, config[:ssh_port]) do |local_tunnel_port|
         | 
| 203 | 
            +
            					status = tcp_test_ssh('localhost', local_tunnel_port, &block)
         | 
| 204 | 
            +
            					Chef::Log.debug "Opened local port #{local_tunnel_port} to tunnel the connection."
         | 
| 205 | 
            +
            				end
         | 
| 206 | 
            +
            				status
         | 
| 207 | 
            +
            				rescue SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ENETUNREACH, IOError
         | 
| 208 | 
            +
            					sleep 2
         | 
| 209 | 
            +
            					false
         | 
| 210 | 
            +
            				rescue Errno::EPERM, Errno::ETIMEDOUT
         | 
| 211 | 
            +
            					false
         | 
| 212 | 
            +
            				rescue Errno::Disconnect
         | 
| 213 | 
            +
            					sleep @initial_sleep_delay
         | 
| 214 | 
            +
            					retry
         | 
| 215 | 
            +
            			end
         | 
| 216 | 
            +
             | 
| 217 | 
            +
            			def wait_for_direct_sshd(hostname, ssh_port)
         | 
| 218 | 
            +
            				Chef::Log.debug("Connecting directly to #{hostname} over port #{ssh_port}")
         | 
| 219 | 
            +
            				print("#{ui.color(".", :magenta)}") until tcp_test_ssh(ssh_connect_host, ssh_port) {
         | 
| 220 | 
            +
            					sleep @initial_sleep_delay ||= (vpc_mode? ? 40 : 10)
         | 
| 221 | 
            +
            					puts("#{ui.color(". Done.", :magenta)}")
         | 
| 222 | 
            +
            				}
         | 
| 223 | 
            +
            			end
         | 
| 224 | 
            +
             | 
| 225 | 
            +
            			def ssh_connect_host
         | 
| 226 | 
            +
            				@ssh_connect_host ||= if config[:server_connect_attribute]
         | 
| 227 | 
            +
            					server.send(config[:server_connect_attribute])
         | 
| 228 | 
            +
            				else
         | 
| 229 | 
            +
            					Chef::Log.debug("Connecting to #{@primary_ip}")
         | 
| 230 | 
            +
            					@primary_ip
         | 
| 231 | 
            +
            					# vpc_mode? ? server.private_ip_address : server.dns_name
         | 
| 232 | 
            +
            				end
         | 
| 233 | 
            +
            			end
         | 
| 234 | 
            +
             | 
| 235 | 
            +
            			def tcp_test_ssh(hostname, ssh_port)
         | 
| 236 | 
            +
            				Chef::Log.debug("Conecting to #{hostname} on #{ssh_port}.")
         | 
| 237 | 
            +
            				print("#{ui.color(".", :magenta)}")
         | 
| 238 | 
            +
            				tcp_socket = TCPSocket.new(hostname, ssh_port)
         | 
| 239 | 
            +
            				readable = IO.select([tcp_socket], nil, nil, 5)
         | 
| 240 | 
            +
            				if readable
         | 
| 241 | 
            +
            					Chef::Log.debug("sshd accepting connections on #{hostname}, banner is #{tcp_socket.gets}")
         | 
| 242 | 
            +
            				yield
         | 
| 243 | 
            +
            					true
         | 
| 244 | 
            +
            				else
         | 
| 245 | 
            +
            					false
         | 
| 246 | 
            +
            				end
         | 
| 247 | 
            +
            				rescue SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ENETUNREACH, IOError
         | 
| 248 | 
            +
            					sleep 2
         | 
| 249 | 
            +
            					false
         | 
| 250 | 
            +
            				rescue Errno::EPERM, Errno::ETIMEDOUT
         | 
| 251 | 
            +
            					false
         | 
| 252 | 
            +
            				rescue Errno::Disconnect
         | 
| 253 | 
            +
            					sleep @initial_sleep_delay
         | 
| 254 | 
            +
            					retry
         | 
| 255 | 
            +
            				ensure
         | 
| 256 | 
            +
            				tcp_socket && tcp_socket.close
         | 
| 257 | 
            +
            			end
         | 
| 258 | 
            +
             | 
| 259 | 
            +
            			def check_port_available(public_port, ipaddressid)
         | 
| 260 | 
            +
            				Chef::Log.debug("Checking if port #{public_port} is available.")
         | 
| 261 | 
            +
            				pubport = public_port.to_i
         | 
| 262 | 
            +
            				port_forward_rules_query = connection.list_port_forwarding_rules({'ipaddressid' => ipaddressid })
         | 
| 263 | 
            +
            				port_rules = port_forward_rules_query['listportforwardingrulesresponse']['portforwardingrule']
         | 
| 264 | 
            +
            				is_available = true
         | 
| 265 | 
            +
            				some_possible_rules = port_rules.select { |rule| rule['publicport'].to_i <= pubport }
         | 
| 266 | 
            +
            				possible_rules = some_possible_rules.select { |rule| rule['publicendport'].to_i >= pubport }
         | 
| 267 | 
            +
            				possible_rules.each do |rule|
         | 
| 268 | 
            +
            					startport = rule['publicport'].to_i
         | 
| 269 | 
            +
            					endport = rule['publicendport'].to_i
         | 
| 270 | 
            +
            					Chef::Log.debug("Determining if #{pubport} is between #{startport} and #{endport}.")
         | 
| 271 | 
            +
            					if (endport != startport)
         | 
| 272 | 
            +
            						if pubport.between?(startport, endport)
         | 
| 273 | 
            +
            							is_available = false
         | 
| 274 | 
            +
            						else
         | 
| 275 | 
            +
            							is_available = true
         | 
| 276 | 
            +
            						end
         | 
| 277 | 
            +
            					else
         | 
| 278 | 
            +
            						if (pubport == startport)
         | 
| 279 | 
            +
            							is_available = false
         | 
| 280 | 
            +
            						else
         | 
| 281 | 
            +
            							is_available = true
         | 
| 282 | 
            +
            						end
         | 
| 283 | 
            +
            					end
         | 
| 284 | 
            +
            				end
         | 
| 285 | 
            +
            				return is_available
         | 
| 286 | 
            +
            			end
         | 
| 287 | 
            +
             | 
| 288 | 
            +
            			def add_port_forward(public_start_port, public_end_port, server_id, ipaddressid, privateport)
         | 
| 289 | 
            +
            				pfwdops = {}
         | 
| 290 | 
            +
            				pfwdops['ipaddressid'] = ipaddressid
         | 
| 291 | 
            +
            				pfwdops['privateport'] = privateport
         | 
| 292 | 
            +
            				pfwdops['protocol'] = "TCP"
         | 
| 293 | 
            +
            				pfwdops['virtualmachineid'] = server_id
         | 
| 294 | 
            +
            				pfwdops['openfirewall'] = "true"
         | 
| 295 | 
            +
            				pfwdops['publicport'] = public_start_port
         | 
| 296 | 
            +
            				pfwdops['publicendport'] = public_end_port
         | 
| 297 | 
            +
            				rule_create_job = connection.create_port_forwarding_rule(pfwdops)
         | 
| 298 | 
            +
            				print "#{ui.color("Creating port forwarding rule.", :cyan)}"
         | 
| 299 | 
            +
            				while (@connection.query_async_job_result({'jobid' => rule_create_job['createportforwardingruleresponse']['jobid']})['queryasyncjobresultresponse'].fetch('jobstatus') == 0)
         | 
| 300 | 
            +
            					print("#{ui.color(".", :cyan)}")
         | 
| 301 | 
            +
            					sleep 2
         | 
| 302 | 
            +
            				end
         | 
| 303 | 
            +
            				print("\n")
         | 
| 304 | 
            +
            			end
         | 
| 305 | 
            +
             | 
| 306 | 
            +
            			def create_server_def
         | 
| 307 | 
            +
            				server_def = {
         | 
| 308 | 
            +
            					"templateid" => locate_config_value(:cloudstack_templateid),
         | 
| 309 | 
            +
            					"serviceofferingid" => locate_config_value(:cloudstack_serviceid),
         | 
| 310 | 
            +
            					"zoneid" => locate_config_value(:cloudstack_zoneid)
         | 
| 311 | 
            +
            				}
         | 
| 312 | 
            +
             | 
| 313 | 
            +
            				if locate_config_value(:server_name) != nil
         | 
| 314 | 
            +
            					server_def["displayname"] = locate_config_value(:server_name)
         | 
| 315 | 
            +
            				end
         | 
| 316 | 
            +
             | 
| 317 | 
            +
            				if locate_config_value(:host_name) != nil
         | 
| 318 | 
            +
            					server_def["name"] = locate_config_value(:host_name)
         | 
| 319 | 
            +
            				end
         | 
| 320 | 
            +
             | 
| 321 | 
            +
            				network_ids = []
         | 
| 322 | 
            +
            				if locate_config_value(:cloudstack_networkids) != []
         | 
| 323 | 
            +
            					cs_networkids = locate_config_value(:cloudstack_networkids)
         | 
| 324 | 
            +
            					cs_networkids.each do |id|
         | 
| 325 | 
            +
            						network_ids.push(id)
         | 
| 326 | 
            +
            					end
         | 
| 327 | 
            +
            					server_def["networkids"] = network_ids
         | 
| 328 | 
            +
            				end
         | 
| 329 | 
            +
             | 
| 330 | 
            +
            				security_groups = []
         | 
| 331 | 
            +
            				if locate_config_value(:cloudstack_groupids) != []
         | 
| 332 | 
            +
            					cs_groupids = locate_config_value(:cloudstack_groupids)
         | 
| 333 | 
            +
            					cs_groupids.each do |id|
         | 
| 334 | 
            +
            						security_groups.push(id)
         | 
| 335 | 
            +
            					end
         | 
| 336 | 
            +
            					server_def["securitygroupids"] = security_groups
         | 
| 337 | 
            +
            				elsif locate_config_value(:cloudstack_groupnames) != []
         | 
| 338 | 
            +
            					cs_groupnames = locate_config_value(:cloudstack_groupnames)
         | 
| 339 | 
            +
            					cs_groupnames.each do |name|
         | 
| 340 | 
            +
            						security_groups.push(name)
         | 
| 341 | 
            +
            					end
         | 
| 342 | 
            +
            					server_def["securitygroupnames"] = security_groups
         | 
| 343 | 
            +
            				end
         | 
| 344 | 
            +
             | 
| 345 | 
            +
            				if locate_config_value(:keypair) != nil
         | 
| 346 | 
            +
            					server_def["keypair"] = locate_config_value(:keypair)
         | 
| 347 | 
            +
            				end
         | 
| 348 | 
            +
             | 
| 349 | 
            +
            				if locate_config_value(:diskoffering) != nil
         | 
| 350 | 
            +
            					server_def["diskofferingid"] = locate_config_value(:diskoffering)
         | 
| 351 | 
            +
            				end
         | 
| 352 | 
            +
             | 
| 353 | 
            +
            				if locate_config_value(:size) != nil
         | 
| 354 | 
            +
            					server_def["size"] = locate_config_value(:size)
         | 
| 355 | 
            +
            				end
         | 
| 356 | 
            +
             | 
| 357 | 
            +
            				server_def
         | 
| 358 | 
            +
            			end
         | 
| 359 | 
            +
             | 
| 360 | 
            +
            			def run
         | 
| 361 | 
            +
            				$stdout.sync = true
         | 
| 362 | 
            +
            				options = create_server_def
         | 
| 363 | 
            +
            				Chef::Log.debug("Options: #{options} \n")
         | 
| 364 | 
            +
             | 
| 365 | 
            +
            				@initial_sleep_delay = 10				
         | 
| 366 | 
            +
            				@sshport = 22
         | 
| 367 | 
            +
            				if locate_config_value(:ssh_port) != nil
         | 
| 368 | 
            +
            					@sshport = locate_config_value(:ssh_port).to_i
         | 
| 369 | 
            +
            				end
         | 
| 370 | 
            +
             | 
| 371 | 
            +
            				serverdeploy = connection.deploy_virtual_machine(options)
         | 
| 372 | 
            +
            				jobid = serverdeploy['deployvirtualmachineresponse'].fetch('jobid')
         | 
| 373 | 
            +
             | 
| 374 | 
            +
            				server_start = connection.query_async_job_result('jobid'=>jobid)
         | 
| 375 | 
            +
             | 
| 376 | 
            +
            				Chef::Log.debug("Job ID: #{jobid} \n")
         | 
| 377 | 
            +
             | 
| 378 | 
            +
            				print "#{ui.color("Waiting for server", :magenta)}"
         | 
| 379 | 
            +
            				while server_start['queryasyncjobresultresponse'].fetch('jobstatus') == 0
         | 
| 380 | 
            +
            					print "#{ui.color(".", :magenta)}"
         | 
| 381 | 
            +
            					sleep @initial_sleep_delay
         | 
| 382 | 
            +
            					server_start = connection.query_async_job_result('jobid'=>jobid)
         | 
| 383 | 
            +
            					Chef::Log.debug("Server_Start: #{server_start} \n")
         | 
| 384 | 
            +
            				end
         | 
| 385 | 
            +
            				puts "\n\n"
         | 
| 386 | 
            +
             | 
| 387 | 
            +
            				if server_start['queryasyncjobresultresponse'].fetch('jobstatus') == 2
         | 
| 388 | 
            +
            					errortext = server_start['queryasyncjobresultresponse'].fetch('jobresult').fetch('errortext')
         | 
| 389 | 
            +
            					puts "#{ui.color("ERROR! Job failed with #{errortext}", :red)}"
         | 
| 390 | 
            +
            				end
         | 
| 391 | 
            +
             | 
| 392 | 
            +
            				if server_start['queryasyncjobresultresponse'].fetch('jobstatus') == 1
         | 
| 393 | 
            +
             | 
| 394 | 
            +
            					Chef::Log.debug("Job ID: #{jobid} \n")
         | 
| 395 | 
            +
            					Chef::Log.debug("Options: #{options} \n")
         | 
| 396 | 
            +
            					server_start = connection.query_async_job_result('jobid'=>jobid)
         | 
| 397 | 
            +
            					Chef::Log.debug("Server_Start: #{server_start} \n")
         | 
| 398 | 
            +
             | 
| 399 | 
            +
            					@server = server_start['queryasyncjobresultresponse']['jobresult']['virtualmachine']
         | 
| 400 | 
            +
             | 
| 401 | 
            +
            					server_name = @server['displayname']
         | 
| 402 | 
            +
            					server_id = @server['name']
         | 
| 403 | 
            +
            					server_serviceoffering = @server['serviceofferingname']
         | 
| 404 | 
            +
            					server_template = @server['templatename']
         | 
| 405 | 
            +
            					if @server['password'] != nil
         | 
| 406 | 
            +
            						ssh_password = @server['password']
         | 
| 407 | 
            +
            					else
         | 
| 408 | 
            +
            						ssh_password = locate_config_value(:ssh_password)
         | 
| 409 | 
            +
            					end
         | 
| 410 | 
            +
             | 
| 411 | 
            +
            					ssh_user = locate_config_value(:ssh_user)
         | 
| 412 | 
            +
             | 
| 413 | 
            +
            					@primary_ip = nil
         | 
| 414 | 
            +
             | 
| 415 | 
            +
            					if @server['nic'].size > 0
         | 
| 416 | 
            +
            						@primary_ip = @server['nic'].first['ipaddress']
         | 
| 417 | 
            +
            					end
         | 
| 418 | 
            +
             | 
| 419 | 
            +
            					if locate_config_value(:random_ssh_port) != nil
         | 
| 420 | 
            +
            						public_ips = connection.list_public_ip_addresses("associatednetworkid" => @server['nic'][0]['networkid'])
         | 
| 421 | 
            +
            						primary_public_ip_id = public_ips['listpublicipaddressesresponse']['publicipaddress'][0]['id']
         | 
| 422 | 
            +
            						@primary_ip = public_ips['listpublicipaddressesresponse']['publicipaddress'][0]['ipaddress']
         | 
| 423 | 
            +
            						pubport = rand(49152..65535)
         | 
| 424 | 
            +
            						while (check_port_available(pubport, primary_public_ip_id) == false)
         | 
| 425 | 
            +
            							pubport = rand(49152..65535)
         | 
| 426 | 
            +
            						end
         | 
| 427 | 
            +
            						add_port_forward(pubport, pubport, server_id, primary_public_ip_id, @sshport)
         | 
| 428 | 
            +
            						@sshport = pubport
         | 
| 429 | 
            +
            					end
         | 
| 430 | 
            +
             | 
| 431 | 
            +
             | 
| 432 | 
            +
             | 
| 433 | 
            +
            					Chef::Log.debug("Connecting over port #{@sshport}")
         | 
| 434 | 
            +
             | 
| 435 | 
            +
            					puts "\n\n"
         | 
| 436 | 
            +
            					puts "#{ui.color("Name", :cyan)}: #{server_name}"
         | 
| 437 | 
            +
            					puts "#{ui.color("Primary IP", :cyan)}: #{@primary_ip}"
         | 
| 438 | 
            +
            					puts "#{ui.color("Username", :cyan)}: #{ssh_user}"
         | 
| 439 | 
            +
            					puts "#{ui.color("Password", :cyan)}: #{ssh_password}"
         | 
| 440 | 
            +
             | 
| 441 | 
            +
            					print "\n#{ui.color("Waiting for sshd", :magenta)}"
         | 
| 442 | 
            +
            					wait_for_sshd(ssh_connect_host)
         | 
| 443 | 
            +
             | 
| 444 | 
            +
            					puts("#{ui.color("Waiting for password/keys to sync.", :magenta)}")
         | 
| 445 | 
            +
            					sleep @initial_sleep_delay
         | 
| 446 | 
            +
            					sleep @initial_sleep_delay
         | 
| 447 | 
            +
            					sleep @initial_sleep_delay
         | 
| 448 | 
            +
             | 
| 449 | 
            +
            					Chef::Log.debug("Connnecting to #{@server} via #{ssh_connect_host} and bootstrapping Chef.")
         | 
| 450 | 
            +
             | 
| 451 | 
            +
            					bootstrap_for_node(@server,ssh_connect_host).run
         | 
| 452 | 
            +
             | 
| 453 | 
            +
            					Chef::Log.debug("#{@server}")
         | 
| 454 | 
            +
             | 
| 455 | 
            +
            					puts "\n"
         | 
| 456 | 
            +
            					puts "#{ui.color("Instance Name", :green)}: #{server_name}"
         | 
| 457 | 
            +
            					puts "#{ui.color("Instance ID", :green)}: #{server_id}"
         | 
| 458 | 
            +
            					puts "#{ui.color("Service Offering", :green)}: #{server_serviceoffering}"
         | 
| 459 | 
            +
            					puts "#{ui.color("Template", :green)}: #{server_template}"
         | 
| 460 | 
            +
            					puts "#{ui.color("Public IP Address", :green)}: #{@primary_ip}"
         | 
| 461 | 
            +
            					puts "#{ui.color("Port", :green)}: #{@sshport}"
         | 
| 462 | 
            +
            					puts "#{ui.color("User", :green)}: #{ssh_user}"
         | 
| 463 | 
            +
            					puts "#{ui.color("Password", :green)}: #{ssh_password}"
         | 
| 464 | 
            +
            					puts "#{ui.color("Environment", :green)}: #{config[:environment] || '_default'}"
         | 
| 465 | 
            +
            					puts "#{ui.color("Run List", :green)}: #{config[:run_list].join(', ')}"
         | 
| 466 | 
            +
            				end
         | 
| 467 | 
            +
             | 
| 468 | 
            +
            			end
         | 
| 317 469 |  | 
| 318 | 
            -
             | 
| 319 | 
            -
             | 
| 470 | 
            +
            		end
         | 
| 471 | 
            +
            	end
         | 
| 320 472 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: knife-cloudstack-fog
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.4.0
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| @@ -13,7 +13,7 @@ authors: | |
| 13 13 | 
             
            autorequire: 
         | 
| 14 14 | 
             
            bindir: bin
         | 
| 15 15 | 
             
            cert_chain: []
         | 
| 16 | 
            -
            date: 2013- | 
| 16 | 
            +
            date: 2013-10-14 00:00:00.000000000 Z
         | 
| 17 17 | 
             
            dependencies:
         | 
| 18 18 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 19 19 | 
             
              name: fog
         | 
| @@ -104,7 +104,8 @@ files: | |
| 104 104 | 
             
            - README.rdoc
         | 
| 105 105 | 
             
            - LICENSE
         | 
| 106 106 | 
             
            homepage: https://github.com/fifthecho/knife-cloudstack-fog
         | 
| 107 | 
            -
            licenses: | 
| 107 | 
            +
            licenses:
         | 
| 108 | 
            +
            - Apache 2.0
         | 
| 108 109 | 
             
            post_install_message: 
         | 
| 109 110 | 
             
            rdoc_options: []
         | 
| 110 111 | 
             
            require_paths:
         |