Code Monkey home page Code Monkey logo

rafter's Introduction

Rafter

Go Report Card Slack

rafter


⚠️ Warning ⚠️

Rafter is looking for new maintainers

The project will no longer be developed within the kyma-project organization. Contact us if you are interested in becoming a new maintainer. If we fail to find new maintainers, the project will be archived. Until then, no new features will be developed and maintenance activities will be limited to the bare minimum.


Overview

Rafter is a solution for storing and managing different types of files called assets. It uses MinIO as object storage. The whole concept of Rafter relies on Kubernetes custom resources (CRs) managed by the Rafter Controller Manager. These CRs include:

  • Asset CR which manages single assets or asset packages from URLs or ConfigMaps
  • Bucket CR which manages buckets
  • AssetGroup CR which manages a group of Asset CRs of a specific type to make it easier to use and extract webhook information

Rafter enables you to manage assets using supported webhooks. For example, if you use Rafter to store a file such as a specification, you can additionally define a webhook service that Rafter should call before the file is sent to storage. The webhook service can:

  • Validate the file
  • Mutate the file
  • Extract some of the file information and put it in the status of the custom resource

Rafter comes with the following set of services and extensions compatible with Rafter webhooks:

NOTE: To learn how Rafter is implemented in Kyma, read Rafter documentation.

What Rafter is not

What Rafter can be used for

  • Rafter is based on CRs. Therefore, it is an extension of Kubernetes API and should be used mainly by developers building their solutions on top of Kubernetes,
  • Rafter is a file store that allows you to programmatically modify, validate the files and/or extract their metadata before they go to storage. Content of those files can be fetched using an API. This is a basic functionality of the headless CMS concept. If you want to deploy an application to Kubernetes and enrich it with additional documentation or specifications, you can do it using Rafter,
  • Rafter is an S3-like file store also for files written in HTML, CSS, and JS. It means that Rafter can be used as a hosting solution for client-side applications.

Quick start

Try out this set of interactive tutorials to see Rafter in action on Minikube. These tutorials show how to:

  • Quickly install Rafter with our Helm Chart.
  • Host a simple static site.
  • Use Rafter as headless CMS with the support of Rafter metadata webhook and Front Matter service. This example is based on a use case of storing Markdown files.
  • Use Rafter as headless CMS with the support of Rafter validation and conversion webhooks. This example is based on a use case of storing AsyncAPI specifications.

NOTE: Read this development guide to start developing the project.

Installation

Prerequisites

  • Kubernetes 1.14 or higher / Minikube 1.3 or higher
  • Helm 2.16.0 or higher

Steps

  1. Add a new chart's repository to Helm. Run:

    helm repo add rafter-charts https://kyma-project.github.io/rafter

  2. Install Rafter:

    helm install --name rafter --set rafter-controller-manager.minio.service.type=NodePort rafter-charts/rafter

rafter's People

Contributors

aerfio avatar clebs avatar dbadura avatar derberg avatar hudymi avatar klaudiagrz avatar kwiatekus avatar m00g3n avatar magicmatatjahu avatar mmitoraj avatar parostatkiem-zz avatar piotrmiskiewicz avatar pkosiec avatar polskikiel avatar pprecel avatar tgorgol avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rafter's Issues

Enable communication via S3 API compatible client using Bucket CR names

Description

Rafter manages buckets in MinIO and in remote storage by Bucket CR. Unfortunately, it is not possible to communicate with MinIO by Bucket CR name. The problem is that changes in buckets may generate new names in storage and client needs to monitor CR to be up-to-date.

We need to create a simple proxy service that will be able to translate Bucket CR to remote names and will be still compatible with S3 API. Thanks to that you can use any S3 client and communicate by Bucket CR names.

Whats need to be done:

  • A proxy that translates Bucket CR names to remote names and is still compatible with S3
  • Link in Bucket CR should point to proxy with nice Bucket CR name (goodbye hash)
  • Define a label on Bucket CR that determines if bucket should be migrated or recreated during switching to MinIO Gateway mode
  • Documentation updated
  • Tutorial updated

Reasons

It will definitely simplify the usage of Rafter and links generated by it. You will no longer see ugly hashes in links and also the link will be static, not regenerated with changes on remote bucket names.

Another benefit is that it will be possible to use Rafter as storage for in-cluster Docker Registry.

Update MinIO dependencies and images

Description

It's become very hard to update MinIO images as the dependencies are very old (minio/mc image is almost a year old), and the minio subchart is very old too (we have v2.5, newest is v5.0.15!!!). Minio-go is out of date also, but in this case I've tried updating it and no breaking changes were encountered.

