)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":2759,"name":"Huang Zhiteng","email":"winston.d@gmail.com","username":"zhiteng-huang"},"change_message_id":"2b479021c1ca8fd4f2cf74dd52e73a2c12101423","unresolved":false,"context_lines":[{"line_number":9,"context_line":"This change adds support for iSCSI CHAP with randomly generated"},{"line_number":10,"context_line":"secrets for each initiator. Due to some restrictions with storing meta"},{"line_number":11,"context_line":"data in the backend these secrets need to be stored someplace accessible"},{"line_number":12,"context_line":"from the driver. We have opted for a file on the host running the cinder"},{"line_number":13,"context_line":"service. The file is created with read/write for only the cinder user,"},{"line_number":14,"context_line":"and will contain a mapping between initiators and their configured CHAP"},{"line_number":15,"context_line":"information."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"5a890539_2d8c9bd6","line":12,"updated":"2014-11-26 09:18:33.000000000","message":"If I understand correctly, the CHAP credential for a volume is generated using connector[\u0027host\u0027] as seed(for lacking fo a better name),  and use files to store the CHAP.  My understanding is volume and it\u0027s corresponding CHAP should be one-to-one mapping, isn\u0027t it?  There are some situations I\u0027d like to understand how this proposal can work: 1) cinder-vol service being deployed in active-active manner, which means more than one c-vol services are up \u0026 running at the same time connecting to same Pure backend.  File based CHAP store means it\u0027s local to c-vol, which means c-vol running on a different host has no idea a CHAP exists for a vol.  Is that expected and does it work in this case?  Fact: other driver like solidfire store CHAP for vol into Cinder DB.\n2) what would happen if two instances on same hypervisor (i.e. their connector[\u0027host\u0027] is the same) try to connect to two different vols?","commit_id":"16c5f3ad5113719347c44c5dd16a63f885e0854a"},{"author":{"_account_id":2759,"name":"Huang Zhiteng","email":"winston.d@gmail.com","username":"zhiteng-huang"},"change_message_id":"69a927296c381096f2c6ba3236bac8adf79c7ee7","unresolved":false,"context_lines":[{"line_number":9,"context_line":"This change adds support for iSCSI CHAP with randomly generated"},{"line_number":10,"context_line":"secrets for each initiator. Due to some restrictions with storing meta"},{"line_number":11,"context_line":"data in the backend these secrets need to be stored someplace accessible"},{"line_number":12,"context_line":"from the driver. We have opted for a file on the host running the cinder"},{"line_number":13,"context_line":"service. The file is created with read/write for only the cinder user,"},{"line_number":14,"context_line":"and will contain a mapping between initiators and their configured CHAP"},{"line_number":15,"context_line":"information."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"5a890539_dfb46137","line":12,"updated":"2014-11-28 08:26:58.000000000","message":"Thanks for the detailed explanation about how Pure backend works.\n\nIf I read your code right, Pure backend is able to stores a copy the pre-initiator CHAP credentials (and it must have to be) using set_host(), why not relies on the backend (treat it as single source of truth) to sync the CHAP credentials between active-active c-vol services?  The workflow would be:\n  When attaching volume request comes, Pure Cinder driver checks if local \u0027cache\u0027 (the file) has a CHAP entry for the host, if not it queries the backend for the CHAP; if the backend has it, driver can cache that CHAP credential for future use,  otherwise generates CHAP credentials and let the back knows (persist it to backend via set_host()).\n  This workflow is able work with active-active deployment with the cost of extra communication between cinder driver and backend, but we can use file to \u0027cache\u0027 CHAP credentials.  The only missing piece is some RESTful API to retrieve host attributes in current Cinder driver.  Does it make sense?","commit_id":"16c5f3ad5113719347c44c5dd16a63f885e0854a"},{"author":{"_account_id":12924,"name":"Patrick East","email":"east.patrick@gmail.com","username":"patrick.east"},"change_message_id":"3164ea80f7b7b04704ba83c48616ff30a145d6ab","unresolved":false,"context_lines":[{"line_number":9,"context_line":"This change adds support for iSCSI CHAP with randomly generated"},{"line_number":10,"context_line":"secrets for each initiator. Due to some restrictions with storing meta"},{"line_number":11,"context_line":"data in the backend these secrets need to be stored someplace accessible"},{"line_number":12,"context_line":"from the driver. We have opted for a file on the host running the cinder"},{"line_number":13,"context_line":"service. The file is created with read/write for only the cinder user,"},{"line_number":14,"context_line":"and will contain a mapping between initiators and their configured CHAP"},{"line_number":15,"context_line":"information."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"5a890539_22dbb422","line":12,"in_reply_to":"5a890539_2d8c9bd6","updated":"2014-11-26 18:47:26.000000000","message":"In the Pure arrays we don\u0027t associate CHAP credentials directly with volumes, which doesn\u0027t really match up with how Cinder seems to be designed and is partially why this is being implemented in kind of a.. less than ideal way. For us we have an idea of a \"Host\" in Purity which is (for iSCSI) associated with one or more iqn. These host objects then can have CHAP credentials set for them to use when connecting with initiators that belong to those iqn\u0027s. We then \"attach\" volumes to a host within Purity which will expose it as a lun for that host, and in turn any initiator connected to the Array associated with that host. What this means is that we don\u0027t have the same per-volume CHAP credentials but instead have per-initiator credentials.\n\nSo, with that in mind, for the two scenarios you mentioned:\n\n1) Excellent point... I don\u0027t think we had taken that into account when choosing this option as it definitely won\u0027t work if there are two active c-vol services on different hosts for the same array. Our original implementation of this did use the database and we would keep track of credentials on the volume objects (similar to what other drivers do), but we ran into problems with that approach. The primary issue being that at any point in time where all of the volumes are deleted we won\u0027t have a way to retrive the credentials and it becomes lost. This maybe isn\u0027t so bad if we can assume that the host in Purity is only being used by Cinder and it is safe to change credentials on it, but we can\u0027t guarantee we won\u0027t interrupt some other connection by changing the host credentials. Another issue we ran into is that in Nova and Cinder there are times where the iSCSI connection is not closed down properly and can end up in an error state where it will sit there and keep attempting to reconnect. If we change the credentials it will be permanantly locked out, and the code in Nova/Cinder to connect iSCSI portals is not (currently) detecting error states like that and re-initializing. It will see it as \"connected\" and leave it alone even though in the syslog there are connection errors (and if we change the credentials, authentication errors). This may actually be an iSCSI implementation \"feature\" specific to our array when all volumes are \"disconnected\" from hosts, I\u0027m not familiar with how other ones work. Because of this we needed a way to keep a mapping of hosts with credentials. The assumption we made is that attempting to add a new table or something to the cinder db would be... difficult, we wen\u0027t the route of a file on the system.\n\nTL;DR: We were unable to get acceptable stability by storing credentials on the volume objects in the cinder database.\n\n2) They get the same credentials since we see it as the same iSCSI connection from a single initiator to a host in Purity.","commit_id":"16c5f3ad5113719347c44c5dd16a63f885e0854a"},{"author":{"_account_id":12924,"name":"Patrick East","email":"east.patrick@gmail.com","username":"patrick.east"},"change_message_id":"b84e4dd49d7b01151a422c818537c2cbcfd598b0","unresolved":false,"context_lines":[{"line_number":9,"context_line":"This change adds support for iSCSI CHAP with randomly generated"},{"line_number":10,"context_line":"secrets for each initiator. Due to some restrictions with storing meta"},{"line_number":11,"context_line":"data in the backend these secrets need to be stored someplace accessible"},{"line_number":12,"context_line":"from the driver. We have opted for a file on the host running the cinder"},{"line_number":13,"context_line":"service. The file is created with read/write for only the cinder user,"},{"line_number":14,"context_line":"and will contain a mapping between initiators and their configured CHAP"},{"line_number":15,"context_line":"information."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"5a890539_649ae7c6","line":12,"in_reply_to":"5a890539_dfb46137","updated":"2014-11-30 19:28:04.000000000","message":"Unfortunately we do not have a way to retrieve the credentials from the backend, we can only set them. This is why we needed to store the credentials somewhere else (currently in the local file). We will have to work around that limitation somehow... The cinder db seems like it would be perfect for the job, but I would prefer to avoid having to try and add anything new schema-wise.","commit_id":"16c5f3ad5113719347c44c5dd16a63f885e0854a"}],"cinder/db/sqlalchemy/models.py":[{"author":{"_account_id":2243,"name":"John Griffith","email":"john.griffith8@gmail.com","username":"john-griffith"},"change_message_id":"ab3c28cc64cd07a01c1cd823d847a497f92fc0dd","unresolved":false,"context_lines":[{"line_number":474,"context_line":"                          \u0027IscsiTarget.deleted\u003d\u003dFalse)\u0027)"},{"line_number":475,"context_line":""},{"line_number":476,"context_line":""},{"line_number":477,"context_line":"class IscsiInitiator(BASE, CinderBase):"},{"line_number":478,"context_line":"    \"\"\"Represents an iscsi initiator\"\"\""},{"line_number":479,"context_line":"    __tablename__ \u003d \u0027iscsi_initiator\u0027"},{"line_number":480,"context_line":"    id \u003d Column(Integer, primary_key\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":11,"id":"3a961159_04a49555","line":477,"updated":"2014-12-10 17:29:59.000000000","message":"I\u0027d prefer a different name, only because we don\u0027t want this to somehow be construed as an Initiator when it\u0027s just creds info.","commit_id":"47a030ecb755525ac0315178633761906d1e662e"},{"author":{"_account_id":12924,"name":"Patrick East","email":"east.patrick@gmail.com","username":"patrick.east"},"change_message_id":"8ad9e6df8b83fb8c8ef1fadf5e0305b770839ef1","unresolved":false,"context_lines":[{"line_number":474,"context_line":"                          \u0027IscsiTarget.deleted\u003d\u003dFalse)\u0027)"},{"line_number":475,"context_line":""},{"line_number":476,"context_line":""},{"line_number":477,"context_line":"class IscsiInitiator(BASE, CinderBase):"},{"line_number":478,"context_line":"    \"\"\"Represents an iscsi initiator\"\"\""},{"line_number":479,"context_line":"    __tablename__ \u003d \u0027iscsi_initiator\u0027"},{"line_number":480,"context_line":"    id \u003d Column(Integer, primary_key\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":11,"id":"3a961159_06fad5bc","line":477,"in_reply_to":"3a961159_04a49555","updated":"2014-12-10 20:12:11.000000000","message":"Done","commit_id":"47a030ecb755525ac0315178633761906d1e662e"}],"cinder/tests/test_pure.py":[{"author":{"_account_id":7198,"name":"Jay Bryant","email":"jungleboyj@electronicjungle.net","username":"jsbryant"},"change_message_id":"0c4bac9d0a269510065ed96beef31e15dabb0dbb","unresolved":false,"context_lines":[{"line_number":421,"context_line":"        result[\"data\"][\"auth_username\"] \u003d chap_username"},{"line_number":422,"context_line":"        result[\"data\"][\"auth_password\"] \u003d chap_password"},{"line_number":423,"context_line":""},{"line_number":424,"context_line":"        self.config.pure_use_chap \u003d True"},{"line_number":425,"context_line":""},{"line_number":426,"context_line":"        # Branch where no credentials were generated"},{"line_number":427,"context_line":"        real_result \u003d self.driver.initialize_connection(VOLUME,"}],"source_content_type":"text/x-python","patch_set":25,"id":"ba7be1f8_a53df92e","line":424,"updated":"2015-02-27 18:54:46.000000000","message":"Think it is better to use override_config here.","commit_id":"05acef11cddd3efe435520bd8190cc194e9f32b0"},{"author":{"_account_id":12924,"name":"Patrick East","email":"east.patrick@gmail.com","username":"patrick.east"},"change_message_id":"e27e4aa83f967622bb279b1b69449440a49fb3b7","unresolved":false,"context_lines":[{"line_number":421,"context_line":"        result[\"data\"][\"auth_username\"] \u003d chap_username"},{"line_number":422,"context_line":"        result[\"data\"][\"auth_password\"] \u003d chap_password"},{"line_number":423,"context_line":""},{"line_number":424,"context_line":"        self.config.pure_use_chap \u003d True"},{"line_number":425,"context_line":""},{"line_number":426,"context_line":"        # Branch where no credentials were generated"},{"line_number":427,"context_line":"        real_result \u003d self.driver.initialize_connection(VOLUME,"}],"source_content_type":"text/x-python","patch_set":25,"id":"ba7be1f8_c08c6d82","line":424,"in_reply_to":"ba7be1f8_a53df92e","updated":"2015-02-27 19:55:21.000000000","message":"I tried it out, and then realized that I don\u0027t think it will work since we are mocking out the config object in the driver. I\u0027ve updated the name and access the tests reference of the mock instead of directly changing the driver value so it makes it easier to see what is going on.","commit_id":"05acef11cddd3efe435520bd8190cc194e9f32b0"}],"cinder/volume/drivers/pure.py":[{"author":{"_account_id":2759,"name":"Huang Zhiteng","email":"winston.d@gmail.com","username":"zhiteng-huang"},"change_message_id":"2b479021c1ca8fd4f2cf74dd52e73a2c12101423","unresolved":false,"context_lines":[{"line_number":243,"context_line":""},{"line_number":244,"context_line":"        host \u003d connector[\"host\"]"},{"line_number":245,"context_line":"        if self.configuration.pure_use_chap:"},{"line_number":246,"context_line":"            (auth_username, auth_password) \u003d \\"},{"line_number":247,"context_line":"                self._get_chap_credentials(host)"},{"line_number":248,"context_line":""},{"line_number":249,"context_line":"        connection \u003d self._connect(volume, connector,"}],"source_content_type":"text/x-python","patch_set":2,"id":"5a890539_4dbe4766","line":246,"updated":"2014-11-26 09:18:33.000000000","message":"It seems like if there were two or more Pure volumes being attached to multiple instances on the same host (hypervisor), they would be using same CHAP credential?  Is that expected?","commit_id":"16c5f3ad5113719347c44c5dd16a63f885e0854a"},{"author":{"_account_id":12924,"name":"Patrick East","email":"east.patrick@gmail.com","username":"patrick.east"},"change_message_id":"3164ea80f7b7b04704ba83c48616ff30a145d6ab","unresolved":false,"context_lines":[{"line_number":243,"context_line":""},{"line_number":244,"context_line":"        host \u003d connector[\"host\"]"},{"line_number":245,"context_line":"        if self.configuration.pure_use_chap:"},{"line_number":246,"context_line":"            (auth_username, auth_password) \u003d \\"},{"line_number":247,"context_line":"                self._get_chap_credentials(host)"},{"line_number":248,"context_line":""},{"line_number":249,"context_line":"        connection \u003d self._connect(volume, connector,"}],"source_content_type":"text/x-python","patch_set":2,"id":"5a890539_22bad471","line":246,"in_reply_to":"5a890539_4dbe4766","updated":"2014-11-26 18:47:26.000000000","message":"Yep, that is how CHAP works for our flash array. The credentials are associated with the Purity host (which in turn is a direct mapping to a host/hypervisor) and not directly with the volumes.","commit_id":"16c5f3ad5113719347c44c5dd16a63f885e0854a"},{"author":{"_account_id":6491,"name":"xing-yang","email":"xingyang105@gmail.com","username":"xing-yang"},"change_message_id":"33590530cf6d427e5461c362f73fdd5ed03a262e","unresolved":false,"context_lines":[{"line_number":347,"context_line":"                          {\"host_name\": host_name,"},{"line_number":348,"context_line":"                           \"iqn\": connector[\"initiator\"]})"},{"line_number":349,"context_line":"                raise exception.PureDriverException("},{"line_number":350,"context_line":"                    reason\u003d_LE(\"Unable to re-use a host that is not\""},{"line_number":351,"context_line":"                               \"managed by Cinder with pure_use_chap\u003dTrue,\"))"},{"line_number":352,"context_line":"        else:"},{"line_number":353,"context_line":"            host_name \u003d _generate_purity_host_name(connector[\"host\"])"}],"source_content_type":"text/x-python","patch_set":2,"id":"5a890539_39000f02","line":350,"updated":"2014-11-29 20:46:17.000000000","message":"This message doesn\u0027t need a _LE marker because it is in a user facing exception. See example in the guidelines: http://docs.openstack.org/developer/oslo.i18n/guidelines.html","commit_id":"16c5f3ad5113719347c44c5dd16a63f885e0854a"},{"author":{"_account_id":12924,"name":"Patrick East","email":"east.patrick@gmail.com","username":"patrick.east"},"change_message_id":"1e1362586a3d5d340fb133fde0f6a19ee4cdfd98","unresolved":false,"context_lines":[{"line_number":347,"context_line":"                          {\"host_name\": host_name,"},{"line_number":348,"context_line":"                           \"iqn\": connector[\"initiator\"]})"},{"line_number":349,"context_line":"                raise exception.PureDriverException("},{"line_number":350,"context_line":"                    reason\u003d_LE(\"Unable to re-use a host that is not\""},{"line_number":351,"context_line":"                               \"managed by Cinder with pure_use_chap\u003dTrue,\"))"},{"line_number":352,"context_line":"        else:"},{"line_number":353,"context_line":"            host_name \u003d _generate_purity_host_name(connector[\"host\"])"}],"source_content_type":"text/x-python","patch_set":2,"id":"5a890539_3d20db9a","line":350,"in_reply_to":"5a890539_39000f02","updated":"2014-12-01 19:11:34.000000000","message":"Done","commit_id":"16c5f3ad5113719347c44c5dd16a63f885e0854a"},{"author":{"_account_id":2759,"name":"Huang Zhiteng","email":"winston.d@gmail.com","username":"zhiteng-huang"},"change_message_id":"69a927296c381096f2c6ba3236bac8adf79c7ee7","unresolved":false,"context_lines":[{"line_number":348,"context_line":"                           \"iqn\": connector[\"initiator\"]})"},{"line_number":349,"context_line":"                raise exception.PureDriverException("},{"line_number":350,"context_line":"                    reason\u003d_LE(\"Unable to re-use a host that is not\""},{"line_number":351,"context_line":"                               \"managed by Cinder with pure_use_chap\u003dTrue,\"))"},{"line_number":352,"context_line":"        else:"},{"line_number":353,"context_line":"            host_name \u003d _generate_purity_host_name(connector[\"host\"])"},{"line_number":354,"context_line":"            iqn \u003d connector[\"initiator\"]"}],"source_content_type":"text/x-python","patch_set":2,"id":"5a890539_ff803d4b","line":351,"updated":"2014-11-28 08:26:58.000000000","message":"needs a \u0027else\u0027 branch here to handle the case where pure_use_chap config option is set to True and host is managed by Cinder (possibly by another c-vol instance or previously un-cleaned up session, like:\n\n    else:\n        chap_usr, chap_pwd \u003d self._get_host_chap()\n        ...","commit_id":"16c5f3ad5113719347c44c5dd16a63f885e0854a"},{"author":{"_account_id":2759,"name":"Huang Zhiteng","email":"winston.d@gmail.com","username":"zhiteng-huang"},"change_message_id":"69a927296c381096f2c6ba3236bac8adf79c7ee7","unresolved":false,"context_lines":[{"line_number":349,"context_line":"                raise exception.PureDriverException("},{"line_number":350,"context_line":"                    reason\u003d_LE(\"Unable to re-use a host that is not\""},{"line_number":351,"context_line":"                               \"managed by Cinder with pure_use_chap\u003dTrue,\"))"},{"line_number":352,"context_line":"        else:"},{"line_number":353,"context_line":"            host_name \u003d _generate_purity_host_name(connector[\"host\"])"},{"line_number":354,"context_line":"            iqn \u003d connector[\"initiator\"]"},{"line_number":355,"context_line":"            LOG.info(_LI(\"Creating host object %(host_name)r with IQN:\""}],"source_content_type":"text/x-python","patch_set":2,"id":"5a890539_1f86e965","line":352,"updated":"2014-11-28 08:26:58.000000000","message":"Move the generate CHAP secret logic here.","commit_id":"16c5f3ad5113719347c44c5dd16a63f885e0854a"},{"author":{"_account_id":12924,"name":"Patrick East","email":"east.patrick@gmail.com","username":"patrick.east"},"change_message_id":"1e1362586a3d5d340fb133fde0f6a19ee4cdfd98","unresolved":false,"context_lines":[{"line_number":349,"context_line":"                raise exception.PureDriverException("},{"line_number":350,"context_line":"                    reason\u003d_LE(\"Unable to re-use a host that is not\""},{"line_number":351,"context_line":"                               \"managed by Cinder with pure_use_chap\u003dTrue,\"))"},{"line_number":352,"context_line":"        else:"},{"line_number":353,"context_line":"            host_name \u003d _generate_purity_host_name(connector[\"host\"])"},{"line_number":354,"context_line":"            iqn \u003d connector[\"initiator\"]"},{"line_number":355,"context_line":"            LOG.info(_LI(\"Creating host object %(host_name)r with IQN:\""}],"source_content_type":"text/x-python","patch_set":2,"id":"5a890539_fd9ad3c3","line":352,"in_reply_to":"5a890539_1f86e965","updated":"2014-12-01 19:11:34.000000000","message":"I think it makes more sense to leave the generate logic up a level, without the other changes from your suggestions I don\u0027t think this method needs to know anything about where the credentials come from.","commit_id":"16c5f3ad5113719347c44c5dd16a63f885e0854a"},{"author":{"_account_id":2759,"name":"Huang Zhiteng","email":"winston.d@gmail.com","username":"zhiteng-huang"},"change_message_id":"f11f19adde68fb46f3be8c616c42dc45386d8e14","unresolved":false,"context_lines":[{"line_number":262,"context_line":"        if self.configuration.pure_use_chap:"},{"line_number":263,"context_line":"            properties[\"data\"][\"auth_method\"] \u003d \"CHAP\""},{"line_number":264,"context_line":"            properties[\"data\"][\"auth_username\"] \u003d auth_username"},{"line_number":265,"context_line":"            properties[\"data\"][\"auth_password\"] \u003d auth_password"},{"line_number":266,"context_line":""},{"line_number":267,"context_line":"        LOG.debug(\"Leave PureISCSIDriver.initialize_connection. \""},{"line_number":268,"context_line":"                  \"Return value: \" + str(properties))"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a890539_8645ee44","line":265,"updated":"2014-12-02 07:02:03.000000000","message":"See the comment in _connect() function, the CHAP credential we return to Nova could be wrong.","commit_id":"04e41b40338b7221754cc54db6e2ed66ec50eb68"},{"author":{"_account_id":2759,"name":"Huang Zhiteng","email":"winston.d@gmail.com","username":"zhiteng-huang"},"change_message_id":"f11f19adde68fb46f3be8c616c42dc45386d8e14","unresolved":false,"context_lines":[{"line_number":347,"context_line":"                           \"iqn\": connector[\"initiator\"]})"},{"line_number":348,"context_line":"                raise exception.PureDriverException("},{"line_number":349,"context_line":"                    reason\u003d_(\"Unable to re-use a host that is not\""},{"line_number":350,"context_line":"                             \"managed by Cinder with pure_use_chap\u003dTrue,\"))"},{"line_number":351,"context_line":"        else:"},{"line_number":352,"context_line":"            host_name \u003d _generate_purity_host_name(connector[\"host\"])"},{"line_number":353,"context_line":"            iqn \u003d connector[\"initiator\"]"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a890539_a673cab2","line":350,"updated":"2014-12-02 07:02:03.000000000","message":"Like I mentioned in patch set 2, what happens when self.configuration.pure_use_chap and GENERATED_NAME.match(host_name) are both true is non-deterministic with current CHAP support approach, if cinder-vol are deployed in active-active manner.  Because the CHAP secret could be set by this instance of cinder-vol or another one, and there is no way for Pure driver to tell which situation it could be.","commit_id":"04e41b40338b7221754cc54db6e2ed66ec50eb68"},{"author":{"_account_id":2243,"name":"John Griffith","email":"john.griffith8@gmail.com","username":"john-griffith"},"change_message_id":"c06246946352b2e0190a2ecaa57cf5946e73c29e","unresolved":false,"context_lines":[{"line_number":82,"context_line":""},{"line_number":83,"context_line":"def _generate_chap_secret():"},{"line_number":84,"context_line":"    char_set \u003d string.ascii_uppercase + string.digits + \\"},{"line_number":85,"context_line":"        string.ascii_lowercase"},{"line_number":86,"context_line":"    return \u0027\u0027.join(random.sample(char_set, PURE_CHAP_SECRET_LENGTH))"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5a890539_5bb0f342","line":85,"updated":"2014-12-03 19:32:04.000000000","message":"FYI most are moving to using the generators in volume/utils:generate_password and the like.  Might be worth looking at.","commit_id":"d96fe06b83252389a7261b8fc718f07ebfd7f557"},{"author":{"_account_id":12924,"name":"Patrick East","email":"east.patrick@gmail.com","username":"patrick.east"},"change_message_id":"f879aacdf094deafac193032e35ca4a46dd0e7f6","unresolved":false,"context_lines":[{"line_number":82,"context_line":""},{"line_number":83,"context_line":"def _generate_chap_secret():"},{"line_number":84,"context_line":"    char_set \u003d string.ascii_uppercase + string.digits + \\"},{"line_number":85,"context_line":"        string.ascii_lowercase"},{"line_number":86,"context_line":"    return \u0027\u0027.join(random.sample(char_set, PURE_CHAP_SECRET_LENGTH))"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5a890539_e979c782","line":85,"in_reply_to":"5a890539_5bb0f342","updated":"2014-12-04 00:47:45.000000000","message":"Done","commit_id":"d96fe06b83252389a7261b8fc718f07ebfd7f557"},{"author":{"_account_id":2243,"name":"John Griffith","email":"john.griffith8@gmail.com","username":"john-griffith"},"change_message_id":"c06246946352b2e0190a2ecaa57cf5946e73c29e","unresolved":false,"context_lines":[{"line_number":101,"context_line":"                              self.__class__.__name__)"},{"line_number":102,"context_line":"        self.volumes_dir \u003d self.configuration.safe_get(\u0027volumes_dir\u0027)"},{"line_number":103,"context_line":"        self.chap_mappings_file \u003d os.path.join(self.volumes_dir,"},{"line_number":104,"context_line":"                                               CHAP_MAPPING_FILE_NAME)"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"    def do_setup(self, context):"},{"line_number":107,"context_line":"        \"\"\"Performs driver initialization steps that could raise exceptions.\"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"5a890539_1b3f4b88","line":104,"updated":"2014-12-03 19:32:04.000000000","message":"I still don\u0027t really fully get this as opposed to using the provider_auth field (ie go ahead and create provider_auth entry on create like we used to do).  I still need to go through all the bugs you referenced.  Seems odd.\n\nThat being said putting this in the volumes_dir is much better, and aligns with how we do the persistence file.","commit_id":"d96fe06b83252389a7261b8fc718f07ebfd7f557"},{"author":{"_account_id":12924,"name":"Patrick East","email":"east.patrick@gmail.com","username":"patrick.east"},"change_message_id":"f879aacdf094deafac193032e35ca4a46dd0e7f6","unresolved":false,"context_lines":[{"line_number":101,"context_line":"                              self.__class__.__name__)"},{"line_number":102,"context_line":"        self.volumes_dir \u003d self.configuration.safe_get(\u0027volumes_dir\u0027)"},{"line_number":103,"context_line":"        self.chap_mappings_file \u003d os.path.join(self.volumes_dir,"},{"line_number":104,"context_line":"                                               CHAP_MAPPING_FILE_NAME)"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"    def do_setup(self, context):"},{"line_number":107,"context_line":"        \"\"\"Performs driver initialization steps that could raise exceptions.\"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"5a890539_c9d40b49","line":104,"in_reply_to":"5a890539_1b3f4b88","updated":"2014-12-04 00:47:45.000000000","message":"The core problem is that the volume lifecycle doesn\u0027t match up with the \"host\" lifecycle in Purity which is a problem if we try to associate credentials with volume objects when they are actually associated with host objects for us.\n\nThat being said, we can kind of make it work since we were able to make their lifecycles very very similar. The problem being in those bugs I linked and however many more there are yet to be filed that prevent us from being guaranteed they can match up.\n\nWhat we\u0027ve done instead is ditch that effort and instead only associate the credentials with the hosts and ignore any direct volume mappings.\n\nI\u0027ll put a change set that uses the database to do this which will address the HA problems too... we\u0027ll see which one is the lesser evil \u003e:D","commit_id":"d96fe06b83252389a7261b8fc718f07ebfd7f557"},{"author":{"_account_id":2243,"name":"John Griffith","email":"john.griffith8@gmail.com","username":"john-griffith"},"change_message_id":"c06246946352b2e0190a2ecaa57cf5946e73c29e","unresolved":false,"context_lines":[{"line_number":193,"context_line":"        LOG.debug(\"Leave PureISCSIDriver.delete_snapshot.\")"},{"line_number":194,"context_line":""},{"line_number":195,"context_line":"    def ensure_export(self, context, volume):"},{"line_number":196,"context_line":"        pass"},{"line_number":197,"context_line":""},{"line_number":198,"context_line":"    def create_export(self, context, volume):"},{"line_number":199,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":4,"id":"5a890539_dbbb03e3","line":196,"updated":"2014-12-03 19:32:04.000000000","message":"So IIUC the issue here is that you can\u0027t get the CHAP info from the device right?  So there\u0027s nothing to really be done here.  Might be worth querying the chap file you created on this and create to handle things like service restarts.\n\nAlso, might be able to figure out a way to mirror that so you can deal with the HA issue Walt mentioned.","commit_id":"d96fe06b83252389a7261b8fc718f07ebfd7f557"},{"author":{"_account_id":12924,"name":"Patrick East","email":"east.patrick@gmail.com","username":"patrick.east"},"change_message_id":"f879aacdf094deafac193032e35ca4a46dd0e7f6","unresolved":false,"context_lines":[{"line_number":193,"context_line":"        LOG.debug(\"Leave PureISCSIDriver.delete_snapshot.\")"},{"line_number":194,"context_line":""},{"line_number":195,"context_line":"    def ensure_export(self, context, volume):"},{"line_number":196,"context_line":"        pass"},{"line_number":197,"context_line":""},{"line_number":198,"context_line":"    def create_export(self, context, volume):"},{"line_number":199,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":4,"id":"5a890539_69eeb7ee","line":196,"in_reply_to":"5a890539_dbbb03e3","updated":"2014-12-04 00:47:45.000000000","message":"Correct, we can\u0027t really do anything in them. Even with a way to retrieve the credentials we are unable to get them without knowing the initiator iqn so it has to wait until initialize_connection() is called.","commit_id":"d96fe06b83252389a7261b8fc718f07ebfd7f557"},{"author":{"_account_id":1207,"name":"Duncan Thomas","email":"duncan.thomas@gmail.com","username":"duncan-thomas"},"change_message_id":"7d51ddb658e628db7c46eb5023fe5431a8ca5366","unresolved":false,"context_lines":[{"line_number":250,"context_line":"    @utils.synchronized(\u0027PureISCSI-get-chap-credentials\u0027, external\u003dTrue)"},{"line_number":251,"context_line":"    def _get_chap_credentials(self, host, iqn):"},{"line_number":252,"context_line":"        ctx \u003d context.get_admin_context()"},{"line_number":253,"context_line":"        initiator \u003d self.db.iscsi_initiator_credentials_get_by_iqn(ctx, iqn)"},{"line_number":254,"context_line":"        if initiator:"},{"line_number":255,"context_line":"            auth_username \u003d initiator.chap_username"},{"line_number":256,"context_line":"            auth_password \u003d initiator.chap_secret"}],"source_content_type":"text/x-python","patch_set":18,"id":"fa81d914_40b0758b","line":253,"updated":"2015-01-28 20:57:02.000000000","message":"Can we get a wrapper round round this so the is no context or db access directly in the driver please?","commit_id":"36c1723d2a3c60557d51ea121f8b72e4f0559736"},{"author":{"_account_id":7198,"name":"Jay Bryant","email":"jungleboyj@electronicjungle.net","username":"jsbryant"},"change_message_id":"0c4bac9d0a269510065ed96beef31e15dabb0dbb","unresolved":false,"context_lines":[{"line_number":45,"context_line":"    cfg.StrOpt(\"pure_api_token\","},{"line_number":46,"context_line":"               default\u003dNone,"},{"line_number":47,"context_line":"               help\u003d\"REST API authorization token.\"),"},{"line_number":48,"context_line":"    cfg.BoolOpt(\"pure_use_chap\","},{"line_number":49,"context_line":"                default\u003dFalse,"},{"line_number":50,"context_line":"                help\u003d\"Use CHAP authentication with iscsi.\")"},{"line_number":51,"context_line":"]"}],"source_content_type":"text/x-python","patch_set":25,"id":"ba7be1f8_8513950c","line":48,"updated":"2015-02-27 18:54:46.000000000","message":"Can you make use of the config options here instead of adding new ones?  https://review.openstack.org/#/c/148091/","commit_id":"05acef11cddd3efe435520bd8190cc194e9f32b0"},{"author":{"_account_id":12924,"name":"Patrick East","email":"east.patrick@gmail.com","username":"patrick.east"},"change_message_id":"e27e4aa83f967622bb279b1b69449440a49fb3b7","unresolved":false,"context_lines":[{"line_number":45,"context_line":"    cfg.StrOpt(\"pure_api_token\","},{"line_number":46,"context_line":"               default\u003dNone,"},{"line_number":47,"context_line":"               help\u003d\"REST API authorization token.\"),"},{"line_number":48,"context_line":"    cfg.BoolOpt(\"pure_use_chap\","},{"line_number":49,"context_line":"                default\u003dFalse,"},{"line_number":50,"context_line":"                help\u003d\"Use CHAP authentication with iscsi.\")"},{"line_number":51,"context_line":"]"}],"source_content_type":"text/x-python","patch_set":25,"id":"ba7be1f8_003cc592","line":48,"in_reply_to":"ba7be1f8_8513950c","updated":"2015-02-27 19:55:21.000000000","message":"Ahh nice, I remember talking with John about that a long time ago when this patch was first started. I guess since then someone actually did it :D","commit_id":"05acef11cddd3efe435520bd8190cc194e9f32b0"},{"author":{"_account_id":7198,"name":"Jay Bryant","email":"jungleboyj@electronicjungle.net","username":"jsbryant"},"change_message_id":"0c4bac9d0a269510065ed96beef31e15dabb0dbb","unresolved":false,"context_lines":[{"line_number":351,"context_line":"                     {\"host_name\": host_name})"},{"line_number":352,"context_line":"            if self.configuration.pure_use_chap:"},{"line_number":353,"context_line":"                if not GENERATED_NAME.match(host_name):"},{"line_number":354,"context_line":"                    LOG.error(_LE(\"Purity host %(host_name)s is not managed by\""},{"line_number":355,"context_line":"                                  \" Cinder and can\u0027t have CHAP credentials \""},{"line_number":356,"context_line":"                                  \"modified. Remove IQN %(iqn)s from the host \""},{"line_number":357,"context_line":"                                  \"to resolve this issue.\") %"}],"source_content_type":"text/x-python","patch_set":25,"id":"ba7be1f8_c5c58d3e","line":354,"updated":"2015-02-27 18:54:46.000000000","message":"I know this is a nit, but can we have the space at the end of the line to be consistent please?  Thanks!","commit_id":"05acef11cddd3efe435520bd8190cc194e9f32b0"},{"author":{"_account_id":12924,"name":"Patrick East","email":"east.patrick@gmail.com","username":"patrick.east"},"change_message_id":"e27e4aa83f967622bb279b1b69449440a49fb3b7","unresolved":false,"context_lines":[{"line_number":351,"context_line":"                     {\"host_name\": host_name})"},{"line_number":352,"context_line":"            if self.configuration.pure_use_chap:"},{"line_number":353,"context_line":"                if not GENERATED_NAME.match(host_name):"},{"line_number":354,"context_line":"                    LOG.error(_LE(\"Purity host %(host_name)s is not managed by\""},{"line_number":355,"context_line":"                                  \" Cinder and can\u0027t have CHAP credentials \""},{"line_number":356,"context_line":"                                  \"modified. Remove IQN %(iqn)s from the host \""},{"line_number":357,"context_line":"                                  \"to resolve this issue.\") %"}],"source_content_type":"text/x-python","patch_set":25,"id":"ba7be1f8_c01c6dc4","line":354,"in_reply_to":"ba7be1f8_c5c58d3e","updated":"2015-02-27 19:55:21.000000000","message":"Done","commit_id":"05acef11cddd3efe435520bd8190cc194e9f32b0"},{"author":{"_account_id":12088,"name":"Anish Bhatt","email":"anish.7@gmail.com","username":"anish"},"change_message_id":"9bdfd140c2f56617d6a52d2c76a32df1bad6571a","unresolved":false,"context_lines":[{"line_number":351,"context_line":"                    LOG.error(_LE(\"Purity host %(host_name)s is not managed \""},{"line_number":352,"context_line":"                                  \"by Cinder and can\u0027t have CHAP credentials \""},{"line_number":353,"context_line":"                                  \"modified. Remove IQN %(iqn)s from the host \""},{"line_number":354,"context_line":"                                  \"to resolve this issue.\") %"},{"line_number":355,"context_line":"                              {\"host_name\": host_name,"},{"line_number":356,"context_line":"                               \"iqn\": connector[\"initiator\"]})"},{"line_number":357,"context_line":"                    raise exception.PureDriverException("}],"source_content_type":"text/x-python","patch_set":29,"id":"9a80dd14_be4b1aaf","line":354,"updated":"2015-03-05 06:30:50.000000000","message":"Needs to be \u0027,\u0027 not \u0027%\u0027 for all the LOG.error messages you are adding","commit_id":"68079ae1ddebfdffad983aec4be7a0da9d5985ad"},{"author":{"_account_id":12924,"name":"Patrick East","email":"east.patrick@gmail.com","username":"patrick.east"},"change_message_id":"9ccde3b400bf06274fe86ca6e56136e3d664561f","unresolved":false,"context_lines":[{"line_number":351,"context_line":"                    LOG.error(_LE(\"Purity host %(host_name)s is not managed \""},{"line_number":352,"context_line":"                                  \"by Cinder and can\u0027t have CHAP credentials \""},{"line_number":353,"context_line":"                                  \"modified. Remove IQN %(iqn)s from the host \""},{"line_number":354,"context_line":"                                  \"to resolve this issue.\") %"},{"line_number":355,"context_line":"                              {\"host_name\": host_name,"},{"line_number":356,"context_line":"                               \"iqn\": connector[\"initiator\"]})"},{"line_number":357,"context_line":"                    raise exception.PureDriverException("}],"source_content_type":"text/x-python","patch_set":29,"id":"9a80dd14_23c4535e","line":354,"in_reply_to":"9a80dd14_be4b1aaf","updated":"2015-03-05 17:32:11.000000000","message":"Done","commit_id":"68079ae1ddebfdffad983aec4be7a0da9d5985ad"},{"author":{"_account_id":12088,"name":"Anish Bhatt","email":"anish.7@gmail.com","username":"anish"},"change_message_id":"9bdfd140c2f56617d6a52d2c76a32df1bad6571a","unresolved":false,"context_lines":[{"line_number":360,"context_line":"                elif chap_username is None or chap_password is None:"},{"line_number":361,"context_line":"                    LOG.error(_LE(\"Purity host %(host_name)s is managed by \""},{"line_number":362,"context_line":"                                  \"Cinder but CHAP credentials could not be \""},{"line_number":363,"context_line":"                                  \"retrieved from the Cinder database.\") %"},{"line_number":364,"context_line":"                              {\"host_name\": host_name})"},{"line_number":365,"context_line":"                    raise exception.PureDriverException("},{"line_number":366,"context_line":"                        reason\u003d_(\"Unable to re-use host with unknown CHAP \""}],"source_content_type":"text/x-python","patch_set":29,"id":"9a80dd14_feccb237","line":363,"updated":"2015-03-05 06:30:50.000000000","message":"Same","commit_id":"68079ae1ddebfdffad983aec4be7a0da9d5985ad"},{"author":{"_account_id":12924,"name":"Patrick East","email":"east.patrick@gmail.com","username":"patrick.east"},"change_message_id":"9ccde3b400bf06274fe86ca6e56136e3d664561f","unresolved":false,"context_lines":[{"line_number":360,"context_line":"                elif chap_username is None or chap_password is None:"},{"line_number":361,"context_line":"                    LOG.error(_LE(\"Purity host %(host_name)s is managed by \""},{"line_number":362,"context_line":"                                  \"Cinder but CHAP credentials could not be \""},{"line_number":363,"context_line":"                                  \"retrieved from the Cinder database.\") %"},{"line_number":364,"context_line":"                              {\"host_name\": host_name})"},{"line_number":365,"context_line":"                    raise exception.PureDriverException("},{"line_number":366,"context_line":"                        reason\u003d_(\"Unable to re-use host with unknown CHAP \""}],"source_content_type":"text/x-python","patch_set":29,"id":"9a80dd14_63a56bb4","line":363,"in_reply_to":"9a80dd14_feccb237","updated":"2015-03-05 17:32:11.000000000","message":"Done","commit_id":"68079ae1ddebfdffad983aec4be7a0da9d5985ad"}],"etc/cinder/cinder.conf.sample":[{"author":{"_account_id":2243,"name":"John Griffith","email":"john.griffith8@gmail.com","username":"john-griffith"},"change_message_id":"c06246946352b2e0190a2ecaa57cf5946e73c29e","unresolved":false,"context_lines":[{"line_number":1869,"context_line":"#pure_api_token\u003d\u003cNone\u003e"},{"line_number":1870,"context_line":""},{"line_number":1871,"context_line":"# Use CHAP authentication with iscsi. (boolean value)"},{"line_number":1872,"context_line":"#pure_use_chap\u003dfalse"},{"line_number":1873,"context_line":""},{"line_number":1874,"context_line":""},{"line_number":1875,"context_line":"#"}],"source_content_type":"application/octet-stream","patch_set":4,"id":"5a890539_bb6e3762","line":1872,"updated":"2014-12-03 19:32:04.000000000","message":"Not your problem but I find it HIGHLY annoying that every driver has a \"\u003cvendor\u003e_use_chap\u003d\u003cbool\u003e\" in the config file.  We really should just have a default and let each driver declare it in their section.  Like I said, not your problem, but note to myself or anybody who reads this for some low hanging fruit. :)","commit_id":"d96fe06b83252389a7261b8fc718f07ebfd7f557"},{"author":{"_account_id":12924,"name":"Patrick East","email":"east.patrick@gmail.com","username":"patrick.east"},"change_message_id":"f879aacdf094deafac193032e35ca4a46dd0e7f6","unresolved":false,"context_lines":[{"line_number":1869,"context_line":"#pure_api_token\u003d\u003cNone\u003e"},{"line_number":1870,"context_line":""},{"line_number":1871,"context_line":"# Use CHAP authentication with iscsi. (boolean value)"},{"line_number":1872,"context_line":"#pure_use_chap\u003dfalse"},{"line_number":1873,"context_line":""},{"line_number":1874,"context_line":""},{"line_number":1875,"context_line":"#"}],"source_content_type":"application/octet-stream","patch_set":4,"id":"5a890539_89b12346","line":1872,"in_reply_to":"5a890539_bb6e3762","updated":"2014-12-04 00:47:45.000000000","message":"Yea I opted to be a good sheep and follow the herd with this config option... did enough wandering off the path with the rest of the change ;)","commit_id":"d96fe06b83252389a7261b8fc718f07ebfd7f557"}]}
