Add new kubectl.py functions, modify some libjuju.py functions, add unit tests

- Kubectl.py: two new functions added (get_configuration and get_default_storage_class)
  - get_configuration(): Returns a kubernetes Configuration object.
    It can be used to properly parse the kubeconfig.
  - get_default_storage_class(): Searches for the default storage class of a k8s cluster.
- Libjuju.py: modified add_k8s function and get_k8s_cloud_credential function was added.
  - add_k8s(): Improves the way of generation Cloud and CloudCredential objects for the K8s Cloud
  - get_k8s_cloud_credential(): It parses the kubeconfig to properly determine the authentication
    method type that should be used for that k8s cluster.
- Unit tests: Added unit tests for all the new functions added.
- Exceptions: Make all Juju Exceptions to inherit from N2VC Exception.
  Now Juju exceptions have the message attribute, that is useful for unit testing, to not only check that
  an exception raised, but to check the message too.
- Move get_k8s_cloud_credential() function to n2vc/utils in order to share that code between different connectors.

Change-Id: Ife9027d80663fe95f1f3ad883cb9a3376b047d0b
Signed-off-by: David Garcia <david.garcia@canonical.com>
diff --git a/n2vc/exceptions.py b/n2vc/exceptions.py
index 256860e..721b1f4 100644
--- a/n2vc/exceptions.py
+++ b/n2vc/exceptions.py
@@ -13,66 +13,6 @@
 #     limitations under the License.
 
 
-class JujuCharmNotFound(Exception):
-    """The Charm can't be found or is not readable."""
-
-
-class JujuControllerFailedConnecting(Exception):
-    """Failed connecting to juju controller."""
-
-
-class JujuModelAlreadyExists(Exception):
-    """The model already exists."""
-
-
-class JujuApplicationExists(Exception):
-    """The Application already exists."""
-
-
-class JujuApplicationNotFound(Exception):
-    """The Application cannot be found."""
-
-
-class JujuLeaderUnitNotFound(Exception):
-    """The Application cannot be found."""
-
-
-class JujuActionNotFound(Exception):
-    """The Action cannot be found."""
-
-
-class JujuMachineNotFound(Exception):
-    """The machine cannot be found."""
-
-
-class JujuK8sProxycharmNotSupported(Exception):
-    """K8s Proxy Charms not supported in this installation."""
-
-
-class N2VCPrimitiveExecutionFailed(Exception):
-    """Something failed while attempting to execute a primitive."""
-
-
-class NetworkServiceDoesNotExist(Exception):
-    """The Network Service being acted against does not exist."""
-
-
-class PrimitiveDoesNotExist(Exception):
-    """The Primitive being executed does not exist."""
-
-
-class NoRouteToHost(Exception):
-    """There was no route to the specified host."""
-
-
-class AuthenticationFailed(Exception):
-    """The authentication for the specified user failed."""
-
-
-class MethodNotImplemented(Exception):
-    """The method is not implemented."""
-
-
 class N2VCException(Exception):
     """
     N2VC exception base class
@@ -189,3 +129,67 @@
 
 class EntityInvalidException(Exception):
     """Entity is not valid, the type does not match any EntityType."""
+
+
+class JujuInvalidK8sConfiguration(N2VCException):
+    """Invalid K8s configuration."""
+
+
+class JujuCharmNotFound(N2VCException):
+    """The Charm can't be found or is not readable."""
+
+
+class JujuControllerFailedConnecting(N2VCException):
+    """Failed connecting to juju controller."""
+
+
+class JujuModelAlreadyExists(N2VCException):
+    """The model already exists."""
+
+
+class JujuApplicationExists(N2VCException):
+    """The Application already exists."""
+
+
+class JujuApplicationNotFound(N2VCException):
+    """The Application cannot be found."""
+
+
+class JujuLeaderUnitNotFound(N2VCException):
+    """The Application cannot be found."""
+
+
+class JujuActionNotFound(N2VCException):
+    """The Action cannot be found."""
+
+
+class JujuMachineNotFound(N2VCException):
+    """The machine cannot be found."""
+
+
+class JujuK8sProxycharmNotSupported(N2VCException):
+    """K8s Proxy Charms not supported in this installation."""
+
+
+class N2VCPrimitiveExecutionFailed(N2VCException):
+    """Something failed while attempting to execute a primitive."""
+
+
+class NetworkServiceDoesNotExist(N2VCException):
+    """The Network Service being acted against does not exist."""
+
+
+class PrimitiveDoesNotExist(N2VCException):
+    """The Primitive being executed does not exist."""
+
+
+class NoRouteToHost(N2VCException):
+    """There was no route to the specified host."""
+
+
+class AuthenticationFailed(N2VCException):
+    """The authentication for the specified user failed."""
+
+
+class MethodNotImplemented(N2VCException):
+    """The method is not implemented."""