)]}'
{"contrib/rackspace/heat/engine/plugins/cloud_loadbalancer.py":[{"author":{"_account_id":7230,"name":"Vijendar Komalla","email":"vijendar.komalla@rackspace.com","username":"vijendar"},"change_message_id":"9366f4bd8119bf7606107d6aa8f6e4c30287cc82","unresolved":false,"context_lines":[{"line_number":169,"context_line":"                schema\u003d{"},{"line_number":170,"context_line":"                    NODE_ADDRESSES: properties.Schema("},{"line_number":171,"context_line":"                        properties.Schema.LIST,"},{"line_number":172,"context_line":"                        default\u003d[\u0027192.0.2.1\u0027],"},{"line_number":173,"context_line":"                        required\u003dTrue,"},{"line_number":174,"context_line":"                        constraints\u003d["},{"line_number":175,"context_line":"                            constraints.Length(min\u003d1)"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAUH%2F%2BoMo%3D","line":172,"updated":"2014-01-23 19:01:48.000000000","message":"Since it is required property, do you need default value here?\nI think it is not required.","commit_id":"ad9290685351ffcef0c8f672bdc656b97c644d54"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"a447d5aead4152ec6c2e350e18234019505cb8b4","unresolved":false,"context_lines":[{"line_number":169,"context_line":"                schema\u003d{"},{"line_number":170,"context_line":"                    NODE_ADDRESSES: properties.Schema("},{"line_number":171,"context_line":"                        properties.Schema.LIST,"},{"line_number":172,"context_line":"                        default\u003d[\u0027192.0.2.1\u0027],"},{"line_number":173,"context_line":"                        required\u003dTrue,"},{"line_number":174,"context_line":"                        constraints\u003d["},{"line_number":175,"context_line":"                            constraints.Length(min\u003d1)"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAUH%2F%2BoGw%3D","line":172,"in_reply_to":"AAAAUH%2F%2BoMo%3D","updated":"2014-01-23 19:06:03.000000000","message":"Yes, because it needs a value at stack-create time so that validate doesn\u0027t fail when its value is the attribute of another resource that hasn\u0027t been created yet.","commit_id":"ad9290685351ffcef0c8f672bdc656b97c644d54"},{"author":{"_account_id":7230,"name":"Vijendar Komalla","email":"vijendar.komalla@rackspace.com","username":"vijendar"},"change_message_id":"9366f4bd8119bf7606107d6aa8f6e4c30287cc82","unresolved":false,"context_lines":[{"line_number":456,"context_line":"    def _process_nodes(self, node_list):"},{"line_number":457,"context_line":"        ret \u003d []"},{"line_number":458,"context_line":"        for node in node_list:"},{"line_number":459,"context_line":"            ret.extend(self._process_node(node))"},{"line_number":460,"context_line":"        return ret"},{"line_number":461,"context_line":""},{"line_number":462,"context_line":"    def handle_create(self):"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAUH%2F%2BoKA%3D","line":459,"updated":"2014-01-23 19:01:48.000000000","message":"do you need extend here? It seems _process_node is not returning a list!","commit_id":"ad9290685351ffcef0c8f672bdc656b97c644d54"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"a447d5aead4152ec6c2e350e18234019505cb8b4","unresolved":false,"context_lines":[{"line_number":456,"context_line":"    def _process_nodes(self, node_list):"},{"line_number":457,"context_line":"        ret \u003d []"},{"line_number":458,"context_line":"        for node in node_list:"},{"line_number":459,"context_line":"            ret.extend(self._process_node(node))"},{"line_number":460,"context_line":"        return ret"},{"line_number":461,"context_line":""},{"line_number":462,"context_line":"    def handle_create(self):"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAUH%2F%2BoF4%3D","line":459,"in_reply_to":"AAAAUH%2F%2BoKA%3D","updated":"2014-01-23 19:06:03.000000000","message":"yup because _process_node is a generator.","commit_id":"ad9290685351ffcef0c8f672bdc656b97c644d54"}],"contrib/rackspace/heat/tests/test_cloud_loadbalancer.py":[{"author":{"_account_id":6577,"name":"Sergey Kraynev","email":"sergejyit@gmail.com","username":"skraynev"},"change_message_id":"6f25d1a8295c0addf86205dbd6750cca9c21edcf","unresolved":false,"context_lines":[{"line_number":515,"context_line":""},{"line_number":516,"context_line":"        self.m.StubOutWithMock(rsrc.stack, \u0027resource_by_refid\u0027)"},{"line_number":517,"context_line":""},{"line_number":518,"context_line":"        class FakeFn(object):"},{"line_number":519,"context_line":"            def FnGetAtt(self, attr):"},{"line_number":520,"context_line":"                return expected_ip"},{"line_number":521,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAUH%2F9pK4%3D","line":518,"updated":"2014-02-05 12:04:03.000000000","message":"I think, that this class should be deleted as unused now.","commit_id":"777d68cca1ea8bcae6531340fa5245a95dcc4492"}],"contrib/rackspace/rackspace/resources/cloud_loadbalancer.py":[{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"605a524adc8fde3aefab602a48bd3238ef4181ba","unresolved":false,"context_lines":[{"line_number":164,"context_line":"                properties.Schema.MAP,"},{"line_number":165,"context_line":"                schema\u003d{"},{"line_number":166,"context_line":"                    NODE_ADDRESSES: properties.Schema("},{"line_number":167,"context_line":"                        properties.Schema.LIST,"},{"line_number":168,"context_line":"                        default\u003d[\u0027192.0.2.1\u0027],"},{"line_number":169,"context_line":"                        required\u003dTrue,"},{"line_number":170,"context_line":"                        constraints\u003d["}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAVn%2F%2FqPU%3D","line":167,"updated":"2014-03-05 19:59:02.000000000","message":"This list should have a schema to define it as a list of strings.","commit_id":"983a25499e08cc5143b7c9205750208f1fda10a8"},{"author":{"_account_id":7395,"name":"Andrew Plunk","email":"andrew.plunk@rackspace.com","username":"aplunk"},"change_message_id":"5083576fd063e054c90a99348cde51e77d4d94ed","unresolved":false,"context_lines":[{"line_number":165,"context_line":"                schema\u003d{"},{"line_number":166,"context_line":"                    NODE_ADDRESSES: properties.Schema("},{"line_number":167,"context_line":"                        properties.Schema.LIST,"},{"line_number":168,"context_line":"                        default\u003d[\u0027192.0.2.1\u0027],"},{"line_number":169,"context_line":"                        required\u003dTrue,"},{"line_number":170,"context_line":"                        constraints\u003d["},{"line_number":171,"context_line":"                            constraints.Length(min\u003d1)"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAVn%2F%2F1nI%3D","line":168,"updated":"2014-03-03 21:24:09.000000000","message":"I think this should default to an empty list.","commit_id":"983a25499e08cc5143b7c9205750208f1fda10a8"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"03eb363478d84c91e005b106e09c65b7cbb30913","unresolved":false,"context_lines":[{"line_number":165,"context_line":"                schema\u003d{"},{"line_number":166,"context_line":"                    NODE_ADDRESSES: properties.Schema("},{"line_number":167,"context_line":"                        properties.Schema.LIST,"},{"line_number":168,"context_line":"                        default\u003d[\u0027192.0.2.1\u0027],"},{"line_number":169,"context_line":"                        required\u003dTrue,"},{"line_number":170,"context_line":"                        constraints\u003d["},{"line_number":171,"context_line":"                            constraints.Length(min\u003d1)"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAVn%2F%2Fz%2FM%3D","line":168,"in_reply_to":"AAAAVn%2F%2F1nI%3D","updated":"2014-03-04 03:22:46.000000000","message":"Nope. It has to have at least one item in the list per the constraint.","commit_id":"983a25499e08cc5143b7c9205750208f1fda10a8"},{"author":{"_account_id":7395,"name":"Andrew Plunk","email":"andrew.plunk@rackspace.com","username":"aplunk"},"change_message_id":"5083576fd063e054c90a99348cde51e77d4d94ed","unresolved":false,"context_lines":[{"line_number":449,"context_line":"                del norm_node[self.NODE_ADDRESSES]"},{"line_number":450,"context_line":"                yield norm_node"},{"line_number":451,"context_line":""},{"line_number":452,"context_line":"    def _process_nodes(self, node_list):"},{"line_number":453,"context_line":"        ret \u003d []"},{"line_number":454,"context_line":"        for node in node_list:"},{"line_number":455,"context_line":"            ret.extend(self._process_node(node))"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAVn%2F%2F1ig%3D","line":452,"updated":"2014-03-03 21:24:09.000000000","message":"Is there a reason why this function does not return a generator like the above _process_node?","commit_id":"983a25499e08cc5143b7c9205750208f1fda10a8"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"03eb363478d84c91e005b106e09c65b7cbb30913","unresolved":false,"context_lines":[{"line_number":449,"context_line":"                del norm_node[self.NODE_ADDRESSES]"},{"line_number":450,"context_line":"                yield norm_node"},{"line_number":451,"context_line":""},{"line_number":452,"context_line":"    def _process_nodes(self, node_list):"},{"line_number":453,"context_line":"        ret \u003d []"},{"line_number":454,"context_line":"        for node in node_list:"},{"line_number":455,"context_line":"            ret.extend(self._process_node(node))"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAVn%2F%2Fz%2B8%3D","line":452,"in_reply_to":"AAAAVn%2F%2F1ig%3D","updated":"2014-03-04 03:22:46.000000000","message":"Because the caller wants a list to pass to the service or an empty list and the syntax on line 459 would be atrocious otherwise.","commit_id":"983a25499e08cc5143b7c9205750208f1fda10a8"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"605a524adc8fde3aefab602a48bd3238ef4181ba","unresolved":false,"context_lines":[{"line_number":449,"context_line":"                del norm_node[self.NODE_ADDRESSES]"},{"line_number":450,"context_line":"                yield norm_node"},{"line_number":451,"context_line":""},{"line_number":452,"context_line":"    def _process_nodes(self, node_list):"},{"line_number":453,"context_line":"        ret \u003d []"},{"line_number":454,"context_line":"        for node in node_list:"},{"line_number":455,"context_line":"            ret.extend(self._process_node(node))"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAVn%2F%2FqSg%3D","line":452,"in_reply_to":"AAAAVn%2F%2Fz%2B8%3D","updated":"2014-03-05 19:59:02.000000000","message":"Huh? The result is only iterated over (on lines 460 \u0026 513) and never used as a list, so there would be no syntax changes.\n\nBTW this function could be rewritten as:\n\n  return itertools.chain.from_iterator(itertools.imap(self._process_node, node_list))","commit_id":"983a25499e08cc5143b7c9205750208f1fda10a8"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"605a524adc8fde3aefab602a48bd3238ef4181ba","unresolved":false,"context_lines":[{"line_number":456,"context_line":"        return ret"},{"line_number":457,"context_line":""},{"line_number":458,"context_line":"    def handle_create(self):"},{"line_number":459,"context_line":"        node_list \u003d self._process_nodes(self.properties.get(self.NODES, []))"},{"line_number":460,"context_line":"        nodes \u003d [self.clb.Node(**node) for node in node_list]"},{"line_number":461,"context_line":"        vips \u003d self.properties.get(self.VIRTUAL_IPS)"},{"line_number":462,"context_line":"        virtual_ips \u003d self._setup_properties(vips, self.clb.VirtualIP)"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAVn%2F%2FqQE%3D","line":459,"updated":"2014-03-05 19:59:02.000000000","message":"If you want an empty list to be the default, you need to set it as the default in the schema. get() will return None here.","commit_id":"983a25499e08cc5143b7c9205750208f1fda10a8"},{"author":{"_account_id":7395,"name":"Andrew Plunk","email":"andrew.plunk@rackspace.com","username":"aplunk"},"change_message_id":"c7a8dd39fe0d7921e4a497c9789bad88ce790460","unresolved":false,"context_lines":[{"line_number":166,"context_line":"                    NODE_ADDRESSES: properties.Schema("},{"line_number":167,"context_line":"                        properties.Schema.LIST,"},{"line_number":168,"context_line":"                        default\u003d[\u0027192.0.2.1\u0027],"},{"line_number":169,"context_line":"                        required\u003dTrue,"},{"line_number":170,"context_line":"                        constraints\u003d["},{"line_number":171,"context_line":"                            constraints.Length(min\u003d1)"},{"line_number":172,"context_line":"                        ]"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAVn%2F%2FfEQ%3D","line":169,"updated":"2014-03-05 20:09:13.000000000","message":"This constraint does not appear to be valid for cloud loadbalancers anymore. A clb can be created with no nodes, so NODE_ADDRESSES should default to an empty list and the constraint below should be removed. I just tested this with the default to an empty list and the constraint removed and the clb creates correctly.","commit_id":"7e3c91c4690f834644cf9836679753628e3baafa"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"6aba9ac32d042fe6292407c1bcd543786dbdcee5","unresolved":false,"context_lines":[{"line_number":165,"context_line":"                schema\u003d{"},{"line_number":166,"context_line":"                    NODE_ADDRESSES: properties.Schema("},{"line_number":167,"context_line":"                        properties.Schema.LIST,"},{"line_number":168,"context_line":"                        required\u003dTrue,"},{"line_number":169,"context_line":"                        default\u003d[],"},{"line_number":170,"context_line":"                        description\u003d(\"IP addresses for the load balancer \""},{"line_number":171,"context_line":"                                     \"node. Must have at least one \""}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAVn%2F%2B2ZQ%3D","line":168,"updated":"2014-03-11 18:44:04.000000000","message":"(Done)\nI can remove the required.","commit_id":"45b8c6baccebc785f6d8642c7a39c712af515bdf"},{"author":{"_account_id":6577,"name":"Sergey Kraynev","email":"sergejyit@gmail.com","username":"skraynev"},"change_message_id":"3dab12c448a045404df3b7b9e4a3fda5e3d36b69","unresolved":false,"context_lines":[{"line_number":446,"context_line":"        if not node.get(self.NODE_ADDRESSES):"},{"line_number":447,"context_line":"            yield node"},{"line_number":448,"context_line":"        else:"},{"line_number":449,"context_line":"            for addr in node.get(self.NODE_ADDRESSES, []):"},{"line_number":450,"context_line":"                norm_node \u003d copy.deepcopy(node)"},{"line_number":451,"context_line":"                norm_node[\u0027address\u0027] \u003d addr"},{"line_number":452,"context_line":"                del norm_node[self.NODE_ADDRESSES]"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAVn%2F%2B6rQ%3D","line":449,"updated":"2014-03-11 10:10:25.000000000","message":"I think, that it\u0027s redundant code, because we have three place with similar aims: \n\n\n1. NODE_ADDRESSES has option required, so it means, that node address option will be necessarily provided in template\n\n\n2.  NODE_ADDRESSES has default value equal [], which will be never used because of required\u003dTrue\n\n\n3. In line 449 you call get with default value []. It will give same result with variant #2.","commit_id":"45b8c6baccebc785f6d8642c7a39c712af515bdf"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"6aba9ac32d042fe6292407c1bcd543786dbdcee5","unresolved":false,"context_lines":[{"line_number":446,"context_line":"        if not node.get(self.NODE_ADDRESSES):"},{"line_number":447,"context_line":"            yield node"},{"line_number":448,"context_line":"        else:"},{"line_number":449,"context_line":"            for addr in node.get(self.NODE_ADDRESSES, []):"},{"line_number":450,"context_line":"                norm_node \u003d copy.deepcopy(node)"},{"line_number":451,"context_line":"                norm_node[\u0027address\u0027] \u003d addr"},{"line_number":452,"context_line":"                del norm_node[self.NODE_ADDRESSES]"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAVn%2F%2B3Lc%3D","line":449,"in_reply_to":"AAAAVn%2F%2B6rQ%3D","updated":"2014-03-11 18:44:04.000000000","message":"(Done)\nI can remove the [] here since it will be the default value, but the default value *will* be used in cases where the template is initially validated at create time and the user has used get_attr to specify the value of the addresses property.","commit_id":"45b8c6baccebc785f6d8642c7a39c712af515bdf"},{"author":{"_account_id":7230,"name":"Vijendar Komalla","email":"vijendar.komalla@rackspace.com","username":"vijendar"},"change_message_id":"4babe5cf809142de08439041ebdcc30a8a17f4ab","unresolved":false,"context_lines":[{"line_number":166,"context_line":"                    NODE_ADDRESSES: properties.Schema("},{"line_number":167,"context_line":"                        properties.Schema.LIST,"},{"line_number":168,"context_line":"                        required\u003dTrue,"},{"line_number":169,"context_line":"                        description\u003d(\"IP addresses for the load balancer \""},{"line_number":170,"context_line":"                                     \"node. Must have at least one \""},{"line_number":171,"context_line":"                                     \"address.\"),"},{"line_number":172,"context_line":"                        schema\u003dproperties.Schema("}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAAWH%2F%2F004%3D","line":169,"updated":"2014-03-13 15:16:20.000000000","message":"nit. Include string in _(\u0027\u0027) for localization.","commit_id":"ae69e7ce21cc847835ba59b2cbe8c716261b049f"},{"author":{"_account_id":10048,"name":"Ying Li","email":"ying.li@rackspace.com","username":"cyli"},"change_message_id":"436c8c461e643f56183271e1c893c0a15db2a300","unresolved":false,"context_lines":[{"line_number":167,"context_line":"                        properties.Schema.LIST,"},{"line_number":168,"context_line":"                        required\u003dTrue,"},{"line_number":169,"context_line":"                        description\u003d(_(\"IP addresses for the load balancer \""},{"line_number":170,"context_line":"                                     \"node. Must have at least one \""},{"line_number":171,"context_line":"                                     \"address.\")),"},{"line_number":172,"context_line":"                        schema\u003dproperties.Schema("},{"line_number":173,"context_line":"                            properties.Schema.STRING"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAWH%2F%2Fx%2FQ%3D","line":170,"updated":"2014-03-13 21:36:07.000000000","message":"The description says that there must be at least one address - should a constraints.Length(min\u003d1) be added as a constraint  (along with a test for the empty address list case), then?\n\nAlternately, if that is not a requirement, should the description be modified?","commit_id":"9509ce0960b573aa0e0fb134b4aecb4f3b512573"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"40ceb2ba75c6a54ecec36129325711f2828f6aa3","unresolved":false,"context_lines":[{"line_number":167,"context_line":"                        properties.Schema.LIST,"},{"line_number":168,"context_line":"                        required\u003dTrue,"},{"line_number":169,"context_line":"                        description\u003d(_(\"IP addresses for the load balancer \""},{"line_number":170,"context_line":"                                     \"node. Must have at least one \""},{"line_number":171,"context_line":"                                     \"address.\")),"},{"line_number":172,"context_line":"                        schema\u003dproperties.Schema("},{"line_number":173,"context_line":"                            properties.Schema.STRING"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAWH%2F%2FxqY%3D","line":170,"in_reply_to":"AAAAWH%2F%2Fx%2FQ%3D","updated":"2014-03-13 21:43:50.000000000","message":"This was the original code. It causes issues when you set the value of this property to the attribute of another resource (like a resource group), so it has to be un-constrained here and have the clb service validate the node at create time. Not ideal, but it works.","commit_id":"9509ce0960b573aa0e0fb134b4aecb4f3b512573"}],"contrib/rackspace/rackspace/tests/test_cloud_loadbalancer.py":[{"author":{"_account_id":6577,"name":"Sergey Kraynev","email":"sergejyit@gmail.com","username":"skraynev"},"change_message_id":"3dab12c448a045404df3b7b9e4a3fda5e3d36b69","unresolved":false,"context_lines":[{"line_number":493,"context_line":"        scheduler.TaskRunner(rsrc.create)()"},{"line_number":494,"context_line":"        self.m.VerifyAll()"},{"line_number":495,"context_line":""},{"line_number":496,"context_line":"    def test_update_add_node(self):"},{"line_number":497,"context_line":"        expected_ip \u003d \u0027172.168.1.4\u0027"},{"line_number":498,"context_line":"        added_node \u003d {\u0027nodes\u0027: ["},{"line_number":499,"context_line":"            {\"addresses\": [\"166.78.103.141\"], \"port\": 80,"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAVn%2F%2B7Sc%3D","line":496,"updated":"2014-03-11 10:10:25.000000000","message":"Currently this test is similar on test_update_add_node_by_address.\nSo I guess, that it should be removed or changed back to using reference instead ip address.","commit_id":"45b8c6baccebc785f6d8642c7a39c712af515bdf"},{"author":{"_account_id":7256,"name":"Randall Burt","email":"randall.burt@rackspace.com","username":"randall-burt"},"change_message_id":"6aba9ac32d042fe6292407c1bcd543786dbdcee5","unresolved":false,"context_lines":[{"line_number":493,"context_line":"        scheduler.TaskRunner(rsrc.create)()"},{"line_number":494,"context_line":"        self.m.VerifyAll()"},{"line_number":495,"context_line":""},{"line_number":496,"context_line":"    def test_update_add_node(self):"},{"line_number":497,"context_line":"        expected_ip \u003d \u0027172.168.1.4\u0027"},{"line_number":498,"context_line":"        added_node \u003d {\u0027nodes\u0027: ["},{"line_number":499,"context_line":"            {\"addresses\": [\"166.78.103.141\"], \"port\": 80,"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAVn%2F%2B3J0%3D","line":496,"in_reply_to":"AAAAVn%2F%2B7Sc%3D","updated":"2014-03-11 18:44:04.000000000","message":"Ref isn\u0027t supported, so I\u0027ll remove this test. Thanks!","commit_id":"45b8c6baccebc785f6d8642c7a39c712af515bdf"}]}
