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

Capabilities: Initial functionality scenarios #2

Closed
jmprusi opened this issue Nov 22, 2018 · 3 comments
Closed

Capabilities: Initial functionality scenarios #2

jmprusi opened this issue Nov 22, 2018 · 3 comments
Labels
capabilities managing 3scale

Comments

@jmprusi
Copy link
Contributor

jmprusi commented Nov 22, 2018

The capabilities part of the 3scale-operator is meant to configure an already existing deployment of 3scale.

The main focus of this part of the operator is to better integrate 3scale in the CI/CD flows, and allow the user to configure and operate the 3scale account in a more cloud-native way.

Requirements

  • Using this operator shouldn't require any other tool than the openshift CLI and some editor

Scenarios

Scenario 1

I'm a hobbyist, and I have an API in a production environment, that I want to deploy using continuous integration to OpenShift Online using 3scale SaaS.
My Git repository includes source code, API management definition for the production environment.

Option Jenkins

If Jenkins is available, we can provide a pipeline that builds the app using build config and updates the API management in k8s. The developer can customise the order of those steps.

Option BuildConfig

BuildConfig can take API management definitions from the source code and push them to k8s or push to an ImageStream, that deploys DeploymentConfig and pushes those objects to k8s.

Scenario 2

I'm a development team that has several APIs in several GitHub repositories deployed in several OpenShift projects using one 3scale deployed in own project.

Each of those projects is going to need a Service in 3scale, as they are publicly exposed APIs.

Scenario 3

Same as scenario 2, but I want to expose them as one facade service. Each API would configure its limits, but the shared configuration would be managed in the 3scale project.

Scenario 4

I'm a development team that has both production and staging environment deployed in one OpenShift project, because of some shared resource. I'd like to have API management for both environments in one project using two different tenants.

Scenario 5

I'm driving my application through several stages (development, staging, production) and want to have API management configuration versioned with it.

The workflow looks like:

  • Open a PR
    • Deploy a "review branch" to a new, isolated OpenShift project
    • Configure API management for that deployed project
  • Merge PR
    • Deploy the app master branch to the staging environment project
    • Configure API management for that deployed project
  • Deploy to production
    • Deploy the last staging revision to the production environment project
    • Configure API management for that deployed project
  • Rollback production deployment
    • Rollback the last deployment to production
    • Rollback the last API management change

The challenge is two-fold:

  • Keep the Gateway configuration up-to-date with changes to the backend between environments
  • Rollback API management configuration (for example removing plan, etc.)

Scenario 6

Like scenario 5, but with different objects in some stages:

  • Development environment has different limits and plans.

  • Staging environment has signup disabled.

Scenario 7

I have a complex plan structure, that has many common limits. I'd like to share those limits between application plans.

Option override

Plans A,B and C share common limits 100 hits/day, but Plan C has 1000 limits a day.

Scenario 8

I'm taking a design-first and want to use OAI spec to drive the metrics definition.
By creating the OIS spec in OpenShift I expect to not have to create Metrics by hand and just create Limits.

Scenario 9

I'm deploying my app to staging and production environment on a different OpenShift clusters, using different 3scale Tenant and using the same upstream host.
I'd like those two Services to be managed by one custom resource.

Option

The staging and production environments have just different upstream, otherwise all settings are the same. Living in different Tenants and Clusters.

@jmprusi
Copy link
Contributor Author

jmprusi commented Nov 22, 2018

I need some help defining proper scenarios to cover in the first iteration of the 3scale "Capabilities" operator. There's no formal definition anywhere, so this will allow us to make some design decisions.

@andrewdavidmackenzie @mikz @vramosp

@mikz
Copy link
Contributor

mikz commented Nov 27, 2018

Scenario 1

I'm a hobbyist, and I have an API in a production environment, that I want to deploy using continuous integration to OpenShift Online using 3scale SaaS.
My Git repository includes source code, API management definition for the production environment.

Option Jenkins

If Jenkins is available, we can provide a pipeline that builds the app using build config and updates the API management in k8s. The developer can customise the order of those steps.

Option BuildConfig

BuildConfig can take API management definitions from the source code and push them to k8s or push to an ImageStream, that deploys DeploymentConfig and pushes those objects to k8s.

Scenario 2

I'm a development team that has several APIs in several GitHub repositories deployed in several OpenShift projects using one 3scale deployed in own project.

Each of those projects is going to need a Service in 3scale, as they are publicly exposed APIs.

Scenario 3

