Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs and style fixes, limitrange and HPA implementation #186

Merged
merged 7 commits into from
Dec 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions converter/converters/koki_hpa_to_kube.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package converters

import (
autoscaling "k8s.io/api/autoscaling/v1"

"github.com/koki/short/types"
)

func Convert_Koki_HPA_to_Kube(wrapper *types.HorizontalPodAutoscalerWrapper) (*autoscaling.HorizontalPodAutoscaler, error) {
kube := &autoscaling.HorizontalPodAutoscaler{}
koki := wrapper.HPA

kube.Name = koki.Name
kube.Namespace = koki.Namespace
if len(koki.Version) == 0 {
kube.APIVersion = "autoscaling/v1"
} else {
kube.APIVersion = koki.Version
}
kube.Kind = "HorizontalPodAutoscaler"
kube.ClusterName = koki.Cluster
kube.Labels = koki.Labels
kube.Annotations = koki.Annotations

kube.Spec = revertHPASpec(koki.HorizontalPodAutoscalerSpec)
kube.Status = revertHPAStatus(koki.HorizontalPodAutoscalerStatus)

return kube, nil
}

func revertHPASpec(kokiSpec types.HorizontalPodAutoscalerSpec) autoscaling.HorizontalPodAutoscalerSpec {
return autoscaling.HorizontalPodAutoscalerSpec{
ScaleTargetRef: revertCrossVersionObjectReference(kokiSpec.ScaleTargetRef),
MinReplicas: kokiSpec.MinReplicas,
MaxReplicas: kokiSpec.MaxReplicas,
TargetCPUUtilizationPercentage: kokiSpec.TargetCPUUtilizationPercentage,
}
}

func revertHPAStatus(kokiStatus types.HorizontalPodAutoscalerStatus) autoscaling.HorizontalPodAutoscalerStatus {
return autoscaling.HorizontalPodAutoscalerStatus{
ObservedGeneration: kokiStatus.ObservedGeneration,
LastScaleTime: kokiStatus.LastScaleTime,
CurrentReplicas: kokiStatus.CurrentReplicas,
DesiredReplicas: kokiStatus.DesiredReplicas,
CurrentCPUUtilizationPercentage: kokiStatus.CurrentCPUUtilizationPercentage,
}
}

func revertCrossVersionObjectReference(kokiRef types.CrossVersionObjectReference) autoscaling.CrossVersionObjectReference {
return autoscaling.CrossVersionObjectReference{
Kind: kokiRef.Kind,
Name: kokiRef.Name,
APIVersion: kokiRef.APIVersion,
}
}
81 changes: 81 additions & 0 deletions converter/converters/koki_limitrange_to_kube.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package converters

import (
"k8s.io/api/core/v1"

"github.com/koki/short/types"
serrors "github.com/koki/structurederrors"
)

func Convert_Koki_LimitRange_to_Kube(wrapper *types.LimitRangeWrapper) (*v1.LimitRange, error) {
var err error
kube := &v1.LimitRange{}
koki := wrapper.LimitRange

kube.Name = koki.Name
kube.Namespace = koki.Namespace
if len(koki.Version) == 0 {
kube.APIVersion = "v1"
} else {
kube.APIVersion = koki.Version
}
kube.Kind = "LimitRange"
kube.ClusterName = koki.Cluster
kube.Labels = koki.Labels
kube.Annotations = koki.Annotations

kube.Spec.Limits, err = revertLimitRangeItems(koki.Limits)
if err != nil {
return nil, serrors.ContextualizeErrorf(err, "LimitRange.Spec.Limits")
}

return kube, nil
}

func revertLimitRangeItems(kokiItems []types.LimitRangeItem) ([]v1.LimitRangeItem, error) {
if len(kokiItems) == 0 {
return nil, nil
}

var err error
kubeItems := make([]v1.LimitRangeItem, len(kokiItems))
for i, kokiItem := range kokiItems {
kubeItems[i], err = revertLimitRangeItem(kokiItem)
if err != nil {
return nil, serrors.ContextualizeErrorf(err, "[%d]", i)
}
}

return kubeItems, nil
}

func revertLimitRangeItem(kokiItem types.LimitRangeItem) (v1.LimitRangeItem, error) {
kubeItem := v1.LimitRangeItem{
Max: kokiItem.Max,
Min: kokiItem.Min,
Default: kokiItem.Default,
DefaultRequest: kokiItem.DefaultRequest,
MaxLimitRequestRatio: kokiItem.MaxLimitRequestRatio,
}

var err error
kubeItem.Type, err = revertLimitType(kokiItem.Type)
return kubeItem, err
}

