Skip to content

Commit

Permalink
prepare first open source release (#13)
Browse files Browse the repository at this point in the history
* add docs and changelog

* add unit tests

* add CLI

* add CLI

* finalize API and readme

* sort components, fix ascii art

* add go releaser

* prepare for release
  • Loading branch information
avivpxi authored Feb 17, 2024
1 parent b7d8f86 commit 4472a04
Show file tree
Hide file tree
Showing 69 changed files with 2,033 additions and 362 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*
.idea
/envite

dist/
35 changes: 35 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
version: 1

before:
hooks:
- go mod tidy

builds:
- env:
- CGO_ENABLED=0
goos:
- linux
- windows
- darwin
main: ./cmd/envite

archives:
- format: tar.gz
name_template: >-
{{ .ProjectName }}_
{{- title .Os }}_
{{- if eq .Arch "amd64" }}x86_64
{{- else if eq .Arch "386" }}i386
{{- else }}{{ .Arch }}{{ end }}
{{- if .Arm }}v{{ .Arm }}{{ end }}
# use zip for windows archives
format_overrides:
- goos: windows
format: zip

changelog:
sort: asc
filters:
exclude:
- "^docs:"
- "^test:"
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,26 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [[0.0.1](https://github.com/PerimeterX/envite/releases/tag/v0.0.1)] - 2023-12-21

Initial release.

## [[0.0.2](https://github.com/PerimeterX/envite/compare/v0.0.1...v0.0.2)] - 2023-12-24

### Fixed

- fix error handling on stop container.

## [[0.0.3](https://github.com/PerimeterX/envite/compare/v0.0.2...v0.0.3)] - 2024-02-17

Prepare for open source.

### Added

- CLI support.
- Go releaser support.
- Unit tests.
- Go docs.
- Improved README.md.
- Added several small changes to the SDK API to allow smoother experience in the CLI.
257 changes: 228 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,45 @@
# ENVITE

![ENVITE Logo](https://raw.githubusercontent.com/PerimeterX/envite/assets/logo3.svg?token=GHSAT0AAAAAACK6DPG4JUCV4OGT2OMCPPYYZLLEDVQ)

ENVITE helps define and provision environments for development, testing, and continuous integration.

It's designed to allow switching between local development needs and automated environments seamlessly
and provide the best tooling to describe, provision, and monitor integrated components.

A demo screen capture can be found [here](https://github.com/PerimeterX/envite/raw/assets/demo.mov).

---

## Motivation

Any software that interacts with external components requires some solutions. In production environments you need
these two components to be able to interact in a safe and secure fashion. Obviously, there are countless solutions
for these needs such as cloud-managed products, container orchestration solutions such as Kubernetes, load balancers,
service discovery solutions, service mesh products, and so on. ENVITE doesn't aim to help there.

Next, if you want to run non-production automation such as integration testing during a CI/CD pipeline, you're going
to need to create an environment similar to production to be able to execute these tests.

Lastly, development processes require a similar environment to function properly.

ENVITE aims to help with the last 2 use cases - development, and non-production automation. It aims to make them
completely similar to allow full reproducibility, on the one hand, and the best tooling for development needs, on the
other hand.

## Alternatives
<img align="right" width="200" alt="envite-logo" src="https://raw.githubusercontent.com/PerimeterX/envite/assets/logo3.svg?token=GHSAT0AAAAAACK6DPG4JUCV4OGT2OMCPPYYZLLEDVQ">

Modern software components have dependencies and interactions. Ensuring these interactions are safe and secure in
production environments is paramount. While a plethora of solutions exist to address these needs in production - from
cloud-managed products and container orchestration solutions like Kubernetes to load balancers and service meshes,
ENVITE sets its sights on solving the challenges of providing such environments for testing,
development, and automation processes like Continuous Integration. Recognizing the imperative need for environments
in integration testing and development to mirror production closely for accuracy and effectiveness,
ENVITE is designed to facilitate environments that are highly reproducible, mirroring production as closely
as possible, while integrating tooling to streamline development processes.

Integration test environments can be very complex to understand, very non-intuitive to manage and maintain,
and very hard to execute. ENVITE is a framework to manage your development and testing environments.

## Contents

* [Why ENVITE?](#why-envite-)
- [So why not stick to what you use today?](#so-why-not-stick-to-what-you-use-today-)
* [Using Kubernetes for production, CI, and development](#using-kubernetes-for-production--ci--and-development)
* [Using docker-compose for CI and development](#using-docker-compose-for-ci-and-development)
* [Using a remote staging/dev environment](#using-a-remote-staging-dev-environment)
* [Using testcontainers or a similar library to write container management code for CI and development](#using-testcontainers-or-a-similar-library-to-write-container-management-code-for-ci-and-development)
* [Can ENVITE meet my needs?](#can-envite-meet-my-needs-)
* [Usage](#envite-usage)
* [Go SDK Usage](#envite-go-sdk-usage)
* [CLI Usage](#envite-cli-usage)
* [Demo](#demo)
* [Execution Modes](#execution-modes)
* [Flags and Options](#flags-and-options)
* [Adding Custom Components](#adding-custom-components)
* [Key Elements of ENVITE](#key-elements-of-envite)
* [Local Development](#local-development)
* [Contact and Contribute](#contact-and-contribute)
* [ENVITE Logo](#envite-logo)

## Why ENVITE?

#### So why not stick to what you use today?

For starters, you might want to do that. Let's see when you actually need ENVITE.
For starters, you might want to do that. Let's see when you **actually** need ENVITE.
Here are the popular alternatives and how they compare with ENVITE.

##### Using Kubernetes for production, CI, and development
Expand Down Expand Up @@ -123,8 +131,199 @@ As mentioned earlier, if you need 50 components up and running to run your tests
feasible. You will have to use multiple remote machines for that. If this is your use case, an interesting company
that does it well is [Raftt](https://www.raftt.io/) and I suggest reading more about what they do.

## Usage

ENVITE offers flexibility in environment management through both a Go SDK and a CLI.
Depending on your use case, you can choose the method that best fits your needs.

The Go SDK provides fine-grained control over environment configuration and components.
For example, you can create conditions to determine what the environment looks like or create a special connection
between assets, particularly in seed data.
However, the Go SDK is exclusively applicable within a Go environment and is most suitable for organizations
or individuals already using or open to incorporating it into their tech stack.
Regardless of the programming languages employed, if you opt to write your tests in Go,
the ENVITE Go SDK is likely a more powerful choice.

Otherwise, the CLI is an easy-to-install and intuitive alternative, independent of any tech stack,
and resembles docker-compose in its setup and usage. However, it's more powerful in many use cases
([more info here](Using-docker-compose-for-CI-and-development)).

##### Go SDK Usage

```go
package main

import (
"fmt"
"github.com/docker/docker/client"
"github.com/perimeterx/envite"
"github.com/perimeterx/envite/docker"
"github.com/perimeterx/envite/seed/mongo"
)

func runTestEnv() error {
dockerClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
return err
}

network, err := docker.NewNetwork(dockerClient, "docker-network-or-empty-to-create-one", "my-test-env")
if err != nil {
return err
}

persistence, err := network.NewComponent(docker.Config{
Name: "mongo",
Image: "mongo:7.0.5",
Ports: []docker.Port{{Port: "27017"}},
Waiters: []docker.Waiter{docker.WaitForLog("Waiting for connections")},
})
if err != nil {
return err
}

cache, err := network.NewComponent(docker.Config{
Name: "redis",
Image: "redis:7.2.4",
Ports: []docker.Port{{Port: "6379"}},
Waiters: []docker.Waiter{docker.WaitForLog("Ready to accept connections tcp")},
})
if err != nil {
return err
}

seed := mongo.NewSeedComponent(mongo.SeedConfig{
URI: fmt.Sprintf("mongodb://%s:27017", persistence.Host()),
})

env, err := envite.NewEnvironment(
"my-test-env",
envite.NewComponentGraph().
AddLayer(map[string]envite.Component{
"persistence": persistence,
"cache": cache,
}).
AddLayer(map[string]envite.Component{
"seed": seed,
}),
)
if err != nil {
return err
}

server := envite.NewServer("4005", env)
return envite.Execute(server, envite.ExecutionModeDaemon)
}
```

##### CLI Usage

1. Install ENVITE: go install github.com/perimeterx/envite@latest
(help will be appreciated in distributing to package managers via goReleaser or other tools).
2. Create an envite.yml file:
```yaml
default_id: "my-test-env"
components:
-
persistence:
type: docker component
image: mongo:7.0.5
name: mongo
ports:
- port: '27017'
waiters:
- string: Waiting for connections
type: string
cache:
type: docker component
image: redis:7.2.4
name: redis
ports:
- port: '6379'
waiters:
- string: Ready to accept connections tcp
type: string
-
seed:
type: mongo seed
uri: mongodb://{{ persistence }}:27017
data:
- db: data
collection: users
documents:
- first_name: John
last_name: Doe
```
3. Run ENVITE: `envite`.

##### Demo

With either approach, the result is a UI served via the browser. It enables managing the environment, monitor,
initiate and halt components, conducting detailed inspections, debugging, and providing all essential functionalities
for local development, testing, as well as automated and CI/CD processes.
Here's a demo showcasing ENVITE daemon mode. (TODO link)

##### Execution Modes

ENVITE supports three execution modes:

* Daemon Mode (`envite -mode daemon`): Start execution mode, which starts all components in the environment,
and then exits.
* Start Mode (`envite -mode start`): Stops all components in the environment, performs cleanup, and then exits.
* Stop Mode (`envite -mode stop`): Starts ENVITE as a daemon and serving a web UI.

Typically, the `daemon` mode will be used for local purposes, and a combination of `start` and `stop` modes will be
used for Continuous Integration or other automated systems.

##### Flags and Options

All flags and options are described via envite -help command:

```bash
mode
Mode to operate in (default: daemon)
-file value
Path to an environment yaml file (default: `envite.yml`)
-id value
Override the environment ID provided by the environment yaml
-network value
Docker network identifier to be used. Used only if docker components exist in the environment file. If not provided, ENVITE will create a dedicated open docker network.
-port value
Web UI port to be used if mode is daemon (default: `4005`)
```
##### Adding Custom Components
Integrate your own components into the environment, either as Docker containers or by providing implementations
of the `envite.Component` interface.

## Key Elements of ENVITE

ENVITE contains several different elements:
* Environment: Represents the entire configuration, containing components and controlling them to provide a fully
functional environment.
* Component: Represents a specific part of the environment, such as a Docker container or a custom component.
* Component Graph: Organizes components into layers and defines their relationships.
* Server: Allow serving a UI to manage the environment.

## Local Development

To locally work on the UI, cd into the `ui` dir and run react dev server using `npm start`.

To build the UI into shipped static files run `./build-ui.sh`.

## Contact and Contribute

Reporting issues and requesting features may be done in our [GitHub issues page](https://github.com/PerimeterX/envite/issues).
For any further questions or comments you can reach us out at [[email protected]](mailto:[email protected]).

Any type of contribution is warmly welcome and appreciated ❤️
Please read our [contribution](CONTRIBUTING.md) guide for more info.

If you're looking for something to get started with, tou can always follow our [issues page](https://github.com/PerimeterX/envite/issues) and look for
[good first issue](https://github.com/PerimeterX/envite/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) and
[help wanted](https://github.com/PerimeterX/envite/issues?q=is%3Aissue+label%3A%22help+wanted%22+is%3Aopen) labels.

## ENVITE Logo

ENVITE logo and assets by [Adva Rom](https://www.linkedin.com/in/adva-rom-7a6738127/) are licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>.<br />
Loading

0 comments on commit 4472a04

Please sign in to comment.