Same as scenario 2, but I want to expose them as one facade service. Each API would configure its limits, but the shared configuration would be managed in the 3scale project.

Scenario 4

I'm a development team that has both production and staging environment deployed in one OpenShift project, because of some shared resource. I'd like to have API management for both environments in one project using two different tenants.

Scenario 5

I'm driving my application through several stages (development, staging, production) and want to have API management configuration versioned with it.

The workflow looks like:

  • Open a PR
    • Deploy a "review branch" to a new, isolated OpenShift project
    • Configure API management for that deployed project
  • Merge PR
    • Deploy the app master branch to the staging environment project
    • Configure API management for that deployed project
  • Deploy to production
    • Deploy the last staging revision to the production environment project
    • Configure API management for that deployed project
  • Rollback production deployment
    • Rollback the last deployment to production
    • Rollback the last API management change

The challenge is two-fold:

  • Keep the Gateway configuration up-to-date with changes to the backend between environments
  • Rollback API management configuration (for example removing plan, etc.)

Scenario 6

Like scenario 5, but with different objects in some stages:

  • Development environment has different limits and plans.

  • Staging environment has signup disabled.

Scenario 7

I have a complex plan structure, that has many common limits. I'd like to share those limits between application plans.

Option override

Plans A,B and C share common limits 100 hits/day, but Plan C has 1000 limits a day.

Scenario 8

I'm taking a design-first and want to use OAI spec to drive the metrics definition.
By creating the OIS spec in OpenShift I expect to not have to create Metrics by hand and just create Limits.

Scenario 9

I'm deploying my app to staging and production environment on a different OpenShift clusters, using different 3scale Tenant and using the same upstream host.
I'd like those two Services to be managed by one custom resource.

Option

The staging and production environments have just different upstream, otherwise all settings are the same. Living in different Tenants and Clusters.

@jmprusi
Copy link
Contributor Author

jmprusi commented Nov 29, 2018

Proposed Solutions

Objects reference

                              ┌───────────────┐          ┌ ─ ─ ─ ─ ─ ─ ─ ─                      ┌ ─ ─ ─ ─ ─ ─ ─ ─ 
                              │               │                           │                                      │
                              │               │ Creates  │  Credentials                         │  Credentials    
                              │    Tenant     │─ ─ ─ ─ ─▶      Secret     │                           Secret     │
                              │               │          │                                      │                 
                              │               │           ─ ─ ─ ─ ─ ─ ─ ─ ┘                      ─ ─ ─ ─ ─ ─ ─ ─ ┘
                              └───────────────┘                   ▲                                      ▲        
                                                                  │                                 ObjectRef     
                                                                  │                                      │        
                                                              ObjectRef                                  │        
                                                                  │                               ┌─────────────┐ 
                                                          ┌───────────────┐                       │             │ 
                                                          │               │                       │   Binding   │ 
                                                          │    Binding    │                       │             │ 
                                                          │               │                       └─────────────┘ 
                                                          └───────────────┘                              │        
                                                               Selector                              Selector     
                                                                  │ └───────────────────┐                │        
                                                                  ▼                     ▼                ▼        
                      ┌─────────────────┐                  ┌────────────┐        ┌────────────┐   ┌────────────┐  
                      │                 │                  │            │        │            │   │            │  
       ┌───Selector───│IntegrationMethod│◀───ObjectRef─────│    API     │        │    API     │   │    API     │  
       │              │                 │                  │            │        │            │   │            │  
       │              └─────────────────┘                  └────────────┘        └────────────┘   └────────────┘  
       │                       │                               │  │ │                   │                │        
       │          ┌────────────┘                               Selector             Selector             │        
       │          │   Selector                ┌────────────────┘  │ └─────────────────┐ │             Selector    
       │          ▼                           │                   │                   │ │                │        
       │  ┌──────────────┐                    ▼                   ▼                   ▼ ▼                ▼        
       │  │ ┌────────────┴─┐           ┌─────────────┐     ┌─────────────┐     ┌─────────────┐    ┌─────────────┐ 
       │  │ │ ┌────────────┴─┐         │ ┌───────────┴─┐   │             │     │             │    │             │ 
       │  │ │ │              ├────────▶│ │             │   │    Plan     │     │    Plan     │    │             │ 
       │  └─┤ │ MappingRules │─────────┼▶│   Metric    │   │             │     │             │    │             │ 
       │    └─┤              │         └─┤             │   └─────────────┘     └─────────────┘    │             │ 
       │      └──────────────┘ObjectRef  └─────────────┘          │                   │           │     ...     │ 
       │                                        ▲             Selector             Selector       │             │ 
       ▼                                        │                 │                   │           │             │ 
