Git Product home page Git Product logo

direktiv-ui's Introduction

direktiv


License Go Report Card GitHub release GitHub stars GitHub contributors Maintenance made-with-Go Slack

Event-Driven Serverless Orchestration, Integration and Automation

Run Workflows and Create Services in Seconds

Documentation · Blog · Report Bug · Request Feature

Features & Standards

  • YAML: Define flows and subflows with simple YAML including if/else switches, error handling, retries, validations and more.
  • Serverless: Call multiple serverless functions from a flow and merge and modify the responses to a single consumable function call.
  • Event-Based: Catch events within the system or from external sources like AWS or Github and execute flows based on that event.
  • JSON Inputs & States: Use JSON as input for flows and respond with JSON to the caller. JSON will be saved between the states fo a flow.
  • API Gateway: Includes an API gateway to expose flows as services for third-party consumers including authentication.
  • CloudEvents: Supports CNCF's CloudEvents natively.
  • GitOps Approach: All configurations, services and flows can be synced from Git. Git becomes the single source of truth.
  • Observability: Integrated into Prometheus (metrics), Fluent Bit (logging) & OpenTelemetry (instrumentation & tracing).
  • Periodic Tasks: Call flows periodically via cron jobs for repeating tasks.
  • Scalable: Direktiv scales on mulitple levels with Kubernetes scaling and Knative's scaling features.
  • Easily Extendable: Add custom functions with simple Docker containers.

Quick Start

Direktiv provides a Docker container with all required components pre-installed (Linux only). The initial startup can take a couple of minutes to download all required images.

docker run --privileged -p 8080:80 -ti direktiv/direktiv-kube

If the upper limit for inotify instances is too low the pods might be stuck in pending. Increase that limit if necessary with the command sudo sysctl fs.inotify.max_user_instances=4096

If you are not using Linux please follow the installation instructions on the documentation page.

About Direktiv

Direktiv is an event-driven workflow engine made for orchestration, integration, and automation. In it's core it is a state machine which uses containers as functions within workflows and passes JSON structured data between states. It offers key features like retries, error handling, and conditional logic. The flow's state, stored as JSON, allows for dynamic transformations during execution using JQ or JavaScript.

direktiv_api: workflow/v1
states:
- id: start
  type: noop
  transform:
    result: Hello world!
  transition: second
- id: second
  type: noop
  log: second state
  transform:
    final: this value is from state one jq(.result)

Workflows can be triggered by events, start periodically via crons or can be started by a HTTP POST request where the data is the initial state fo the workflow.

Writing Workflows

Writing workflows is a very simple task. The basic idea is that there are multiple states where the workflow steps through. These states are of different types to provide switches, errors or other functionality. The most important type is the action state. This state calls a function which is basically a simple container.

Writing workflows is quite simple. Essentially, a workflow is progressing through different states with a JSOJ payload passed between those states. These states come in various types, providing switches, error management, and more. The most important type is the action state. The action state is basically a call to a container. Internally Direktiv spins up a serverless Knative function and passes data to that container. The response of that call becomes part of the JSON state of the flow.

direktiv_api: workflow/v1

functions:
- id: request
  image: gcr.io/direktiv/functions/http-request:1.0
  type: knative-workflow

states:
- id: joke 
  type: action
  action:
    function: request
    input: 
      method: GET
      url: https://api.chucknorris.io/jokes/random?category=jq(.category // "dev")
  transform:
    joke: jq(.return[0].result.value)

The above example is a very simple one-step workflow. It uses the http-request function. This function accepts multiple input parameters e.g. the HTTP method or the URL. The section under input defines the data send to the function as JSON. In this case Direktiv would post the following payload to the container:

{
  "method": "GET",
  "url": "https://api.chucknorris.io/jokes/random?category=dev"
}

In this example, there's a JQ statement, jq(.category // "dev"), which is getting evaluated at runtime. If the 'category' value is defined in the state, it's utilized in the URL; otherwise, dev is used as the default. For instance, initiating the workflow with a payload like { "category": "animal" } would result in the URL: https://api.chucknorris.io/jokes/random?category=animal.

The state can be transformed after each state of the workflow. In this case the JQ command fetches the joke from the return values of the function and sets it as new state.

Custom Functions

Although every standard container can be used in Direktiv it is easy to write a custom function if necessary. The basic requirement for a custom function is a container listening to port 8080 and accepting JSON as a payload. There is more information about writing custom functions in the documentation but the following code snippet shows a very simple Rust example of a a custom function.

use actix_web::{App, HttpResponse, HttpServer, Responder, post};
use actix_web::web::Json;

use serde::{Deserialize, Serialize};

#[derive(Deserialize)]
struct Input {
    name: String,
}

#[derive(Serialize)]
struct Output {
    greeting: String,
}

#[post("/")]
async fn index(info: Json<Input>) -> impl Responder {
    HttpResponse::Ok().json(Output { greeting: format!("Welcome to Direktiv, {}!", info.name) })
}

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .service(index)
    })
        .bind("0.0.0.0:8080")?
        .run()
        .await
}

Documentation

Talk to us!

Code of Conduct

We have adopted the Contributor Covenant code of conduct.

Contributing

