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

Adding Rate Limiting kind #2

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
# k8s-apim-operator
# k8s-apim-operator
1 change: 1 addition & 0 deletions apim-operator/build/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ ENV OPERATOR=/usr/local/bin/apim-operator \

# install operator binary
COPY build/_output/bin/apim-operator ${OPERATOR}
COPY build/policy.mustache /usr/local/bin

COPY build/bin /usr/local/bin
RUN /usr/local/bin/user_setup
Expand Down
58 changes: 58 additions & 0 deletions apim-operator/build/policy.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import ballerina/io;
import ballerina/runtime;
import ballerina/http;
import ballerina/log;
import wso2/gateway;

stream<gateway:IntermediateStream> s{{name}}intermediateStream = new;
stream<gateway:GlobalThrottleStreamDTO> s{{name}}resultStream = new;
stream<gateway:EligibilityStreamDTO> s{{name}}eligibilityStream = new;
stream<gateway:RequestStreamDTO> s{{name}}reqCopy= gateway:requestStream;
stream<gateway:GlobalThrottleStreamDTO> s{{name}}globalThrotCopy = gateway:globalThrottleStream;

function {{funcName}}() {

forever {
from s{{name}}reqCopy
select s{{name}}reqCopy.messageID as messageID, (s{{name}}reqCopy.{{tierType}} == "{{name}}") as
isEligible, s{{name}}reqCopy.{{policyKey}} as throttleKey, 0 as expiryTimestamp
=> (gateway:EligibilityStreamDTO[] counts) {
foreach var c in counts{
s{{name}}eligibilityStream.publish(c);
}
}

from s{{name}}eligibilityStream
throttler:timeBatch({{unitTime}})
where s{{name}}eligibilityStream.isEligible == true
select s{{name}}eligibilityStream.throttleKey as throttleKey, count() as eventCount, {{stopOnQuotaReach}} as
stopOnQuota, expiryTimeStamp
group by s{{name}}eligibilityStream.throttleKey
=> (gateway:IntermediateStream[] counts) {
foreach var c in counts{
s{{name}}intermediateStream.publish(c);
}
}

from s{{name}}intermediateStream
select s{{name}}intermediateStream.throttleKey, s{{name}}intermediateStream.eventCount>= {{count}} as isThrottled,
s{{name}}intermediateStream.stopOnQuota, s{{name}}intermediateStream.expiryTimeStamp
group by s{{name}}eligibilityStream.throttleKey
=> (gateway:GlobalThrottleStreamDTO[] counts) {
foreach var c in counts{
s{{name}}resultStream.publish(c);
}
}

from s{{name}}resultStream
throttler:emitOnStateChange(s{{name}}resultStream.throttleKey, s{{name}}resultStream.isThrottled)
select s{{name}}resultStream.throttleKey as throttleKey, s{{name}}resultStream.isThrottled,
s{{name}}resultStream.stopOnQuota, s{{name}}resultStream.expiryTimeStamp
=> (gateway:GlobalThrottleStreamDTO[] counts) {
foreach var c in counts{
s{{name}}globalThrotCopy.publish(c);
}
}
}
}

9 changes: 1 addition & 8 deletions apim-operator/cmd/manager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
"github.com/apim-crd/apim-operator/pkg/apis"
"github.com/apim-crd/apim-operator/pkg/controller"