┌─────────────┐                                 │                 ▼                   ▼           │             │ 
│ ┌───────────┴─┐                               │        ┌─────────────┐       ┌─────────────┐    │             │ 
│ │ ┌───────────┴─┐                             │        │ ┌───────────┴─┐     │             │    └─────────────┘ 
│ │ │             │                             │        │ │ ┌───────────┴─┐   │             │                    
└─┤ │  Policies   │                             │        │ │ │             │   │             │                    
  └─┤             │                             │        └─┤ │    Limit    │   │             │                    
    └─────────────┘                             │          └─┤             │   │     ...     │                    
                                                │            └─────────────┘   │             │                    
                                                │                   │          │             │                    
                                                │                   │          │             │                    
                                                └────ObjectRef──────┘          │             │                    
                                                                               └─────────────┘                    

Scenario 1

I'm a hobbyist, and I have an API in a production environment, that I want to deploy using continuous integration to OpenShift Online using 3scale SaaS.
My Git repository includes source code, API management definition for the production environment.

Solution:

apiVersion: v1
kind: Secret
metadata:
  name: saascredentials
type: Opaque
data:
  accessToken: XXXXXXXXXXXXXXXXXXXXXX
  adminURL: https://myAccount-admin.3scale.net/
---
apiVersion: api.3scale.net/v1alpha1
kind: BINDING
metada:
  name: mySaaSAccount
spec:
  SecretRef:
    name: saascredentials
  APISelector:
    matchLabels:
       environment: production
----
apiVersion: api.3scale.net/v1alpha1
kind: API
metadata:
  name: myapi
  labels:
     environment: production
spec:
  description: "3scale service for my awesome api"
  integrationMethodRef: apicastIntegration
  PlanSelector:
    matchLabel: 
      environment: production
      api: myapi
  metricSelector:
    matchLabel: 
      api: myapi
  # This object requires more fields for defining the integration method and other settings.
----
apiVersion: api.3scale.net/v1alpha1
kind: PLAN
metadata:
  name: basic
  labels:
    environment: production
    api: myapi
spec:
  trialPeriod: 10
  aprovalRequired: true
  costs:
    - setupFee: 0
    - costMonth: 10
  limitSelector:
    matchLabels:
      plan: basic
----
apiVersion: api.3scale.net/v1alpha1
kind: METRIC
metadata:
  name: list_apps
  labels:
    api: myapi
spec:
  description: "Example method" 
  unit: hit
  incrementHits: true
----
apiVersion: api.3scale.net/v1alpha1
kind: METRIC
metadata:
  name: create_app
  labels:
    api: myapi
spec:
  unit: hit 
  description: "Example metric" 
----
apiVersion: api.3scale.net/v1alpha1
kind: LIMIT
metadata:
  name: list_apps_eternity_100
  labels:
    plan: basic
spec:
  metric:
    name: list_apps
  description: "Limit for list_apps in basic plan"
  period: enternity
  maxValue: 100
---- 
apiVersion: api.3scale.net/v1alpha1
kind: LIMIT
metadata:
  name: list_apps_month_1
  labels:
    api: myapi
    plan: basic
spec:
  metric:
    name: list_apps
  description: "Limit for list_apps in basic plan"
  period: month
  maxValue: 1

Scenario 2

I'm a development team that has several APIs in several GitHub repositories deployed in several OpenShift projects using one 3scale deployed in own project.

Each of those projects is going to need a Service in 3scale, as they are publicly exposed APIs.

Solution:

Using the tenant objects, an operator watching all namespaces will be able to create a new tenant.

That operator should have a 3scale Master Credential, so it can create tenants on a 3scale deployment.

apiVersion: api.3scale.net/v1alpha1
kind: TENANT
metada:
  name: projectTenant
spec:
  crendentialSecretName: projectcredentials
  APISelector:
    matchLabels:
       environment: production
----
apiVersion: api.3scale.net/v1alpha1
kind: BINDING
metada:
  name: project
spec:
  SecretRef:
    name: projectcredentials
  APISelector:
    matchLabels:
       environment: production
----
apiVersion: api.3scale.net/v1alpha1
kind: API
metadata:
  name: myapi
  labels:
     environment: production
spec:
  description: "3scale service for my awesome api"
  integrationMethodRef: apicastIntegration
  PlanSelector:
    matchLabel: 
      environment: production
      api: myapi
  metricSelector:
    matchLabel: 
      api: myapi
  # This object requires more fields for defining the integration method and other settings.
