Skip to content

Commit

Permalink
Add DeploymentTemplate controller for GitOps support (#8001)
Browse files Browse the repository at this point in the history
# Description

* Add `rad bicep generate-kubernetes-manifest` CLI
* Add DeploymentTemplate controller
* Add DeploymentResource controller

## Type of change

<!--

Please select **one** of the following options that describes your
change and delete the others. Clearly identifying the type of change you
are making will help us review your PR faster, and is used in authoring
release notes.

If you are making a bug fix or functionality change to Radius and do not
have an associated issue link please create one now.

-->

- This pull request adds or changes features of Radius and has an
approved issue (issue link required).

<!--

Please update the following to link the associated issue. This is
required for some kinds of changes (see above).

-->

#6689

## Contributor checklist
Please verify that the PR meets the following requirements, where
applicable:

- [x] An overview of proposed schema changes is included in a linked
GitHub issue.
- [x] A design document PR is created in the [design-notes
repository](https://github.com/radius-project/design-notes/), if new
APIs are being introduced.
- [x] If applicable, design document has been reviewed and approved by
Radius maintainers/approvers.
- [x] A PR for the [samples
repository](https://github.com/radius-project/samples) is created, if
existing samples are affected by the changes in this PR.
- [x] A PR for the [documentation
repository](https://github.com/radius-project/docs) is created, if the
changes in this PR affect the documentation or any user facing updates
are made.
- [x] A PR for the [recipes
repository](https://github.com/radius-project/recipes) is created, if
existing recipes are affected by the changes in this PR.

---------

Signed-off-by: willdavsmith <[email protected]>
Signed-off-by: Will Smith <[email protected]>
  • Loading branch information
willdavsmith authored Jan 28, 2025
1 parent 9c0a579 commit 835abb0
Show file tree
Hide file tree
Showing 60 changed files with 5,071 additions and 173 deletions.
4 changes: 2 additions & 2 deletions cmd/rad/cmd/bicep.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import (

var bicepCmd = &cobra.Command{
Use: "bicep",
Short: "Manage bicep compiler",
Long: `Manage bicep compiler used by Radius`,
Short: "Handle bicep-specific tasks for Radius",
Long: `Handle bicep-specific tasks for Radius`,
}

func init() {
Expand Down
4 changes: 4 additions & 0 deletions cmd/rad/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
app_list "github.com/radius-project/radius/pkg/cli/cmd/app/list"
app_show "github.com/radius-project/radius/pkg/cli/cmd/app/show"
app_status "github.com/radius-project/radius/pkg/cli/cmd/app/status"
bicep_generate_kubernetes_manifest "github.com/radius-project/radius/pkg/cli/cmd/bicep/generatekubernetesmanifest"
bicep_publish "github.com/radius-project/radius/pkg/cli/cmd/bicep/publish"
bicep_publishextension "github.com/radius-project/radius/pkg/cli/cmd/bicep/publishextension"
credential "github.com/radius-project/radius/pkg/cli/cmd/credential"
Expand Down Expand Up @@ -349,6 +350,9 @@ func initSubCommands() {
bicepPublishCmd, _ := bicep_publish.NewCommand(framework)
bicepCmd.AddCommand(bicepPublishCmd)

bicepGenerateKubernetesManifestCmd, _ := bicep_generate_kubernetes_manifest.NewCommand(framework)
bicepCmd.AddCommand(bicepGenerateKubernetesManifestCmd)

bicepPublishExtensionCmd, _ := bicep_publishextension.NewCommand(framework)
bicepCmd.AddCommand(bicepPublishExtensionCmd)

Expand Down
90 changes: 90 additions & 0 deletions deploy/Chart/crds/radius/radapp.io_deploymentresources.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.16.0
name: deploymentresources.radapp.io
spec:
group: radapp.io
names:
categories:
- all
- radius
kind: DeploymentResource
listKind: DeploymentResourceList
plural: deploymentresources
singular: deploymentresource
scope: Namespaced
versions:
- additionalPrinterColumns:
- description: Status of the resource
jsonPath: .status.phrase
name: Status
type: string
name: v1alpha3
schema:
openAPIV3Schema:
description: DeploymentResource is the Schema for the DeploymentResources
API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: DeploymentResourceSpec defines the desired state of a DeploymentResource
resource.
properties:
id:
description: Id is the resource id of the Radius resource.
type: string
type: object
status:
description: DeploymentResourceStatus defines the observed state of a
DeploymentResource resource.
properties:
id:
description: Id is the resource id of the Radius resource.
type: string
observedGeneration:
description: ObservedGeneration is the most recent generation observed
for this DeploymentResource.
format: int64
type: integer
operation:
description: Operation tracks the status of an in-progress provisioning
operation.
properties:
operationKind:
description: OperationKind describes the type of operation being
performed.
type: string
resumeToken:
description: ResumeToken is a token that can be used to resume
an in-progress provisioning operation.
type: string
type: object
phrase:
description: Phrase indicates the current status of the Deployment
Resource.
type: string
type: object
type: object
served: true
storage: true
subresources:
status: {}
106 changes: 106 additions & 0 deletions deploy/Chart/crds/radius/radapp.io_deploymenttemplates.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.16.0
name: deploymenttemplates.radapp.io
spec:
group: radapp.io
names:
categories:
- all
- radius
kind: DeploymentTemplate
listKind: DeploymentTemplateList
plural: deploymenttemplates
singular: deploymenttemplate
scope: Namespaced
versions:
- additionalPrinterColumns:
- description: Status of the resource
jsonPath: .status.phrase
name: Status
type: string
name: v1alpha3
schema:
openAPIV3Schema:
description: DeploymentTemplate is the Schema for the deploymenttemplates
API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: DeploymentTemplateSpec defines the desired state of a DeploymentTemplate
resource.
properties:
parameters:
additionalProperties:
type: string
description: Parameters is the ARM JSON parameters for the template.
type: object
providerConfig:
description: ProviderConfig specifies the scopes for resources.
type: string
template:
description: Template is the ARM JSON manifest that defines the resources
to deploy.
type: string
type: object
status:
description: DeploymentTemplateStatus defines the observed state of a
DeploymentTemplate resource.
properties:
observedGeneration:
description: ObservedGeneration is the most recent generation observed
for this DeploymentTemplate.
format: int64
type: integer
operation:
description: Operation tracks the status of an in-progress provisioning
operation.
properties:
operationKind:
description: OperationKind describes the type of operation being
performed.
type: string
resumeToken:
description: ResumeToken is a token that can be used to resume
an in-progress provisioning operation.
type: string
type: object
outputResources:
description: OutputResources is a list of the resourceIDs that were
created by the template on the last deployment.
items:
type: string
type: array
phrase:
description: Phrase indicates the current status of the Deployment
Template.
type: string
statusHash:
description: StatusHash is a hash of the DeploymentTemplate's state
(template, parameters, and provider config).
type: string
type: object
type: object
served: true
storage: true
subresources:
status: {}
4 changes: 4 additions & 0 deletions deploy/Chart/templates/controller/rbac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ rules:
resources:
- recipes
- recipes/status
- deploymenttemplates
- deploymenttemplates/status
- deploymentresources
- deploymentresources/status
verbs:
- create
- delete
Expand Down
18 changes: 4 additions & 14 deletions pkg/cli/bicep/deployment_parameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,32 +19,22 @@ package bicep
import (
"encoding/json"
"fmt"
"io/fs"
"os"
"strings"

"github.com/radius-project/radius/pkg/cli/clients"
"github.com/radius-project/radius/pkg/cli/filesystem"
)

// ParameterParser is used to parse the parameters as part of the `rad deploy` command. See the docs for `rad deploy` for examples
// of what we need to support here.
type ParameterParser struct {
FileSystem fs.FS
}

type OSFileSystem struct {
FileSystem filesystem.FileSystem
}

type ParameterFile struct {
Parameters clients.DeploymentParameters `json:"parameters"`
}

// The Open function opens the file specified by the name parameter and returns a file object and an error if the file
// cannot be opened.
func (OSFileSystem) Open(name string) (fs.File, error) {
return os.Open(name)
}

// ParseFileContents takes in a map of strings and any type and returns a DeploymentParameters object and
// an error if one occurs during the process.
func (pp ParameterParser) ParseFileContents(input map[string]any) (clients.DeploymentParameters, error) {
Expand Down Expand Up @@ -90,7 +80,7 @@ func (pp ParameterParser) parseSingle(input string, output clients.DeploymentPar
if strings.HasPrefix(input, "@") {
// input is a file that declares multiple parameters
filePath := strings.TrimPrefix(input, "@")
b, err := fs.ReadFile(pp.FileSystem, filePath)
b, err := pp.FileSystem.ReadFile(filePath)
if err != nil {
return err
}
Expand All @@ -111,7 +101,7 @@ func (pp ParameterParser) parseSingle(input string, output clients.DeploymentPar
if strings.HasPrefix(parameterValue, "@") {
// input is a file that declares a single parameter
filePath := strings.TrimPrefix(parameterValue, "@")
b, err := fs.ReadFile(pp.FileSystem, filePath)
b, err := pp.FileSystem.ReadFile(filePath)
if err != nil {
return err
}
Expand Down
20 changes: 12 additions & 8 deletions pkg/cli/bicep/deployment_parameters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"testing/fstest"

"github.com/radius-project/radius/pkg/cli/clients"
"github.com/radius-project/radius/pkg/cli/filesystem"
"github.com/stretchr/testify/require"
)

Expand All @@ -36,7 +37,7 @@ func Test_Parameters_Invalid(t *testing.T) {
}

parser := ParameterParser{
FileSystem: fstest.MapFS{},
FileSystem: filesystem.NewMemMapFileSystem(),
}

for _, input := range inputs {
Expand All @@ -56,13 +57,16 @@ func Test_ParseParameters_Overwrite(t *testing.T) {
"key3=value3",
}

// Initialize the ParameterParser with the in-memory filesystem
parser := ParameterParser{
FileSystem: fstest.MapFS{
"many.json": {
Data: []byte(`{ "parameters": { "key1": { "value": { "someValue": true } }, "key2": { "value": "overridden-value" } } }`),
},
"single.json": {
Data: []byte(`{ "someValue": "another-value" }`),
FileSystem: filesystem.MemMapFileSystem{
InternalFileSystem: fstest.MapFS{
"many.json": {
Data: []byte(`{ "parameters": { "key1": { "value": { "someValue": true } }, "key2": { "value": "overridden-value" } } }`),
},
"single.json": {
Data: []byte(`{ "someValue": "another-value" }`),
},
},
},
}
Expand Down Expand Up @@ -91,7 +95,7 @@ func Test_ParseParameters_Overwrite(t *testing.T) {

func Test_ParseParameters_File(t *testing.T) {
parser := ParameterParser{
FileSystem: fstest.MapFS{},
FileSystem: filesystem.NewMemMapFileSystem(),
}

input, err := os.ReadFile(filepath.Join("testdata", "test-parameters.json"))
Expand Down
Loading

0 comments on commit 835abb0

Please sign in to comment.