#!/usr/bin/python # -*- coding: utf-8 -*- # This file is part of Cockpit. # # Copyright (C) 2015 Red Hat, Inc. # # Cockpit is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. # # Cockpit is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with Cockpit; If not, see . import parent import unittest from testlib import * import kubelib @skipImage("No kubernetes packaged", "debian-stable", "debian-testing", "ubuntu-1604", "ubuntu-stable", "fedora-i386") @skipImage("No cockpit-kubernetes packaged", "continuous-atomic", "fedora-atomic", "rhel-atomic") class TestKubernetes(kubelib.KubernetesCase, kubelib.KubernetesCommonTests): def setUp(self): kubelib.KubernetesCase.setUp(self) m = self.machine self.start_kubernetes() m.upload(["verify/files/mock-k8s-tiny-app.json"], "/tmp") self.wait_api_server() @skipImage("No kubernetes packaged", "debian-stable", "debian-testing", "ubuntu-1604", "ubuntu-stable", "fedora-i386") @skipImage("No cockpit-kubernetes packaged", "continuous-atomic", "fedora-atomic", "rhel-atomic") class TestConnection(kubelib.KubernetesCase): def testConnect(self): m = self.machine b = self.browser # Connect without starting a kube server self.login_and_go("/kubernetes") b.wait_present(".curtains-ct") b.wait_visible(".curtains-ct") b.wait_in_text(".curtains-ct", "Couldn't connect to server") b.wait_in_text(".curtains-ct", "Couldn't find running API server") self.assertIn("Reconnect", b.text("#kubernetes-reconnect")) # Start a kube-apiserver with a 'wrong' http port, forcing use of https m.execute("echo 'KUBE_API_PORT=\"--port=1111\"' >> /etc/kubernetes/apiserver") m.execute("sed -i s/8080/1111/g /etc/kubernetes/*") self.start_kubernetes() self.wait_api_server(port=6443, scheme='https') # Setup the kube stuff in the right place m.upload(["verify/files/mock-kube-config-basic.json"], "/tmp") m.execute("mkdir -p /home/admin/.kube/ && mv /tmp/mock-kube-config-basic.json /home/admin/.kube/config") # Click the Reconnect button b.click("#kubernetes-reconnect") b.wait_present("#node-list") b.wait_in_text("#node-list", "127.0.0.1") b.logout() # Check that this failed as a double check output = m.execute("curl -sS http://localhost:8080/api 2>&1 || true") self.assertIn("Connection refused", output) # Check that this failed as a double check output = m.execute("curl -k -sS https://localhost:6443/api 2>&1 || true") self.assertRegexpMatches(output, "Unauthorized|No policy matched") m.execute("rm -r /home/admin/.kube") self.login_and_go("/kubernetes") b.wait_present(".curtains-ct") b.wait_present("#kubernetes-connection-tb") b.click("#kubernetes-connection-tb") b.wait_present("modal-dialog") b.wait_in_text("div.modal-footer div.dialog-error", "Connection Error:") b.wait_present("#kubernetes-address") b.wait_present("#kubernetes-cluster") b.wait_not_present("#kubernetes-user") b.wait_present("#kubernetes-cluster ul.dropdown-menu") b.wait_in_text("#kubernetes-cluster button", "Add New Cluster") b.click("#kubernetes-requires-auth") b.wait_present("#kubernetes-user") b.wait_present("#kubernetes-username") b.wait_in_text("#kubernetes-user button", "Add New User") b.set_val("#kubernetes-address", "") b.click("modal-dialog div.modal-footer button.btn-primary") b.wait_present("#kubernetes-address + div.dialog-error") b.wait_present("#kubernetes-username + div.dialog-error") b.set_val("#kubernetes-address", "https://127.0.0.1:6443") b.set_val("#kubernetes-username", "bad") b.set_val("#kubernetes-password", "password") b.click("modal-dialog div.modal-footer button.btn-primary") b.wait_present("modal-dialog input[value='pem']") b.wait_present("modal-dialog input[value='skip']") b.wait_in_text("modal-dialog pre", "Certificate:") b.click("modal-dialog input[value='pem']") b.click("modal-dialog div.modal-footer button.btn-primary") b.wait_present("#kubernetes-address") b.wait_present("#kubernetes-user") b.wait_in_text("div.modal-footer div.dialog-error", "Connection Error:") # Data not saved b.wait_in_text("#kubernetes-cluster button", "Add New Cluster") b.wait_in_text("#kubernetes-user button", "Add New User") # Form is b.wait_val("#kubernetes-address", "https://127.0.0.1:6443") b.wait_present("#kubernetes-requires-auth:checked") b.wait_val("#kubernetes-username", "bad") b.set_val("#kubernetes-username", "admin") b.set_val("#kubernetes-password", "fubar") b.click("modal-dialog div.modal-footer button.btn-primary") b.wait_not_present("modal-dialog") b.wait_present("#node-list") b.wait_in_text("#node-list", "127.0.0.1") b.wait_not_present("#kubernetes-change-connection") # Temp certificate isn't saved b.reload() b.enter_page("/kubernetes") b.wait_present(".curtains-ct") b.wait_present("#kubernetes-connection-tb") b.click("#kubernetes-connection-tb") b.wait_present("modal-dialog input[value='pem']") b.wait_present("modal-dialog input[value='skip']") b.click("modal-dialog input[value='skip']") b.click("modal-dialog div.modal-footer button.btn-primary") b.wait_not_present("modal-dialog") b.wait_present("#node-list") b.wait_in_text("#node-list", "127.0.0.1") # Reload works b.reload() b.enter_page("/kubernetes") b.wait_present("#node-list") b.wait_in_text("#node-list", "127.0.0.1") # Changing works b.wait_present("#kubernetes-change-connection") b.click("#kubernetes-change-connection") b.wait_present("modal-dialog") b.wait_present("#kubernetes-cluster") b.wait_present("#kubernetes-user") b.wait_in_text("#kubernetes-cluster button", "127-0-0-1:6443") b.wait_in_text("#kubernetes-user button", "admin/127-0-0-1:6443") b.wait_val("#kubernetes-address", "https://127.0.0.1:6443") b.wait_present("#kubernetes-requires-auth:checked") b.wait_val("#kubernetes-username", "admin") b.wait_present("#kubernetes-skip-verify:checked") b.set_val("#kubernetes-address", "https://localhost:6443") b.set_val("#kubernetes-username", "scruffy") b.set_val("#kubernetes-password", "scruffy") b.click("modal-dialog div.modal-footer button.btn-primary") b.wait_not_present("modal-dialog") # Changes took and dropdowns work b.wait_present("#kubernetes-change-connection") b.click("#kubernetes-change-connection") b.wait_present("modal-dialog") b.wait_present("#kubernetes-cluster") b.wait_present("#kubernetes-user") b.wait_in_text("#kubernetes-cluster button", "127-0-0-1:6443") b.click("#kubernetes-cluster button") b.click("#kubernetes-cluster ul li:last-child a") b.wait_in_text("#kubernetes-cluster button", "Add New Cluster") b.wait_val("#kubernetes-address", "") b.wait_present("#kubernetes-skip-verify:not(:checked)") b.click("#kubernetes-cluster button") b.click("#kubernetes-cluster ul li:first-child a") b.wait_in_text("#kubernetes-cluster button", "127-0-0-1:6443") b.wait_val("#kubernetes-address", "https://localhost:6443") b.wait_present("#kubernetes-requires-auth:checked") b.wait_present("#kubernetes-skip-verify:checked") b.wait_in_text("#kubernetes-user button", "admin/127-0-0-1:6443") b.wait_val("#kubernetes-username", "scruffy") b.click("#kubernetes-user button") b.click("#kubernetes-user ul li:last-child a") b.wait_in_text("#kubernetes-user button", "Add New User") b.wait_val("#kubernetes-username", "") b.wait_val("#kubernetes-password", "") b.click("#kubernetes-user button") b.click("#kubernetes-user ul li:first-child a") b.wait_in_text("#kubernetes-user button", "admin/127-0-0-1:6443") b.wait_val("#kubernetes-username", "scruffy") b.wait_val("#kubernetes-password", "scruffy") b.click("modal-dialog div.modal-footer button.btn-cancel") b.wait_not_present("modal-dialog") b.wait_present("#node-list") b.wait_in_text("#node-list", "127.0.0.1") self.allow_journal_messages(".*: couldn't connect: Connection refused", ".*: Unacceptable TLS certificate.*", ".*: Connection reset by peer.*", "connection unexpectedly closed by peer", ".*: Error sending data: Broken pipe.*") @skipImage("No kubernetes packaged", "debian-stable", "debian-testing", "ubuntu-1604", "ubuntu-stable", "fedora-i386") @unittest.skipIf(True, "Nulecule deploys temporarily removed.") class TestNulecule(kubelib.KubernetesCase): def setUp(self): kubelib.KubernetesCase.setUp(self) self.start_kubernetes() self.wait_api_server() def testDeployDialog(self): b = self.browser m = self.machine self.login_and_go("/kubernetes") b.wait_present("#node-list") b.wait_in_text("#node-list", "127.0.0.1") # 1)check atomic version output = m.execute("atomic -v 2>&1") self.assertTrue(float(output) >= 1.1) # 2) fail invalid image b.click("#deploy-app") b.wait_popup("deploy-app-dialog") b.set_val("#deploy-app-type", "nulecule") b.set_val("#deploy-app-nulecule-image", "submod/helloapache1") b.set_val("#deploy-app-namespace", "mynamespace") b.dialog_complete("#deploy-app-dialog", result="fail") b.dialog_cancel("#deploy-app-dialog") # 3) pass when valid image b.click("#deploy-app") b.wait_popup("deploy-app-dialog") b.set_val("#deploy-app-type", "nulecule") b.set_val("#deploy-app-nulecule-image", "submod/helloapache:0.1.11") b.set_val("#deploy-app-namespace", "mynamespace") b.click("#deploy-app-start") self.allow_journal_messages('Could not find any image matching "submod/helloapache:0.1.11".') b.wait_not_attr("#deploy-app-start", "disabled", "disabled") b.dialog_cancel("#deploy-app-dialog") # 4) fail when atomic is not installed m.needs_writable_usr() m.execute("rm /usr/bin/atomic") b.click("#deploy-app") b.wait_popup("deploy-app-dialog") b.set_val("#deploy-app-type", "nulecule") b.set_val("#deploy-app-nulecule-image", "submod/helloapache") b.set_val("#deploy-app-namespace", "mynamespace") b.dialog_complete("#deploy-app-dialog", result="fail") b.dialog_cancel("#deploy-app-dialog") if __name__ == '__main__': test_main()