The charts here and in Kyma repo are also old.

Reasons

If we want to develop this project in the future we need to work with most patched version.
Also the reason I've tried to update Minio was security -> minio images use vulnerable images, old alpines etc

Attachments

Improve Rafter docs on AssetGroup CRs

Description

Improve the AssetGroup custom resource lifecycle document in the Rafter documentation - its structure should actually more resemble the structure of two other similar docs Asset custom resource lifecycle & Bucket custom resource lifecycle which show what happens when you create, modify, and remove the given custom resource.
So far, the document shows AssetGroup CR dependencies and details so perhaps it would be better to extract its current content to a separate document and provide the create, modify, and remove subsections with proper diagrams instead.

Official testing pipeline and instruction for switching Rafter Minio into Gateway mode that uses AWS S3

Description

  • Get instruction on how to writch Rafter to use AWS S3 through Minio Gateway mode
  • Have a testing pipeline that always tests any changes to asset store against gateway mode with AWS S3

Reasons

We expect users to use Rafter with Minio Gateway. Minio supports many providers but we should always make sure they are supported within Asset Store and then we need to officially mention it in documentation

Execute first Rafter release

Description

  • Tag repo with v0.1.0 - important
  • Create a release in GitHub with changelog
  • specify what docker images are considered to be part of 0.1.0
  • Make sure docs point to rafter and not asset store any more
  • Push release helm chart to our gcs bucket with current chart
  • specify in a release that what is blocking us from 1.0 release is lack of support for private buckets and not standard contract on extraction webhook
  • Document release process

Reasons

it is a mature project that is already used in production for over 6months so it is time to release it officially

Add support for removing uploaded content in Rafter Upload Service

Description

Currently, the Asset Upload Service gives nice functionality for uploading content to Minio.

We need to have also an option to remove that uploaded content. For example, it could be done manually by making DELETE call on resource endpoint or automatically garbage collected if none of ClusterDocsTopics/DocTopics are using that.

AC

  • there is an option to remove content uploaded via Asset Upload Service

Private buckets support in Rafter

Description

  • Support private storage in Asset Store
  • Support private storage in Asset Store Upload Service
  • Support private storage in Headless CMS:
    • have default private bucket for hcms
    • mark on docstopic and clusterdocstopic info that it is private
  • Provide proper documentation/tutorials/diagrams
  • upload service - validate proposal against current upload service functionality that returns external url to uploaded asset. We need to decide which way to choose, external or internal and if it will even work with private buckets

Reasons

There are use cases when you want to use the Asset Store to store files privately. You should be able to store files in a bucket and allow to read it only if the reader is authorized. Some kind of proxy is needed

Improve status code counter

Description

All services have a problem with counting returned status codes other than 200 on the Grafana dashboard.

I observed this issue when I was trying to cause errors on the Upload Service then the Grafana didn't count their

Create a Helm Chart for Rafter

Description

Create a Helm Chart that will work without Kyma, but can be reused in Kyma.

AC:

  • All exposed values are described in chart Readme

  • Leader election is enabled when controller deployment has more than one instance

  • Globals from Kyma are not used

  • Chart should also install CRD by default, but there should be a way to disable it with a value like install_crd true or something like that

  • Once above points are done and accepted - Have it in Helm Repo (create PR). We know we depend on helm people to approve it, but still, we need to do it.

Reasons

Improve Rafter adoption in Kubernetes users.

Related issue(s)
kyma-project/kyma#5585

Creation of Bucket as part of Asset resource in Rafter

Description

  • Asset spec should make it possible for a user to specify that he wants a default bucket created for him, so he doesn't have to do it on his own by creating Bucket CR
  • Evaluate how such automated bucket creation might look like, to what extent. Maybe only for public buckets as for private the definition would be too complicated?
  • Should we define a specific field in a spec or maybe best practice is to use spec.template standard and specify that the user can provide a full Bucket definition?

Reasons

Sometimes you just need to store 1 or 2 assets using an application and creating a bucket separately might be overhead.

Create build pipelines for Rafter

Description

After consolidation and migration to the new repository, makefiles probably not work and we don't have pipelines that build whole Rafter applications.

AC:

  • Makefiles are adjusted to the new repository structure
  • All components are built on PR/merge. Make sure PR images land in pr folder in docker registry
  • Unit tests and formatters are executed and checked

Reasons

Having everything as automated and simplified as possible.