----
apiVersion: api.3scale.net/v1alpha1
kind: API
metadata:
  name: myapi2
  labels:
     environment: production
spec:
  description: "3scale service for my awesome api"
  integrationMethodRef: apicastIntegration
  PlanSelector:
    matchLabel: 
      environment: production
      api: myapi
  metricSelector:
    matchLabel: 
      api: myapi
----
apiVersion: api.3scale.net/v1alpha1
kind: PLAN
metadata:
  name: basic
  labels:
    environment: production
    api: myapi
spec:
  trialPeriod: 10
  aprovalRequired: true
  costs:
    - setupFee: 0
    - costMonth: 10
  limitSelector:
    matchLabels:
      plan: basic
----
apiVersion: api.3scale.net/v1alpha1
kind: METRIC
metadata:
  name: list_apps
  labels:
    api: myapi
spec:
  description: "Example method" 
  unit: hit
  incrementHits: true
----
apiVersion: api.3scale.net/v1alpha1
kind: METRIC
metadata:
  name: create_app
  labels:
    api: myapi
spec:
  unit: hit 
  description: "Example metric" 
----
apiVersion: api.3scale.net/v1alpha1
kind: LIMIT
metadata:
  name: list_apps_eternity_100
  labels:
    plan: basic
spec:
  metric:
    name: list_apps
  description: "Limit for list_apps in basic plan"
  period: enternity
  maxValue: 100
---- 
apiVersion: api.3scale.net/v1alpha1
kind: LIMIT
metadata:
  name: list_apps_month_1
  labels:
    api: myapi
    plan: basic
spec:
  metric:
    name: list_apps
  description: "Limit for list_apps in basic plan"
  period: month
  maxValue: 1

Scenario 3

Same as scenario 2, but I want to expose them as one facade service. Each API would configure its limits, but the shared configuration would be managed in the 3scale project.

Scenario 4

I'm a development team that has both production and staging environment deployed in one OpenShift project, because of some shared resource. I'd like to have API management for both environments in one project using two different tenants.

Solution:

apiVersion: api.3scale.net/v1alpha1
kind: TENANT
metada:
  name: production
spec:
  crendentialSecretName: production
  APISelector:
    matchLabels:
       environment: production
----
apiVersion: api.3scale.net/v1alpha1
kind: TENANT
metada:
  name: staging
spec:
  crendentialSecretName: staging
  APISelector:
    matchLabels:
       environment: staging
----
apiVersion: api.3scale.net/v1alpha1
kind: BINDING
metada:
  name: production
spec:
  SecretRef:
    name: production
  APISelector:
    matchLabels:
       environment: production