func revertLimitType(kokiType types.LimitType) (v1.LimitType, error) {
if len(kokiType) == 0 {
return "", nil
}

switch kokiType {
case types.LimitTypePod:
return v1.LimitTypePod, nil
case types.LimitTypeContainer:
return v1.LimitTypeContainer, nil
case types.LimitTypePersistentVolumeClaim:
return v1.LimitTypePersistentVolumeClaim, nil
default:
return "", serrors.InvalidInstanceError(kokiType)
}
}
53 changes: 53 additions & 0 deletions converter/converters/kube_hpa_to_koki.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package converters

import (
autoscaling "k8s.io/api/autoscaling/v1"

"github.com/koki/short/types"
)

func Convert_Kube_HPA_to_Koki(kube *autoscaling.HorizontalPodAutoscaler) (*types.HorizontalPodAutoscalerWrapper, error) {
koki := &types.HorizontalPodAutoscaler{}

koki.Name = kube.Name
koki.Namespace = kube.Namespace
koki.Version = kube.APIVersion
koki.Cluster = kube.ClusterName
koki.Labels = kube.Labels
koki.Annotations = kube.Annotations

koki.HorizontalPodAutoscalerSpec = convertHPASpec(kube.Spec)
koki.HorizontalPodAutoscalerStatus = convertHPAStatus(kube.Status)

return &types.HorizontalPodAutoscalerWrapper{
HPA: *koki,
}, nil
}

func convertHPASpec(kubeSpec autoscaling.HorizontalPodAutoscalerSpec) types.HorizontalPodAutoscalerSpec {
return types.HorizontalPodAutoscalerSpec{
ScaleTargetRef: convertCrossVersionObjectReference(kubeSpec.ScaleTargetRef),

MinReplicas: kubeSpec.MinReplicas,
MaxReplicas: kubeSpec.MaxReplicas,
TargetCPUUtilizationPercentage: kubeSpec.TargetCPUUtilizationPercentage,
}
}

func convertHPAStatus(kubeStatus autoscaling.HorizontalPodAutoscalerStatus) types.HorizontalPodAutoscalerStatus {
return types.HorizontalPodAutoscalerStatus{
ObservedGeneration: kubeStatus.ObservedGeneration,
LastScaleTime: kubeStatus.LastScaleTime,
CurrentReplicas: kubeStatus.CurrentReplicas,
DesiredReplicas: kubeStatus.DesiredReplicas,
CurrentCPUUtilizationPercentage: kubeStatus.CurrentCPUUtilizationPercentage,
}
}

func convertCrossVersionObjectReference(kubeRef autoscaling.CrossVersionObjectReference) types.CrossVersionObjectReference {
return types.CrossVersionObjectReference{
Kind: kubeRef.Kind,
Name: kubeRef.Name,
APIVersion: kubeRef.APIVersion,
}
}
77 changes: 77 additions & 0 deletions converter/converters/kube_limitrange_to_koki.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package converters

import (
"k8s.io/api/core/v1"

"github.com/koki/short/types"
serrors "github.com/koki/structurederrors"
)

func Convert_Kube_LimitRange_to_Koki(kube *v1.LimitRange) (*types.LimitRangeWrapper, error) {
var err error
koki := &types.LimitRange{}

koki.Name = kube.Name
koki.Namespace = kube.Namespace
koki.Version = kube.APIVersion
koki.Cluster = kube.ClusterName
koki.Labels = kube.Labels
koki.Annotations = kube.Annotations

koki.Limits, err = convertLimitRangeItems(kube.Spec.Limits)
if err != nil {
return nil, serrors.ContextualizeErrorf(err, "limit_range limits")
}

return &types.LimitRangeWrapper{
LimitRange: *koki,
}, nil
}

func convertLimitRangeItems(kubeItems []v1.LimitRangeItem) ([]types.LimitRangeItem, error) {
if len(kubeItems) == 0 {
return nil, nil
}

var err error
kokiItems := make([]types.LimitRangeItem, len(kubeItems))
for i, kubeItem := range kubeItems {
kokiItems[i], err = convertLimitRangeItem(kubeItem)
if err != nil {
return nil, serrors.ContextualizeErrorf(err, "[%d]", i)
}
}

return kokiItems, nil
}

func convertLimitRangeItem(kubeItem v1.LimitRangeItem) (types.LimitRangeItem, error) {
kokiItem := types.LimitRangeItem{
Max: kubeItem.Max,
Min: kubeItem.Min,
Default: kubeItem.Default,
DefaultRequest: kubeItem.DefaultRequest,
MaxLimitRequestRatio: kubeItem.MaxLimitRequestRatio,
}

var err error
kokiItem.Type, err = convertLimitType(kubeItem.Type)
return kokiItem, err
}