Related issue(s)
kyma-project/kyma#5585

Consolidate AssetStore and HCMS docs to describe Rafter

Description

  • Update docs and diagrams to describe AssetGroup instead of DocsTopic
  • merge two topics into one topic, for now the proposal is Content Management
  • update links to docs in rafter/readme.md
  • update example in the example repo

Reasons

  • We have now all features in one component
  • Make logical split between Rafter without Kyma and Rafter in Kyma

Enable Istio metrics and tracing in Rafter

Description

This task is followup to kyma-project/kyma#5085 - what needs to be done:

Copy pasted stretch, which is now in scope too:

  • have tracing enabled so I can see time spent on asset between fetching and uploading to minio, to measure which step is a bottleneck in performance. Make sure sampling is set to 100 in performance cluster (check if possible)
  • have sidecars where needed for tracing if needed

Reasons

Have metrics for controllers and services to be able to see how solution behaves and if the load handling matches the defined SLO

Switch from Webhook ConfigMap to CRs

TL;DR;

Remove defining webhooks by custom ConfigMap and switch to CRs - Cluster(WebHook) and Cluster(WebHooksScenario).

Reasons

At the moment webhooks are applied in Rafter by custom ConfigMap or inline in (Cluster)Assets (this is not a problem). Problems with ConfigMap (and not only):

  • webhooks (for (Cluster)AssetGroups) are applied in global scope (in meaning: applied for all cluster and namespaces resources), and user cannot disable webhook for appropriate ClusterAssetGroup or AssetGroup.
  • poor configuration for scenario (in meaning: order in which Rafter processes them) - at the moment we have hardcoded this part: first is mutation, then validation, and at the end metadata (extractor).
  • we haven't Procedural webhook for custom action (not only for mutation, extractor or validation) - for examples: request to another service if asset will be md file. So from my perspective, user should have possibility to write custom hook.
  • we have hardcoded external ports through which Rafter communicate with services (and user cannot change it) - I would like to ask for correction because I did not find anything about it in the code, but I have heard it several times and I am not sure now whether it is true

New types

Rafter would have such webhooks:

  • Mutation webhook - modifies fetched assets before the Asset Controller uploads them into the bucket.
  • Extraction webhook - extract metadata from assets and inserts it under the status.assetRef.files.metadata field in the Asset/ClusterAsset CR.
  • Procedural webhook - perform custom actions like checking if content of file meets some criteria (like an old validation hook).

and CRs pointed to character of webhooks:

  • ClusterWebHook/WebHook CR - specific characteristic of webhook with fields:
    • spec.type - type of webhook (types are describe above): mutation | extraction | procedural.
    • spec.sourceTypes - array of types admitted to the webhook (based on type field of source in (Cluster)AssetGroup CR and in (Cluster)Asset - we must also fix it, because we have only type field on sources of AssetGroup CR). OPTIONAL field, because user can allows all types.
    • endpoint - endpoint to perform action. Example https://example.com/v1/convert.
    • spec.serviceRef - reference to service which exposes endpoint for mutation/extraction/other actions.
    • spec.serviceRef.name - name of service.
    • spec.serviceRef.namespace - namespace of service.
    • spec.serviceRef.endpoint - endpoint of service to perform action.
    • spec.parameters - additional parameters (in object) which are passed to endpoint. OPTIONAL field.
    • spec.filter - determines what files are to be sent from the asset to the webhook by regex. OPTIONAL field.

NOTE: One of spec.endpoint or spec.serviceRef must be specified. Otherwise an error will occur.

Examples:

apiVersion: rafter.kyma-project.io/v1beta1
kind: ClusterWebHook/WebHook
metadata:
  name: asyncapi-converter
  namespace: kyma-system # if kind is WebHook
spec:
  type: "mutation"
  sourceTypes:
    - asyncapi
  endpoint: https://example.com/v1/convert
  filter: "\\.yaml$"
  parameters:
    foo: bar
apiVersion: rafter.kyma-project.io/v1beta1
kind: ClusterWebHook/WebHook
metadata:
  name: asyncapi-converter
  namespace: kyma-system # if kind is WebHook
spec:
  type: "mutation"
  sourceTypes:
    - asyncapi
  serviceRef:
    name: rafter-asyncapi-service
    namespace: kyma-system
    endpoint: "/v1/convert"
  filter: "\\.yaml$"
  parameters:
    foo: bar
  • ClusterWebHooksScenario/WebHooksScenario CR - scenario of webhooks (in meaning: order in which Rafter processes them):
    • spec.scenario - list of webhooks pointed by name. Element of list must contains:
      • webhookRef - reference to ClusterWebHook/WebHook CR.
      • webhookRef.kind - ClusterWebHook or WebHook type.
      • webhookRef.name - name of webhook.
      • webhook - implementation of spec field of ClusterWebHook/WebHook.