"github.com/operator-framework/operator-sdk/pkg/k8sutil"
"github.com/operator-framework/operator-sdk/pkg/leader"
"github.com/operator-framework/operator-sdk/pkg/log/zap"
"github.com/operator-framework/operator-sdk/pkg/metrics"
Expand Down Expand Up @@ -62,12 +61,6 @@ func main() {

printVersion()

namespace, err := k8sutil.GetWatchNamespace()
if err != nil {
log.Error(err, "Failed to get watch namespace")
os.Exit(1)
}

// Get a config to talk to the apiserver
cfg, err := config.GetConfig()
if err != nil {
Expand All @@ -86,7 +79,7 @@ func main() {

// Create a new Cmd to provide shared dependencies and start components
mgr, err := manager.New(cfg, manager.Options{
Namespace: namespace,
Namespace: "",
MapperProvider: restmapper.NewDynamicRESTMapper,
MetricsBindAddress: fmt.Sprintf("%s:%d", metricsHost, metricsPort),
})
Expand Down
25 changes: 25 additions & 0 deletions apim-operator/deploy/crds/wso2_v1alpha1_ratelimiting_cr.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
apiVersion: wso2.com/v1alpha1
kind: RateLimiting
metadata:
name: testing1-ratelimiting
spec:
type: subscription # application ,subscription
description: Allow 1000 requests per minute # optional
timeUnit: min # min or sec
unitTime: 1
requestCount:
limit: 1000
bandwidth: # optional
dataAmount: ""
dataUnit: ""
stopOnQuotaReach: false # not required for application policies
conditions: # optional
headerCondition:
headerName: “host”
headerValue: “abc.com”
ipCondition:
type: ipRange
specificIp: ""
negation : no
startIp: 10.100.7.2
endIp: 10.100.7.255
106 changes: 106 additions & 0 deletions apim-operator/deploy/crds/wso2_v1alpha1_ratelimiting_crd.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ratelimitings.wso2.com
spec:
group: wso2.com
names:
kind: RateLimiting
listKind: RateLimitingList
plural: ratelimitings
singular: ratelimiting
scope: Namespaced
subresources:
status: {}
validation:
openAPIV3Schema:
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
properties:
bandwidth:
properties:
dataAmount:
type: string
dataUnit:
type: string
required:
- dataAmount
- dataUnit
type: object
conditions:
properties:
headerCondition:
properties:
headerName:
type: string
headerValue:
type: string
required:
- headerName
- headerValue
type: object
ipCondition:
properties:
endIp:
type: string
negation:
type: boolean
specificIp:
type: string
startIp:
type: string
type:
type: string
required:
- type
- specificIp
- negation
- startIp
- endIp
type: object
required:
- headerCondition
- ipCondition
type: object
description:
type: string
requestCount:
properties:
limit:
format: int64
type: integer
required:
- limit
type: object
stopOnQuotaReach:
type: boolean
timeUnit:
type: string
type:
type: string
unitTime:
format: int64
type: integer
required:
- type
- timeUnit
- unitTime
- requestCount
type: object
version: v1alpha1
versions:
- name: v1alpha1
served: true
storage: true
6 changes: 6 additions & 0 deletions apim-operator/deploy/namespace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Namespace
apiVersion: v1
metadata:
name: wso2-system
labels:
name: wso2-system
7 changes: 3 additions & 4 deletions apim-operator/deploy/operator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: apim-operator
namespace: wso2-system
spec:
replicas: 1
selector:
Expand All @@ -16,15 +17,13 @@ spec:
containers:
- name: apim-operator
# Replace this with the built image name
image: pubudu/apim-operator:1.0.0
image: rameshakaru/api-operator:v0.0.1
command:
- apim-operator
imagePullPolicy: Always
env:
- name: WATCH_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
value: ""
- name: POD_NAME
valueFrom:
fieldRef:
Expand Down
4 changes: 3 additions & 1 deletion apim-operator/deploy/role.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
kind: ClusterRole
metadata:
creationTimestamp: null
name: apim-operator
namespace: wso2-system
rules:
- apiGroups:
- ""
Expand Down Expand Up @@ -44,5 +45,6 @@ rules:
- wso2.com
resources:
- '*'
- ratelimitings
verbs:
- '*'
7 changes: 5 additions & 2 deletions apim-operator/deploy/role_binding.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
kind: RoleBinding
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: apim-operator
namespace: wso2-system
subjects:
- kind: ServiceAccount
name: apim-operator
# Replace this with the namespace the operator is deployed in.
namespace: wso2-system
roleRef:
kind: Role
kind: ClusterRole
name: apim-operator
apiGroup: rbac.authorization.k8s.io
1 change: 1 addition & 0 deletions apim-operator/deploy/service_account.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ apiVersion: v1
kind: ServiceAccount
metadata:
name: apim-operator
namespace: wso2-system
90 changes: 90 additions & 0 deletions apim-operator/pkg/apis/wso2/v1alpha1/ratelimiting_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package v1alpha1

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.

// RateLimitingSpec defines the desired state of RateLimiting
// +k8s:openapi-gen=true
type RateLimitingSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "operator-sdk generate k8s" to regenerate code after modifying this file
// Add custom validation using kubebuilder tags: https://book.kubebuilder.io/beyond_basics/generating_crd.html

Type string `json:"type"`
TimeUnit string `json:"timeUnit"`
UnitTime int `json:"unitTime"`
RequestCount RequestCount `json:"requestCount"`
StopOnQuotaReach bool `json:"stopOnQuotaReach"`
Description string `json:"description"`
Bandwidth Bandwidth `json:"bandwidth"`
Conditions Conditions `json:"conditions"`
}

//RequestCount is exported type in Ratelimiting Spec
type RequestCount struct {
Limit int `json:"limit"`
}

//Bandwidth is exported type in Ratelimiting Spec
type Bandwidth struct {
DataAmount string `json:"dataAmount"`
DataUnit string `json:"dataUnit"`
}

//Conditions is exported type in Ratelimiting Spec
type Conditions struct {
HeaderCondition HeaderCondition `json:"headerCondition"`
IPCondition IPCondition `json:"ipCondition"`
}

//HeaderCondition is exported type in Ratelimiting Spec
type HeaderCondition struct {
HeaderName string `json:"headerName"`
HeaderValue string `json:"headerValue"`
}

//IPCondition is exported type in Ratelimiting Spec
type IPCondition struct {
Type string `json:"type"`
SpecificIP string `json:"specificIp"`
Negation bool `json:"negation"`
StartIP string `json:"startIp"`
EndIP string `json:"endIp"`
}

// RateLimitingStatus defines the observed state of RateLimiting
// +k8s:openapi-gen=true
type RateLimitingStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "operator-sdk generate k8s" to regenerate code after modifying this file
// Add custom validation using kubebuilder tags: https://book.kubebuilder.io/beyond_basics/generating_crd.html
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// RateLimiting is the Schema for the ratelimitings API
// +k8s:openapi-gen=true
type RateLimiting struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec RateLimitingSpec `json:"spec,omitempty"`
//Status RateLimitingStatus `json:"status,omitempty"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// RateLimitingList contains a list of RateLimiting
type RateLimitingList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []RateLimiting `json:"items"`
}

func init() {
SchemeBuilder.Register(&RateLimiting{}, &RateLimitingList{})
}
Loading