Any feedback and contributions are welcome. Read our contributing guidelines for details.

License

Distributed under the Apache 2.0 License. See LICENSE for more information.

See Also

direktiv-ui's People

Contributors

al-bez avatar alankm avatar alex-olexenko avatar dependabot[bot] avatar h8718 avatar jalfvort avatar jamesjmurtagh avatar jensg-st avatar julia-zielke avatar porleaaron avatar sebxian avatar sir-hassan avatar stefan-kracht avatar trentis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

direktiv-ui's Issues

Index Page: No Namespace available / selected

Summary

If no namespace is available the namespace selector should be hidden / not displayed. Additionally there needs to be a "warning text" in the center like in the old UI that the user needs to create or join a namespace. Not "index route :)"

index1

The navigation items are all active and should be visible but inactive, not clickable, if there is no namespace selected.

Instance List: Display values

The list should show seconds in the two tie columns. If the working revision is running the revision id column is empty but should show maybe something like "latest"?

instances1

Instance View: Save a new revisions

Summary

Save as new revision is always active even if the actual version can not be used as revision, e.g. nothing had been changed. There is no error message coming back either if clicked and no revision had been created.

I would rename the button to "Create Revision" and it is only active if the actual content has been saved.

instance1

Shadows too much?

Summary

Is that the same shadow we are using for the '+' as well. Looks a bit strong / much.

explorer

Explorer Page: Create workflow box size

Summary

If I resize the "create workflow" view the layout is strange. The box resizes but not the input field. It is not scroll-able either so there is no way to even cancel the view.

workflow1

Events listeners, history, and replay.

New APIs added. Here's what you can do:

Event Listeners

Flow server has new RPCs: EventListeners and EventListenersStream. These can be used to show what workflows and instances are currently waiting to receive events.

The flow cli has a command event-listeners to use the above two gRPCs.

The API server has routes exposing these as HTTP APIs:

handlerPair(r, RN_EventListeners, "/namespaces/{ns}/events", h.EventListeners, h.EventListenersSSE)

Event History

Flow server has new RPCs: EventHistory and EventHistoryStream. These can be used to see what events have been received recently.

The flow cli has a command event-history to use the above two gRPCs.

The API server has routes exposing these as HTTP APIs:

handlerPair(r, RN_EventHistory, "/namespaces/{ns}/events", h.EventHistory, h.EventHistorySSE)

Event Replay

Flow server has a new RPC: ReplayEvent. This can be used to retrigger an event through the system.

The flow cli has a command replay-event to use the above gRPC.

The API server has a route for this API:

r.HandleFunc("/namespaces/{ns}/events/{event}/replay", h.ReplayEvent).Name(RN_NamespaceEvent).Methods(http.MethodPost)

Run on Workflkow overview page

Summary

I like that we have the overview page first with workflow. I'm wondering if having a '+' on the instance box would be a nice addition? To run one from here quickly. But the problem might be which revision we are string here.

For the majority of prod services that is very nice but we need to think about us too :) The developers. At the moment the test flow seems to be:

  • Run latest revision
  • Press "View Workflow"
  • Go to latest revision
  • Run latest revision

Any ideas for a good shortcut?

Settings: Test Connection for registries

Summary

It would be nice if we could have a "test connection" for the registries. We need to find a generic API in registries which we can call and see if we can connect.

Explorer Page: Create Workflow / Directory

We should test if the name field of the workflow is empty before we send the request to the backend and disable the "add button". This applies to add directories and add workflows.

explorer1

Settings: Headers in variable box

Although it is in the design I think the header of the table with name, value size, action can go. Isn't that obvious what that is? We don't have this anywhere else.

Settings: Registry list username

We should obfuscate the username for docker registries but maybe we get the length of the username and * the middle X characters based on the length, admin becomes ad**n. At least you have an idea what user you did add.

Revision metadata.

main has been updated so that generic metadata payloads can be attached to the commit/savehead request. The intention is that this could be used to store commit messages and possibly information about the author. The frontend will need to handle much of this.

Services: Sliders for scale and traffic have no display value

Summary

The sliders for scale and traffic don't show any value. It needs to have a number for scale and the percentage for traffic.

Function requests (namespace, global) to API e.g. http://localhost:8080/api/functions/namespaces/hello return the max scale for a function. The slider should show a 0 on he left and the max value coming from the backend on the right.

I don't know if that is possible but we should display the actual value when the slider is being used showing the value it would use if the slider would stay at that position.

namespace2

Percentage slider for new revision

revision1

Settings: Variable mimetype

Variable mimetypes is a free text field at the moment. We should make it a free-text/pulldown combo wit json, yaml, txt etc. as options. The little editor can do syntax highlighting based on that value.

Services: Active as a special case

Summary

The "Active" value is a special value for Knative services. It basically means that it doesn't receive any traffic at the moment. Basically there is no active pod at the moment. We show it as an error but we should treat it as a different case not as an error.

Sankey by revision.

The sankey metrics API on main has been updated to split data by revision. Be sure to adapt the UI to handle this.

Settings: Confirming namespace delete

Maybe we should add an input field where you have to type in the name of the namespace to delete again. Like github does when you delete a project. It can be either in the box or in the modal to confirm.

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.