Example:

apiVersion: rafter.kyma-project.io/v1beta1
kind: ClusterWebHooksScenario/WebHooksScenario
metadata:
  name: sample-webhook-scenario
  namespace: kyma-system # if kind is WebHooksScenario
spec:
  scenario: 
  - webhookRef: 
      kind: ClusterWebHook
      name: markdown-front-matter-extractor
  - webhookRef:
      kind: WebHook 
      name: asyncapi-converter # WebHook in kyma-system namespace
  # we can also create anonymous WebHooks in scenario with this same fields like in `ClusterWebHook/WebHook`
  - webhook:
      type: "mutation"
      sourceTypes:
        - asyncapi
      serviceRef:
        name: rafter-asyncapi-service
        namespace: kyma-system
        endpoint: "/v1/convert"
      filter: "\\.yaml$"
      parameters:
        foo: bar
  - webhook:
      type: "mutation"
      sourceTypes:
        - asyncapi
      endpoint: https://example.com/v1/convert
      filter: "\\.yaml$"
      parameters:
        foo: bar

As we can see, we have a limitation for scenarios:

  • for WebHooksScenarios we can bind ClusterWebHooks and WebHooks (of course with this same namespace as WebHooksScenario).
  • for ClusterWebHooksScenarios we can bind only ClusterWebHooks.

Failure of one hook in the scenario interrupts further operations and sets resource status to Failed.

Procedural webhook

I introduce Procedural webhooks, because they allow custom actions independent of the webhook type and I think that separating the validation process into a separate one (webhook type) is not necessary, so validation hook will be implemented in a procedural hook from now.

Binding WebHooks in (Cluster)Assets and (Cluster)AssetGroups

As I mentioned in Reason section, webhooks defined in ConfigMap are applied in global scope (in meaning: applied for all cluster and namespaces Assets CR) and user cannot disable webhook for appropriate ClusterAssetGroup or AssetGroup.

So, my proposition is inject webhooks by ClusterWebHooksScenario/WebHooksScenario and/or single ClusterWebHook/WebHook:

For ClusterAsset/Asset

apiVersion: rafter.kyma-project.io/v1beta1
kind: Asset
metadata:
  name: sample-asset
  namespace: kyma-system
spec:
  ...
  webhooks:
    - scenarioRef:
        kind: WebHooksScenario
        name: sample-webhook-scenario
    - webhookRef:
        kind: ClusterWebHook
        name: markdown-front-matter-extractor
    - webhook:
        type: "mutation"
        endpoint: https://example.com/v1/convert
        filter: "\\.yaml$"
        parameters:
          foo: bar

For ClusterAssetGroup/AssetGroup

apiVersion: rafter.kyma-project.io/v1beta1
kind: AssetGroup
metadata:
  name: sample-assetgroup
  namespace: kyma-system
spec:
  ...
  webhooks:
  - scenarioRef:
      kind: WebHooksScenario
      name: sample-webhook-scenario
  sources:
  - ...
    webhooks:
      - webhookRef:
          kind: ClusterWebHook
          name: markdown-front-matter-extractor
      - webhook:
          type: "mutation"
          endpoint: https://example.com/v1/convert
          filter: "\\.yaml$"
          parameters:
            foo: bar

In case, when user defines webhooks for single assets, then webhooks injected in ClusterAssetGroup/AssetGroup will be completely overwritten for them (this same behavior like now).

Service specification requirements

  • service for Mutation webhook must expose endpoints that:

    • accept parameters and content properties, where parameters is additional parameters defined in ClusterWebHook/WebHook CR or inline in ClusterWebHooksScenario/WebHooksScenario CR, and content is a content of file.
    • return the 200 response with new file content.
    • return the 304 response informing that the file content was not modified.
  • service for Extraction webhook must expose endpoints that:

    • accept parameters and content properties, where parameters is additional parameters defined in ClusterWebHook/WebHook CR or inline in ClusterWebHooksScenario/WebHooksScenario CR, and content is a content of file.
    • return the 200 response confirming that validation succeeded.
    • return the 422 response informing why validation failed.
  • service for Procedural webhook must expose endpoints that:

    • accept parameters and content properties, where parameters is additional parameters defined in ClusterWebHook/WebHook CR or inline in ClusterWebHooksScenario/WebHooksScenario CR, and content is a content of file.
    • return the 2** response with custom message about successful operation.
    • return the 4** response with custom message about failed operation.

