These two libraries improve contributor experience and development speed by reducing the burden of sustaining the plethora of Meshery adapters, allowing contributors to focus on exposing any given infrastructure component's differentiated value, instead of having to redundantly implement plumbing for managing cloud native infrastructure.
MeshKit
MeshKit was formerly named gokit and was renamed recently to align with the other Meshery components' names (and avoid confusion with the go-kit project). MeshKit can be considered a derivative of go-kit with specific focus on cloud native management.
In the Meshery v0.5.0 release, MeshKit has been enhanced and expanded substantially. Considering that the MeshKit library provides broadly useful functionality, it is used in a growing number of Meshery components. It is intended to be one of the top level libraries in the Meshery ecosystem.
MeshKit is a toolkit for Layer5’s microservices, and is positioned to become Layer5’s middleware component for Layer5’s microservices, leveraging other libraries like go-kit/kit. In complement to functionality provided by any given cloud native infrastructure component, its purpose is to provide implementations for common cross-cutting concerns like error handling, logging, and tracing. Uniform error handling and logging across all Meshery components helps to implement efficient tooling for observability, monitoring and troubleshooting. The library provides some common data models for Meshery and Meshery's ecosystem of extensions.
Another central component in Meshkit is the utils package.
This package provides a Kubernetes and a Helm client that implements functionality based on the Go libraries of these tools. The API exposed by these libraries is quite low-level, and the higher-level functions of the utils package simplifies usage of Kubernetes and Helm clients significantly.
Another advantage MeshKit that it is not necessary to use the command line versions of these tools, providing a more tailored experience for developers,
and better logging and error handling integration.
MeshKit is simple and straight forward to use, as the following code example illustrates.
Meshery Adapters
Meshery adapters are management plane components and manage the lifecycle of cloud native infra. This includes installation and deletion, configuration, and verification that an installation follows recommended practices. As example use of Meshery adapters is for purposes of compliance verification, actively attesting whether whether infrastructure complies to an open standard, like that of Service Mesh Interface. Meshery adapters support management of multiple versions of their respective capabilites and also come bundled with sample applications that can be deployed for easy and quick exploration of infrastructure (or other) capabilities.
A Meshery adapter is a gRPC server that exposes the MeshServiceServer interface:
CreateInstancesets up the Kubernetes client. It does not, as the name might imply, create an instance of an infrastructure component.Namereturns the name of the infrastructure component, configured in the adapter.SupportedOperationsreturns all supported operations, configured in the adapter. An operation is e.g. the installation of any given cloud native infrastructure component or service.ApplyOperationexecutes the operation specified in the request. It is one of the supported operations.StreamEventsallows sending events from the server to the client.
This API is one of the extension points of Meshery, making it easy to add support for new cloud native technologies to Meshery. Meshery adapters abstract away differences in installation and configuration of the various technologies. Various cloud native technologies are installed and configured in their own way. For instance, some projects have their own installer, like istioctl for Istio, while others use Helm charts, like Consul. One of the purposes of Meshery adapters is to abstract these differences away.
Meshery Adapter Library
As can be expected, adapters for the various meshes have a lot of code in common. Initially, this common code was copied from one adapter implementation to the next. The question arose whether common code should be factored out to one or several libraries. After some discussion, the community decided to move some of the more general code to Meshkit, and adapter specific code to a new library.
Thus, the Meshery Adapter Library was born.
It reduces the amount of boilerplate code in the adapters substantially, making adapter code easier to follow. This is especially valuable in an open source community where typically many developers contribute, for varying amounts of time. For the same reasons, it is important such libraries are easily understandable.
Also, it means new adapters can be implemented quickly, as only configuration and operations that differ between services meshes need to be implemented.
The Meshery Adapter Library provides a common and consistent set of functionality that Meshery adapters use for managing the lifecycle of cloud infrastructure and their workloads.
The initial commit was submitted on October 6th, 2020 based on a refactoring effort in the adapter for the Kuma service mesh. Within a few months, several adapters have been refactored or implemented from scratch based on the Meshery Adapter Library.
The main purpose of the Meshery Adapter Library is to:
- provide a set of interfaces, some with default implementations, to be used and extended by adapters.
- implement cross-cutting concerns like logging, error handling, and tracing.
- provide a mini framework implementing the gRPC server that allows plugging in the mesh specific configuration and operations implemented in the adapters.
The core interface in the library is the adapter Handler interface:
It corresponds closely to the gRPC API discussed above, and indeed these methods are called in the implementation of the MeshServiceServer interface. This implementation is also part of the Meshery Adapter Library.
Using struct embedding, an adapter extends the default implementation Adapter of the interface Handler from the library.
Usually, it is sufficient that this adapter handler overrides only the ApplyOperation function from the default implementation.
(There, it is a no-op implementation.)
The figure below illustrates this and the usage of the library in an adapter.
In the main package of the adapter, the default configuration provider Viper from the library is instantiated, and reads the adapter specific configuration. This includes a specification of all available operations. As configuration providers are implementations of an interface, you can choose any of the providers from the library, or implement your own.
Next, an instance of the adapter handler is created. Other components, for instance a logger, may be created depending on needs and requirements, which is symbolize by the three dots in the figure.
The service is a struct that holds all the parameters that specify an adapter service, like the port the gRPC server is running on, and the instance of the adapter handler created in a previous step. This struct is passed to the Start function from the library. This Start function wraps the gRPC server, wiring up all necessary components, and starts the service. The developer does not need to touch any gRPC code.
Conclusion
Extracting common code from adapters to the two new libraries has proven to be a worthwhile investment. It led to cleaner code as well as cleaner application architecture, shortened implementation time for new adapters considerably, and upleveled the quality of Meshery's adapters through consistency of implementation.