func convertLimitType(kubeItem v1.LimitType) (types.LimitType, error) {
if len(kubeItem) == 0 {
return "", nil
}

switch kubeItem {
case v1.LimitTypePod:
return types.LimitTypePod, nil
case v1.LimitTypeContainer:
return types.LimitTypeContainer, nil
case v1.LimitTypePersistentVolumeClaim:
return types.LimitTypePersistentVolumeClaim, nil
default:
return "", serrors.InvalidInstanceError(kubeItem)
}
}
9 changes: 9 additions & 0 deletions converter/koki_converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
apps "k8s.io/api/apps/v1"
appsv1beta1 "k8s.io/api/apps/v1beta1"
appsv1beta2 "k8s.io/api/apps/v1beta2"
autoscaling "k8s.io/api/autoscaling/v1"
batchv1 "k8s.io/api/batch/v1"
batchv1beta1 "k8s.io/api/batch/v1beta1"
batchv2alpha1 "k8s.io/api/batch/v2alpha1"
Expand Down Expand Up @@ -47,12 +48,16 @@ func DetectAndConvertFromKokiObj(kokiObj interface{}) (interface{}, error) {
return converters.Convert_Koki_Endpoints_to_Kube_v1_Endpoints(kokiObj)
case *types.EventWrapper:
return converters.Convert_Koki_Event_to_Kube(kokiObj)
case *types.HorizontalPodAutoscalerWrapper:
return converters.Convert_Koki_HPA_to_Kube(kokiObj)
case *types.IngressWrapper:
return converters.Convert_Koki_Ingress_to_Kube_Ingress(kokiObj)
case *types.InitializerConfigWrapper:
return converters.Convert_Koki_InitializerConfig_to_Kube_InitializerConfig(kokiObj)
case *types.JobWrapper:
return converters.Convert_Koki_Job_to_Kube_Job(kokiObj)
case *types.LimitRangeWrapper:
return converters.Convert_Koki_LimitRange_to_Kube(kokiObj)
case *types.NamespaceWrapper:
return converters.Convert_Koki_Namespace_to_Kube_Namespace(kokiObj)
case *types.PersistentVolumeClaimWrapper:
Expand Down Expand Up @@ -110,12 +115,16 @@ func DetectAndConvertFromKubeObj(kubeObj runtime.Object) (interface{}, error) {
return converters.Convert_Kube_v1_Endpoints_to_Koki_Endpoints(kubeObj)
case *v1.Event:
return converters.Convert_Kube_Event_to_Koki(kubeObj)
case *autoscaling.HorizontalPodAutoscaler:
return converters.Convert_Kube_HPA_to_Koki(kubeObj)
case *exts.Ingress:
return converters.Convert_Kube_Ingress_to_Koki_Ingress(kubeObj)
case *admissionregv1alpha1.InitializerConfiguration:
return converters.Convert_Kube_InitializerConfig_to_Koki_InitializerConfig(kubeObj)
case *batchv1.Job:
return converters.Convert_Kube_Job_to_Koki_Job(kubeObj)
case *v1.LimitRange:
return converters.Convert_Kube_LimitRange_to_Koki(kubeObj)
case *v1.Namespace:
return converters.Convert_Kube_Namespace_to_Koki_Namespace(kubeObj)
case *v1.PersistentVolume:
Expand Down
42 changes: 42 additions & 0 deletions docs/resources/controller-revision.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Introduction

ControllerRevision is an immutable snapshot of state.
It's primarily intended for internal use by controllers.
For example, it's used by the DaemonSet and StatefulSet controllers for update and rollback.

Here's an example Kubernetes ControllerRevision:
```yaml
apiVersion: apps/v1
kind: ControllerRevision
metadata:
name: example
data:
key: value
revision: 1
```

The following sections contain detailed information about each field in Short syntax, including how the field translates to and from Kubernetes syntax.

# API Overview

| Field | Type | K8s counterpart(s) | Description |
|:------|:-----|:--------|:-----------------------|
|version| `string` | `apiVersion` | The version of the resource object |
|cluster| `string` | `metadata.clusterName` | The name of the cluster on which this Job is running |
|name | `string` | `metadata.name`| The name of the Job |
|namespace | `string` | `metadata.namespace` | The K8s namespace this Job will be a member of |
|labels | `string` | `metadata.labels`| Metadata about the Job, including identifying information |
|annotations| `string` | `metadata.annotations`| Non-identifying information about the Job |
|data| YAML | `data` | This field can hold any valid YAML. |
|revision| `int64` | The revision number |

# Examples / Skeleton

Here's a starter skeleton of a Short ControllerRevision.
```yaml
controller_revision:
name: example
data:
key: value
revision: 1
```
Loading