We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
ImportError in cfme/infrastructure/test_host.py
PR #4905 removed credential_form from cfme.infrastructure.host, resulting in an ImportError on test setup.

```ImportError while importing test module '/home/mshriver/repos/integration_tests/cfme/tests/infrastructure/test_host.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
cfme/tests/infrastructure/test_host.py:6: in <module>
    from cfme.infrastructure.host import credential_form
E   ImportError: cannot import name credential_form
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `cfme/common/host_views.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 from widgetastic.utils import ParametrizedLocator
3 from widgetastic.widget import ParametrizedView, Text, View
4 from widgetastic_manageiq import (
5     BaseEntitiesView,
6     BaseEntity,
7     BaseListEntity,
8     BaseQuadIconEntity,
9     BaseTileIconEntity,
10     BootstrapTreeview,
11     BreadCrumb,
12     Button,
13     Checkbox,
14     Input,
15     ItemsToolBarViewSelector,
16     PaginationPane,
17     SummaryTable,
18     Table,
19     TimelinesView
20 )
21 from widgetastic_patternfly import (
22     BootstrapSelect,
23     CheckableBootstrapTreeview,
24     Dropdown,
25     FlashMessages,
26     Tab
27 )
28 
29 from cfme.base.login import BaseLoggedInPage
30 
31 
32 class ComputeInfrastructureHostsView(BaseLoggedInPage):
33     """Common parts for host views."""
34     title = Text('.//div[@id="center_div" or @id="main-content"]//h1')
35     flash = FlashMessages(
36         './/div[@id="flash_msg_div"]/div[@id="flash_text_div" or '
37         'contains(@class, "flash_text_div")]'
38     )
39 
40     @property
41     def in_compute_infrastructure_hosts(self):
42         return (
43             self.logged_in_as_current_user and
44             self.navigation.currently_selected == ["Compute", "Infrastructure", "Hosts"]
45         )
46 
47 
48 class HostQuadIconEntity(BaseQuadIconEntity):
49 
50     # TODO Move these properties to one 'data' property
51     @property
52     def no_vm(self):
53         return int(self.browser.text(self.QUADRANT.format(pos="a")))
54 
55     @property
56     def status(self):
57         return self.browser.get_attribute("style", self.QUADRANT.format(pos="b"))
58 
59     @property
60     def vendor(self):
61         return self.browser.get_attribute("alt", self.QUADRANT.format(pos="c"))
62 
63     @property
64     def creds(self):
65         return self.browser.get_attribute("alt", self.QUADRANT.format(pos="d"))
66 
67 
68 class HostTileIconEntity(BaseTileIconEntity):
69     quad_icon = ParametrizedView.nested(HostQuadIconEntity)
70 
71 
72 class HostListEntity(BaseListEntity):
73     pass
74 
75 
76 class HostEntity(BaseEntity):
77     quad_entity = HostQuadIconEntity
78     list_entity = HostListEntity
79     tile_entity = HostTileIconEntity
80 
81 
82 class HostDetailsToolbar(View):
83     """Represents host toolbar and its controls."""
84     monitoring = Dropdown(text="Monitoring")
85     configuration = Dropdown(text="Configuration")
86     policy = Dropdown(text="Policy")
87     power = Dropdown(text="Power")
88 
89 
90 class HostDetailsEntities(View):
91     """Represents Details page."""
92     properties = SummaryTable(title="Properties")
93     relationships = SummaryTable(title="Relationships")
94     compliance = SummaryTable(title="Compliance")
95     configuration = SummaryTable(title="Configuration")
96     smart_management = SummaryTable(title="Smart Management")
97     authentication_status = SummaryTable(title="Authentication Status")
98 
99 
100 class HostDetailsView(ComputeInfrastructureHostsView):
101     """Main Host details page."""
102     breadcrumb = BreadCrumb(locator='.//ol[@class="breadcrumb"]')
103     toolbar = View.nested(HostDetailsToolbar)
104     entities = View.nested(HostDetailsEntities)
105 
106     @property
107     def is_displayed(self):
108         title = "{name} (Summary)".format(name=self.context["object"].name)
109         return self.in_compute_infrastructure_hosts and self.breadcrumb.active_location == title
110 
111 
112 class HostDriftHistory(ComputeInfrastructureHostsView):
113     breadcrumb = BreadCrumb(locator='.//ol[@class="breadcrumb"]')
114     history_table = Table(locator='.//div[@id="main_div"]/table')
115     analyze_button = Button(title="Select up to 10 timestamps for Drift Analysis")
116 
117     @property
118     def is_displayed(self):
119         return (
120             self.in_compute_infrastructure_hosts and
121             self.title.text == "Drift History" and
122             self.history_table.is_displayed
123         )
124 
125 
126 class HostDriftAnalysis(ComputeInfrastructureHostsView):
127     apply_button = Button("Apply")
128     drift_sections = CheckableBootstrapTreeview(tree_id="all_sectionsbox")
129 
130     @ParametrizedView.nested
131     class drift_analysis(ParametrizedView):  # noqa
132         PARAMETERS = ("drift_section", )
133         CELLS = "../td//i"
134         row = Text(ParametrizedLocator(".//div[@id='compare-grid']/"
135                                        "/th[normalize-space(.)={drift_section|quote}]"))
136 
137         @property
138         def is_changed(self):
139             cells = self.browser.elements(self.CELLS, parent=self.row)
140             attrs = [self.browser.get_attribute("class", cell) for cell in cells]
141             return "drift-delta" in attrs
142 
143     @View.nested
144     class toolbar(View):  # noqa
145         all_attributes = Button(title="All attributes")
146         different_values_attributes = Button(title="Attributes with different")
147         same_values_attributes = Button(title="Attributes with same values")
148         details_mode = Button(title="Details Mode")
149         exists_mode = Button(title="Exists Mode")
150 
151     @property
152     def is_displayed(self):
153         return (
154             self.in_compute_infrastructure_hosts and
155             self.title.text == "'{}' Drift Analysis".format(self.context["object"].name)
156         )
157 
158 
159 class HostTimelinesView(TimelinesView, ComputeInfrastructureHostsView):
160     """Represents a Host Timelines page."""
161 
162     @property
163     def is_displayed(self):
164         return self.in_compute_infrastructure_hosts and super(TimelinesView, self).is_displayed
165 
166 
167 class HostDiscoverView(ComputeInfrastructureHostsView):
168     """Discover View from Compute/Infrastructure/Hosts page."""
169     esx = Checkbox(name="discover_type_esx")
170     ipmi = Checkbox(name="discover_type_ipmi")
171 
172     from_ip1 = Input(name="from_first")
173     from_ip2 = Input(name="from_second")
174     from_ip3 = Input(name="from_third")
175     from_ip4 = Input(name="from_fourth")
176     to_ip4 = Input(name="to_fourth")
177 
178     start_button = Button("Start")
179     cancel_button = Button("Cancel")
180 
181     @property
182     def is_displayed(self):
183         return self.in_compute_infrastructure_hosts and self.title.text == "Hosts / Nodes Discovery"
184 
185 
186 class HostManagePoliciesView(BaseLoggedInPage):
187     """Host's Manage Policies view."""
188     policies = BootstrapTreeview("protectbox")
189     save_button = Button("Save")
190     reset_button = Button("Reset")
191     cancel_button = Button("Cancel")
192 
193     @property
194     def is_displayed(self):
195         return False
196 
197 
198 class HostEditTagsView(BaseLoggedInPage):
199     """Host's Edit Tags view."""
200     tag_category = BootstrapSelect("tag_cat")
201     tag = BootstrapSelect("tag_add")
202     chosen_tags = Table(locator='.//div[@id="assignments_div"]/table')
203 
204     save_button = Button("Save")
205     reset_button = Button("Reset")
206     cancel_button = Button("Cancel")
207 
208     @property
209     def is_displayed(self):
210         return False
211 
212 
213 class HostsToolbar(View):
214     """Represents hosts toolbar and its controls."""
215     configuration = Dropdown(text="Configuration")
216     policy = Dropdown(text="Policy")
217     lifecycle = Dropdown(text="Lifecycle")
218     monitoring = Dropdown(text="Monitoring")
219     power = Dropdown(text="Power")
220     view_selector = View.nested(ItemsToolBarViewSelector)
221 
222 
223 class HostSideBar(View):
224     """Represents left side bar. It usually contains navigation, filters, etc."""
225     pass
226 
227 
228 class HostEntitiesView(BaseEntitiesView):
229     """Represents the view with different items like hosts."""
230     @property
231     def entity_class(self):
232         return HostEntity
233 
234 
235 class HostsView(ComputeInfrastructureHostsView):
236     toolbar = View.nested(HostsToolbar)
237     sidebar = View.nested(HostSideBar)
238     paginator = View.nested(PaginationPane)
239     including_entities = View.include(HostEntitiesView, use_parent=True)
240 
241     @property
242     def is_displayed(self):
243         return self.in_compute_infrastructure_hosts and self.title.text == "Hosts"
244 
245 
246 class HostFormView(ComputeInfrastructureHostsView):
247     # Info/Settings
248     title = Text(".//div[@id='main-content']//h1")
249     name = Input(name="name")
250     hostname = Input(name="hostname")
251     custom_ident = Input(name="custom_1")
252     ipmi_address = Input(name="ipmi_address")
253     mac_address = Input(name="mac_address")
254 
255     @View.nested
256     class endpoints(View):  # noqa
257         @View.nested
258         class default(Tab):  # noqa
259             username = Input(name="default_userid")
260             password = Input(name="default_password")
261             confirm_password = Input(name="default_verify")
262             validate_button = Button("Validate")
263 
264         @View.nested
265         class remote_login(Tab):  # noqa
266             TAB_NAME = "Remote Login"
267             username = Input(name="remote_userid")
268             password = Input(name="remote_password")
269             confirm_password = Input(name="remote_verify")
270             validate_button = Button("Validate")
271 
272         @View.nested
273         class web_services(Tab):  # noqa
274             TAB_NAME = "Web Services"
275             username = Input(name="ws_userid")
276             password = Input(name="ws_password")
277             confirm_password = Input(name="ws_verify")
278             validate_button = Button("Validate")
279 
280         @View.nested
281         class ipmi(Tab):  # noqa
282             TAB_NAME = "IPMI"
283             username = Input(name="ipmi_userid")
284             password = Input(name="ipmi_password")
285             confirm_password = Input(name="ipmi_verify")
286             validate_button = Button("Validate")
287 
288     cancel_button = Button("Cancel")
289 
290 
291 class HostAddView(HostFormView):
292     host_platform = BootstrapSelect("user_assigned_os")
293     add_button = Button("Add")
294     cancel_button = Button("Cancel")
295 
296     @property
297     def is_displayed(self):
298         return self.in_compute_infrastructure_hosts and self.title.text == "Add New Host"
299 
300 
301 class HostEditView(HostFormView):
302     save_button = Button("Save")
303     reset_button = Button("Reset")
304     change_stored_password = Text(".//a[contains(@ng-hide, 'bChangeStoredPassword')]")
305 
306     @property
307     def is_displayed(self):
308         return self.in_compute_infrastructure_hosts and self.title.text == "Info/Settings"
309
```

Path: `cfme/infrastructure/provider/virtualcenter.py`
Content:
```
1 from cfme.common.provider import DefaultEndpoint, DefaultEndpointForm
2 from . import InfraProvider
3 from wrapanapi.virtualcenter import VMWareSystem
4 
5 
6 class VirtualCenterEndpoint(DefaultEndpoint):
7     pass
8 
9 
10 class VirtualCenterEndpointForm(DefaultEndpointForm):
11     pass
12 
13 
14 class VMwareProvider(InfraProvider):
15     type_name = "virtualcenter"
16     mgmt_class = VMWareSystem
17     db_types = ["Vmware::InfraManager"]
18     endpoints_form = VirtualCenterEndpointForm
19     discover_dict = {"vmware": True}
20 
21     def __init__(self, name=None, endpoints=None, key=None, zone=None, hostname=None,
22                  ip_address=None, start_ip=None, end_ip=None, provider_data=None, appliance=None):
23         super(VMwareProvider, self).__init__(
24             name=name, endpoints=endpoints, zone=zone, key=key, provider_data=provider_data,
25             appliance=appliance)
26         self.hostname = hostname
27         self.start_ip = start_ip
28         self.end_ip = end_ip
29         if ip_address:
30             self.ip_address = ip_address
31 
32     def deployment_helper(self, deploy_args):
33         """ Used in utils.virtual_machines """
34         # Called within a dictionary update. Since we want to remove key/value pairs, return the
35         # entire dictionary
36         deploy_args.pop('username', None)
37         deploy_args.pop('password', None)
38         if "allowed_datastores" not in deploy_args and "allowed_datastores" in self.data:
39             deploy_args['allowed_datastores'] = self.data['allowed_datastores']
40 
41         return deploy_args
42 
43     @classmethod
44     def from_config(cls, prov_config, prov_key, appliance=None):
45         endpoint = VirtualCenterEndpoint(**prov_config['endpoints']['default'])
46 
47         if prov_config.get('discovery_range'):
48             start_ip = prov_config['discovery_range']['start']
49             end_ip = prov_config['discovery_range']['end']
50         else:
51             start_ip = end_ip = prov_config.get('ipaddress')
52         return cls(name=prov_config['name'],
53                    endpoints={endpoint.name: endpoint},
54                    zone=prov_config['server_zone'],
55                    key=prov_key,
56                    start_ip=start_ip,
57                    end_ip=end_ip,
58                    appliance=appliance)
59 
60     @property
61     def view_value_mapping(self):
62         return {'name': self.name,
63                 'prov_type': 'VMware vCenter'
64                 }
65
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/cfme/common/host_views.py b/cfme/common/host_views.py
--- a/cfme/common/host_views.py
+++ b/cfme/common/host_views.py
@@ -299,6 +299,7 @@
 
 
 class HostEditView(HostFormView):
