)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"baa27ec6e31a93d3f8fac2dc2a710285973e72f4","unresolved":false,"context_lines":[{"line_number":11,"context_line":"Modified sample_config to include amphorae on load balancer"},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"Change-Id: I3fc2423a480ecc4b1b732a83fa1d4981c213da47"},{"line_number":14,"context_line":"Implements: bp/haproxy-amphora-driver"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":15,"id":"9aa53dc9_5e9f6d03","line":14,"updated":"2015-04-07 07:15:08.000000000","message":"should be Implements: blueprint bp/haproxy-amphora-driver","commit_id":"bca9322a174f853f4f365fc6830f079790b99ab3"}],"etc/octavia.conf":[{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"6263886a7fce109b84de571cea1d484701f78524","unresolved":false,"context_lines":[{"line_number":41,"context_line":"# Network to communicate with amphora"},{"line_number":42,"context_line":"# lb_network_name \u003d"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"[amphora]"},{"line_number":45,"context_line":"# Key used to access amphora"},{"line_number":46,"context_line":"# key_name \u003d custom_key"},{"line_number":47,"context_line":"# base_path \u003d /var/lib/octavia"}],"source_content_type":"text/plain","patch_set":11,"id":"1a6ced46_e7d683f0","line":44,"updated":"2015-03-25 21:21:47.000000000","message":"let\u0027s make sure we share that with the config for https://review.openstack.org/#/c/160034/ -- so I will change mine to amphora from agent?","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"5bdbd93f853772dda9f232c13ef7dcbc2b47575a","unresolved":false,"context_lines":[{"line_number":41,"context_line":"# Network to communicate with amphora"},{"line_number":42,"context_line":"# lb_network_name \u003d"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"[amphora]"},{"line_number":45,"context_line":"# Key used to access amphora"},{"line_number":46,"context_line":"# key_name \u003d custom_key"},{"line_number":47,"context_line":"# base_path \u003d /var/lib/octavia"}],"source_content_type":"text/plain","patch_set":11,"id":"da9b358b_faf52483","line":44,"in_reply_to":"1a6ced46_e7d683f0","updated":"2015-03-30 19:42:49.000000000","message":"Maybe a distinction is necessary between client/server configuration options?  Meaning, your config pertaining to server side, mine being client side?","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"f4eac09eb44f834134206c4e7348aa2d810875c1","unresolved":false,"context_lines":[{"line_number":41,"context_line":"# Network to communicate with amphora"},{"line_number":42,"context_line":"# lb_network_name \u003d"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"[amphora]"},{"line_number":45,"context_line":"# Key used to access amphora"},{"line_number":46,"context_line":"# key_name \u003d custom_key"},{"line_number":47,"context_line":"# base_path \u003d /var/lib/octavia"}],"source_content_type":"text/plain","patch_set":11,"id":"baa041b7_75102a4f","line":44,"in_reply_to":"baa041b7_2ff9354e","updated":"2015-04-01 15:52:42.000000000","message":"Brandon and I talked a bit, and as far as I recall, he suggested we use a separate config section for any given driver.","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"a758285d40b573f0b67496edb0961b5735f9b19c","unresolved":false,"context_lines":[{"line_number":41,"context_line":"# Network to communicate with amphora"},{"line_number":42,"context_line":"# lb_network_name \u003d"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"[amphora]"},{"line_number":45,"context_line":"# Key used to access amphora"},{"line_number":46,"context_line":"# key_name \u003d custom_key"},{"line_number":47,"context_line":"# base_path \u003d /var/lib/octavia"}],"source_content_type":"text/plain","patch_set":11,"id":"baa041b7_2ff9354e","line":44,"in_reply_to":"da9b358b_554150a8","updated":"2015-04-01 15:28:16.000000000","message":"In principal I agree but both drivers are for haproxy and we share some things like the jinja template engine and I like to keep the file layout on the amphora the same -- so in this case I think we should share config. On that note we probably should name it haproxy-amphora-driver or something similar since amphora is really too broad a name.","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"a0d102b80b762bf844d3f1f40dc3bbbc30a87197","unresolved":false,"context_lines":[{"line_number":41,"context_line":"# Network to communicate with amphora"},{"line_number":42,"context_line":"# lb_network_name \u003d"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"[amphora]"},{"line_number":45,"context_line":"# Key used to access amphora"},{"line_number":46,"context_line":"# key_name \u003d custom_key"},{"line_number":47,"context_line":"# base_path \u003d /var/lib/octavia"}],"source_content_type":"text/plain","patch_set":11,"id":"da9b358b_554150a8","line":44,"in_reply_to":"da9b358b_faf52483","updated":"2015-04-01 04:29:24.000000000","message":"since these are two different drivers I\u0027d say that they should each have their own section, unless you know for a fact there will be overlap for all possible implementations.  This is similar to neutron-lbaas where radware, netscaler, have their own section defined in the services.conf.","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"6263886a7fce109b84de571cea1d484701f78524","unresolved":false,"context_lines":[{"line_number":43,"context_line":""},{"line_number":44,"context_line":"[amphora]"},{"line_number":45,"context_line":"# Key used to access amphora"},{"line_number":46,"context_line":"# key_name \u003d custom_key"},{"line_number":47,"context_line":"# base_path \u003d /var/lib/octavia"},{"line_number":48,"context_line":"# base_cert_dir \u003d /certs"},{"line_number":49,"context_line":"# haproxy_template \u003d /var/lib/octavia/custom_template"}],"source_content_type":"text/plain","patch_set":11,"id":"1a6ced46_c7f0a793","line":46,"updated":"2015-03-25 21:21:47.000000000","message":"I think we will need a multi key system to make sure things are secure and not have one key to rule them all... or so","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"5bdbd93f853772dda9f232c13ef7dcbc2b47575a","unresolved":false,"context_lines":[{"line_number":43,"context_line":""},{"line_number":44,"context_line":"[amphora]"},{"line_number":45,"context_line":"# Key used to access amphora"},{"line_number":46,"context_line":"# key_name \u003d custom_key"},{"line_number":47,"context_line":"# base_path \u003d /var/lib/octavia"},{"line_number":48,"context_line":"# base_cert_dir \u003d /certs"},{"line_number":49,"context_line":"# haproxy_template \u003d /var/lib/octavia/custom_template"}],"source_content_type":"text/plain","patch_set":11,"id":"da9b358b_dae5c0a8","line":46,"in_reply_to":"1a6ced46_c7f0a793","updated":"2015-03-30 19:42:49.000000000","message":"I agree, but I believe that would require more changes on a few other fronts than just here in the SSH driver :)","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"6263886a7fce109b84de571cea1d484701f78524","unresolved":false,"context_lines":[{"line_number":46,"context_line":"# key_name \u003d custom_key"},{"line_number":47,"context_line":"# base_path \u003d /var/lib/octavia"},{"line_number":48,"context_line":"# base_cert_dir \u003d /certs"},{"line_number":49,"context_line":"# haproxy_template \u003d /var/lib/octavia/custom_template"}],"source_content_type":"text/plain","patch_set":11,"id":"1a6ced46_a73e4b26","line":49,"updated":"2015-03-25 21:21:47.000000000","message":"we should have a way to control where haproxy logs land","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"5bdbd93f853772dda9f232c13ef7dcbc2b47575a","unresolved":false,"context_lines":[{"line_number":46,"context_line":"# key_name \u003d custom_key"},{"line_number":47,"context_line":"# base_path \u003d /var/lib/octavia"},{"line_number":48,"context_line":"# base_cert_dir \u003d /certs"},{"line_number":49,"context_line":"# haproxy_template \u003d /var/lib/octavia/custom_template"}],"source_content_type":"text/plain","patch_set":11,"id":"da9b358b_daaa6019","line":49,"in_reply_to":"1a6ced46_a73e4b26","updated":"2015-03-30 19:42:49.000000000","message":"I agree.  So should that be included in the interface as a parameter to the update/start methods or should it just be pulled and utilized in the drivers automagically without some kind of documentation distinction?","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"48f94ad0580fab32b250235071d349800d9862e3","unresolved":false,"context_lines":[{"line_number":46,"context_line":"# key_name \u003d custom_key"},{"line_number":47,"context_line":"# base_path \u003d /var/lib/octavia"},{"line_number":48,"context_line":"# base_cert_dir \u003d /certs"},{"line_number":49,"context_line":"# haproxy_template \u003d /var/lib/octavia/custom_template"}],"source_content_type":"text/plain","patch_set":12,"id":"baa041b7_2820f69a","line":49,"updated":"2015-04-02 04:47:55.000000000","message":"I think the LOG directory should be configurable here in the config - if we need special log directories for listeners we can at least configure the base directory here. Haproxy is using syslog so it is conceivable that some operator likes to send logs over the wire... but won\u0027t be us so likely for a future version ;-)","commit_id":"dee820449a0eb39bebd33bf2379818d0e678a443"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"f2d9bc0426a180756d3bec7474f7ddd454d6bba4","unresolved":false,"context_lines":[{"line_number":48,"context_line":"# base_cert_dir \u003d /certs"},{"line_number":49,"context_line":"# haproxy_template \u003d /var/lib/octavia/custom_template"},{"line_number":50,"context_line":"# The following may need to be an absolute location:"},{"line_number":51,"context_line":"# base_log_dir \u003d /logs"}],"source_content_type":"text/plain","patch_set":13,"id":"baa041b7_9873ade7","line":51,"updated":"2015-04-02 21:22:55.000000000","message":"I have to talk to Phil about this option specifically.  I think there is something I\u0027ve missed in current Jinja config generation.","commit_id":"8fe74b0fc1638be09b557306ec4f46940999a8ef"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"76fcf3e100dfebbf358cc259a87367fc799ad627","unresolved":false,"context_lines":[{"line_number":41,"context_line":"# Network to communicate with amphora"},{"line_number":42,"context_line":"# lb_network_name \u003d"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"[amphora]"},{"line_number":45,"context_line":"# Key used to access amphora"},{"line_number":46,"context_line":"# key_name \u003d custom_key"},{"line_number":47,"context_line":"# base_path \u003d /var/lib/octavia"}],"source_content_type":"text/plain","patch_set":14,"id":"baa041b7_bbbbe4e4","line":44,"updated":"2015-04-04 01:44:00.000000000","message":"should we name that haproxy-amphora? Thoughts?","commit_id":"3d2a478cb16b2e3fb46bd52fda8be8d59b5d6eeb"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"6a05b2e4d398c1e56c5af187e7b875e707d9f3c6","unresolved":false,"context_lines":[{"line_number":41,"context_line":"# Network to communicate with amphora"},{"line_number":42,"context_line":"# lb_network_name \u003d"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"[amphora]"},{"line_number":45,"context_line":"# Key used to access amphora"},{"line_number":46,"context_line":"# key_name \u003d custom_key"},{"line_number":47,"context_line":"# base_path \u003d /var/lib/octavia"}],"source_content_type":"text/plain","patch_set":14,"id":"9aa53dc9_7a824654","line":44,"in_reply_to":"9aa53dc9_a8e1bf00","updated":"2015-04-06 23:41:27.000000000","message":"+1","commit_id":"3d2a478cb16b2e3fb46bd52fda8be8d59b5d6eeb"},{"author":{"_account_id":6437,"name":"Susanne Balle","email":"sleipnir012@gmail.com","username":"susanne-balle"},"change_message_id":"cd5d23034f19c267e4df9eb8e7bfe86c828bd1f5","unresolved":false,"context_lines":[{"line_number":41,"context_line":"# Network to communicate with amphora"},{"line_number":42,"context_line":"# lb_network_name \u003d"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"[amphora]"},{"line_number":45,"context_line":"# Key used to access amphora"},{"line_number":46,"context_line":"# key_name \u003d custom_key"},{"line_number":47,"context_line":"# base_path \u003d /var/lib/octavia"}],"source_content_type":"text/plain","patch_set":14,"id":"9aa53dc9_a8e1bf00","line":44,"in_reply_to":"baa041b7_bbbbe4e4","updated":"2015-04-06 13:35:30.000000000","message":"I agree. This need to be more specific since it is currently only for the ha-proxy amphora (driver).","commit_id":"3d2a478cb16b2e3fb46bd52fda8be8d59b5d6eeb"}],"octavia/amphorae/drivers/haproxy/jinja/jinja_cfg.py":[{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"aa8bce80c09ceb01281a7d5d5d59ae71e37e6bba","unresolved":false,"context_lines":[{"line_number":130,"context_line":"            \u0027protocol\u0027: listener.protocol"},{"line_number":131,"context_line":"        }"},{"line_number":132,"context_line":"        if listener.connection_limit and listener.connection_limit \u003e -1:"},{"line_number":133,"context_line":"            ret_value[\u0027connection_limit\u0027] \u003d listener.connection_limit"},{"line_number":134,"context_line":"        if listener.tls_container_id:"},{"line_number":135,"context_line":"            ret_value[\u0027default_tls_path\u0027] \u003d \u0027%s/%s/%s.pem\u0027 % ("},{"line_number":136,"context_line":"                self.cert_store_path, listener.id, tls_cert.primary_cn)"}],"source_content_type":"text/x-python","patch_set":15,"id":"9aa53dc9_3eedc98b","line":133,"updated":"2015-04-07 07:14:29.000000000","message":"can you change this to tls_certificate_id in this review too?","commit_id":"bca9322a174f853f4f365fc6830f079790b99ab3"}],"octavia/amphorae/drivers/haproxy/ssh_driver.py":[{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"a0d102b80b762bf844d3f1f40dc3bbbc30a87197","unresolved":false,"context_lines":[{"line_number":19,"context_line":"from octavia.common.config import cfg"},{"line_number":20,"context_line":"from octavia.common import data_models as data_models"},{"line_number":21,"context_line":"from octavia.common.tls_utils import cert_parser"},{"line_number":22,"context_line":"from octavia.openstack.common import log as logging"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"import tempfile"},{"line_number":25,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"da9b358b_15786829","line":22,"updated":"2015-04-01 04:29:24.000000000","message":"need to change this to from oslo_log import log as logging after rebasing off master","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"6263886a7fce109b84de571cea1d484701f78524","unresolved":false,"context_lines":[{"line_number":26,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"class LoggingMixIn(driver_base.HealthMixin, driver_base.StatsMixin):"},{"line_number":30,"context_line":"    def update_stats(self, stats):"},{"line_number":31,"context_line":"        LOG.debug(\"Amphora %s haproxy, update stats %s\","},{"line_number":32,"context_line":"                  self.__class__.__name__, stats)"}],"source_content_type":"text/x-python","patch_set":11,"id":"1a6ced46_8756af5a","line":29,"updated":"2015-03-25 21:21:47.000000000","message":"This can be removed. Will come in through the health manager - aka the halth manager will have an implementation which actually uses the HealthMixin to monitor amphora health.","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"5bdbd93f853772dda9f232c13ef7dcbc2b47575a","unresolved":false,"context_lines":[{"line_number":26,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"class LoggingMixIn(driver_base.HealthMixin, driver_base.StatsMixin):"},{"line_number":30,"context_line":"    def update_stats(self, stats):"},{"line_number":31,"context_line":"        LOG.debug(\"Amphora %s haproxy, update stats %s\","},{"line_number":32,"context_line":"                  self.__class__.__name__, stats)"}],"source_content_type":"text/x-python","patch_set":11,"id":"da9b358b_f4464fbe","line":29,"in_reply_to":"1a6ced46_8756af5a","updated":"2015-03-30 19:42:49.000000000","message":"Done.","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"6263886a7fce109b84de571cea1d484701f78524","unresolved":false,"context_lines":[{"line_number":78,"context_line":"            sftp \u003d self.client.open_sftp()"},{"line_number":79,"context_line":"            sftp.put(temp.name, \u0027{0}/{1}/haproxy.cfg\u0027.format("},{"line_number":80,"context_line":"                self.amp_config.base_path, listener.id))"},{"line_number":81,"context_line":"            self.client.exec_command("},{"line_number":82,"context_line":"                \u0027haproxy -f {0} -p {1}/{2}.pid -sf {1}/{2}.pid\u0027.format("},{"line_number":83,"context_line":"                    config, self.amp_config.base_path, listener.id))"},{"line_number":84,"context_line":"            self.client.close()"}],"source_content_type":"text/x-python","patch_set":11,"id":"1a6ced46_c72d07aa","line":81,"updated":"2015-03-25 21:21:47.000000000","message":"why are we not reusing the start method for this?","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"5bdbd93f853772dda9f232c13ef7dcbc2b47575a","unresolved":false,"context_lines":[{"line_number":78,"context_line":"            sftp \u003d self.client.open_sftp()"},{"line_number":79,"context_line":"            sftp.put(temp.name, \u0027{0}/{1}/haproxy.cfg\u0027.format("},{"line_number":80,"context_line":"                self.amp_config.base_path, listener.id))"},{"line_number":81,"context_line":"            self.client.exec_command("},{"line_number":82,"context_line":"                \u0027haproxy -f {0} -p {1}/{2}.pid -sf {1}/{2}.pid\u0027.format("},{"line_number":83,"context_line":"                    config, self.amp_config.base_path, listener.id))"},{"line_number":84,"context_line":"            self.client.close()"}],"source_content_type":"text/x-python","patch_set":11,"id":"da9b358b_0b4cf840","line":81,"in_reply_to":"1a6ced46_c72d07aa","updated":"2015-03-30 19:42:49.000000000","message":"I don\u0027t want to establish the SSH connection multiple times for uploading a file, and then again for starting HAProxy.","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"6263886a7fce109b84de571cea1d484701f78524","unresolved":false,"context_lines":[{"line_number":90,"context_line":"                  listener.protocol_port, vip.ip_address)"},{"line_number":91,"context_line":"        process \u003d \u0027`cat {0}/{1}/{1}.pid`\u0027.format(self.amp_config.base_path,"},{"line_number":92,"context_line":"                                                 listener.id)"},{"line_number":93,"context_line":"        for amp in listener.load_balancer.amphorae:"},{"line_number":94,"context_line":"            self.client.connect(hostname\u003damp.lb_network_ip,"},{"line_number":95,"context_line":"                                key_filename\u003dcfg.CONF.amphora.key_name)"},{"line_number":96,"context_line":"            self.client.exec_command(\u0027kill -9 {0}\u0027.format(process))"}],"source_content_type":"text/x-python","patch_set":11,"id":"1a6ced46_a2dc7974","line":93,"updated":"2015-03-25 21:21:47.000000000","message":"I see that pattern a lot so I would do something like :\n\ndef execute(amp, cmd):\n  self.client.connect(hostname\u003damp.lb_network_ip,\t75\n\t\t\tkey_filename\u003dcfg.CONF.amphora.key_name)\n   self.client.exec_command(cmd)\n   self.client.close()\n\nand then just\n[execute(amp, cmd) for amp in listener.load_balancer.amphorae] or just keep the for loop","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"6c51a05998e89e717ed5c0ce094a4e48ffd451f6","unresolved":false,"context_lines":[{"line_number":90,"context_line":"                  listener.protocol_port, vip.ip_address)"},{"line_number":91,"context_line":"        process \u003d \u0027`cat {0}/{1}/{1}.pid`\u0027.format(self.amp_config.base_path,"},{"line_number":92,"context_line":"                                                 listener.id)"},{"line_number":93,"context_line":"        for amp in listener.load_balancer.amphorae:"},{"line_number":94,"context_line":"            self.client.connect(hostname\u003damp.lb_network_ip,"},{"line_number":95,"context_line":"                                key_filename\u003dcfg.CONF.amphora.key_name)"},{"line_number":96,"context_line":"            self.client.exec_command(\u0027kill -9 {0}\u0027.format(process))"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa963961_d7349e4b","line":93,"in_reply_to":"1a6ced46_a2dc7974","updated":"2015-03-26 15:46:37.000000000","message":"maybe you can also use some syntactic sugar and lambda the whole thing then you can also cover the sftp case, e.g.\ndef for_all_hosts(func):\n[func(amp) for amp in listener.load_balancer.amphorae] \n\nfor_all_hosts(lambda amp: execute(amp, \u003ccommand\u003e)\n\nand then for sftp you can just write another method ;-)","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"5bdbd93f853772dda9f232c13ef7dcbc2b47575a","unresolved":false,"context_lines":[{"line_number":90,"context_line":"                  listener.protocol_port, vip.ip_address)"},{"line_number":91,"context_line":"        process \u003d \u0027`cat {0}/{1}/{1}.pid`\u0027.format(self.amp_config.base_path,"},{"line_number":92,"context_line":"                                                 listener.id)"},{"line_number":93,"context_line":"        for amp in listener.load_balancer.amphorae:"},{"line_number":94,"context_line":"            self.client.connect(hostname\u003damp.lb_network_ip,"},{"line_number":95,"context_line":"                                key_filename\u003dcfg.CONF.amphora.key_name)"},{"line_number":96,"context_line":"            self.client.exec_command(\u0027kill -9 {0}\u0027.format(process))"}],"source_content_type":"text/x-python","patch_set":11,"id":"da9b358b_cb03b0b7","line":93,"in_reply_to":"fa963961_d7349e4b","updated":"2015-03-30 19:42:49.000000000","message":"I WILL look at abstracting it as a method, but I think I\u0027ll try to make it look a little more clean than that :)","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"6263886a7fce109b84de571cea1d484701f78524","unresolved":false,"context_lines":[{"line_number":109,"context_line":"                                key_filename\u003dcfg.CONF.amphora.key_name)"},{"line_number":110,"context_line":"            self.client.exec_command(\u0027rm -rf {0}\u0027.format(directory))"},{"line_number":111,"context_line":"            self.client.close()"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    def start(self, listener, vip):"},{"line_number":114,"context_line":"        LOG.debug(\"Amphora %s haproxy, enabling listener %s, vip %s\","},{"line_number":115,"context_line":"                  self.__class__.__name__,"}],"source_content_type":"text/x-python","patch_set":11,"id":"1a6ced46_023aad98","line":112,"updated":"2015-03-25 21:21:47.000000000","message":"Logs? Stats socket?","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"5bdbd93f853772dda9f232c13ef7dcbc2b47575a","unresolved":false,"context_lines":[{"line_number":109,"context_line":"                                key_filename\u003dcfg.CONF.amphora.key_name)"},{"line_number":110,"context_line":"            self.client.exec_command(\u0027rm -rf {0}\u0027.format(directory))"},{"line_number":111,"context_line":"            self.client.close()"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    def start(self, listener, vip):"},{"line_number":114,"context_line":"        LOG.debug(\"Amphora %s haproxy, enabling listener %s, vip %s\","},{"line_number":115,"context_line":"                  self.__class__.__name__,"}],"source_content_type":"text/x-python","patch_set":11,"id":"da9b358b_95e94b1d","line":112,"in_reply_to":"1a6ced46_023aad98","updated":"2015-03-30 19:42:49.000000000","message":"I don\u0027t understand the question.","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"f4eac09eb44f834134206c4e7348aa2d810875c1","unresolved":false,"context_lines":[{"line_number":109,"context_line":"                                key_filename\u003dcfg.CONF.amphora.key_name)"},{"line_number":110,"context_line":"            self.client.exec_command(\u0027rm -rf {0}\u0027.format(directory))"},{"line_number":111,"context_line":"            self.client.close()"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    def start(self, listener, vip):"},{"line_number":114,"context_line":"        LOG.debug(\"Amphora %s haproxy, enabling listener %s, vip %s\","},{"line_number":115,"context_line":"                  self.__class__.__name__,"}],"source_content_type":"text/x-python","patch_set":11,"id":"da9b358b_e60c4196","line":112,"in_reply_to":"da9b358b_68ec9cc7","updated":"2015-04-01 15:52:42.000000000","message":"Logs directory I follow... stats socket?  Does HAProxy do something that isn\u0027t \"un-done\" when you kill its process?","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"5c98c7a978ea7d63319e03cfa582385c948db215","unresolved":false,"context_lines":[{"line_number":109,"context_line":"                                key_filename\u003dcfg.CONF.amphora.key_name)"},{"line_number":110,"context_line":"            self.client.exec_command(\u0027rm -rf {0}\u0027.format(directory))"},{"line_number":111,"context_line":"            self.client.close()"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    def start(self, listener, vip):"},{"line_number":114,"context_line":"        LOG.debug(\"Amphora %s haproxy, enabling listener %s, vip %s\","},{"line_number":115,"context_line":"                  self.__class__.__name__,"}],"source_content_type":"text/x-python","patch_set":11,"id":"da9b358b_68ec9cc7","line":112,"in_reply_to":"da9b358b_95e94b1d","updated":"2015-03-30 21:46:23.000000000","message":"I was wondering if we want to delete the stats socket along with the logs when deleting an lb","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"6263886a7fce109b84de571cea1d484701f78524","unresolved":false,"context_lines":[{"line_number":121,"context_line":"        for amp in listener.load_balancer.amphorae:"},{"line_number":122,"context_line":"            self.client.connect(hostname\u003damp.lb_network_ip,"},{"line_number":123,"context_line":"                                key_filename\u003dcfg.CONF.amphora.key_name)"},{"line_number":124,"context_line":"            self.client.exec_command(\u0027haproxy -f {0} -p {1}/{2}.pid\u0027.format("},{"line_number":125,"context_line":"                config, self.amp_config.base_path, listener.id))"},{"line_number":126,"context_line":"            self.client.close()"},{"line_number":127,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"1a6ced46_0250ed09","line":124,"updated":"2015-03-25 21:21:47.000000000","message":"That\u0027s ok for a demo but we found that haproxy crashes under DOS attacks and it is nice if some upstart will restart... and during the DOS it\u0027s hard to reach the machine to do something from the outside...","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"5bdbd93f853772dda9f232c13ef7dcbc2b47575a","unresolved":false,"context_lines":[{"line_number":121,"context_line":"        for amp in listener.load_balancer.amphorae:"},{"line_number":122,"context_line":"            self.client.connect(hostname\u003damp.lb_network_ip,"},{"line_number":123,"context_line":"                                key_filename\u003dcfg.CONF.amphora.key_name)"},{"line_number":124,"context_line":"            self.client.exec_command(\u0027haproxy -f {0} -p {1}/{2}.pid\u0027.format("},{"line_number":125,"context_line":"                config, self.amp_config.base_path, listener.id))"},{"line_number":126,"context_line":"            self.client.close()"},{"line_number":127,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"da9b358b_b5b68f3b","line":124,"in_reply_to":"1a6ced46_0250ed09","updated":"2015-03-30 19:42:49.000000000","message":"Any suggestions for that?  Like, a cron job or something?","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"f4eac09eb44f834134206c4e7348aa2d810875c1","unresolved":false,"context_lines":[{"line_number":121,"context_line":"        for amp in listener.load_balancer.amphorae:"},{"line_number":122,"context_line":"            self.client.connect(hostname\u003damp.lb_network_ip,"},{"line_number":123,"context_line":"                                key_filename\u003dcfg.CONF.amphora.key_name)"},{"line_number":124,"context_line":"            self.client.exec_command(\u0027haproxy -f {0} -p {1}/{2}.pid\u0027.format("},{"line_number":125,"context_line":"                config, self.amp_config.base_path, listener.id))"},{"line_number":126,"context_line":"            self.client.close()"},{"line_number":127,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"da9b358b_d8891528","line":124,"in_reply_to":"da9b358b_28f6948f","updated":"2015-04-01 15:52:42.000000000","message":"Personally I think that\u0027s something that should be added a bit later, so I can just use that utility file like you have.","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"5c98c7a978ea7d63319e03cfa582385c948db215","unresolved":false,"context_lines":[{"line_number":121,"context_line":"        for amp in listener.load_balancer.amphorae:"},{"line_number":122,"context_line":"            self.client.connect(hostname\u003damp.lb_network_ip,"},{"line_number":123,"context_line":"                                key_filename\u003dcfg.CONF.amphora.key_name)"},{"line_number":124,"context_line":"            self.client.exec_command(\u0027haproxy -f {0} -p {1}/{2}.pid\u0027.format("},{"line_number":125,"context_line":"                config, self.amp_config.base_path, listener.id))"},{"line_number":126,"context_line":"            self.client.close()"},{"line_number":127,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"da9b358b_28f6948f","line":124,"in_reply_to":"da9b358b_b5b68f3b","updated":"2015-03-30 21:46:23.000000000","message":"we are using an upstart script to facilitate automatic restarts. I added it to my agent api server review.","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"6263886a7fce109b84de571cea1d484701f78524","unresolved":false,"context_lines":[{"line_number":141,"context_line":"                  self.__class__.__name__, amphora.id)"},{"line_number":142,"context_line":"        self.amphoraconfig[amphora.id] \u003d (amphora.id, \u0027finalize amphora\u0027)"},{"line_number":143,"context_line":""},{"line_number":144,"context_line":"    def _process_tls_certificates(self, listener):"},{"line_number":145,"context_line":"        \"\"\"Processes TLS data from the listener."},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"        Converts and uploads PEM data to the Amphora API"}],"source_content_type":"text/x-python","patch_set":11,"id":"1a6ced46_e2ecb1f5","line":144,"updated":"2015-03-25 21:21:47.000000000","message":"Can we move the TLS stuff into it\u0027s own patch/file so we can reuse it for the Agent API Server approach like the templating?","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"5bdbd93f853772dda9f232c13ef7dcbc2b47575a","unresolved":false,"context_lines":[{"line_number":141,"context_line":"                  self.__class__.__name__, amphora.id)"},{"line_number":142,"context_line":"        self.amphoraconfig[amphora.id] \u003d (amphora.id, \u0027finalize amphora\u0027)"},{"line_number":143,"context_line":""},{"line_number":144,"context_line":"    def _process_tls_certificates(self, listener):"},{"line_number":145,"context_line":"        \"\"\"Processes TLS data from the listener."},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"        Converts and uploads PEM data to the Amphora API"}],"source_content_type":"text/x-python","patch_set":11,"id":"da9b358b_b5bb2f0e","line":144,"in_reply_to":"1a6ced46_e2ecb1f5","updated":"2015-03-30 19:42:49.000000000","message":"I want to say Phil Toohill or Adam Harwell was going to do that at some point, but I\u0027ll double check that.","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"6263886a7fce109b84de571cea1d484701f78524","unresolved":false,"context_lines":[{"line_number":158,"context_line":"            if listener.tls_container_id:"},{"line_number":159,"context_line":"                tls_cert \u003d self._map_cert_tls_container("},{"line_number":160,"context_line":"                    self.barbican_client.get_cert(listener.tls_container_id))"},{"line_number":161,"context_line":"                temp_default_pem \u003d tempfile.NamedTemporaryFile(delete\u003dTrue)"},{"line_number":162,"context_line":"                temp_default_pem.write(self._build_pem(tls_cert))"},{"line_number":163,"context_line":"                sftp.put(temp_default_pem.name,"},{"line_number":164,"context_line":"                         \u0027{0}/{1}/certificates/{2}.pem\u0027.format("}],"source_content_type":"text/x-python","patch_set":11,"id":"1a6ced46_0208edd8","line":161,"updated":"2015-03-25 21:21:47.000000000","message":"are you sure those tempfiles can\u0027t be read by other users on the system? Make sure to chmod them before writing to them","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"5bdbd93f853772dda9f232c13ef7dcbc2b47575a","unresolved":false,"context_lines":[{"line_number":158,"context_line":"            if listener.tls_container_id:"},{"line_number":159,"context_line":"                tls_cert \u003d self._map_cert_tls_container("},{"line_number":160,"context_line":"                    self.barbican_client.get_cert(listener.tls_container_id))"},{"line_number":161,"context_line":"                temp_default_pem \u003d tempfile.NamedTemporaryFile(delete\u003dTrue)"},{"line_number":162,"context_line":"                temp_default_pem.write(self._build_pem(tls_cert))"},{"line_number":163,"context_line":"                sftp.put(temp_default_pem.name,"},{"line_number":164,"context_line":"                         \u0027{0}/{1}/certificates/{2}.pem\u0027.format("}],"source_content_type":"text/x-python","patch_set":11,"id":"da9b358b_d55593c6","line":161,"in_reply_to":"1a6ced46_0208edd8","updated":"2015-03-30 19:42:49.000000000","message":"Do you mean chmod or chown?  Also, I\u0027m not sure, but the temp files are deleted after this method completes.","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":7398,"name":"Carlos Garza","email":"carlos.garza@rackspace.com","username":"crc32"},"change_message_id":"9d446deda8f351c7b74b47add5df74f36c971908","unresolved":false,"context_lines":[{"line_number":158,"context_line":"            if listener.tls_container_id:"},{"line_number":159,"context_line":"                tls_cert \u003d self._map_cert_tls_container("},{"line_number":160,"context_line":"                    self.barbican_client.get_cert(listener.tls_container_id))"},{"line_number":161,"context_line":"                temp_default_pem \u003d tempfile.NamedTemporaryFile(delete\u003dTrue)"},{"line_number":162,"context_line":"                temp_default_pem.write(self._build_pem(tls_cert))"},{"line_number":163,"context_line":"                sftp.put(temp_default_pem.name,"},{"line_number":164,"context_line":"                         \u0027{0}/{1}/certificates/{2}.pem\u0027.format("}],"source_content_type":"text/x-python","patch_set":11,"id":"da9b358b_9f915355","line":161,"in_reply_to":"1a6ced46_0208edd8","updated":"2015-03-31 01:54:35.000000000","message":"tempfiles use a mask of 0600.","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"5c98c7a978ea7d63319e03cfa582385c948db215","unresolved":false,"context_lines":[{"line_number":158,"context_line":"            if listener.tls_container_id:"},{"line_number":159,"context_line":"                tls_cert \u003d self._map_cert_tls_container("},{"line_number":160,"context_line":"                    self.barbican_client.get_cert(listener.tls_container_id))"},{"line_number":161,"context_line":"                temp_default_pem \u003d tempfile.NamedTemporaryFile(delete\u003dTrue)"},{"line_number":162,"context_line":"                temp_default_pem.write(self._build_pem(tls_cert))"},{"line_number":163,"context_line":"                sftp.put(temp_default_pem.name,"},{"line_number":164,"context_line":"                         \u0027{0}/{1}/certificates/{2}.pem\u0027.format("}],"source_content_type":"text/x-python","patch_set":11,"id":"da9b358b_8835a047","line":161,"in_reply_to":"da9b358b_d55593c6","updated":"2015-03-30 21:46:23.000000000","message":"Yep, chmod and chown... just making sure there is no attack vector...","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"6263886a7fce109b84de571cea1d484701f78524","unresolved":false,"context_lines":[{"line_number":163,"context_line":"                sftp.put(temp_default_pem.name,"},{"line_number":164,"context_line":"                         \u0027{0}/{1}/certificates/{2}.pem\u0027.format("},{"line_number":165,"context_line":"                             self.amp_config.base_path, listener.id,"},{"line_number":166,"context_line":"                             tls_cert.primary_cn))"},{"line_number":167,"context_line":"                temp_default_pem.close()"},{"line_number":168,"context_line":"            if listener.sni_containers:"},{"line_number":169,"context_line":"                # Retrieve, map and store SNI certificates"}],"source_content_type":"text/x-python","patch_set":11,"id":"1a6ced46_a2f8f9c3","line":166,"updated":"2015-03-25 21:21:47.000000000","message":"Same here... you likely need to chmod on the amphora, too","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":7398,"name":"Carlos Garza","email":"carlos.garza@rackspace.com","username":"crc32"},"change_message_id":"1d1cdfaadcec5e5109996f266a23a3d7ee1ef472","unresolved":false,"context_lines":[{"line_number":186,"context_line":""},{"line_number":187,"context_line":"    def _get_primary_cn(self, tls_cert):"},{"line_number":188,"context_line":"        \"\"\"Returns primary CN for Certificate.\"\"\""},{"line_number":189,"context_line":"        return cert_parser.get_host_names(tls_cert.get_certificate())[\u0027cn\u0027]"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"    def _map_cert_tls_container(self, cert):"},{"line_number":192,"context_line":"        return data_models.TLSContainer("}],"source_content_type":"text/x-python","patch_set":11,"id":"1a6ced46_24a33902","line":189,"updated":"2015-03-25 20:35:37.000000000","message":"Are we supposed to only count the CN from the cert and disregard any SubjectAltName extensions? I\u0027ll plus one either way. Just want you to make sure that is the intended behavior.","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"5bdbd93f853772dda9f232c13ef7dcbc2b47575a","unresolved":false,"context_lines":[{"line_number":186,"context_line":""},{"line_number":187,"context_line":"    def _get_primary_cn(self, tls_cert):"},{"line_number":188,"context_line":"        \"\"\"Returns primary CN for Certificate.\"\"\""},{"line_number":189,"context_line":"        return cert_parser.get_host_names(tls_cert.get_certificate())[\u0027cn\u0027]"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"    def _map_cert_tls_container(self, cert):"},{"line_number":192,"context_line":"        return data_models.TLSContainer("}],"source_content_type":"text/x-python","patch_set":11,"id":"da9b358b_55b4e3f0","line":189,"in_reply_to":"1a6ced46_24a33902","updated":"2015-03-30 19:42:49.000000000","message":"Most of this was borrowed from Phil\u0027s review to be honest.  However, I still don\u0027t know the answer to your question :S","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":7398,"name":"Carlos Garza","email":"carlos.garza@rackspace.com","username":"crc32"},"change_message_id":"1d1cdfaadcec5e5109996f266a23a3d7ee1ef472","unresolved":false,"context_lines":[{"line_number":204,"context_line":"        pem \u003d list()"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"        for c in tls_cert.intermediates:"},{"line_number":207,"context_line":"            pem \u003d pem + [c]"},{"line_number":208,"context_line":"        pem \u003d pem + [tls_cert.certificate, tls_cert.private_key]"},{"line_number":209,"context_line":""},{"line_number":210,"context_line":"        return \"\\n\".join(pem)"}],"source_content_type":"text/x-python","patch_set":11,"id":"1a6ced46_2497b93c","line":207,"updated":"2015-03-25 20:35:37.000000000","message":"consider replacing the loop with\n\npem \u003d tls_certs.intermediates[:]","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":7398,"name":"Carlos Garza","email":"carlos.garza@rackspace.com","username":"crc32"},"change_message_id":"1d1cdfaadcec5e5109996f266a23a3d7ee1ef472","unresolved":false,"context_lines":[{"line_number":205,"context_line":""},{"line_number":206,"context_line":"        for c in tls_cert.intermediates:"},{"line_number":207,"context_line":"            pem \u003d pem + [c]"},{"line_number":208,"context_line":"        pem \u003d pem + [tls_cert.certificate, tls_cert.private_key]"},{"line_number":209,"context_line":""},{"line_number":210,"context_line":"        return \"\\n\".join(pem)"}],"source_content_type":"text/x-python","patch_set":11,"id":"1a6ced46_c4ab4573","line":208,"updated":"2015-03-25 20:35:37.000000000","message":"consider replacing with\npem.extend([tls_cert.certificate, tls_cert.private_key])","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"5bdbd93f853772dda9f232c13ef7dcbc2b47575a","unresolved":false,"context_lines":[{"line_number":205,"context_line":""},{"line_number":206,"context_line":"        for c in tls_cert.intermediates:"},{"line_number":207,"context_line":"            pem \u003d pem + [c]"},{"line_number":208,"context_line":"        pem \u003d pem + [tls_cert.certificate, tls_cert.private_key]"},{"line_number":209,"context_line":""},{"line_number":210,"context_line":"        return \"\\n\".join(pem)"}],"source_content_type":"text/x-python","patch_set":11,"id":"da9b358b_8e9ed554","line":208,"in_reply_to":"1a6ced46_c4ab4573","updated":"2015-03-30 19:42:49.000000000","message":"I\u0027ve made both changes.  Pretty slick, didn\u0027t know about the list one above.","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"48f94ad0580fab32b250235071d349800d9862e3","unresolved":false,"context_lines":[{"line_number":160,"context_line":"                    self.barbican_client.get_cert(listener.tls_container_id))"},{"line_number":161,"context_line":"                temp_default_pem \u003d tempfile.NamedTemporaryFile(delete\u003dTrue)"},{"line_number":162,"context_line":"                temp_default_pem.write(self._build_pem(tls_cert))"},{"line_number":163,"context_line":"                sftp.put(temp_default_pem.name,"},{"line_number":164,"context_line":"                         \u0027{0}/{1}/certificates/{2}.pem\u0027.format("},{"line_number":165,"context_line":"                             self.amp_config.base_path, listener.id,"},{"line_number":166,"context_line":"                             tls_cert.primary_cn))"}],"source_content_type":"text/x-python","patch_set":12,"id":"baa041b7_c83e2ab8","line":163,"updated":"2015-04-02 04:47:55.000000000","message":"Please check on the amphora if the chmod is 0600 after the scp. Thanks Carlos, I wasn\u0027t aware of that... but better safe ten sorry ;-)","commit_id":"dee820449a0eb39bebd33bf2379818d0e678a443"},{"author":{"_account_id":7398,"name":"Carlos Garza","email":"carlos.garza@rackspace.com","username":"crc32"},"change_message_id":"7d5feb30d7fc45a7c492727a2f7c4b10ac7af3c8","unresolved":false,"context_lines":[{"line_number":201,"context_line":"        encoded certificate file"},{"line_number":202,"context_line":"        \"\"\""},{"line_number":203,"context_line":"        # TODO(ptoohill): Maybe this should be part of utils or manager?"},{"line_number":204,"context_line":"        pem \u003d list()"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"        for c in tls_cert.intermediates:"},{"line_number":207,"context_line":"            pem \u003d pem + [c]"}],"source_content_type":"text/x-python","patch_set":12,"id":"baa041b7_fc6894bc","line":204,"updated":"2015-04-02 01:15:21.000000000","message":"Follow the suggestions in the comments for PatchSet 11","commit_id":"dee820449a0eb39bebd33bf2379818d0e678a443"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"f2d9bc0426a180756d3bec7474f7ddd454d6bba4","unresolved":false,"context_lines":[{"line_number":160,"context_line":"                    self.barbican_client.get_cert(listener.tls_container_id))"},{"line_number":161,"context_line":"                temp_default_pem \u003d tempfile.NamedTemporaryFile(delete\u003dTrue)"},{"line_number":162,"context_line":"                temp_default_pem.write(self._build_pem(tls_cert))"},{"line_number":163,"context_line":"                sftp.put(temp_default_pem.name,"},{"line_number":164,"context_line":"                         \u0027{0}/{1}/certificates/{2}.pem\u0027.format("},{"line_number":165,"context_line":"                             self.amp_config.base_path, listener.id,"},{"line_number":166,"context_line":"                             tls_cert.primary_cn))"}],"source_content_type":"text/x-python","patch_set":13,"id":"baa041b7_f844f974","line":163,"updated":"2015-04-02 21:22:55.000000000","message":"Will verify shortly.  Wanted to catch the changes I missed.","commit_id":"8fe74b0fc1638be09b557306ec4f46940999a8ef"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"6a05b2e4d398c1e56c5af187e7b875e707d9f3c6","unresolved":false,"context_lines":[{"line_number":73,"context_line":"        # Upload the configuration to each amphora"},{"line_number":74,"context_line":"        for amp in listener.load_balancer.amphorae:"},{"line_number":75,"context_line":"            self.client.connect(hostname\u003damp.lb_network_ip,"},{"line_number":76,"context_line":"                                key_filename\u003dcfg.CONF.amphora.key_name)"},{"line_number":77,"context_line":"            # Upload config"},{"line_number":78,"context_line":"            sftp \u003d self.client.open_sftp()"},{"line_number":79,"context_line":"            sftp.put(temp.name, \u0027{0}/{1}/haproxy.cfg\u0027.format("}],"source_content_type":"text/x-python","patch_set":14,"id":"9aa53dc9_9a52aadc","line":76,"updated":"2015-04-06 23:41:27.000000000","message":"i think the user should be configurable.","commit_id":"3d2a478cb16b2e3fb46bd52fda8be8d59b5d6eeb"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"34db6780980735aec488e2c063d35d5d7e03f3ed","unresolved":false,"context_lines":[{"line_number":73,"context_line":"        # Upload the configuration to each amphora"},{"line_number":74,"context_line":"        for amp in listener.load_balancer.amphorae:"},{"line_number":75,"context_line":"            self.client.connect(hostname\u003damp.lb_network_ip,"},{"line_number":76,"context_line":"                                key_filename\u003dcfg.CONF.amphora.key_name)"},{"line_number":77,"context_line":"            # Upload config"},{"line_number":78,"context_line":"            sftp \u003d self.client.open_sftp()"},{"line_number":79,"context_line":"            sftp.put(temp.name, \u0027{0}/{1}/haproxy.cfg\u0027.format("}],"source_content_type":"text/x-python","patch_set":14,"id":"9aa53dc9_a96c0a9d","line":76,"in_reply_to":"9aa53dc9_9a52aadc","updated":"2015-04-07 04:29:03.000000000","message":"Agreed.  Oversight on my part, sorry.  I\u0027ll add.","commit_id":"3d2a478cb16b2e3fb46bd52fda8be8d59b5d6eeb"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"6a05b2e4d398c1e56c5af187e7b875e707d9f3c6","unresolved":false,"context_lines":[{"line_number":94,"context_line":"                                                 listener.id)"},{"line_number":95,"context_line":"        for amp in listener.load_balancer.amphorae:"},{"line_number":96,"context_line":"            self.client.connect(hostname\u003damp.lb_network_ip,"},{"line_number":97,"context_line":"                                key_filename\u003dcfg.CONF.amphora.key_name)"},{"line_number":98,"context_line":"            self.client.exec_command(\u0027kill -9 {0}\u0027.format(process))"},{"line_number":99,"context_line":"            self.client.close()"},{"line_number":100,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"9aa53dc9_a609de33","line":97,"updated":"2015-04-06 23:41:27.000000000","message":"why not use self.amp_config.key_name?","commit_id":"3d2a478cb16b2e3fb46bd52fda8be8d59b5d6eeb"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"34db6780980735aec488e2c063d35d5d7e03f3ed","unresolved":false,"context_lines":[{"line_number":94,"context_line":"                                                 listener.id)"},{"line_number":95,"context_line":"        for amp in listener.load_balancer.amphorae:"},{"line_number":96,"context_line":"            self.client.connect(hostname\u003damp.lb_network_ip,"},{"line_number":97,"context_line":"                                key_filename\u003dcfg.CONF.amphora.key_name)"},{"line_number":98,"context_line":"            self.client.exec_command(\u0027kill -9 {0}\u0027.format(process))"},{"line_number":99,"context_line":"            self.client.close()"},{"line_number":100,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"9aa53dc9_091416f3","line":97,"in_reply_to":"9aa53dc9_a609de33","updated":"2015-04-07 04:29:03.000000000","message":"...because I said so...","commit_id":"3d2a478cb16b2e3fb46bd52fda8be8d59b5d6eeb"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"9de9a1619ea8a38c709f02a3dc61d42692eacffc","unresolved":false,"context_lines":[{"line_number":157,"context_line":"            self.client.connect(hostname\u003damp.lb_network_ip,"},{"line_number":158,"context_line":"                                key_filename\u003dcfg.CONF.amphora.key_name)"},{"line_number":159,"context_line":"            sftp \u003d self.client.open_sftp()"},{"line_number":160,"context_line":"            if listener.tls_container_id:"},{"line_number":161,"context_line":"                tls_cert \u003d self._map_cert_tls_container("},{"line_number":162,"context_line":"                    self.barbican_client.get_cert(listener.tls_container_id))"},{"line_number":163,"context_line":"                temp_default_pem \u003d tempfile.NamedTemporaryFile(delete\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":14,"id":"9aa53dc9_7a8fe623","line":160,"updated":"2015-04-06 23:49:23.000000000","message":"shouldn\u0027t this be tls_certificate_id? the data_model should probably be updated.","commit_id":"3d2a478cb16b2e3fb46bd52fda8be8d59b5d6eeb"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"34db6780980735aec488e2c063d35d5d7e03f3ed","unresolved":false,"context_lines":[{"line_number":157,"context_line":"            self.client.connect(hostname\u003damp.lb_network_ip,"},{"line_number":158,"context_line":"                                key_filename\u003dcfg.CONF.amphora.key_name)"},{"line_number":159,"context_line":"            sftp \u003d self.client.open_sftp()"},{"line_number":160,"context_line":"            if listener.tls_container_id:"},{"line_number":161,"context_line":"                tls_cert \u003d self._map_cert_tls_container("},{"line_number":162,"context_line":"                    self.barbican_client.get_cert(listener.tls_container_id))"},{"line_number":163,"context_line":"                temp_default_pem \u003d tempfile.NamedTemporaryFile(delete\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":14,"id":"9aa53dc9_4931fea1","line":160,"in_reply_to":"9aa53dc9_7a8fe623","updated":"2015-04-07 04:29:03.000000000","message":"I thought the cert was in a barbican \"container\", so this made sense.  Maybe I misunderstood?  Either way it would be a different review to update the data_model :)","commit_id":"3d2a478cb16b2e3fb46bd52fda8be8d59b5d6eeb"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"b01e1b0f79c5267fad9c7245074c899a528e5eb4","unresolved":false,"context_lines":[{"line_number":68,"context_line":"        config \u003d self.jinja.build_config(listener, certs[\u0027tls_cert\u0027],"},{"line_number":69,"context_line":"                                         certs[\u0027sni_certs\u0027])"},{"line_number":70,"context_line":"        temp \u003d tempfile.NamedTemporaryFile(delete\u003dTrue)"},{"line_number":71,"context_line":"        temp.write(config)"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"        # Upload the configuration to each amphora"},{"line_number":74,"context_line":"        for amp in listener.load_balancer.amphorae:"}],"source_content_type":"text/x-python","patch_set":15,"id":"9aa53dc9_bbee8bea","line":71,"updated":"2015-04-07 06:23:02.000000000","message":"temp.flush()","commit_id":"bca9322a174f853f4f365fc6830f079790b99ab3"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"970097d9960dceace44dc5fd49e9c9e2d3b817a9","unresolved":false,"context_lines":[{"line_number":78,"context_line":"            # Upload config"},{"line_number":79,"context_line":"            sftp \u003d self.client.open_sftp()"},{"line_number":80,"context_line":"            sftp.put(temp.name, \u0027{0}/{1}/haproxy.cfg\u0027.format("},{"line_number":81,"context_line":"                self.amp_config.base_path, listener.id))"},{"line_number":82,"context_line":"            self.client.exec_command(\u0027chmod 600 {0}/{1}/haproxy.cfg\u0027.format("},{"line_number":83,"context_line":"                self.amp_config.base_path, listener.id))"},{"line_number":84,"context_line":"            self.client.exec_command("}],"source_content_type":"text/x-python","patch_set":15,"id":"9aa53dc9_3bcf1bb2","line":81,"updated":"2015-04-07 06:16:02.000000000","message":"this doesn\u0027t work for new listeners, listener.id directory won\u0027t exist on amphora so this will error.","commit_id":"bca9322a174f853f4f365fc6830f079790b99ab3"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"d4af0195ad58436ed07a3112d2700250981e61c4","unresolved":false,"context_lines":[{"line_number":83,"context_line":"                self.amp_config.base_path, listener.id))"},{"line_number":84,"context_line":"            self.client.exec_command("},{"line_number":85,"context_line":"                \u0027haproxy -f {0} -p {1}/{2}.pid -sf {1}/{2}.pid\u0027.format("},{"line_number":86,"context_line":"                    config, self.amp_config.base_path, listener.id))"},{"line_number":87,"context_line":"            self.client.close()"},{"line_number":88,"context_line":"        temp.close()"},{"line_number":89,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"9aa53dc9_9eba95e0","line":86,"updated":"2015-04-07 07:02:19.000000000","message":"you dont want to pass config on the command line.  it should just take the path to the config file.\n\nalso the exec_command returns stdin, stout, stderr.  you should read these and raise exceptions if something goes wrong, but maybe we can improve upon this with something like that in subsequent review.  Either way we are going to have to deal with the fact that a the base_path may point to a directory that the ssh user does not have the correct permissions for.","commit_id":"bca9322a174f853f4f365fc6830f079790b99ab3"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"970097d9960dceace44dc5fd49e9c9e2d3b817a9","unresolved":false,"context_lines":[{"line_number":162,"context_line":"                                username\u003dself.amp_config.username,"},{"line_number":163,"context_line":"                                key_filename\u003dself.amp_config.key_name)"},{"line_number":164,"context_line":"            sftp \u003d self.client.open_sftp()"},{"line_number":165,"context_line":"            if listener.tls_container_id:"},{"line_number":166,"context_line":"                tls_cert \u003d self._map_cert_tls_container("},{"line_number":167,"context_line":"                    self.barbican_client.get_cert(listener.tls_container_id))"},{"line_number":168,"context_line":"                temp_default_pem \u003d tempfile.NamedTemporaryFile(delete\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":15,"id":"9aa53dc9_fbc1b381","line":165,"updated":"2015-04-07 06:16:02.000000000","message":"this should still change to listener.tls_certificate_id","commit_id":"bca9322a174f853f4f365fc6830f079790b99ab3"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"b01e1b0f79c5267fad9c7245074c899a528e5eb4","unresolved":false,"context_lines":[{"line_number":166,"context_line":"                tls_cert \u003d self._map_cert_tls_container("},{"line_number":167,"context_line":"                    self.barbican_client.get_cert(listener.tls_container_id))"},{"line_number":168,"context_line":"                temp_default_pem \u003d tempfile.NamedTemporaryFile(delete\u003dTrue)"},{"line_number":169,"context_line":"                temp_default_pem.write(self._build_pem(tls_cert))"},{"line_number":170,"context_line":"                sftp.put(temp_default_pem.name,"},{"line_number":171,"context_line":"                         \u0027{0}/{1}/certificates/{2}.pem\u0027.format("},{"line_number":172,"context_line":"                             self.amp_config.base_path, listener.id,"}],"source_content_type":"text/x-python","patch_set":15,"id":"9aa53dc9_7bbfe3d0","line":169,"updated":"2015-04-07 06:23:02.000000000","message":"temp.default_pem.flush()","commit_id":"bca9322a174f853f4f365fc6830f079790b99ab3"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"41551d7b7365c5414c81f5c53a3411121927b063","unresolved":false,"context_lines":[{"line_number":85,"context_line":"            self.client.exec_command("},{"line_number":86,"context_line":"                \u0027chmod 600 {0}/haproxy.cfg\u0027.format(conf_path))"},{"line_number":87,"context_line":"            self.client.exec_command(\u0027haproxy -f {0}/haproxy.cfg -p \u0027"},{"line_number":88,"context_line":"                                     \u0027{0}/{1}.pid -sf {0}/{1}.pid\u0027.format("},{"line_number":89,"context_line":"                                         conf_path, listener.id))"},{"line_number":90,"context_line":"            self.client.close()"},{"line_number":91,"context_line":"        temp.close()"}],"source_content_type":"text/x-python","patch_set":16,"id":"9aa53dc9_804a14c4","line":88,"updated":"2015-04-07 18:54:07.000000000","message":"-sf requires the actual contents of the pid file, so you need to do -sf $(cat {0}/{1}.pid)","commit_id":"6781504e2c7e76b70ff0a039b9cd23dc7f20bfb4"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"c76f9b9e79a47e87b9bfa3c8f199d10d8a86fb83","unresolved":false,"context_lines":[{"line_number":81,"context_line":"            self.client.exec_command(\u0027mkdir -p {0}\u0027.format(conf_path))"},{"line_number":82,"context_line":"            # Upload config"},{"line_number":83,"context_line":"            sftp \u003d self.client.open_sftp()"},{"line_number":84,"context_line":"            sftp.put(temp.name, conf_path)"},{"line_number":85,"context_line":"            self.client.exec_command("},{"line_number":86,"context_line":"                \u0027chmod 600 {0}/haproxy.cfg\u0027.format(conf_path))"},{"line_number":87,"context_line":"            self.client.exec_command("}],"source_content_type":"text/x-python","patch_set":17,"id":"9aa53dc9_0c5f51e6","line":84,"updated":"2015-04-08 02:28:20.000000000","message":"this needs to be:\n\nsftp.put(temp.name, \u0027{0}/haproxy.cfg\u0027.format(conf_path))","commit_id":"2ee5832b4ccc58803f436c4d7f6f635d342fff65"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"de58ff4a458411533adafceb894dc64959f55663","unresolved":false,"context_lines":[{"line_number":86,"context_line":"                \u0027chmod 600 {0}/haproxy.cfg\u0027.format(conf_path))"},{"line_number":87,"context_line":"            self.client.exec_command("},{"line_number":88,"context_line":"                \u0027haproxy -f {0}/haproxy.cfg -p {0}/{1}.pid -sf \u0027"},{"line_number":89,"context_line":"                \u0027$(cat {0}/{1}.pid)\u0027.format(conf_path, listener.id))"},{"line_number":90,"context_line":"            self.client.close()"},{"line_number":91,"context_line":"        temp.close()"},{"line_number":92,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"9aa53dc9_c01c9715","line":89,"updated":"2015-04-07 20:53:34.000000000","message":"you should run this command and all other commands with sudo, bc haproxy won\u0027t be able to bind to system ports.  it should be assumed the user connecting to these has sudo rights.","commit_id":"2ee5832b4ccc58803f436c4d7f6f635d342fff65"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"95e3dcf5c6d063e233da1b4630a647141d3c1afa","unresolved":false,"context_lines":[{"line_number":26,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"class LoggingMixIn(driver_base.HealthMixin, driver_base.StatsMixin):"},{"line_number":30,"context_line":"    def update_stats(self, stats):"},{"line_number":31,"context_line":"        LOG.debug(\"Amphora %s haproxy, update stats %s\","},{"line_number":32,"context_line":"                  self.__class__.__name__, stats)"}],"source_content_type":"text/x-python","patch_set":18,"id":"9aa53dc9_39afd195","line":29,"updated":"2015-04-08 18:38:34.000000000","message":"You can remove this class: The HaelthMixin from https://github.com/stackforge/octavia/blob/master/octavia/controller/healthmanager/update_health_mixin.py will be used. Stats are not yet collected but I am sure we will write soemthing which is not logging...\n\nThe idea is that the drivers new start_health method will collect the health from the amphora and then call the Mixin to get it into the database.","commit_id":"dc8ef1dd9dfe85900a475362b4f3685e1f6adce0"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"95e3dcf5c6d063e233da1b4630a647141d3c1afa","unresolved":false,"context_lines":[{"line_number":83,"context_line":"            sftp \u003d self.client.open_sftp()"},{"line_number":84,"context_line":"            sftp.put(temp.name, \u0027{0}/haproxy.cfg\u0027.format(conf_path))"},{"line_number":85,"context_line":"            self.client.exec_command("},{"line_number":86,"context_line":"                \u0027chmod 600 {0}/haproxy.cfg\u0027.format(conf_path))"},{"line_number":87,"context_line":"            self.client.exec_command("},{"line_number":88,"context_line":"                \u0027sudo haproxy -f {0}/haproxy.cfg -p {0}/{1}.pid -sf \u0027"},{"line_number":89,"context_line":"                \u0027$(cat {0}/{1}.pid)\u0027.format(conf_path, listener.id))"}],"source_content_type":"text/x-python","patch_set":18,"id":"9aa53dc9_d907c51a","line":86,"updated":"2015-04-08 18:38:34.000000000","message":"Don\u0027t we need to run a different command if that haproxy is alreday running, e.g. some kill - `cat pid`","commit_id":"dc8ef1dd9dfe85900a475362b4f3685e1f6adce0"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"1840f6badae2f0719295d7c88ae2f4a6898930e7","unresolved":false,"context_lines":[{"line_number":83,"context_line":"            sftp \u003d self.client.open_sftp()"},{"line_number":84,"context_line":"            sftp.put(temp.name, \u0027{0}/haproxy.cfg\u0027.format(conf_path))"},{"line_number":85,"context_line":"            self.client.exec_command("},{"line_number":86,"context_line":"                \u0027chmod 600 {0}/haproxy.cfg\u0027.format(conf_path))"},{"line_number":87,"context_line":"            self.client.exec_command("},{"line_number":88,"context_line":"                \u0027sudo haproxy -f {0}/haproxy.cfg -p {0}/{1}.pid -sf \u0027"},{"line_number":89,"context_line":"                \u0027$(cat {0}/{1}.pid)\u0027.format(conf_path, listener.id))"}],"source_content_type":"text/x-python","patch_set":18,"id":"9aa53dc9_2413250f","line":86,"in_reply_to":"9aa53dc9_51b149e0","updated":"2015-04-08 21:03:45.000000000","message":"Sorry, you are right. Missed the -sf part","commit_id":"dc8ef1dd9dfe85900a475362b4f3685e1f6adce0"},{"author":{"_account_id":11302,"name":"Phillip Toohill","email":"phillip.toohill@rackspace.com","username":"ptoohill1"},"change_message_id":"20ef122f8e2b4098bc116290ee190ff64f8dcab2","unresolved":false,"context_lines":[{"line_number":83,"context_line":"            sftp \u003d self.client.open_sftp()"},{"line_number":84,"context_line":"            sftp.put(temp.name, \u0027{0}/haproxy.cfg\u0027.format(conf_path))"},{"line_number":85,"context_line":"            self.client.exec_command("},{"line_number":86,"context_line":"                \u0027chmod 600 {0}/haproxy.cfg\u0027.format(conf_path))"},{"line_number":87,"context_line":"            self.client.exec_command("},{"line_number":88,"context_line":"                \u0027sudo haproxy -f {0}/haproxy.cfg -p {0}/{1}.pid -sf \u0027"},{"line_number":89,"context_line":"                \u0027$(cat {0}/{1}.pid)\u0027.format(conf_path, listener.id))"}],"source_content_type":"text/x-python","patch_set":18,"id":"9aa53dc9_51b149e0","line":86,"in_reply_to":"9aa53dc9_d907c51a","updated":"2015-04-08 20:41:01.000000000","message":"Not sure why this is needed. This is a graceful restart.","commit_id":"dc8ef1dd9dfe85900a475362b4f3685e1f6adce0"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"95e3dcf5c6d063e233da1b4630a647141d3c1afa","unresolved":false,"context_lines":[{"line_number":96,"context_line":"                  listener.protocol_port, vip.ip_address)"},{"line_number":97,"context_line":"        process \u003d \u0027`cat {0}/{1}/{1}.pid`\u0027.format(self.amp_config.base_path,"},{"line_number":98,"context_line":"                                                 listener.id)"},{"line_number":99,"context_line":"        for amp in listener.load_balancer.amphorae:"},{"line_number":100,"context_line":"            self.client.connect(hostname\u003damp.lb_network_ip,"},{"line_number":101,"context_line":"                                username\u003dself.amp_config.username,"},{"line_number":102,"context_line":"                                key_filename\u003dself.amp_config.key_name)"}],"source_content_type":"text/x-python","patch_set":18,"id":"9aa53dc9_146a94b3","line":99,"updated":"2015-04-08 18:38:34.000000000","message":"You know I still like to see that with some syntactic sugar so we don\u0027t replicate the same for loop unnecessarily 5 times","commit_id":"dc8ef1dd9dfe85900a475362b4f3685e1f6adce0"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"479e13cdf1fa2236d9f3a2282ad9293826e96bb4","unresolved":false,"context_lines":[{"line_number":96,"context_line":"                  listener.protocol_port, vip.ip_address)"},{"line_number":97,"context_line":"        process \u003d \u0027`cat {0}/{1}/{1}.pid`\u0027.format(self.amp_config.base_path,"},{"line_number":98,"context_line":"                                                 listener.id)"},{"line_number":99,"context_line":"        for amp in listener.load_balancer.amphorae:"},{"line_number":100,"context_line":"            self.client.connect(hostname\u003damp.lb_network_ip,"},{"line_number":101,"context_line":"                                username\u003dself.amp_config.username,"},{"line_number":102,"context_line":"                                key_filename\u003dself.amp_config.key_name)"}],"source_content_type":"text/x-python","patch_set":18,"id":"9aa53dc9_2e2ae42c","line":99,"in_reply_to":"9aa53dc9_146a94b3","updated":"2015-04-08 20:37:49.000000000","message":"yeah a method that takes in a command string (or list of command strings) to run against every amphora would clean this up.  Though for the update method it still needs to do the sftp calls, so it can stay put unless that same method is made extra complicated.","commit_id":"dc8ef1dd9dfe85900a475362b4f3685e1f6adce0"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"95e3dcf5c6d063e233da1b4630a647141d3c1afa","unresolved":false,"context_lines":[{"line_number":115,"context_line":"            self.client.connect(hostname\u003damp.lb_network_ip,"},{"line_number":116,"context_line":"                                username\u003dself.amp_config.username,"},{"line_number":117,"context_line":"                                key_filename\u003dself.amp_config.key_name)"},{"line_number":118,"context_line":"            self.client.exec_command(\u0027rm -rf {0}\u0027.format(directory))"},{"line_number":119,"context_line":"            self.client.close()"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"    def start(self, listener, vip):"}],"source_content_type":"text/x-python","patch_set":18,"id":"9aa53dc9_d44c2c72","line":118,"updated":"2015-04-08 18:38:34.000000000","message":"Not sure if that is enough:\n1) The original plan was to have all certs on a ramdrive. I doubt we mount different ramdrives for each listener ;-)\n2) (Sorry about that). An operator might but the log files on a special drive instead of under the listener\u0027s directory","commit_id":"dc8ef1dd9dfe85900a475362b4f3685e1f6adce0"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"479e13cdf1fa2236d9f3a2282ad9293826e96bb4","unresolved":false,"context_lines":[{"line_number":115,"context_line":"            self.client.connect(hostname\u003damp.lb_network_ip,"},{"line_number":116,"context_line":"                                username\u003dself.amp_config.username,"},{"line_number":117,"context_line":"                                key_filename\u003dself.amp_config.key_name)"},{"line_number":118,"context_line":"            self.client.exec_command(\u0027rm -rf {0}\u0027.format(directory))"},{"line_number":119,"context_line":"            self.client.close()"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"    def start(self, listener, vip):"}],"source_content_type":"text/x-python","patch_set":18,"id":"9aa53dc9_2e5c24ec","line":118,"in_reply_to":"9aa53dc9_d44c2c72","updated":"2015-04-08 20:37:49.000000000","message":"That sounds like something that can be added in iteratively.","commit_id":"dc8ef1dd9dfe85900a475362b4f3685e1f6adce0"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"479e13cdf1fa2236d9f3a2282ad9293826e96bb4","unresolved":false,"context_lines":[{"line_number":159,"context_line":"        return TLS_CERT and SNI_CERTS"},{"line_number":160,"context_line":"        \"\"\""},{"line_number":161,"context_line":"        tls_cert \u003d None"},{"line_number":162,"context_line":"        sni_certs \u003d []"},{"line_number":163,"context_line":"        # Retrieve, map and store default TLS certificate"},{"line_number":164,"context_line":"        for amp in listener.load_balancer.amphorae:"},{"line_number":165,"context_line":"            self.client.connect(hostname\u003damp.lb_network_ip,"}],"source_content_type":"text/x-python","patch_set":18,"id":"9aa53dc9_8ebb30e5","line":162,"updated":"2015-04-08 20:37:49.000000000","message":"add an if statement here that checks whether listener.tls_certificate_id or sni_containers exists so we aren\u0027t unnecessarily ssh\u0027ing to the amphora if they don\u0027t exist.  also, can probably just pull them before the loop as german suggested, saves a round trip or more","commit_id":"dc8ef1dd9dfe85900a475362b4f3685e1f6adce0"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"95e3dcf5c6d063e233da1b4630a647141d3c1afa","unresolved":false,"context_lines":[{"line_number":171,"context_line":"            sftp \u003d self.client.open_sftp()"},{"line_number":172,"context_line":"            if listener.tls_certificate_id:"},{"line_number":173,"context_line":"                tls_cert \u003d self._map_cert_tls_container("},{"line_number":174,"context_line":"                    self.barbican_client.get_cert(listener.tls_certificate_id))"},{"line_number":175,"context_line":"                temp_default_pem \u003d tempfile.NamedTemporaryFile(delete\u003dTrue)"},{"line_number":176,"context_line":"                temp_default_pem.write(self._build_pem(tls_cert))"},{"line_number":177,"context_line":"                temp_default_pem.flush()"}],"source_content_type":"text/x-python","patch_set":18,"id":"9aa53dc9_b4b52832","line":174,"updated":"2015-04-08 18:38:34.000000000","message":"shouldn\u0027t we get the certs before the loop? I doubt they are different for each ampohora...","commit_id":"dc8ef1dd9dfe85900a475362b4f3685e1f6adce0"},{"author":{"_account_id":11302,"name":"Phillip Toohill","email":"phillip.toohill@rackspace.com","username":"ptoohill1"},"change_message_id":"20ef122f8e2b4098bc116290ee190ff64f8dcab2","unresolved":false,"context_lines":[{"line_number":171,"context_line":"            sftp \u003d self.client.open_sftp()"},{"line_number":172,"context_line":"            if listener.tls_certificate_id:"},{"line_number":173,"context_line":"                tls_cert \u003d self._map_cert_tls_container("},{"line_number":174,"context_line":"                    self.barbican_client.get_cert(listener.tls_certificate_id))"},{"line_number":175,"context_line":"                temp_default_pem \u003d tempfile.NamedTemporaryFile(delete\u003dTrue)"},{"line_number":176,"context_line":"                temp_default_pem.write(self._build_pem(tls_cert))"},{"line_number":177,"context_line":"                temp_default_pem.flush()"}],"source_content_type":"text/x-python","patch_set":18,"id":"9aa53dc9_71e1edcf","line":174,"in_reply_to":"9aa53dc9_b4b52832","updated":"2015-04-08 20:41:01.000000000","message":"This is a good point. The certs would only differ by listener, not amp.","commit_id":"dc8ef1dd9dfe85900a475362b4f3685e1f6adce0"},{"author":{"_account_id":11628,"name":"Michael Johnson","email":"johnsomor@gmail.com","username":"johnsom"},"change_message_id":"eb35b1105f1583b25d459d37b88b256e11d60db1","unresolved":false,"context_lines":[{"line_number":30,"context_line":""},{"line_number":31,"context_line":"    amp_config \u003d cfg.CONF.haproxy_amphora"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"    def __init__(self):"},{"line_number":34,"context_line":"        super(HaproxyManager, self).__init__()"},{"line_number":35,"context_line":"        self.amphoraconfig \u003d {}"},{"line_number":36,"context_line":"        self.client \u003d paramiko.SSHClient()"}],"source_content_type":"text/x-python","patch_set":20,"id":"9aa53dc9_8ab2cae3","line":33,"updated":"2015-04-09 22:23:44.000000000","message":"The noop and Susanne\u0027s driver take a log param here.\nCan you guys discuss and align?","commit_id":"d84bb06e4a3a8eac2f8bc3ddac260bab8a2c1ae5"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"3be42202c0fa40bc561df00cf770dfbb374d7152","unresolved":false,"context_lines":[{"line_number":30,"context_line":""},{"line_number":31,"context_line":"    amp_config \u003d cfg.CONF.haproxy_amphora"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"    def __init__(self):"},{"line_number":34,"context_line":"        super(HaproxyManager, self).__init__()"},{"line_number":35,"context_line":"        self.amphoraconfig \u003d {}"},{"line_number":36,"context_line":"        self.client \u003d paramiko.SSHClient()"}],"source_content_type":"text/x-python","patch_set":20,"id":"7aaa499b_505cf24a","line":33,"in_reply_to":"9aa53dc9_8ab2cae3","updated":"2015-04-13 15:50:05.000000000","message":"I believe we discussed this in channel, and the other drivers should be updated accordingly...","commit_id":"d84bb06e4a3a8eac2f8bc3ddac260bab8a2c1ae5"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"3aaf7b743ac6b851e0606bbfdd850da58444b623","unresolved":false,"context_lines":[{"line_number":132,"context_line":"        \"\"\""},{"line_number":133,"context_line":"        tls_cert \u003d None"},{"line_number":134,"context_line":"        sni_certs \u003d []"},{"line_number":135,"context_line":"        cert_dir \u003d \u0027{0}/{1}/certificates\u0027.format(self.amp_config.base_path,"},{"line_number":136,"context_line":"                                                 listener.id)"},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"        data \u003d []"}],"source_content_type":"text/x-python","patch_set":20,"id":"7aaa499b_27b6f83d","line":135,"updated":"2015-04-10 17:20:17.000000000","message":"I think I pointed that out earlier but Stephen B. was adament that we staore the certificates in a ramdisk. Unless we put all our configuration there I would like to see the path changed or we abandon the ramdisk idea...","commit_id":"d84bb06e4a3a8eac2f8bc3ddac260bab8a2c1ae5"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"3be42202c0fa40bc561df00cf770dfbb374d7152","unresolved":false,"context_lines":[{"line_number":132,"context_line":"        \"\"\""},{"line_number":133,"context_line":"        tls_cert \u003d None"},{"line_number":134,"context_line":"        sni_certs \u003d []"},{"line_number":135,"context_line":"        cert_dir \u003d \u0027{0}/{1}/certificates\u0027.format(self.amp_config.base_path,"},{"line_number":136,"context_line":"                                                 listener.id)"},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"        data \u003d []"}],"source_content_type":"text/x-python","patch_set":20,"id":"7aaa499b_b0357647","line":135,"in_reply_to":"7aaa499b_27b6f83d","updated":"2015-04-13 15:50:05.000000000","message":"So should the SSH Driver also be setting up the ramdisk itself, as in creating it and mounting it and such before writing the certs, or should it assume its already there and then store it based on config values in Octavia, as it still details here?  Personally I don\u0027t think the SSH driver should do the setup, but other people think it should then I can figure out how to get that to work.","commit_id":"d84bb06e4a3a8eac2f8bc3ddac260bab8a2c1ae5"},{"author":{"_account_id":10273,"name":"Adam Harwell","email":"flux.adam@gmail.com","username":"rm_you"},"change_message_id":"2b6c679b4d56b5e9afa820f98b327999a1ed87b1","unresolved":false,"context_lines":[{"line_number":132,"context_line":"        \"\"\""},{"line_number":133,"context_line":"        tls_cert \u003d None"},{"line_number":134,"context_line":"        sni_certs \u003d []"},{"line_number":135,"context_line":"        cert_dir \u003d \u0027{0}/{1}/certificates\u0027.format(self.amp_config.base_path,"},{"line_number":136,"context_line":"                                                 listener.id)"},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"        data \u003d []"}],"source_content_type":"text/x-python","patch_set":20,"id":"7aaa499b_d38dac32","line":135,"in_reply_to":"7aaa499b_b0357647","updated":"2015-04-13 15:57:05.000000000","message":"The driver shouldn\u0027t be responsible for configuring ramdisk/etc -- it should just be given a path from config and drop stuff there, and it\u0027s up to the base-image to have that directory be a ramdisk or whatever it is we want.","commit_id":"d84bb06e4a3a8eac2f8bc3ddac260bab8a2c1ae5"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"fdbcc9b6221fb64fcb623046afeaa810df34ba4b","unresolved":false,"context_lines":[{"line_number":151,"context_line":"        self._exec_on_amphorae(listener.load_balancer.amphorae,"},{"line_number":152,"context_line":"                               [\u0027chmod 600 {0}/*.pem\u0027.format(cert_dir)],"},{"line_number":153,"context_line":"                               make_dir\u003dcert_dir, data\u003ddata,"},{"line_number":154,"context_line":"                               upload_dir\u003dcert_dir)"},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"        return {\u0027tls_cert\u0027: tls_cert, \u0027sni_certs\u0027: sni_certs}"},{"line_number":157,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"9aa53dc9_de943944","line":154,"updated":"2015-04-09 18:31:37.000000000","message":"shouldn\u0027t execute on amphroa if tls_certificateid and sni_containers doesn\u0027t exist, you can do an if data:","commit_id":"d84bb06e4a3a8eac2f8bc3ddac260bab8a2c1ae5"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"27aa292512523aceaa1e2b934b10c24dd59b1f36","unresolved":false,"context_lines":[{"line_number":134,"context_line":"                                key_filename\u003dself.amp_config.key_name)"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"            _, stdout, _ \u003d self.client.exec_command("},{"line_number":137,"context_line":"                \u0027ip link | grep DOWN -m 1 | awk \"{print $2}\"\u0027)"},{"line_number":138,"context_line":"            output \u003d stdout.read()[:-1]"},{"line_number":139,"context_line":"            vip \u003d load_balancer.vip.ip_address"},{"line_number":140,"context_line":"            sections \u003d vip.split(\u0027.\u0027)[:3]"}],"source_content_type":"text/x-python","patch_set":23,"id":"3ab451fb_62cbd273","line":137,"updated":"2015-04-16 21:07:19.000000000","message":"Potentially modify this to grep for a DOWN interface that is not already in the interfaces file.  (could cause an unwanted collision of configurations)","commit_id":"3135ef541d46f140b56b9a796694191ddfe38019"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"cf66a3e92a31d8f07cc191e68832f07d1627929e","unresolved":false,"context_lines":[{"line_number":140,"context_line":"            sections \u003d vip.split(\u0027.\u0027)[:3]"},{"line_number":141,"context_line":"            sections.append(\u0027255\u0027)"},{"line_number":142,"context_line":"            broadcast \u003d \u0027.\u0027.join(sections)"},{"line_number":143,"context_line":"            file_out \u003d (\u0027auto {0} {0}:0\\niface {0} inet dhcp\\n\\n\u0027"},{"line_number":144,"context_line":"                        \u0027iface {0}:0 inet static\\naddress {1}\\n\u0027"},{"line_number":145,"context_line":"                        \u0027broadcast {2}\\nnetmask {3}\u0027.format(output, vip,"},{"line_number":146,"context_line":"                                                            broadcast,"}],"source_content_type":"text/x-python","patch_set":23,"id":"5aa745d1_29ffe802","line":143,"updated":"2015-04-15 23:57:00.000000000","message":"this is sort of messy: I am wondering if we can use a python library like https://github.com/dggreenbaum/debinterface (I am exploring that stuff for the rest driver)","commit_id":"3135ef541d46f140b56b9a796694191ddfe38019"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"e0de2df5939f931dae3fa7725017734004e5906a","unresolved":false,"context_lines":[{"line_number":140,"context_line":"            sections \u003d vip.split(\u0027.\u0027)[:3]"},{"line_number":141,"context_line":"            sections.append(\u0027255\u0027)"},{"line_number":142,"context_line":"            broadcast \u003d \u0027.\u0027.join(sections)"},{"line_number":143,"context_line":"            file_out \u003d (\u0027auto {0} {0}:0\\niface {0} inet dhcp\\n\\n\u0027"},{"line_number":144,"context_line":"                        \u0027iface {0}:0 inet static\\naddress {1}\\n\u0027"},{"line_number":145,"context_line":"                        \u0027broadcast {2}\\nnetmask {3}\u0027.format(output, vip,"},{"line_number":146,"context_line":"                                                            broadcast,"}],"source_content_type":"text/x-python","patch_set":23,"id":"3ab451fb_5f378fe3","line":143,"in_reply_to":"3ab451fb_9cb405d2","updated":"2015-04-16 20:24:50.000000000","message":"Sorry, but I don\u0027t understand why you would do that... I\u0027m adding to a file, not changing what already exists in it.  I don\u0027t need to load the other interfaces into a list.  Besides, pull the file, changing it, and then pushing the file is a series of unnecessary requests over the connection.  Right now I have it as one command.  Less chance for failure my current way as well.","commit_id":"3135ef541d46f140b56b9a796694191ddfe38019"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"ed106412f50d23d3c051c0453f1b11f8f8838391","unresolved":false,"context_lines":[{"line_number":140,"context_line":"            sections \u003d vip.split(\u0027.\u0027)[:3]"},{"line_number":141,"context_line":"            sections.append(\u0027255\u0027)"},{"line_number":142,"context_line":"            broadcast \u003d \u0027.\u0027.join(sections)"},{"line_number":143,"context_line":"            file_out \u003d (\u0027auto {0} {0}:0\\niface {0} inet dhcp\\n\\n\u0027"},{"line_number":144,"context_line":"                        \u0027iface {0}:0 inet static\\naddress {1}\\n\u0027"},{"line_number":145,"context_line":"                        \u0027broadcast {2}\\nnetmask {3}\u0027.format(output, vip,"},{"line_number":146,"context_line":"                                                            broadcast,"}],"source_content_type":"text/x-python","patch_set":23,"id":"5aa745d1_70ca5aa3","line":143,"in_reply_to":"5aa745d1_29ffe802","updated":"2015-04-16 19:50:40.000000000","message":"The library you reference here and in your other comment are for local interface changes.  I won\u0027t be running any python scripts on the amphora after connecting to it, it\u0027ll be much much easier to just exec a command.  Besides, the messiest thing above is string manipulation to create some values.  Otherwise, this file information would have to be generated somewhere, and here is just fine.","commit_id":"3135ef541d46f140b56b9a796694191ddfe38019"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"ddeffd6fe9fee5dfc6d012285db9d80cbd65be52","unresolved":false,"context_lines":[{"line_number":140,"context_line":"            sections \u003d vip.split(\u0027.\u0027)[:3]"},{"line_number":141,"context_line":"            sections.append(\u0027255\u0027)"},{"line_number":142,"context_line":"            broadcast \u003d \u0027.\u0027.join(sections)"},{"line_number":143,"context_line":"            file_out \u003d (\u0027auto {0} {0}:0\\niface {0} inet dhcp\\n\\n\u0027"},{"line_number":144,"context_line":"                        \u0027iface {0}:0 inet static\\naddress {1}\\n\u0027"},{"line_number":145,"context_line":"                        \u0027broadcast {2}\\nnetmask {3}\u0027.format(output, vip,"},{"line_number":146,"context_line":"                                                            broadcast,"}],"source_content_type":"text/x-python","patch_set":23,"id":"3ab451fb_9cb405d2","line":143,"in_reply_to":"5aa745d1_70ca5aa3","updated":"2015-04-16 19:59:07.000000000","message":"Nobody is stopping you from moving the file over parsing it and sending it back...","commit_id":"3135ef541d46f140b56b9a796694191ddfe38019"},{"author":{"_account_id":12403,"name":"Al Miller","email":"al.miller@ajmiller.net","username":"ajmiller"},"change_message_id":"7819b6fa47c14c561dd2b495baea6c6391df72f0","unresolved":false,"context_lines":[{"line_number":144,"context_line":"                        \u0027iface {0}:0 inet static\\naddress {1}\\n\u0027"},{"line_number":145,"context_line":"                        \u0027broadcast {2}\\nnetmask {3}\u0027.format(output, vip,"},{"line_number":146,"context_line":"                                                            broadcast,"},{"line_number":147,"context_line":"                                                            \u0027255.255.255.0\u0027))"},{"line_number":148,"context_line":"            self.client.exec_command("},{"line_number":149,"context_line":"                \u0027sudo echo {0} \u003e\u003e /etc/network/interfaces\u0027.format(file_out))"},{"line_number":150,"context_line":"            self.client.exec_command(\u0027sudo ifup {0}\u0027.format(output))"}],"source_content_type":"text/x-python","patch_set":23,"id":"dac4157f_156e2395","line":147,"updated":"2015-04-22 03:49:38.000000000","message":"This (and the code building the broadcast address on lines 139-142) is making a hard-coded assumption of a that this is a /24 network.  Is that really a good assumption? This would limit the number of amphorae on a single network to \u003c 250-ish.  \n\nAt minimum a comment here pointing this out for future reference would be good.","commit_id":"3135ef541d46f140b56b9a796694191ddfe38019"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"cb6d0cdff36d7eff864c94b01911dfcfcf871ed1","unresolved":false,"context_lines":[{"line_number":144,"context_line":"                        \u0027iface {0}:0 inet static\\naddress {1}\\n\u0027"},{"line_number":145,"context_line":"                        \u0027broadcast {2}\\nnetmask {3}\u0027.format(output, vip,"},{"line_number":146,"context_line":"                                                            broadcast,"},{"line_number":147,"context_line":"                                                            \u0027255.255.255.0\u0027))"},{"line_number":148,"context_line":"            self.client.exec_command("},{"line_number":149,"context_line":"                \u0027sudo echo {0} \u003e\u003e /etc/network/interfaces\u0027.format(file_out))"},{"line_number":150,"context_line":"            self.client.exec_command(\u0027sudo ifup {0}\u0027.format(output))"}],"source_content_type":"text/x-python","patch_set":23,"id":"dac4157f_ebabcb1b","line":147,"in_reply_to":"dac4157f_156e2395","updated":"2015-04-22 06:39:17.000000000","message":"yeah this is something that may just have to go in for the demo as is so we can have something working.  totally agree it shouldn\u0027t be hardcoded.  this type of stuff may have to be passed as information in a Network object.","commit_id":"3135ef541d46f140b56b9a796694191ddfe38019"},{"author":{"_account_id":12403,"name":"Al Miller","email":"al.miller@ajmiller.net","username":"ajmiller"},"change_message_id":"1f31ce6bb4a1dbbebc30a52ba63a6fdc5cccbb6e","unresolved":false,"context_lines":[{"line_number":144,"context_line":"                        \u0027iface {0}:0 inet static\\naddress {1}\\n\u0027"},{"line_number":145,"context_line":"                        \u0027broadcast {2}\\nnetmask {3}\u0027.format(output, vip,"},{"line_number":146,"context_line":"                                                            broadcast,"},{"line_number":147,"context_line":"                                                            \u0027255.255.255.0\u0027))"},{"line_number":148,"context_line":"            self.client.exec_command("},{"line_number":149,"context_line":"                \u0027sudo echo {0} \u003e\u003e /etc/network/interfaces\u0027.format(file_out))"},{"line_number":150,"context_line":"            self.client.exec_command(\u0027sudo ifup {0}\u0027.format(output))"}],"source_content_type":"text/x-python","patch_set":23,"id":"dac4157f_be917df3","line":147,"in_reply_to":"dac4157f_ebabcb1b","updated":"2015-04-22 17:17:44.000000000","message":"Yes, for demo this is fine.  Just don\u0027t want to forget about it and have it lead to some strange production problems when we try to scale up.","commit_id":"3135ef541d46f140b56b9a796694191ddfe38019"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"a13425f82b714649f5c1afa68eb6c21348795a59","unresolved":false,"context_lines":[{"line_number":146,"context_line":"                                                            broadcast,"},{"line_number":147,"context_line":"                                                            \u0027255.255.255.0\u0027))"},{"line_number":148,"context_line":"            self.client.exec_command("},{"line_number":149,"context_line":"                \u0027sudo echo {0} \u003e\u003e /etc/network/interfaces\u0027.format(file_out))"},{"line_number":150,"context_line":"            self.client.exec_command(\u0027sudo ifup {0}\u0027.format(output))"},{"line_number":151,"context_line":"            self.client.exec_command(\u0027sudo ifup {0}:0\u0027.format(output))"},{"line_number":152,"context_line":"            self.client.close()"}],"source_content_type":"text/x-python","patch_set":23,"id":"3ab451fb_4bc4713f","line":149,"updated":"2015-04-16 22:49:12.000000000","message":"My server in HPCS (Ubuntu 14.04.2 LTS) it\u0027s basically sourcing all the config in /etc/network/interfaces.d/ and there I have eth0.cfg\n\nubuntu@amphora-test:~$ cat /etc/network/interfaces.d/eth0.cfg\n# The primary network interface\nauto eth0\niface eth0 inet dhcp\n\nfor various reasons I would prefer that mechanism over appending to the interfaces file.","commit_id":"3135ef541d46f140b56b9a796694191ddfe38019"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"cf66a3e92a31d8f07cc191e68832f07d1627929e","unresolved":false,"context_lines":[{"line_number":147,"context_line":"                                                            \u0027255.255.255.0\u0027))"},{"line_number":148,"context_line":"            self.client.exec_command("},{"line_number":149,"context_line":"                \u0027sudo echo {0} \u003e\u003e /etc/network/interfaces\u0027.format(file_out))"},{"line_number":150,"context_line":"            self.client.exec_command(\u0027sudo ifup {0}\u0027.format(output))"},{"line_number":151,"context_line":"            self.client.exec_command(\u0027sudo ifup {0}:0\u0027.format(output))"},{"line_number":152,"context_line":"            self.client.close()"},{"line_number":153,"context_line":""}],"source_content_type":"text/x-python","patch_set":23,"id":"5aa745d1_299b68cb","line":150,"updated":"2015-04-15 23:57:00.000000000","message":"there is a python package (though a few years old) which does that: https://pypi.python.org/pypi/pyiface/0.0.1","commit_id":"3135ef541d46f140b56b9a796694191ddfe38019"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"ddeffd6fe9fee5dfc6d012285db9d80cbd65be52","unresolved":false,"context_lines":[{"line_number":147,"context_line":"                                                            \u0027255.255.255.0\u0027))"},{"line_number":148,"context_line":"            self.client.exec_command("},{"line_number":149,"context_line":"                \u0027sudo echo {0} \u003e\u003e /etc/network/interfaces\u0027.format(file_out))"},{"line_number":150,"context_line":"            self.client.exec_command(\u0027sudo ifup {0}\u0027.format(output))"},{"line_number":151,"context_line":"            self.client.exec_command(\u0027sudo ifup {0}:0\u0027.format(output))"},{"line_number":152,"context_line":"            self.client.close()"},{"line_number":153,"context_line":""}],"source_content_type":"text/x-python","patch_set":23,"id":"3ab451fb_3cc4d13e","line":150,"in_reply_to":"5aa745d1_299b68cb","updated":"2015-04-16 19:59:07.000000000","message":"I realize now that this one is silly -- so please diregard","commit_id":"3135ef541d46f140b56b9a796694191ddfe38019"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"f1a90c7ac732c86df37a2194ce3a75324a95af2f","unresolved":false,"context_lines":[{"line_number":131,"context_line":"            # Connect to amphora"},{"line_number":132,"context_line":"            self.client.connect(hostname\u003damp.lb_network_ip,"},{"line_number":133,"context_line":"                                username\u003dself.amp_config.username,"},{"line_number":134,"context_line":"                                key_filename\u003dself.amp_config.key_name)"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"            _, stdout, _ \u003d self.client.exec_command("},{"line_number":137,"context_line":"                \"ip link | grep DOWN -m 1 | awk \u0027{print $2}\u0027\")"}],"source_content_type":"text/x-python","patch_set":25,"id":"bab921fb_b490d996","line":134,"updated":"2015-04-23 15:02:37.000000000","message":"testing this out in a \"live\" environment, we\u0027ll probably want to wrap this around a try except block and retry a few times because it takes a while to get an ssh connection accepted directly after an instance boots.  I would just make a _connect private method and everytime you connect call that method.","commit_id":"7d4939c464a3160bbcb5fbaa44748c5de40c832f"},{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"9e0e34816da1a3ccb14bb960389d00247e60972c","unresolved":false,"context_lines":[{"line_number":131,"context_line":"            # Connect to amphora"},{"line_number":132,"context_line":"            self.client.connect(hostname\u003damp.lb_network_ip,"},{"line_number":133,"context_line":"                                username\u003dself.amp_config.username,"},{"line_number":134,"context_line":"                                key_filename\u003dself.amp_config.key_name)"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"            _, stdout, _ \u003d self.client.exec_command("},{"line_number":137,"context_line":"                \"ip link | grep DOWN -m 1 | awk \u0027{print $2}\u0027\")"}],"source_content_type":"text/x-python","patch_set":25,"id":"bab921fb_ef92fe56","line":134,"in_reply_to":"bab921fb_b490d996","updated":"2015-04-23 15:26:21.000000000","message":"We can also leave the retry logic to the deploy worker. We already have precedence when the worker waits for nova --","commit_id":"7d4939c464a3160bbcb5fbaa44748c5de40c832f"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"f1a90c7ac732c86df37a2194ce3a75324a95af2f","unresolved":false,"context_lines":[{"line_number":136,"context_line":"            _, stdout, _ \u003d self.client.exec_command("},{"line_number":137,"context_line":"                \"ip link | grep DOWN -m 1 | awk \u0027{print $2}\u0027\")"},{"line_number":138,"context_line":"            output \u003d stdout.read()[:-2]"},{"line_number":139,"context_line":"            vip \u003d load_balancer.vip"},{"line_number":140,"context_line":"            sections \u003d vip.split(\u0027.\u0027)[:3]"},{"line_number":141,"context_line":"            sections.append(\u0027255\u0027)"},{"line_number":142,"context_line":"            broadcast \u003d \u0027.\u0027.join(sections)"}],"source_content_type":"text/x-python","patch_set":25,"id":"bab921fb_64ef48b1","line":139,"updated":"2015-04-23 15:02:37.000000000","message":"should be vip \u003d load_balancer.vip.ip_address","commit_id":"7d4939c464a3160bbcb5fbaa44748c5de40c832f"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"327752688dcd4cbcfee79953043ef55a75380fb9","unresolved":false,"context_lines":[{"line_number":130,"context_line":"        LOG.debug(\"Add vip to interface for all amphora on %s\","},{"line_number":131,"context_line":"                  load_balancer.id)"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"        for amp in load_balancer.amphorae:"},{"line_number":134,"context_line":"            # Connect to amphora"},{"line_number":135,"context_line":"            attempts \u003d 1"},{"line_number":136,"context_line":"            while attempts is not 10:"}],"source_content_type":"text/x-python","patch_set":26,"id":"bab921fb_c2734814","line":133,"updated":"2015-04-24 16:09:29.000000000","message":"put retry logic in the _connect method","commit_id":"7d28a3e47d6a04625a00d13871dac041423a6320"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"327752688dcd4cbcfee79953043ef55a75380fb9","unresolved":false,"context_lines":[{"line_number":133,"context_line":"        for amp in load_balancer.amphorae:"},{"line_number":134,"context_line":"            # Connect to amphora"},{"line_number":135,"context_line":"            attempts \u003d 1"},{"line_number":136,"context_line":"            while attempts is not 10:"},{"line_number":137,"context_line":"                try:"},{"line_number":138,"context_line":"                    self._connect(hostname\u003damp.lb_network_ip)"},{"line_number":139,"context_line":"                except socket.error:"}],"source_content_type":"text/x-python","patch_set":26,"id":"bab921fb_a2ef3486","line":136,"updated":"2015-04-24 16:09:29.000000000","message":"for attempt in range(cfg.CONF.haproxy_amphora.connection_max_retries)\n\nwill have to make the connection_max_retries config option.","commit_id":"7d28a3e47d6a04625a00d13871dac041423a6320"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"327752688dcd4cbcfee79953043ef55a75380fb9","unresolved":false,"context_lines":[{"line_number":169,"context_line":"        self.client.exec_command(command)"},{"line_number":170,"context_line":"        self.client.close()"},{"line_number":171,"context_line":""},{"line_number":172,"context_line":"    def _connect(self, hostname):"},{"line_number":173,"context_line":"        self.client.connect(hostname\u003dhostname,"},{"line_number":174,"context_line":"                            username\u003dself.amp_config.username,"},{"line_number":175,"context_line":"                            key_filename\u003dself.amp_config.key_name)"}],"source_content_type":"text/x-python","patch_set":26,"id":"bab921fb_821670a5","line":172,"updated":"2015-04-24 16:09:29.000000000","message":"do the retry logic in here","commit_id":"7d28a3e47d6a04625a00d13871dac041423a6320"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"8d831a4a862f2d34a53e10cbc00e04167088e640","unresolved":false,"context_lines":[{"line_number":162,"context_line":""},{"line_number":163,"context_line":"    def _connect(self, hostname):"},{"line_number":164,"context_line":"        attempts \u003d 1"},{"line_number":165,"context_line":"        while attempts is not self.amp_config.connection_max_retries:"},{"line_number":166,"context_line":"            try:"},{"line_number":167,"context_line":"                self.client.connect(hostname\u003dhostname,"},{"line_number":168,"context_line":"                                    username\u003dself.amp_config.username,"}],"source_content_type":"text/x-python","patch_set":27,"id":"bab921fb_5c0cadec","line":165,"updated":"2015-04-24 23:03:31.000000000","message":"for attempts in range(self.amp_config.connection_max_retries)","commit_id":"8705e2577da763f42f3682b36c86159b54df6f2c"},{"author":{"_account_id":10273,"name":"Adam Harwell","email":"flux.adam@gmail.com","username":"rm_you"},"change_message_id":"4fc01ea0b7bb583c5f6aa90528019948734fbfd6","unresolved":false,"context_lines":[{"line_number":162,"context_line":""},{"line_number":163,"context_line":"    def _connect(self, hostname):"},{"line_number":164,"context_line":"        attempts \u003d 1"},{"line_number":165,"context_line":"        while attempts is not self.amp_config.connection_max_retries:"},{"line_number":166,"context_line":"            try:"},{"line_number":167,"context_line":"                self.client.connect(hostname\u003dhostname,"},{"line_number":168,"context_line":"                                    username\u003dself.amp_config.username,"}],"source_content_type":"text/x-python","patch_set":27,"id":"bab921fb_4fa3ce00","line":165,"in_reply_to":"bab921fb_5c0cadec","updated":"2015-04-25 00:22:51.000000000","message":"Use xrange, for great justice (and efficiency)! :P\n\n... Though it doesn\u0027t matter a whole lot here, it\u0027s generally good practice. For polyglot, use xrange from six, because in PY3 xrange is renamed to range and the old range is gone, IIRC.","commit_id":"8705e2577da763f42f3682b36c86159b54df6f2c"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"8d831a4a862f2d34a53e10cbc00e04167088e640","unresolved":false,"context_lines":[{"line_number":168,"context_line":"                                    username\u003dself.amp_config.username,"},{"line_number":169,"context_line":"                                    key_filename\u003dself.amp_config.key_name)"},{"line_number":170,"context_line":"            except socket.error:"},{"line_number":171,"context_line":"                LOG.warn(_LW(\"Could not ssh to instance\"))"},{"line_number":172,"context_line":"                time.sleep(self.amp_config.connection_retry_interval)"},{"line_number":173,"context_line":"                attempts +\u003d 1"},{"line_number":174,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":27,"id":"bab921fb_bcef49e8","line":171,"updated":"2015-04-24 23:03:31.000000000","message":"need to throw an exception if attempts \u003e\u003d self.amp_config.connection_max_retries so the controller can know this amphora is no good","commit_id":"8705e2577da763f42f3682b36c86159b54df6f2c"},{"author":{"_account_id":6951,"name":"Brandon Logan","email":"brandon.logan@rackspace.com","username":"brandon-logan"},"change_message_id":"8d831a4a862f2d34a53e10cbc00e04167088e640","unresolved":false,"context_lines":[{"line_number":172,"context_line":"                time.sleep(self.amp_config.connection_retry_interval)"},{"line_number":173,"context_line":"                attempts +\u003d 1"},{"line_number":174,"context_line":"            else:"},{"line_number":175,"context_line":"                attempts \u003d self.amp_config.connection_max_retries"},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"    def _process_tls_certificates(self, listener):"},{"line_number":178,"context_line":"        \"\"\"Processes TLS data from the listener."}],"source_content_type":"text/x-python","patch_set":27,"id":"bab921fb_7ca3f1b2","line":175,"updated":"2015-04-24 23:03:31.000000000","message":"just return or break here","commit_id":"8705e2577da763f42f3682b36c86159b54df6f2c"}],"octavia/common/config.py":[{"author":{"_account_id":11302,"name":"Phillip Toohill","email":"phillip.toohill@rackspace.com","username":"ptoohill1"},"change_message_id":"9befc9caba9afc81b4fe3da63e0f8e4fad60054b","unresolved":false,"context_lines":[{"line_number":90,"context_line":"    cfg.StrOpt(\u0027base_cert_dir\u0027, help\u003d_(\u0027Base directory for cert storage.\u0027)),"},{"line_number":91,"context_line":"    cfg.StrOpt(\u0027haproxy_template\u0027, help\u003d_(\u0027Custom haproxy template.\u0027)),"},{"line_number":92,"context_line":"    cfg.StrOpt(\u0027connection_max_retries\u0027, help\u003d_(\u0027Retry threshold for \u0027"},{"line_number":93,"context_line":"                                                \u0027connecting to amphorae.\u0027)),"},{"line_number":94,"context_line":"    cfg.StrOpt(\u0027connection_retry_interval\u0027, help\u003d_(\u0027Retry timeout between \u0027"},{"line_number":95,"context_line":"                                                   \u0027attempts.\u0027))"},{"line_number":96,"context_line":"]"}],"source_content_type":"text/x-python","patch_set":28,"id":"5ad0253b_1deea522","line":93,"updated":"2015-04-29 02:02:20.000000000","message":"This needs to be an IntOpt","commit_id":"60796e65d471225c11a4f51515ccf898d9899942"},{"author":{"_account_id":11628,"name":"Michael Johnson","email":"johnsomor@gmail.com","username":"johnsom"},"change_message_id":"742ccd070a751f13207433ba9685a6cfaa549e3d","unresolved":false,"context_lines":[{"line_number":90,"context_line":"    cfg.StrOpt(\u0027base_cert_dir\u0027, help\u003d_(\u0027Base directory for cert storage.\u0027)),"},{"line_number":91,"context_line":"    cfg.StrOpt(\u0027haproxy_template\u0027, help\u003d_(\u0027Custom haproxy template.\u0027)),"},{"line_number":92,"context_line":"    cfg.StrOpt(\u0027connection_max_retries\u0027, help\u003d_(\u0027Retry threshold for \u0027"},{"line_number":93,"context_line":"                                                \u0027connecting to amphorae.\u0027)),"},{"line_number":94,"context_line":"    cfg.StrOpt(\u0027connection_retry_interval\u0027, help\u003d_(\u0027Retry timeout between \u0027"},{"line_number":95,"context_line":"                                                   \u0027attempts.\u0027))"},{"line_number":96,"context_line":"]"}],"source_content_type":"text/x-python","patch_set":28,"id":"3acd31a7_db8284c8","line":93,"in_reply_to":"5ad0253b_1deea522","updated":"2015-04-29 16:27:45.000000000","message":"+1 excepts as StrOpt","commit_id":"60796e65d471225c11a4f51515ccf898d9899942"},{"author":{"_account_id":11302,"name":"Phillip Toohill","email":"phillip.toohill@rackspace.com","username":"ptoohill1"},"change_message_id":"9befc9caba9afc81b4fe3da63e0f8e4fad60054b","unresolved":false,"context_lines":[{"line_number":92,"context_line":"    cfg.StrOpt(\u0027connection_max_retries\u0027, help\u003d_(\u0027Retry threshold for \u0027"},{"line_number":93,"context_line":"                                                \u0027connecting to amphorae.\u0027)),"},{"line_number":94,"context_line":"    cfg.StrOpt(\u0027connection_retry_interval\u0027, help\u003d_(\u0027Retry timeout between \u0027"},{"line_number":95,"context_line":"                                                   \u0027attempts.\u0027))"},{"line_number":96,"context_line":"]"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"core_cli_opts \u003d []"}],"source_content_type":"text/x-python","patch_set":28,"id":"5ad0253b_fdf2c905","line":95,"updated":"2015-04-29 02:02:20.000000000","message":"This needs to be a FloatOpt","commit_id":"60796e65d471225c11a4f51515ccf898d9899942"}],"octavia/tests/unit/amphorae/drivers/haproxy/test_ssh_driver.py":[{"author":{"_account_id":10850,"name":"German Eichberger","email":"german.eichberger@gmail.com","username":"german"},"change_message_id":"6263886a7fce109b84de571cea1d484701f78524","unresolved":false,"context_lines":[{"line_number":74,"context_line":"                    listener.sni_containers)"},{"line_number":75,"context_line":"                self.driver.client.connect("},{"line_number":76,"context_line":"                    mock.ANY, mock.ANY).assert_called_once()"},{"line_number":77,"context_line":"                self.driver.client.open_sftp().assert_called_once()"},{"line_number":78,"context_line":"                self.driver.client.open_sftp().put().assert_called_once()"},{"line_number":79,"context_line":"                self.driver.client.exec_command(mock.ANY).assert_called_once()"},{"line_number":80,"context_line":"                self.driver.client.close().assert_called_once()"}],"source_content_type":"text/x-python","patch_set":11,"id":"1a6ced46_42aae585","line":77,"updated":"2015-03-25 21:21:47.000000000","message":"we should also check the values it got called with","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"5bdbd93f853772dda9f232c13ef7dcbc2b47575a","unresolved":false,"context_lines":[{"line_number":74,"context_line":"                    listener.sni_containers)"},{"line_number":75,"context_line":"                self.driver.client.connect("},{"line_number":76,"context_line":"                    mock.ANY, mock.ANY).assert_called_once()"},{"line_number":77,"context_line":"                self.driver.client.open_sftp().assert_called_once()"},{"line_number":78,"context_line":"                self.driver.client.open_sftp().put().assert_called_once()"},{"line_number":79,"context_line":"                self.driver.client.exec_command(mock.ANY).assert_called_once()"},{"line_number":80,"context_line":"                self.driver.client.close().assert_called_once()"}],"source_content_type":"text/x-python","patch_set":11,"id":"da9b358b_55e8637c","line":77,"in_reply_to":"1a6ced46_42aae585","updated":"2015-03-30 19:42:49.000000000","message":"open_sftp() isn\u0027t called with any values, its called after SSH client is connected.  Checking what values are used for the initial SSH connection might be okay, but I feel like I couldn\u0027t get those exactly figured out.  I\u0027ll look into it though.","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"}],"requirements.txt":[{"author":{"_account_id":7398,"name":"Carlos Garza","email":"carlos.garza@rackspace.com","username":"crc32"},"change_message_id":"1d1cdfaadcec5e5109996f266a23a3d7ee1ef472","unresolved":false,"context_lines":[{"line_number":32,"context_line":"pyasn1"},{"line_number":33,"context_line":"pyasn1_modules"},{"line_number":34,"context_line":"jinja2"},{"line_number":35,"context_line":"paramiko"}],"source_content_type":"text/plain","patch_set":11,"id":"1a6ced46_e4eda1b8","line":35,"updated":"2015-03-25 20:35:37.000000000","message":"consider replacing with\nparamiko\u003e\u003d1.13.0\n\nto conform to openstack/requirments/global-requirements as this project aspires to be in openstack.","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"},{"author":{"_account_id":10806,"name":"Trevor Vardeman","email":"tvardema@redhat.com","username":"tvardeman"},"change_message_id":"5bdbd93f853772dda9f232c13ef7dcbc2b47575a","unresolved":false,"context_lines":[{"line_number":32,"context_line":"pyasn1"},{"line_number":33,"context_line":"pyasn1_modules"},{"line_number":34,"context_line":"jinja2"},{"line_number":35,"context_line":"paramiko"}],"source_content_type":"text/plain","patch_set":11,"id":"da9b358b_9005d9c3","line":35,"in_reply_to":"1a6ced46_e4eda1b8","updated":"2015-03-30 19:42:49.000000000","message":"Good call, didn\u0027t know this req.  Thanks.","commit_id":"667f1d1e2a8f1436fad320a6311441ddb128f86d"}]}
