Create Organizations

To keep Organizations and Ingresses in sync, GoodData Cloud Native (GoodData.CN) lets Kubernetes manage the Organizations. A custom Kubernetes operator called “Organization controller” is deployed as a part of the GoodData.CN Helm chart.

Set Up an Organization

To set up an Organization, do the following:

  1. Generate a salted hash of the administrator password
  2. Prepare a YAML definition of the Organization custom resource
  3. Load the YAML definition to the Kubernetes cluster

Generate a Salted Hash of the Administrator Password

The administrator password is the password of an Organization’s administrator. The administrator password is one of the properties that you will have to provide in the YAML definition of the Organization custom resource, which you will be preparing in Step 2 further in this article.

The administrator password is a part of the bootstrap token. Because the bootstrap token grants unlimited access to the Organization and the administrator password is an essential part of it, never provide the administrator password in the YAML definition in plain text. Instead, generate and use a salted hash of the administrator password.

Steps:

  1. Create a password that you will be using as the administrator password.

  2. Generate a salted hash of the administrator password (MySecretPassword is used as an example password in the following code samples):

    Ubuntu
    Python
    OSX/Windows
    # This works on Alpine and Debian-based distributions (Debian, Ubuntu, ...)
    # Other Linux distros may use Python or Docker method
    mkpasswd -m sha256crypt MySecretPassword
    
    # passlib module needs to be installed extra (i.e. using pip)
    from passlib.hash import sha256_crypt
    print(sha256_crypt.using(rounds=5000).hash("MySecretPassword"))
    
    docker run --rm  alpine:latest mkpasswd -m sha256 MySecretPassword
    

    The resulted salted hash should look similar to the following:

    $5$c/srj5JySMve$NxQRZ1ubtPKBRexCjKcA3V4CkJaBkxegSPsBYFq6U67

Prepare a YAML Definition of the Organization Custom Resource

Use the following template to create a YAML definition of the Organization custom resource:

apiVersion: controllers.gooddata.com/v1
kind: Organization
metadata:
  # The namespace-unique name of the custom resource
  name: alpha-org
spec:
  # The Organization ID
  id: alpha
  # The UI-friendly Organization name
  name: "Alpha, Corp."
  # The DNS name where the Organization will be accessible
  hostname: analytics.alpha.example.com
  # The name of the user group for the Organization administrator
  adminGroup: adminGroup
  # The name of the Organization administrator account
  adminUser: admin
  # The salted hash of the administrator password that you generated earlier at Step 1
  adminUserToken: "$5$hP8MLrkpLGp$P4A.M73Jj5CRJym.yLKp62qBEDQhw.u.Orw7IHBpzuD"
  # An optional `tls` object that describes how the TLS certificate will be handled
  # For more information, see "TLS Configuration of an Organization" further in this article.
  # tls:
  #   # (Required) The name of the Secret where the certificate and the key are stored
  #   secretName: alpha-org-tls
  #   # (Optional) The name of cert-manager's Issuer or ClusterIssuer, if certificates are
  #   # automatically provisioned by cert-manager
  #   issuerName: letsencrypt-prod
  #   # (Optional) The resource that `issuerName` refers to; can be Issuer (default)
  #   # or ClusterIssuer
  #   issuerType: ClusterIssuer

You can find the full OpenAPIv3 specification in the Custom Resource Definition (CRD) in the GoodData.CN Helm chart.

Example: A sample YAML definition for deployment with TLS terminated on an Ingress controller and static certificate

apiVersion: anywhere.gooddata.com/v1
kind: Organization
metadata:
  name: alpha-org
spec:
  id: alpha
  name: "Alpha, Corp."
  hostname: analytics.alpha.example.com
  adminGroup: adminGroup
  adminUser: admin
  adminUserToken: "$5$hP8MLrkpLGp$P4A.M73Jj5CRJym.yLKp62qBEDQhw.u.Orw7IHBpzuD"
  tls:
    secretName: alpha-tls

Example: A sample YAML definition for deployment with TLS terminated on a Load Balancer

apiVersion: controllers.gooddata.com/v1
kind: Organization
metadata:
  name: alpha-org
spec:
  id: alpha
  name: "Alpha, Corp."
  hostname: analytics.alpha.example.com
  adminGroup: adminGroup
  adminUser: admin
  adminUserToken: "$5$hP8MLrkpLGp$P4A.M73Jj5CRJym.yLKp62qBEDQhw.u.Orw7IHBpzuD"

Example: A sample YAML definition for deployment with TLS terminated on an Ingress controller and certificates created by cert-manager (using a cluster-wide issuer)

apiVersion: controllers.gooddata.com/v1
kind: Organization
metadata:
  name: alpha-org
spec:
  id: alpha
  name: "Alpha, Corp."
  hostname: analytics.alpha.example.com
  adminGroup: adminGroup
  adminUser: admin
  adminUserToken: "$5$hP8MLrkpLGp$P4A.M73Jj5CRJym.yLKp62qBEDQhw.u.Orw7IHBpzuD"
  tls:
    secretName: alpha-tls
    issuerName: letsencrypt-prod-issuer
    issuerType: ClusterIssuer

TLS Configuration of an Organization

Follow these rules when configuring the spec.tls section of the YAML definition of the Organization custom resource:

  • If TLS is terminated on a Load Balancer, do not add the spec.tls section at all.

  • If TLS is passed to an Ingress controller, add the spec.tls.secretName section and provide the name of the Kubernetes Secret where the Ingress will find the certificate and key in the secretName section. For information about how to create a TLS Secret, see the Kubernetes user documentation.

    Depending on how you want to manage your certificates, do one of the following:

    • If you want to manage the certificates yourself, make sure that the Secret specified in the spec.tls.secretName section exists and contains a valid certificate and key before you start creating an Organization. You do not have to add any other sections.

    • If you want to delegate certificate management to cert-manager, do the following:

      • Add the spec.tls.issuerName section and provide the name of the Issuer (or ClusterIssuer) in it.
      • Add the spec.tls.issuerType section and provide either Issuer or ClusterIssuer in it depending on what kind of the issuer you want to use.

      For information about deployment options, issuers, and solvers, see the cert-manager user documentation.

For more information about available options of the TLS configuration, see Kubernetes Deployment Considerations.

Load the YAML Definition to the Kubernetes Cluster

Use the the kubectl command:

kubectl -n gooddata-cn create -f your-org-definition.yaml

The Organization controller starts processing the request and performs the following tasks:

  • Creates the Organization.
  • Creates a user group (adminGroup) and an administrator (adminUser) for the Organization.
  • Assigns the hash stored in the adminUserToken section of the YAML definition to adminUser.
  • Creates an OAuth2 client in the internal OIDC identity provider.
  • Creates an Ingress resource according to the hostname and tls sections of the YAML definition.

Once you have created the Organization, set up authentication.

Manage the Organizations

Organizations are Kubernetes resources, therefore you can use the standard tools for managing other Kubernetes resources to manage Organizations, for example:

kubectl -n gooddata-cn get org

The output contains all Organizations and their respective hostnames:

NAME         ID         NAME           HOSTNAME
alpha-org    alpha      Alpha, Corp.   analytics.alpha.example.com
beta-org     beta       Beta, Inc.     visualizations.beta.example.com

You can delete, describe, or edit an Organization similar to other Kubernetes resources. When editing an Organization, make changes only in the spec section.

Do not modify status or annotations that were created automatically.