----`
apiVersion: api.3scale.net/v1alpha1
kind: BINDING
metada:
  name: staging
spec:
  SecretRef:
    name: staging
  APISelector:
    matchLabels:
       environment: staging
----
apiVersion: api.3scale.net/v1alpha1
kind: API
metadata:
  name: myapi
  labels:
     environment: production
spec:
  description: "3scale service for my awesome api"
  integrationMethodRef: apicastIntegration
  PlanSelector:
    matchLabel: 
      environment: production
      api: myapi
  metricSelector:
    matchLabel: 
      api: myapi
----
apiVersion: api.3scale.net/v1alpha1
kind: API
metadata:
  name: myapi
  labels:
     environment: staging
spec:
  description: "3scale service for my awesome api"
  PlanSelector:
    matchLabel: 
      environment: staging
      api: myapi
  metricSelector:
    matchLabel: 
      environment: staging
      api: myapi
----
#
#  Application plans, limits, metrics...
# ...

Scenario 5

I'm driving my application through several stages (development, staging, production) and want to have API management configuration versioned with it.

The workflow looks like:

  • Open a PR
    • Deploy a "review branch" to a new, isolated OpenShift project
    • Configure API management for that deployed project
  • Merge PR
    • Deploy the app master branch to the staging environment project
    • Configure API management for that deployed project
  • Deploy to production
    • Deploy the last staging revision to the production environment project
    • Configure API management for that deployed project
  • Rollback production deployment
    • Rollback the last deployment to production
    • Rollback the last API management change

The challenge is two-fold:

  • Keep the Gateway configuration up-to-date with changes to the backend between environments
  • Rollback API management configuration (for example removing plan, etc.)

Scenario 6

Like scenario 5, but with different objects in some stages:

  • Development environment has different limits and plans.

  • Staging environment has signup disabled.

Scenario 7

I have a complex plan structure, that has many common limits. I'd like to share those limits between application plans.

Option override

Plans A,B and C share common limits 100 hits/day, but Plan C has 1000 limits a day.

Solution:

apiVersion: api.3scale.net/v1alpha1
kind: PLAN
metadata:
  name: a
  labels:
    environment: production
    api: myapi
spec:
  trialPeriod: 10
  aprovalRequired: true
  costs:
    - setupFee: 0
    - costMonth: 10
  limitSelector:
    matchExpressions:
    - {key: plan, operator: In, values: [common,a]}
    - {key: override, operator: NotIn, values: [b,c]]}
----
apiVersion: api.3scale.net/v1alpha1
kind: PLAN
metadata:
  name: b
  labels:
    environment: production
    api: myapi
spec:
  trialPeriod: 10
  aprovalRequired: true
  costs:
    - setupFee: 0
    - costMonth: 10
  limitSelector:
    matchExpressions:
    - {key: plan, operator: In, values: [common,b]}
    - {key: override, operator: NotIn, values: [a,c]]}
----
apiVersion: api.3scale.net/v1alpha1
kind: PLAN
metadata:
  name: c
  labels:
    environment: production
    api: myapi
spec:
  trialPeriod: 10
  aprovalRequired: true
  costs:
    - setupFee: 0
    - costMonth: 10
  limitSelector:
    matchExpressions:
    - {key: plan, operator: In, values: [common,c]}
    - {key: override, operator: NotIn, values: [b,a]]}
----
apiVersion: api.3scale.net/v1alpha1
kind: LIMIT
metadata:
  name: list_apps_eternity_10
  labels:
    plan: common
spec:
  metric:
    name: hits
  description: "Limit for list_apps in basic plan"
  period: day
  maxValue: 100
----
apiVersion: api.3scale.net/v1alpha1
kind: LIMIT
metadata:
  name: list_apps_eternity_100
  labels:
    plan: common
spec:
  metric:
    name: hits
  description: "Limit for list_apps in basic plan"
  period: day
  maxValue: 100
---- 
apiVersion: api.3scale.net/v1alpha1
kind: LIMIT
metadata:
  name: list_apps_eternity_1000
  labels:
    plan: premium
    override: c
spec:
  metric:
    name: hits
  description: "Limit for list_apps in basic plan"
  period: day
  maxValue: 1000

Scenario 8

I'm taking a design-first and want to use OAI spec to drive the metrics definition.
By creating the OIS spec in OpenShift I expect to not have to create Metrics by hand and just create Limits.

---- 
apiVersion: api.3scale.net/v1alpha1
kind: OPENAPIDOCUMENT
metadata:
  name: myOpenAPISpec
spec:
  metricLabels:    #Labels to add to the generated Objects
    - api: myApi
  mappingRuleLabels:  #Labels to add to the generated Objects
    - api: myapi
  Definition: |
    openapi: "3.0.0"
    info:
      title: Simple API overview
      version: 2.0.0
    paths:
      /test:
        get:
          operationId: metricsA
          summary: List Objects
        post:
          operationId: metricsB
          summary: Create Object
---
apiVersion: api.3scale.net/v1alpha1
kind: PLAN
metadata:
  name: a
  labels:
    environment: production
    api: myapi
spec:
  trialPeriod: 10
  aprovalRequired: true
  costs:
    - setupFee: 0
    - costMonth: 10
  limitSelector:
    matchExpressions:
    - {key: plan, operator: In, values: [common]}
---
apiVersion: api.3scale.net/v1alpha1
kind: LIMIT
metadata:
  name: list_apps_eternity_100
  labels:
    plan: common
spec:
  metric:
    name: metricA
  description: "Limit for list_apps in basic plan"
  period: day
  maxValue: 100
---- 
apiVersion: api.3scale.net/v1alpha1
kind: LIMIT
metadata:
  name: list_apps_eternity_1000
  labels:
    plan: premium
spec:
  metric:
    name: metricB
  description: "Limit for list_apps in basic plan"
  period: day
  maxValue: 1000

Scenario 9

I'm deploying my app to staging and production environment on a different OpenShift clusters, using different 3scale Tenant and using the same upstream host.
I'd like those two Services to be managed by one custom resource.

Option

The staging and production environments have just different upstream, otherwise all settings are the same. Living in different Tenants and Clusters.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
capabilities managing 3scale
Projects
None yet
Development

No branches or pull requests

3 participants