+    """View for editing a single host"""
     save_button = Button("Save")
     reset_button = Button("Reset")
     change_stored_password = Text(".//a[contains(@ng-hide, 'bChangeStoredPassword')]")
@@ -306,3 +307,16 @@
     @property
     def is_displayed(self):
         return self.in_compute_infrastructure_hosts and self.title.text == "Info/Settings"
+
+
+class HostsEditView(HostEditView):
+    """View when editing multiple hosts
+        Restricted to endpoints section of the form
+        Title changes
+        Must select host before validation
+    """
+    validation_host = BootstrapSelect('validate_id')  # only shown when editing multiple hosts
+
+    @property
+    def is_displayed(self):
+        return self.in_compute_infrastructure_hosts and self.title.text == 'Credentials/Settings'
diff --git a/cfme/infrastructure/provider/virtualcenter.py b/cfme/infrastructure/provider/virtualcenter.py
--- a/cfme/infrastructure/provider/virtualcenter.py
+++ b/cfme/infrastructure/provider/virtualcenter.py
@@ -1,6 +1,11 @@
+from navmazing import NavigateToSibling
+from wrapanapi.virtualcenter import VMWareSystem
+
 from cfme.common.provider import DefaultEndpoint, DefaultEndpointForm
+from cfme.common.provider_views import ProviderNodesView
+from cfme.exceptions import DestinationNotFound
+from utils.appliance.implementations.ui import CFMENavigateStep, navigator
 from . import InfraProvider