Comments and suggestions are welcome!

I am still thinking about the 4th type of webhook: StatusWebhook, which would perform custom action like Proceural, but based of status of (Cluster)Asset or (Cluster)Asset, but I know it can be done in a different way, unrelated to the Rafter himself, so for now I abandoned investment in this case.

In addition, we must define the option of defining default hooks per namespace or cluster (at the moment we have injecting them in all Cluster(AssetGroup) by ConfigMap). A labels probably will be the best for that case, but we can think about that together :)

Improve status of resources in AssetGroup

@derberg commented on Tue Jun 18 2019

Description

  • Status of the ClusterAssetGroup and AssetGroup should change whenever the resource is updated and underlying Asset cr is processed again
  • Check if the same is not the case with Asset resources

Reasons

At the moment status of resources is not properly updated. If you for example remove one source, or do some other changes and at the end you know that Asset resource is processed, the status should switch to Pending and then again to Ready or Failed.

Make tests more stable in gateway mode

Description

It happened really often that tests for Gateway mode are failing on CI. We should make them more resilient.

Things to consider:

  • retry in gateway mode - communication with GCP/Azure
  • force Kind version

Expected result

Tests are stable

Actual result

Tests are failing on communication with GCP/Azure

Steps to reproduce

Execute tests on PR

Troubleshooting

Create an integration pipeline

Description

Implement integration tests and pipelines for whole Rafter. Execute tests on Kind.

Be careful with credentials in Gateway modes.

AC:

  • Reuse integration tests we have on Kyma
  • Tests are working in and outside the cluster
  • For CI Kind is used
  • Gateway modes are also tested
  • Make sure we generate JUnit reports

Reasons

Automated validation if Rafter works.

Related issue(s)
kyma-project/kyma#5585

Document the configmap mode in Rafter

Description

This task is a follow up to this PR which introduced the possibility of adding the source files of (Cluster)Assets CRs as ConfigMaps.

Find a good place in Rafter docs (here as it is not used in Kyma, or just a general remark in Kyma docs that such an option is possible) to document:

  • the new configmap mode in Asset CRs and ClusterAsset CRs.
  • info that filtering on those CRs also works for this mode (regex)
    (+) - proper tutorial/example - extend the website example and Katakoda tutorials

Reasons

Document the new functionality that allows you to add sources of (Cluster)Asset CRs in a ConfigMap.

Specify in docs that at the moment all data stored in rafter are stored in public buckets only

Description

  • upload service docs and spec should not mention private buckets at all as there is no point to store private data if controller anyway cannot access them
  • in main overview make clear note statement that at the moment Rafter supports only public storage
  • in gateway mode docs specify that we suggest using separate subscriptions in cloud providers to not configure with minio existing subscription where some buckets not managed by Rafter are already created, to make sure that admin of rafter has access only to data managed by rafter

Reasons

Make sure customers do not misunderstand the scope of the component and do not store private data with Rafter

What is the future of Rafter?

Recently, I noticed that all issues were closed with the message:

We dont want to invest in rafter within Kyma organisation.
The rafter use case is no longer valid for kyma runtime

For example #50 (comment)

What that it means for the Rafter? Is there a plan to move it to a different organization? Or maybe it will be archived?

Since the beginning, Rafter was designed to work as a standalone project that doesn't require Kyma, so maybe it is no longer valid for Kyma, but it still can be used by someone in the community.

Use Go instead of bash to start Kind cluster for integration tests

Description

We will be implementing all of the logic for pipelines in bash, as it is faster to do so right now, and we really need to get it asap, but it is not a good solution overall. This POC shows that it is possible, and not that hard to achieve.

Reasons

Bash is sick magic, Go is more testable/easier to read/less error prone etc, etc, so we should migrate to that eventually in every aspect of development.

Improve README.md files for Rafter components

Description

This issue is a follow-up of issue 9 for adding README.md files to Rafter components under the cmd folder.

The following need to be verified and added in these README.md files:

  • Tables with environment variables - some of them can be outdated
  • The section in each README.md on how to verify your code when developing a given component - this depends on the testing approach we accept for Rafter - whether we decide to test given make targets or test the whole Rafter each time.
  • Remove the testing section from the controller manager doc as this part is generic and should be included in the development guide

Issue(s)
Follow-up of #9

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.