Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions cmd/kro/commands/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@
outputFormat string
}

var config = &GenerateConfig{}
var generateConfig = &GenerateConfig{}

func init() {
generateCmd.PersistentFlags().StringVarP(&config.resourceGraphDefinitionFile, "file", "f", "",
generateCmd.PersistentFlags().StringVarP(&generateConfig.resourceGraphDefinitionFile, "file", "f", "",
"Path to the ResourceGraphDefinition file")
generateCmd.PersistentFlags().StringVarP(&config.outputFormat, "format", "o", "yaml", "Output format (yaml|json)")
generateCmd.PersistentFlags().StringVarP(&generateConfig.outputFormat, "format", "o", "yaml", "Output format (yaml|json)")

Check failure on line 41 in cmd/kro/commands/generate.go

View workflow job for this annotation

GitHub Actions / lint

The line is 123 characters long, which exceeds the maximum of 120 characters. (lll)
}

var generateCmd = &cobra.Command{
Expand All @@ -56,11 +56,11 @@
"ResourceGraphDefinition and outputs the corresponding CRD " +
"in the specified format.",
RunE: func(cmd *cobra.Command, args []string) error {
if config.resourceGraphDefinitionFile == "" {
if generateConfig.resourceGraphDefinitionFile == "" {
return fmt.Errorf("ResourceGraphDefinition file is required")
}

data, err := os.ReadFile(config.resourceGraphDefinitionFile)
data, err := os.ReadFile(generateConfig.resourceGraphDefinitionFile)
if err != nil {
return fmt.Errorf("failed to read ResourceGraphDefinition file: %w", err)
}
Expand All @@ -85,11 +85,11 @@
"ResourceGraphDefinition file. This command reads the " +
"ResourceGraphDefinition and outputs the corresponding RGD instance",
RunE: func(cmd *cobra.Command, args []string) error {
if config.resourceGraphDefinitionFile == "" {
if generateConfig.resourceGraphDefinitionFile == "" {
return fmt.Errorf("ResourceGraphDefinition file is required")
}

data, err := os.ReadFile(config.resourceGraphDefinitionFile)
data, err := os.ReadFile(generateConfig.resourceGraphDefinitionFile)
if err != nil {
return fmt.Errorf("failed to read ResourceGraphDefinition file: %w", err)
}
Expand All @@ -114,11 +114,11 @@
"ResourceGraphDefinition and outputs the corresponding diagram " +
"in the specified format.",
RunE: func(cmd *cobra.Command, args []string) error {
if config.resourceGraphDefinitionFile == "" {
if generateConfig.resourceGraphDefinitionFile == "" {
return fmt.Errorf("ResourceGraphDefinition file is required")
}

data, err := os.ReadFile(config.resourceGraphDefinitionFile)
data, err := os.ReadFile(generateConfig.resourceGraphDefinitionFile)
if err != nil {
return fmt.Errorf("failed to read ResourceGraphDefinition file: %w", err)
}
Expand All @@ -145,7 +145,7 @@
crd := rgdGraph.Instance.GetCRD()
crd.SetAnnotations(map[string]string{"kro.run/version": "dev"})

b, err := marshalObject(crd, config.outputFormat)
b, err := marshalObject(crd, generateConfig.outputFormat)
if err != nil {
return fmt.Errorf("failed to marshal CRD: %w", err)
}
Expand Down Expand Up @@ -253,7 +253,7 @@

delete(emulatedObj.Object, "status")

b, err := marshalObject(emulatedObj, config.outputFormat)
b, err := marshalObject(emulatedObj, generateConfig.outputFormat)
if err != nil {
return fmt.Errorf("failed to marshal CRD: %w", err)
}
Expand Down
130 changes: 130 additions & 0 deletions cmd/kro/commands/package.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// Copyright 2025 The Kube Resource Orchestrator Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package commands

import (
"fmt"
"os"
"time"

"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/empty"
"github.com/google/go-containerregistry/pkg/v1/mutate"
"github.com/google/go-containerregistry/pkg/v1/static"
"github.com/google/go-containerregistry/pkg/v1/tarball"
"github.com/google/go-containerregistry/pkg/v1/types"
"github.com/spf13/cobra"
"sigs.k8s.io/yaml"

"github.com/kro-run/kro/api/v1alpha1"
)

type PackageConfig struct {
resourceGraphDefinitionFile string
outputFile string
}

var packageConfig = &PackageConfig{}

func init() {
packageRGDCmd.PersistentFlags().StringVarP(&packageConfig.resourceGraphDefinitionFile, "file", "f", "",
"Path to the ResourceGraphDefinition file")
packageRGDCmd.PersistentFlags().StringVarP(&packageConfig.outputFile, "output", "o", "",
"Output file name for the OCI image tarball")
}

var packageRGDCmd = &cobra.Command{
Use: "package",
Short: "Package ResourceGraphDefinition file into an OCI image",
Long: "Package command packages the ResourceGraphDefinition" +
"file into an OCI image, which can be used for distribution and deployment.",
RunE: func(cmd *cobra.Command, args []string) error {
if packageConfig.resourceGraphDefinitionFile == "" {
return fmt.Errorf("ResourceGraphDefinition file is required")
}

if packageConfig.outputFile == "" {
return fmt.Errorf("output file name is required")
}

data, err := os.ReadFile(packageConfig.resourceGraphDefinitionFile)
if err != nil {
return fmt.Errorf("failed to read ResourceGraphDefinition file: %w", err)
}

var rgd v1alpha1.ResourceGraphDefinition
if err := yaml.Unmarshal(data, &rgd); err != nil {
return fmt.Errorf("failed to unmarshal ResourceGraphDefinition: %w", err)
}

fmt.Fprintf(os.Stderr, "Packaging ResourceGraphDefinition into %s...\n",
packageConfig.outputFile)

if err = packageRGD(data, &rgd); err != nil {
return fmt.Errorf("failed to package ResourceGraphDefinition: %w", err)
}

fmt.Fprintf(os.Stderr, "Successfully packaged ResourceGraphDefinition to %s\n",
packageConfig.outputFile)

return nil
},
}

func packageRGD(data []byte, rgd *v1alpha1.ResourceGraphDefinition) error {
layer := static.NewLayer(data, types.MediaType("application/vnd.kro.resourcegraphdefinition.v1alpha1+yaml"))

img := empty.Image

img, err := mutate.AppendLayers(img, layer)

if err != nil {
return fmt.Errorf("failed to append layer: %w", err)
}

configFile, err := img.ConfigFile()
if err != nil {
return fmt.Errorf("failed to get config file: %w", err)
}

now := time.Now()
configFile.Created = v1.Time{Time: now}

configFile.Config.Labels = map[string]string{
"kro.run/type": "resourcegraphdefinition",
"kro.run/name": rgd.Name,
}

img, err = mutate.ConfigFile(img, configFile)
if err != nil {
return fmt.Errorf("failed to update image config: %w", err)
}

ref, err := name.ParseReference(fmt.Sprintf("kro.run/rgd/%s:latest", rgd.Name))
if err != nil {
return fmt.Errorf("failed to parse image reference: %w", err)
}

if err := tarball.WriteToFile(packageConfig.outputFile, ref, img); err != nil {
return fmt.Errorf("failed to write image to file: %w", err)
}

return nil
}

func AddPackageCommand(rootCmd *cobra.Command) {
rootCmd.AddCommand(packageRGDCmd)
}
1 change: 1 addition & 0 deletions cmd/kro/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,6 @@ func NewRootCommand() *cobra.Command {
// TODO: Command groups
commands.AddValidateCommands(cmd)
commands.AddGenerateCommands(cmd)
commands.AddPackageCommand(cmd)
return cmd
}
33 changes: 20 additions & 13 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ go 1.24.0

require (
github.com/go-echarts/go-echarts/v2 v2.6.1
github.com/go-logr/logr v1.4.2
github.com/go-logr/logr v1.4.3
github.com/gobuffalo/flect v1.0.2
github.com/google/cel-go v0.24.1
github.com/google/go-cmp v0.6.0
github.com/google/go-cmp v0.7.0
github.com/google/go-containerregistry v0.20.6
github.com/onsi/ginkgo/v2 v2.20.0
github.com/onsi/gomega v1.34.1
github.com/prometheus/client_golang v1.19.1
github.com/spf13/cobra v1.8.1
github.com/spf13/cobra v1.9.1
github.com/stretchr/testify v1.10.0
go.uber.org/zap v1.26.0
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
Expand All @@ -26,6 +27,7 @@ require (
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8
sigs.k8s.io/controller-runtime v0.19.0
sigs.k8s.io/release-utils v0.11.0
sigs.k8s.io/yaml v1.4.0
)

require (
Expand All @@ -37,6 +39,7 @@ require (
github.com/bmatcuk/doublestar/v4 v4.6.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be // indirect
github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/go-restful/v3 v3.12.1 // indirect
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
Expand All @@ -61,12 +64,15 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.1 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
Expand All @@ -78,23 +84,25 @@ require (
github.com/spf13/afero v1.9.5 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/pflag v1.0.6 // indirect
github.com/spf13/viper v1.16.0 // indirect
github.com/stoewer/go-strcase v1.2.0 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
github.com/vbatts/tar-split v0.12.1 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/mod v0.22.0 // indirect
golang.org/x/net v0.38.0 // indirect
golang.org/x/oauth2 v0.28.0 // indirect
golang.org/x/sys v0.31.0 // indirect
golang.org/x/term v0.30.0 // indirect
golang.org/x/text v0.23.0 // indirect
golang.org/x/tools v0.28.0 // indirect
golang.org/x/mod v0.25.0 // indirect
golang.org/x/net v0.41.0 // indirect
golang.org/x/oauth2 v0.30.0 // indirect
golang.org/x/sync v0.15.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/term v0.32.0 // indirect
golang.org/x/text v0.26.0 // indirect
golang.org/x/tools v0.34.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 // indirect
google.golang.org/protobuf v1.34.2 // indirect
google.golang.org/protobuf v1.36.3 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
Expand All @@ -103,7 +111,6 @@ require (
k8s.io/klog/v2 v2.130.1 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)

tool (
Expand Down
Loading
Loading