#!/usr/bin/python
# -*- coding: utf-8 -*-

# This file is part of Cockpit.
#
# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.

import os
import sys

base_dir = os.path.dirname(os.path.realpath(__file__))
test_dir = os.path.abspath(os.path.join(base_dir, ".."))

try:
    import testlib
except:
    sys.path.append(test_dir)

from common.testlib import *
from common.testvm import VirtMachine
from verify import kubelib

class KubernetesContainerMachine(VirtMachine):

    def start_cockpit(self, *args, **kwargs):
        host = "172.17.0.1"
        if kwargs.pop('invalid_kube_service', False):
            host = ""

        self.execute("""#!/bin/sh
            systemctl start docker
            # HACK: Allow container to talk to the host
            iptables -I INPUT 4 -i docker0 -j ACCEPT
            /usr/bin/docker run -d -e COCKPIT_KUBE_INSECURE=true -e KUBERNETES_INSECURE=true -e KUBERNETES_SERVICE_PORT=6443 -e KUBERNETES_SERVICE_HOST={0} -p 9090:9090 cockpit/kubernetes
            """.format(host))
        self.wait_for_cockpit_running(self.address, seconds=180)

class KubernetesContainerCase(kubelib.KubernetesCase):
    machine_class = KubernetesContainerMachine

class TestKubernetesLogin(KubernetesContainerCase):

    def testKubernetesLogin(self):
        self.invalid_kube_service = True
        m = self.machine
        b = self.browser

        def login(user, password):
            b.set_val('#login-user-input', user)
            b.set_val('#login-password-input', password)
            b.click('#login-button')

        m.start_cockpit(invalid_kube_service=True)

        # Try to login, no api var
        b.open("/")
        b.wait_visible("#login")
        b.wait_text("#server-name", "Kubernetes Cockpit")
        login("admin", "fubar")
        b.wait_in_text("#login-fatal-message", "No kubernetes")
        b.wait_not_visible('#login-button')

        m.execute('docker stop $(docker ps -q --filter ancestor="cockpit/kubernetes")')
        m.start_cockpit()

        b.open("/")
        b.wait_visible("#login")
        b.wait_text("#server-name", "Kubernetes Cockpit")
        login("admin", "fubar")
        b.wait_in_text("#login-fatal-message", "Couldn't connect to the api")
        b.wait_not_visible('#login-button')

        # Start kubernetes
        self.start_kubernetes()
        self.wait_api_server(port=6443, scheme='https')

        b.reload()
        b.wait_visible("#login")
        login("admin", "bad")
        b.wait_text_not("#login-error-message", "")
        b.wait_visible('#login-button')

        login("admin", "fubar")
        with b.wait_timeout(10) as r:
            b.expect_load()
        b.wait_present("#content")
        b.wait_text('#content-user-name', 'admin')

        # reload, which should log us in with the cookie
        b.reload()
        b.wait_present("#content")
        b.wait_text('#content-user-name', 'admin')
        b.wait_in_text("title", "Kubernetes Cockpit")
        b.enter_page("/kubernetes")
        b.wait_present("#node-list")
        b.logout()

        # Remove authentication stuff
        self.stop_kubernetes()
        m.execute("sed -i '/KUBE_API_ARGS=/d' /etc/kubernetes/apiserver")
        self.start_kubernetes()
        b.reload()
        b.wait_present("#content")
        b.wait_text('#content-user-name', 'Unauthenticated')
        b.wait_in_text("title", "Kubernetes Cockpit")
        b.enter_page("/kubernetes")
        b.wait_present("#node-list")
        b.switch_to_top()
        b.logout()

        # Try to login as user with a wrong password

class KubernetesCase(KubernetesContainerCase, kubelib.KubernetesCommonTests):
    machine_class = KubernetesContainerMachine

    def setUp(self):
        super(KubernetesCase, self).setUp()
        self.start_kubernetes()

        self.browser.password = "fubar"
        self.wait_api_server(port=6443, scheme='https')
        config = os.path.join(test_dir, "verify/files/mock-k8s-tiny-app.json")
        self.machine.upload([config], "/tmp")
        self.wait_api_server(port=6443, scheme='https')

        version = self.machine.execute("rpm -qa | grep kubernetes-master")
        self.supports_websocket = True
        if ("-1.1.0-0.17" in version or version < "kubernetes-master-1.1.0-0.17"):
            self.supports_websocket = False

    def check_logs(self, b):
        if not self.supports_websocket:
            print "No websocket support on kubernetes yet"
        else:
            super(KubernetesCase, self).check_logs(b)

    def check_shell(self, b):
        if not self.supports_websocket:
            print "No websocket support on kubernetes yet"
        else:
            super(KubernetesCase, self).check_shell(b)

if __name__ == '__main__':
    test_main()
