Skip to content

Commit

Permalink
Merge pull request #11 from appuio/feat/organizations
Browse files Browse the repository at this point in the history
Add Organization type
  • Loading branch information
glrf authored Jan 6, 2022
2 parents f1d11a7 + 3d2103e commit f7008bc
Show file tree
Hide file tree
Showing 24 changed files with 2,200 additions and 5 deletions.
1 change: 1 addition & 0 deletions .codeclimate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ exclude_patterns:
- '**/*.d.ts'
- 'e2e/lib/'
- '**/zz_generated.deepcopy.go'
- '**/mock/'
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,6 @@ crd*.yaml

# Go releaser
dist/

# apiserver-runtime
apiserver.local.config/
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ build: generate fmt vet $(BIN_FILENAME) ## Build manager binary

.PHONY: generate
generate: ## Generate manifests e.g. CRD, RBAC etc.
go generate ./...
# Generate code
go run sigs.k8s.io/controller-tools/cmd/controller-gen object paths="./..."
# Generate CRDs
Expand Down Expand Up @@ -58,6 +59,11 @@ build.docker: $(BIN_FILENAME) ## Build the docker image
clean: ## Cleans up the generated resources
rm -rf dist/ cover.out $(BIN_FILENAME) || true

.PHONY: run
KUBECONFIG ?= ~/.kube/config
run: build ## Starts control api against the configured kuberentes cluster
$(BIN_FILENAME) --secure-port 9443 --kubeconfig $(KUBECONFIG) --authentication-kubeconfig $(KUBECONFIG) --authorization-kubeconfig $(KUBECONFIG)

.PHONY: local-env
local-env-setup: ## Setup local kind-based dev environment
$(localenv_make) setup
Expand Down
59 changes: 59 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,62 @@ See the [local-env/README.md](./local-env/README.md) for more details on the loc
Please be aware that the productive deployment of the control-api may run on a different Kubernetes distribution than [kind].

[kind]: https://kind.sigs.k8s.io/


### Running the control-api locally

You can run the control-api locally against the currently configured Kubernetes cluster with

```bash
make run
```

To access the locally running API server you need to register it with the [kind]-based local environment.
You can do this by applying the following.


The `externalName` needs to be changed to your specific host IP.
When running kind on Linux you can find it with `docker inspect


```bash
HOSTIP=$(docker inspect control-api-v1.22.1-control-plane | jq '.[0].NetworkSettings.Networks.kind.Gateway')

cat <<EOF | sed -e "s/172.21.0.1/$HOSTIP/g" | kubectl apply -f -
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
name: v1.organization.appuio.io
spec:
insecureSkipTLSVerify: true
group: organization.appuio.io
groupPriorityMinimum: 1000
versionPriority: 15
service:
name: apiserver
namespace: default
port: 9443
version: v1
---
apiVersion: v1
kind: Service
metadata:
name: apiserver
namespace: default
spec:
ports:
- port: 9443
protocol: TCP
targetPort: 9443
type: ExternalName
externalName: 172.21.0.1 # Change to host IP
EOF
```


After that you should be able to access your (with `make run` running) API server with

```bash
kubectl get organizations
```

21 changes: 21 additions & 0 deletions apis/organization/v1/groupversion_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Package v1 contains API Schema definitions for the control-api v1 API group
// +kubebuilder:object:generate=true
// +kubebuilder:skip
// +groupName=organization.appuio.io
package v1

import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/scheme"
)

var (
// GroupVersion is group version used to register these objects
GroupVersion = schema.GroupVersion{Group: "organization.appuio.io", Version: "v1"}

// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}

// AddToScheme adds the types in this group-version to the given scheme.
AddToScheme = SchemeBuilder.AddToScheme
)
131 changes: 131 additions & 0 deletions apis/organization/v1/organization_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package v1

import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/apiserver-runtime/pkg/builder/resource"
)

var (
// TypeKey is the label key to identify organization namespaces
TypeKey = "appuio.io/resource.type"
// OrgType is the label value to identify organization namespaces
OrgType = "organization"
// DisplayNameKey is the annotation key that stores the display name
DisplayNameKey = "organization.appuio.io/display-name"
)

// NewOrganizationFromNS returns an Organization based on the given namespace
// If the namespace does not represent an organization it will return nil
func NewOrganizationFromNS(ns *corev1.Namespace) *Organization {
if ns == nil || ns.Labels == nil || ns.Labels[TypeKey] != OrgType {
return nil
}
displayName := ""
if ns.Annotations != nil {
displayName = ns.Annotations[DisplayNameKey]
}
org := &Organization{
ObjectMeta: *ns.ObjectMeta.DeepCopy(),
Spec: OrganizationSpec{
DisplayName: displayName,
},
}
if org.Annotations != nil {
delete(org.Annotations, DisplayNameKey)
delete(org.Labels, TypeKey)
}
return org
}

// +kubebuilder:object:root=true

// Organization is a representation of an APPUiO Cloud Organization
type Organization struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

// Spec holds the cluster specific metadata.
Spec OrganizationSpec `json:"spec,omitempty"`
}

// OrganizationSpec defines the desired state of the Organization
type OrganizationSpec struct {
// DisplayName is a human-friendly name
DisplayName string `json:"displayName,omitempty"`
}

// Organization needs to implement the builder resource interface
var _ resource.Object = &Organization{}

// GetObjectMeta returns the objects meta reference.
func (o *Organization) GetObjectMeta() *metav1.ObjectMeta {
return &o.ObjectMeta
}

// GetGroupVersionResource returns the GroupVersionResource for this resource.
// The resource should be the all lowercase and pluralized kind
func (o *Organization) GetGroupVersionResource() schema.GroupVersionResource {
return schema.GroupVersionResource{
Group: GroupVersion.Group,
Version: GroupVersion.Version,
Resource: "organizations",
}
}

// IsStorageVersion returns true if the object is also the internal version -- i.e. is the type defined for the API group or an alias to this object.
// If false, the resource is expected to implement MultiVersionObject interface.
func (o *Organization) IsStorageVersion() bool {
return true
}

// NamespaceScoped returns true if the object is namespaced
func (o *Organization) NamespaceScoped() bool {
return false
}

// New returns a new instance of the resource
func (o *Organization) New() runtime.Object {
return &Organization{}
}

// NewList return a new list instance of the resource
func (o *Organization) NewList() runtime.Object {
return &OrganizationList{}
}

// +kubebuilder:object:root=true

// OrganizationList contains a list of Organizations
type OrganizationList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`

Items []Organization `json:"items"`
}

// OrganizationList needs to implement the builder resource interface
var _ resource.ObjectList = &OrganizationList{}

// GetListMeta returns the list meta reference.
func (in *OrganizationList) GetListMeta() *metav1.ListMeta {
return &in.ListMeta
}

// ToNamespace translates an Organization to the underlying namespace representation
func (o *Organization) ToNamespace() *corev1.Namespace {
ns := &corev1.Namespace{
ObjectMeta: *o.ObjectMeta.DeepCopy(),
}
if ns.Labels == nil {
ns.Labels = map[string]string{}
}
if ns.Annotations == nil {
ns.Annotations = map[string]string{}
}
ns.Labels[TypeKey] = OrgType
ns.Annotations[DisplayNameKey] = o.Spec.DisplayName
return ns
}
Loading

0 comments on commit f7008bc

Please sign in to comment.