-from wrapanapi.virtualcenter import VMWareSystem
 
 
 class VirtualCenterEndpoint(DefaultEndpoint):
@@ -62,3 +67,15 @@
         return {'name': self.name,
                 'prov_type': 'VMware vCenter'
                 }
+
+
+@navigator.register(VMwareProvider, 'ProviderNodes')  # matching other infra class destinations
+class ProviderNodes(CFMENavigateStep):
+    VIEW = ProviderNodesView
+    prerequisite = NavigateToSibling('Details')
+
+    def step(self):
+        try:
+            self.prerequisite_view.contents.relationships.click_at('Hosts')
+        except NameError:
+            raise DestinationNotFound("Hosts aren't present on details page of this provider")

{"golden_diff": "diff --git a/cfme/common/host_views.py b/cfme/common/host_views.py\n--- a/cfme/common/host_views.py\n+++ b/cfme/common/host_views.py\n@@ -299,6 +299,7 @@\n \n \n class HostEditView(HostFormView):\n+    \"\"\"View for editing a single host\"\"\"\n     save_button = Button(\"Save\")\n     reset_button = Button(\"Reset\")\n     change_stored_password = Text(\".//a[contains(@ng-hide, 'bChangeStoredPassword')]\")\n@@ -306,3 +307,16 @@\n     @property\n     def is_displayed(self):\n         return self.in_compute_infrastructure_hosts and self.title.text == \"Info/Settings\"\n+\n+\n+class HostsEditView(HostEditView):\n+    \"\"\"View when editing multiple hosts\n+        Restricted to endpoints section of the form\n+        Title changes\n+        Must select host before validation\n+    \"\"\"\n+    validation_host = BootstrapSelect('validate_id')  # only shown when editing multiple hosts\n+\n+    @property\n+    def is_displayed(self):\n+        return self.in_compute_infrastructure_hosts and self.title.text == 'Credentials/Settings'\ndiff --git a/cfme/infrastructure/provider/virtualcenter.py b/cfme/infrastructure/provider/virtualcenter.py\n--- a/cfme/infrastructure/provider/virtualcenter.py\n+++ b/cfme/infrastructure/provider/virtualcenter.py\n@@ -1,6 +1,11 @@\n+from navmazing import NavigateToSibling\n+from wrapanapi.virtualcenter import VMWareSystem\n+\n from cfme.common.provider import DefaultEndpoint, DefaultEndpointForm\n+from cfme.common.provider_views import ProviderNodesView\n+from cfme.exceptions import DestinationNotFound\n+from utils.appliance.implementations.ui import CFMENavigateStep, navigator\n from . import InfraProvider\n-from wrapanapi.virtualcenter import VMWareSystem\n \n \n class VirtualCenterEndpoint(DefaultEndpoint):\n@@ -62,3 +67,15 @@\n         return {'name': self.name,\n                 'prov_type': 'VMware vCenter'\n                 }\n+\n+\n+@navigator.register(VMwareProvider, 'ProviderNodes')  # matching other infra class destinations\n+class ProviderNodes(CFMENavigateStep):\n+    VIEW = ProviderNodesView\n+    prerequisite = NavigateToSibling('Details')\n+\n+    def step(self):\n+        try:\n+            self.prerequisite_view.contents.relationships.click_at('Hosts')\n+        except NameError:\n+            raise DestinationNotFound(\"Hosts aren't present on details page of this provider\")\n", "issue": "ImportError in cfme/infrastructure/test_host.py\nPR #4905 removed credential_form from cfme.infrastructure.host, resulting in an ImportError on test setup.\r\n\r\n```ImportError while importing test module '/home/mshriver/repos/integration_tests/cfme/tests/infrastructure/test_host.py'.\r\nHint: make sure your test modules/packages have valid Python names.\r\nTraceback:\r\ncfme/tests/infrastructure/test_host.py:6: in <module>\r\n    from cfme.infrastructure.host import credential_form\r\nE   ImportError: cannot import name credential_form\r\n```\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\nfrom widgetastic.utils import ParametrizedLocator\nfrom widgetastic.widget import ParametrizedView, Text, View\nfrom widgetastic_manageiq import (\n    BaseEntitiesView,\n    BaseEntity,\n    BaseListEntity,\n    BaseQuadIconEntity,\n    BaseTileIconEntity,\n    BootstrapTreeview,\n    BreadCrumb,\n    Button,\n    Checkbox,\n    Input,\n    ItemsToolBarViewSelector,\n    PaginationPane,\n    SummaryTable,\n    Table,\n    TimelinesView\n)\nfrom widgetastic_patternfly import (\n    BootstrapSelect,\n    CheckableBootstrapTreeview,\n    Dropdown,\n    FlashMessages,\n    Tab\n)\n\nfrom cfme.base.login import BaseLoggedInPage\n\n\nclass ComputeInfrastructureHostsView(BaseLoggedInPage):\n    \"\"\"Common parts for host views.\"\"\"\n    title = Text('.//div[@id=\"center_div\" or @id=\"main-content\"]//h1')\n    flash = FlashMessages(\n        './/div[@id=\"flash_msg_div\"]/div[@id=\"flash_text_div\" or '\n        'contains(@class, \"flash_text_div\")]'\n    )\n\n    @property\n    def in_compute_infrastructure_hosts(self):\n        return (\n            self.logged_in_as_current_user and\n            self.navigation.currently_selected == [\"Compute\", \"Infrastructure\", \"Hosts\"]\n        )\n\n\nclass HostQuadIconEntity(BaseQuadIconEntity):\n\n    # TODO Move these properties to one 'data' property\n    @property\n    def no_vm(self):\n        return int(self.browser.text(self.QUADRANT.format(pos=\"a\")))\n\n    @property\n    def status(self):\n        return self.browser.get_attribute(\"style\", self.QUADRANT.format(pos=\"b\"))\n\n    @property\n    def vendor(self):\n        return self.browser.get_attribute(\"alt\", self.QUADRANT.format(pos=\"c\"))\n\n    @property\n    def creds(self):\n        return self.browser.get_attribute(\"alt\", self.QUADRANT.format(pos=\"d\"))\n\n\nclass HostTileIconEntity(BaseTileIconEntity):\n    quad_icon = ParametrizedView.nested(HostQuadIconEntity)\n\n\nclass HostListEntity(BaseListEntity):\n    pass\n\n\nclass HostEntity(BaseEntity):\n    quad_entity = HostQuadIconEntity\n    list_entity = HostListEntity\n    tile_entity = HostTileIconEntity\n\n\nclass HostDetailsToolbar(View):\n    \"\"\"Represents host toolbar and its controls.\"\"\"\n    monitoring = Dropdown(text=\"Monitoring\")\n    configuration = Dropdown(text=\"Configuration\")\n    policy = Dropdown(text=\"Policy\")\n    power = Dropdown(text=\"Power\")\n\n\nclass HostDetailsEntities(View):\n    \"\"\"Represents Details page.\"\"\"\n    properties = SummaryTable(title=\"Properties\")\n    relationships = SummaryTable(title=\"Relationships\")\n    compliance = SummaryTable(title=\"Compliance\")\n    configuration = SummaryTable(title=\"Configuration\")\n    smart_management = SummaryTable(title=\"Smart Management\")\n    authentication_status = SummaryTable(title=\"Authentication Status\")\n\n\nclass HostDetailsView(ComputeInfrastructureHostsView):\n    \"\"\"Main Host details page.\"\"\"\n    breadcrumb = BreadCrumb(locator='.//ol[@class=\"breadcrumb\"]')\n    toolbar = View.nested(HostDetailsToolbar)\n    entities = View.nested(HostDetailsEntities)\n\n    @property\n    def is_displayed(self):\n        title = \"{name} (Summary)\".format(name=self.context[\"object\"].name)\n        return self.in_compute_infrastructure_hosts and self.breadcrumb.active_location == title\n\n\nclass HostDriftHistory(ComputeInfrastructureHostsView):\n    breadcrumb = BreadCrumb(locator='.//ol[@class=\"breadcrumb\"]')\n    history_table = Table(locator='.//div[@id=\"main_div\"]/table')\n    analyze_button = Button(title=\"Select up to 10 timestamps for Drift Analysis\")\n\n    @property\n    def is_displayed(self):\n        return (\n            self.in_compute_infrastructure_hosts and\n            self.title.text == \"Drift History\" and\n            self.history_table.is_displayed\n        )\n\n\nclass HostDriftAnalysis(ComputeInfrastructureHostsView):\n    apply_button = Button(\"Apply\")\n    drift_sections = CheckableBootstrapTreeview(tree_id=\"all_sectionsbox\")\n\n    @ParametrizedView.nested\n    class drift_analysis(ParametrizedView):  # noqa\n        PARAMETERS = (\"drift_section\", )\n        CELLS = \"../td//i\"\n        row = Text(ParametrizedLocator(\".//div[@id='compare-grid']/\"\n                                       \"/th[normalize-space(.)={drift_section|quote}]\"))\n\n        @property\n        def is_changed(self):\n            cells = self.browser.elements(self.CELLS, parent=self.row)\n            attrs = [self.browser.get_attribute(\"class\", cell) for cell in cells]\n            return \"drift-delta\" in attrs\n\n    @View.nested\n    class toolbar(View):  # noqa\n        all_attributes = Button(title=\"All attributes\")\n        different_values_attributes = Button(title=\"Attributes with different\")\n        same_values_attributes = Button(title=\"Attributes with same values\")\n        details_mode = Button(title=\"Details Mode\")\n        exists_mode = Button(title=\"Exists Mode\")\n\n    @property\n    def is_displayed(self):\n        return (\n            self.in_compute_infrastructure_hosts and\n            self.title.text == \"'{}' Drift Analysis\".format(self.context[\"object\"].name)\n        )\n\n\nclass HostTimelinesView(TimelinesView, ComputeInfrastructureHostsView):\n    \"\"\"Represents a Host Timelines page.\"\"\"\n\n    @property\n    def is_displayed(self):\n        return self.in_compute_infrastructure_hosts and super(TimelinesView, self).is_displayed\n\n\nclass HostDiscoverView(ComputeInfrastructureHostsView):\n    \"\"\"Discover View from Compute/Infrastructure/Hosts page.\"\"\"\n    esx = Checkbox(name=\"discover_type_esx\")\n    ipmi = Checkbox(name=\"discover_type_ipmi\")\n\n    from_ip1 = Input(name=\"from_first\")\n    from_ip2 = Input(name=\"from_second\")\n    from_ip3 = Input(name=\"from_third\")\n    from_ip4 = Input(name=\"from_fourth\")\n    to_ip4 = Input(name=\"to_fourth\")\n\n    start_button = Button(\"Start\")\n    cancel_button = Button(\"Cancel\")\n\n    @property\n    def is_displayed(self):\n        return self.in_compute_infrastructure_hosts and self.title.text == \"Hosts / Nodes Discovery\"\n\n\nclass HostManagePoliciesView(BaseLoggedInPage):\n    \"\"\"Host's Manage Policies view.\"\"\"\n    policies = BootstrapTreeview(\"protectbox\")\n    save_button = Button(\"Save\")\n    reset_button = Button(\"Reset\")\n    cancel_button = Button(\"Cancel\")\n\n    @property\n    def is_displayed(self):\n        return False\n\n\nclass HostEditTagsView(BaseLoggedInPage):\n    \"\"\"Host's Edit Tags view.\"\"\"\n    tag_category = BootstrapSelect(\"tag_cat\")\n    tag = BootstrapSelect(\"tag_add\")\n    chosen_tags = Table(locator='.//div[@id=\"assignments_div\"]/table')\n\n    save_button = Button(\"Save\")\n    reset_button = Button(\"Reset\")\n    cancel_button = Button(\"Cancel\")\n\n    @property\n    def is_displayed(self):\n        return False\n\n\nclass HostsToolbar(View):\n    \"\"\"Represents hosts toolbar and its controls.\"\"\"\n    configuration = Dropdown(text=\"Configuration\")\n    policy = Dropdown(text=\"Policy\")\n    lifecycle = Dropdown(text=\"Lifecycle\")\n    monitoring = Dropdown(text=\"Monitoring\")\n    power = Dropdown(text=\"Power\")\n    view_selector = View.nested(ItemsToolBarViewSelector)\n\n\nclass HostSideBar(View):\n    \"\"\"Represents left side bar. It usually contains navigation, filters, etc.\"\"\"\n    pass\n\n\nclass HostEntitiesView(BaseEntitiesView):\n    \"\"\"Represents the view with different items like hosts.\"\"\"\n    @property\n    def entity_class(self):\n        return HostEntity\n\n\nclass HostsView(ComputeInfrastructureHostsView):\n    toolbar = View.nested(HostsToolbar)\n    sidebar = View.nested(HostSideBar)\n    paginator = View.nested(PaginationPane)\n    including_entities = View.include(HostEntitiesView, use_parent=True)\n\n    @property\n    def is_displayed(self):\n        return self.in_compute_infrastructure_hosts and self.title.text == \"Hosts\"\n\n\nclass HostFormView(ComputeInfrastructureHostsView):\n    # Info/Settings\n    title = Text(\".//div[@id='main-content']//h1\")\n    name = Input(name=\"name\")\n    hostname = Input(name=\"hostname\")\n    custom_ident = Input(name=\"custom_1\")\n    ipmi_address = Input(name=\"ipmi_address\")\n    mac_address = Input(name=\"mac_address\")\n\n    @View.nested\n    class endpoints(View):  # noqa\n        @View.nested\n        class default(Tab):  # noqa\n            username = Input(name=\"default_userid\")\n            password = Input(name=\"default_password\")\n            confirm_password = Input(name=\"default_verify\")\n            validate_button = Button(\"Validate\")\n\n        @View.nested\n        class remote_login(Tab):  # noqa\n            TAB_NAME = \"Remote Login\"\n            username = Input(name=\"remote_userid\")\n            password = Input(name=\"remote_password\")\n            confirm_password = Input(name=\"remote_verify\")\n            validate_button = Button(\"Validate\")\n\n        @View.nested\n        class web_services(Tab):  # noqa\n            TAB_NAME = \"Web Services\"\n            username = Input(name=\"ws_userid\")\n            password = Input(name=\"ws_password\")\n            confirm_password = Input(name=\"ws_verify\")\n            validate_button = Button(\"Validate\")\n\n        @View.nested\n        class ipmi(Tab):  # noqa\n            TAB_NAME = \"IPMI\"\n            username = Input(name=\"ipmi_userid\")\n            password = Input(name=\"ipmi_password\")\n            confirm_password = Input(name=\"ipmi_verify\")\n            validate_button = Button(\"Validate\")\n\n    cancel_button = Button(\"Cancel\")\n\n\nclass HostAddView(HostFormView):\n    host_platform = BootstrapSelect(\"user_assigned_os\")\n    add_button = Button(\"Add\")\n    cancel_button = Button(\"Cancel\")\n\n    @property\n    def is_displayed(self):\n        return self.in_compute_infrastructure_hosts and self.title.text == \"Add New Host\"\n\n\nclass HostEditView(HostFormView):\n    save_button = Button(\"Save\")\n    reset_button = Button(\"Reset\")\n    change_stored_password = Text(\".//a[contains(@ng-hide, 'bChangeStoredPassword')]\")\n\n    @property\n    def is_displayed(self):\n        return self.in_compute_infrastructure_hosts and self.title.text == \"Info/Settings\"\n", "path": "cfme/common/host_views.py"}, {"content": "from cfme.common.provider import DefaultEndpoint, DefaultEndpointForm\nfrom . import InfraProvider\nfrom wrapanapi.virtualcenter import VMWareSystem\n\n\nclass VirtualCenterEndpoint(DefaultEndpoint):\n    pass\n\n\nclass VirtualCenterEndpointForm(DefaultEndpointForm):\n    pass\n\n\nclass VMwareProvider(InfraProvider):\n    type_name = \"virtualcenter\"\n    mgmt_class = VMWareSystem\n    db_types = [\"Vmware::InfraManager\"]\n    endpoints_form = VirtualCenterEndpointForm\n    discover_dict = {\"vmware\": True}\n\n    def __init__(self, name=None, endpoints=None, key=None, zone=None, hostname=None,\n                 ip_address=None, start_ip=None, end_ip=None, provider_data=None, appliance=None):\n        super(VMwareProvider, self).__init__(\n            name=name, endpoints=endpoints, zone=zone, key=key, provider_data=provider_data,\n            appliance=appliance)\n        self.hostname = hostname\n        self.start_ip = start_ip\n        self.end_ip = end_ip\n        if ip_address:\n            self.ip_address = ip_address\n\n    def deployment_helper(self, deploy_args):\n        \"\"\" Used in utils.virtual_machines \"\"\"\n        # Called within a dictionary update. Since we want to remove key/value pairs, return the\n        # entire dictionary\n        deploy_args.pop('username', None)\n        deploy_args.pop('password', None)\n        if \"allowed_datastores\" not in deploy_args and \"allowed_datastores\" in self.data:\n            deploy_args['allowed_datastores'] = self.data['allowed_datastores']\n\n        return deploy_args\n\n    @classmethod\n    def from_config(cls, prov_config, prov_key, appliance=None):\n        endpoint = VirtualCenterEndpoint(**prov_config['endpoints']['default'])\n\n        if prov_config.get('discovery_range'):\n            start_ip = prov_config['discovery_range']['start']\n            end_ip = prov_config['discovery_range']['end']\n        else:\n            start_ip = end_ip = prov_config.get('ipaddress')\n        return cls(name=prov_config['name'],\n                   endpoints={endpoint.name: endpoint},\n                   zone=prov_config['server_zone'],\n                   key=prov_key,\n                   start_ip=start_ip,\n                   end_ip=end_ip,\n                   appliance=appliance)\n\n    @property\n    def view_value_mapping(self):\n        return {'name': self.name,\n                'prov_type': 'VMware vCenter'\n                }\n", "path": "cfme/infrastructure/provider/virtualcenter.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\nfrom widgetastic.utils import ParametrizedLocator\nfrom widgetastic.widget import ParametrizedView, Text, View\nfrom widgetastic_manageiq import (\n    BaseEntitiesView,\n    BaseEntity,\n    BaseListEntity,\n    BaseQuadIconEntity,\n    BaseTileIconEntity,\n    BootstrapTreeview,\n    BreadCrumb,\n    Button,\n    Checkbox,\n    Input,\n    ItemsToolBarViewSelector,\n    PaginationPane,\n    SummaryTable,\n    Table,\n    TimelinesView\n)\nfrom widgetastic_patternfly import (\n    BootstrapSelect,\n    CheckableBootstrapTreeview,\n    Dropdown,\n    FlashMessages,\n    Tab\n)\n\nfrom cfme.base.login import BaseLoggedInPage\n\n\nclass ComputeInfrastructureHostsView(BaseLoggedInPage):\n    \"\"\"Common parts for host views.\"\"\"\n    title = Text('.//div[@id=\"center_div\" or @id=\"main-content\"]//h1')\n    flash = FlashMessages(\n        './/div[@id=\"flash_msg_div\"]/div[@id=\"flash_text_div\" or '\n        'contains(@class, \"flash_text_div\")]'\n    )\n\n    @property\n    def in_compute_infrastructure_hosts(self):\n        return (\n            self.logged_in_as_current_user and\n            self.navigation.currently_selected == [\"Compute\", \"Infrastructure\", \"Hosts\"]\n        )\n\n\nclass HostQuadIconEntity(BaseQuadIconEntity):\n\n    # TODO Move these properties to one 'data' property\n    @property\n    def no_vm(self):\n        return int(self.browser.text(self.QUADRANT.format(pos=\"a\")))\n\n    @property\n    def status(self):\n        return self.browser.get_attribute(\"style\", self.QUADRANT.format(pos=\"b\"))\n\n    @property\n    def vendor(self):\n        return self.browser.get_attribute(\"alt\", self.QUADRANT.format(pos=\"c\"))\n\n    @property\n    def creds(self):\n        return self.browser.get_attribute(\"alt\", self.QUADRANT.format(pos=\"d\"))\n\n\nclass HostTileIconEntity(BaseTileIconEntity):\n    quad_icon = ParametrizedView.nested(HostQuadIconEntity)\n\n\nclass HostListEntity(BaseListEntity):\n    pass\n\n\nclass HostEntity(BaseEntity):\n    quad_entity = HostQuadIconEntity\n    list_entity = HostListEntity\n    tile_entity = HostTileIconEntity\n\n\nclass HostDetailsToolbar(View):\n    \"\"\"Represents host toolbar and its controls.\"\"\"\n    monitoring = Dropdown(text=\"Monitoring\")\n    configuration = Dropdown(text=\"Configuration\")\n    policy = Dropdown(text=\"Policy\")\n    power = Dropdown(text=\"Power\")\n\n\nclass HostDetailsEntities(View):\n    \"\"\"Represents Details page.\"\"\"\n    properties = SummaryTable(title=\"Properties\")\n    relationships = SummaryTable(title=\"Relationships\")\n    compliance = SummaryTable(title=\"Compliance\")\n    configuration = SummaryTable(title=\"Configuration\")\n    smart_management = SummaryTable(title=\"Smart Management\")\n    authentication_status = SummaryTable(title=\"Authentication Status\")\n\n\nclass HostDetailsView(ComputeInfrastructureHostsView):\n    \"\"\"Main Host details page.\"\"\"\n    breadcrumb = BreadCrumb(locator='.//ol[@class=\"breadcrumb\"]')\n    toolbar = View.nested(HostDetailsToolbar)\n    entities = View.nested(HostDetailsEntities)\n\n    @property\n    def is_displayed(self):\n        title = \"{name} (Summary)\".format(name=self.context[\"object\"].name)\n        return self.in_compute_infrastructure_hosts and self.breadcrumb.active_location == title\n\n\nclass HostDriftHistory(ComputeInfrastructureHostsView):\n    breadcrumb = BreadCrumb(locator='.//ol[@class=\"breadcrumb\"]')\n    history_table = Table(locator='.//div[@id=\"main_div\"]/table')\n    analyze_button = Button(title=\"Select up to 10 timestamps for Drift Analysis\")\n\n    @property\n    def is_displayed(self):\n        return (\n            self.in_compute_infrastructure_hosts and\n            self.title.text == \"Drift History\" and\n            self.history_table.is_displayed\n        )\n\n\nclass HostDriftAnalysis(ComputeInfrastructureHostsView):\n    apply_button = Button(\"Apply\")\n    drift_sections = CheckableBootstrapTreeview(tree_id=\"all_sectionsbox\")\n\n    @ParametrizedView.nested\n    class drift_analysis(ParametrizedView):  # noqa\n        PARAMETERS = (\"drift_section\", )\n        CELLS = \"../td//i\"\n        row = Text(ParametrizedLocator(\".//div[@id='compare-grid']/\"\n                                       \"/th[normalize-space(.)={drift_section|quote}]\"))\n\n        @property\n        def is_changed(self):\n            cells = self.browser.elements(self.CELLS, parent=self.row)\n            attrs = [self.browser.get_attribute(\"class\", cell) for cell in cells]\n            return \"drift-delta\" in attrs\n\n    @View.nested\n    class toolbar(View):  # noqa\n        all_attributes = Button(title=\"All attributes\")\n        different_values_attributes = Button(title=\"Attributes with different\")\n        same_values_attributes = Button(title=\"Attributes with same values\")\n        details_mode = Button(title=\"Details Mode\")\n        exists_mode = Button(title=\"Exists Mode\")\n\n    @property\n    def is_displayed(self):\n        return (\n            self.in_compute_infrastructure_hosts and\n            self.title.text == \"'{}' Drift Analysis\".format(self.context[\"object\"].name)\n        )\n\n\nclass HostTimelinesView(TimelinesView, ComputeInfrastructureHostsView):\n    \"\"\"Represents a Host Timelines page.\"\"\"\n\n    @property\n    def is_displayed(self):\n        return self.in_compute_infrastructure_hosts and super(TimelinesView, self).is_displayed\n\n\nclass HostDiscoverView(ComputeInfrastructureHostsView):\n    \"\"\"Discover View from Compute/Infrastructure/Hosts page.\"\"\"\n    esx = Checkbox(name=\"discover_type_esx\")\n    ipmi = Checkbox(name=\"discover_type_ipmi\")\n\n    from_ip1 = Input(name=\"from_first\")\n    from_ip2 = Input(name=\"from_second\")\n    from_ip3 = Input(name=\"from_third\")\n    from_ip4 = Input(name=\"from_fourth\")\n    to_ip4 = Input(name=\"to_fourth\")\n\n    start_button = Button(\"Start\")\n    cancel_button = Button(\"Cancel\")\n\n    @property\n    def is_displayed(self):\n        return self.in_compute_infrastructure_hosts and self.title.text == \"Hosts / Nodes Discovery\"\n\n\nclass HostManagePoliciesView(BaseLoggedInPage):\n    \"\"\"Host's Manage Policies view.\"\"\"\n    policies = BootstrapTreeview(\"protectbox\")\n    save_button = Button(\"Save\")\n    reset_button = Button(\"Reset\")\n    cancel_button = Button(\"Cancel\")\n\n    @property\n    def is_displayed(self):\n        return False\n\n\nclass HostEditTagsView(BaseLoggedInPage):\n    \"\"\"Host's Edit Tags view.\"\"\"\n    tag_category = BootstrapSelect(\"tag_cat\")\n    tag = BootstrapSelect(\"tag_add\")\n    chosen_tags = Table(locator='.//div[@id=\"assignments_div\"]/table')\n\n    save_button = Button(\"Save\")\n    reset_button = Button(\"Reset\")\n    cancel_button = Button(\"Cancel\")\n\n    @property\n    def is_displayed(self):\n        return False\n\n\nclass HostsToolbar(View):\n    \"\"\"Represents hosts toolbar and its controls.\"\"\"\n    configuration = Dropdown(text=\"Configuration\")\n    policy = Dropdown(text=\"Policy\")\n    lifecycle = Dropdown(text=\"Lifecycle\")\n    monitoring = Dropdown(text=\"Monitoring\")\n    power = Dropdown(text=\"Power\")\n    view_selector = View.nested(ItemsToolBarViewSelector)\n\n\nclass HostSideBar(View):\n    \"\"\"Represents left side bar. It usually contains navigation, filters, etc.\"\"\"\n    pass\n\n\nclass HostEntitiesView(BaseEntitiesView):\n    \"\"\"Represents the view with different items like hosts.\"\"\"\n    @property\n    def entity_class(self):\n        return HostEntity\n\n\nclass HostsView(ComputeInfrastructureHostsView):\n    toolbar = View.nested(HostsToolbar)\n    sidebar = View.nested(HostSideBar)\n    paginator = View.nested(PaginationPane)\n    including_entities = View.include(HostEntitiesView, use_parent=True)\n\n    @property\n    def is_displayed(self):\n        return self.in_compute_infrastructure_hosts and self.title.text == \"Hosts\"\n\n\nclass HostFormView(ComputeInfrastructureHostsView):\n    # Info/Settings\n    title = Text(\".//div[@id='main-content']//h1\")\n    name = Input(name=\"name\")\n    hostname = Input(name=\"hostname\")\n    custom_ident = Input(name=\"custom_1\")\n    ipmi_address = Input(name=\"ipmi_address\")\n    mac_address = Input(name=\"mac_address\")\n\n    @View.nested\n    class endpoints(View):  # noqa\n        @View.nested\n        class default(Tab):  # noqa\n            username = Input(name=\"default_userid\")\n            password = Input(name=\"default_password\")\n            confirm_password = Input(name=\"default_verify\")\n            validate_button = Button(\"Validate\")\n\n        @View.nested\n        class remote_login(Tab):  # noqa\n            TAB_NAME = \"Remote Login\"\n            username = Input(name=\"remote_userid\")\n            password = Input(name=\"remote_password\")\n            confirm_password = Input(name=\"remote_verify\")\n            validate_button = Button(\"Validate\")\n\n        @View.nested\n        class web_services(Tab):  # noqa\n            TAB_NAME = \"Web Services\"\n            username = Input(name=\"ws_userid\")\n            password = Input(name=\"ws_password\")\n            confirm_password = Input(name=\"ws_verify\")\n            validate_button = Button(\"Validate\")\n\n        @View.nested\n        class ipmi(Tab):  # noqa\n            TAB_NAME = \"IPMI\"\n            username = Input(name=\"ipmi_userid\")\n            password = Input(name=\"ipmi_password\")\n            confirm_password = Input(name=\"ipmi_verify\")\n            validate_button = Button(\"Validate\")\n\n    cancel_button = Button(\"Cancel\")\n\n\nclass HostAddView(HostFormView):\n    host_platform = BootstrapSelect(\"user_assigned_os\")\n    add_button = Button(\"Add\")\n    cancel_button = Button(\"Cancel\")\n\n    @property\n    def is_displayed(self):\n        return self.in_compute_infrastructure_hosts and self.title.text == \"Add New Host\"\n\n\nclass HostEditView(HostFormView):\n    \"\"\"View for editing a single host\"\"\"\n    save_button = Button(\"Save\")\n    reset_button = Button(\"Reset\")\n    change_stored_password = Text(\".//a[contains(@ng-hide, 'bChangeStoredPassword')]\")\n\n    @property\n    def is_displayed(self):\n        return self.in_compute_infrastructure_hosts and self.title.text == \"Info/Settings\"\n\n\nclass HostsEditView(HostEditView):\n    \"\"\"View when editing multiple hosts\n        Restricted to endpoints section of the form\n        Title changes\n        Must select host before validation\n    \"\"\"\n    validation_host = BootstrapSelect('validate_id')  # only shown when editing multiple hosts\n\n    @property\n    def is_displayed(self):\n        return self.in_compute_infrastructure_hosts and self.title.text == 'Credentials/Settings'\n", "path": "cfme/common/host_views.py"}, {"content": "from navmazing import NavigateToSibling\nfrom wrapanapi.virtualcenter import VMWareSystem\n\nfrom cfme.common.provider import DefaultEndpoint, DefaultEndpointForm\nfrom cfme.common.provider_views import ProviderNodesView\nfrom cfme.exceptions import DestinationNotFound\nfrom utils.appliance.implementations.ui import CFMENavigateStep, navigator\nfrom . import InfraProvider\n\n\nclass VirtualCenterEndpoint(DefaultEndpoint):\n    pass\n\n\nclass VirtualCenterEndpointForm(DefaultEndpointForm):\n    pass\n\n\nclass VMwareProvider(InfraProvider):\n    type_name = \"virtualcenter\"\n    mgmt_class = VMWareSystem\n    db_types = [\"Vmware::InfraManager\"]\n    endpoints_form = VirtualCenterEndpointForm\n    discover_dict = {\"vmware\": True}\n\n    def __init__(self, name=None, endpoints=None, key=None, zone=None, hostname=None,\n                 ip_address=None, start_ip=None, end_ip=None, provider_data=None, appliance=None):\n        super(VMwareProvider, self).__init__(\n            name=name, endpoints=endpoints, zone=zone, key=key, provider_data=provider_data,\n            appliance=appliance)\n        self.hostname = hostname\n        self.start_ip = start_ip\n        self.end_ip = end_ip\n        if ip_address:\n            self.ip_address = ip_address\n\n    def deployment_helper(self, deploy_args):\n        \"\"\" Used in utils.virtual_machines \"\"\"\n        # Called within a dictionary update. Since we want to remove key/value pairs, return the\n        # entire dictionary\n        deploy_args.pop('username', None)\n        deploy_args.pop('password', None)\n        if \"allowed_datastores\" not in deploy_args and \"allowed_datastores\" in self.data:\n            deploy_args['allowed_datastores'] = self.data['allowed_datastores']\n\n        return deploy_args\n\n    @classmethod\n    def from_config(cls, prov_config, prov_key, appliance=None):\n        endpoint = VirtualCenterEndpoint(**prov_config['endpoints']['default'])\n\n        if prov_config.get('discovery_range'):\n            start_ip = prov_config['discovery_range']['start']\n            end_ip = prov_config['discovery_range']['end']\n        else:\n            start_ip = end_ip = prov_config.get('ipaddress')\n        return cls(name=prov_config['name'],\n                   endpoints={endpoint.name: endpoint},\n                   zone=prov_config['server_zone'],\n                   key=prov_key,\n                   start_ip=start_ip,\n                   end_ip=end_ip,\n                   appliance=appliance)\n\n    @property\n    def view_value_mapping(self):\n        return {'name': self.name,\n                'prov_type': 'VMware vCenter'\n                }\n\n\n@navigator.register(VMwareProvider, 'ProviderNodes')  # matching other infra class destinations\nclass ProviderNodes(CFMENavigateStep):\n    VIEW = ProviderNodesView\n    prerequisite = NavigateToSibling('Details')\n\n    def step(self):\n        try:\n            self.prerequisite_view.contents.relationships.click_at('Hosts')\n        except NameError:\n            raise DestinationNotFound(\"Hosts aren't present on details page of this provider\")\n", "path": "cfme/infrastructure/provider/virtualcenter.py"}]}