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

Allow for Runtime and App Separation #385

Closed
IfSentient opened this issue Sep 3, 2024 · 0 comments · Fixed by #402
Closed

Allow for Runtime and App Separation #385

IfSentient opened this issue Sep 3, 2024 · 0 comments · Fixed by #402
Assignees

Comments

@IfSentient
Copy link
Contributor

Currently, an app is built targeting a specific runtime--the only available one being an operator with kubernetes webhooks (though custom functionality can be layered on top). To better allow apps to be targeted for different deployment types, such as an API server, or running entirely as a multi-tenant (or even single tenant) plugin, or in the future as other runtimes such as WASI, the logic for what an app can do (Control loops, Admission, Conversion, etc.) should be split from how this functionality is called (webhooks for admission/conversion, or inlined in an API server, for example).

The proposal for this is to define an app interface which describes behavior, and runners which can then run the app based on how app interactions from "outside" should be handled (for example, how does a validation request get to the app).

type App interface {
    // App interactions, including, but not limited to:
    Validate(ValidationRequest) (bool, error)
    Mutate(MutationRequest) (MutationResponse, error)
    // ...etc...
}

type AppProvider interface {
    Manifest() AppManifest
    NewApp(AppConfig) (App, error)
}

Runners then consume an AppProvider, and handle initializing the app by providing it with config data, including kube config, which are based on the runtime manner (for example, an API server would use the loopback config, or an Operator would use the config for the API server).

This requires the existence of the App Manifest as described in #353

@IfSentient IfSentient self-assigned this Sep 3, 2024
This was referenced Sep 5, 2024
IfSentient added a commit that referenced this issue Sep 12, 2024
# What This PR Does / Why We Need It

This PR introduces the first step of the **App Manifest**, a concept to
help clarify and drive app development. The App Manifest is the listing
of the app's managed kinds and capabilities (admission, conversion) for
those kinds. This PR introduces admission and conversion capabilities
for kinds in the manifest, be leaves schemas unimplemented.

Added in this PR is the `app` package, which is where the App Manifest
(as `app.Manifest`) lives, and where additional app-centric logic will
reside for future features such as
#385

`app.Manifest` is decoupled from the actual manifest data by having an
`app.ManifestData` type which contains manifest data, and having the
`app.Manifest` contain a pointer to said data (which can be nil), and a
location for the data. This way, an `app.Manifest` can simply point to a
file on-disk, or an API server location, without having to have the data
loaded, and the consumer of the `app.Manifest` should understand how to
fetch the `app.ManifestData`. This allows an app to not need to know the
credentials to fetch the manifest data (such as kube config), but still
be able to tell other components which may have such knowledge where to
fetch the data (this is important in
#385, as the App
Provider will need to provide the manifest and a way of creating the
App, but will not know how to talk to the API server, as the runner will
be able to load those credentials).

Included in this PR is the generation of this in-progress initial
manifest as both an API server CR, and as in-code `app.ManifestData` to
use if and when the manifest type is not available in the API server. An
app author can now specify their app's capabilities for admission and
conversion for kinds via `admission`, `mutations`, and `conversion` in
the `apiResource` field in CUE, and can optionally override those
kind-wide defaults on a per-version basis with `admission` and
`mutation` fields in the version (`conversion` is always only kind-wide,
as all versions must be inter-convertable for `conversion` to be
allowed). The test data has been updated with these additional fields
for manifest generation testing. Two new files will now be generated on
each `grafana-app-sdk generate` call:
`definitions/<app-name>-manifest.(json|yaml)`, and
`pkg/generated/manifest.go`.

Relates to #353, which
will be completed once the manifest contains the CRDs (schemas) as well.

---------

Co-authored-by: Igor Suleymanov <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant