diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000000..d4ece648b9 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,9 @@ +linters-settings: + lll: + line-length: 150 +linters: + enable-all: true + disable: + - dupl + - gochecknoinits + - gochecknoglobals diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000000..b191041ef3 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,6 @@ +- repo: git://github.com/dnephin/pre-commit-golang + sha: HEAD + exclude: + - vendor/.* + hooks: + - id: golangci-lint diff --git a/docs/developers.adoc b/docs/developers.adoc index 80c29cdf75..ffc29e9343 100644 --- a/docs/developers.adoc +++ b/docs/developers.adoc @@ -18,6 +18,16 @@ In order to build the project, you need to comply with the following requirement * **Operator SDK v0.0.7+**: used to build the operator and the Docker images. Instructions in the https://github.com/operator-framework/operator-sdk[Operator SDK website] (binary downloads available in the release page). * **GNU Make**: used to define composite build actions. This should be already installed or available as package if you have a good OS (https://www.gnu.org/software/make/). +[[checks]] +== Running checks +We have checks run via https://pre-commit.com[pre-commit] make sure to install the pre-commit hooks after installing pre-commit by running + + $ pre-commit install + +The pre-commit checks run golangci-lint, to install it look at the https://github.com/golangci/golangci-lint#local-installation[Local Installation] instructions. + +Once installed `git commit` will fail if any of the checks don't pass. + [[checking-out]] == Checking Out the Sources diff --git a/pkg/apis/camel/v1alpha1/types.go b/pkg/apis/camel/v1alpha1/types.go index 5626fef7db..b549e1d8c5 100644 --- a/pkg/apis/camel/v1alpha1/types.go +++ b/pkg/apis/camel/v1alpha1/types.go @@ -87,6 +87,8 @@ const ( LanguageXML Language = "xml" // LanguageKotlin -- LanguageKotlin Language = "kts" + // KamelPlatform -- + KamelPlatform = "platform" ) // A IntegrationTraitSpec contains the configuration of a trait diff --git a/pkg/builder/builder.go b/pkg/builder/builder.go index 163df7f883..db82150020 100644 --- a/pkg/builder/builder.go +++ b/pkg/builder/builder.go @@ -195,9 +195,7 @@ func (b *defaultBuilder) submit(request Request) { } r.Artifacts = make([]v1alpha1.Artifact, 0, len(c.Artifacts)) - for _, artifact := range c.Artifacts { - r.Artifacts = append(r.Artifacts, artifact) - } + r.Artifacts = append(r.Artifacts, c.Artifacts...) // update the cache b.request.Store(request.Meta.Name, r) diff --git a/pkg/builder/builder_steps.go b/pkg/builder/builder_steps.go index 09530c08f3..cac7e75c30 100644 --- a/pkg/builder/builder_steps.go +++ b/pkg/builder/builder_steps.go @@ -98,7 +98,8 @@ func GenerateProject(ctx *Context) error { deps.AddGAV("org.apache.camel.k", "camel-k-runtime-jvm", version.Version) for _, d := range ctx.Request.Dependencies { - if strings.HasPrefix(d, "camel:") { + switch { + case strings.HasPrefix(d, "camel:"): artifactID := strings.TrimPrefix(d, "camel:") if !strings.HasPrefix(artifactID, "camel-") { @@ -106,16 +107,16 @@ func GenerateProject(ctx *Context) error { } deps.AddGAV("org.apache.camel", artifactID, "") - } else if strings.HasPrefix(d, "mvn:") { + case strings.HasPrefix(d, "mvn:"): mid := strings.TrimPrefix(d, "mvn:") gav := strings.Replace(mid, "/", ":", -1) deps.AddEncodedGAV(gav) - } else if strings.HasPrefix(d, "runtime:") { + case strings.HasPrefix(d, "runtime:"): artifactID := strings.Replace(d, "runtime:", "camel-k-runtime-", 1) deps.AddGAV("org.apache.camel.k", artifactID, version.Version) - } else { + default: return fmt.Errorf("unknown dependency type: %s", d) } } @@ -269,7 +270,7 @@ func ListPublishedImages(namespace string) ([]PublishedImage, error) { if ctx.Status.Phase != v1alpha1.IntegrationContextPhaseReady || ctx.Labels == nil { continue } - if ctxType, present := ctx.Labels["camel.apache.org/context.type"]; !present || ctxType != "platform" { + if ctxType, present := ctx.Labels["camel.apache.org/context.type"]; !present || ctxType != v1alpha1.KamelPlatform { continue } @@ -292,7 +293,7 @@ func FindBestImage(images []PublishedImage, entries []v1alpha1.Artifact) (*Publi } var bestImage PublishedImage - bestImageCommonLibs := make(map[string]bool, 0) + bestImageCommonLibs := make(map[string]bool) bestImageSurplusLibs := 0 for _, image := range images { common := make(map[string]bool) diff --git a/pkg/builder/kaniko/publisher.go b/pkg/builder/kaniko/publisher.go index 88ef68ab2a..d9533d0ad2 100644 --- a/pkg/builder/kaniko/publisher.go +++ b/pkg/builder/kaniko/publisher.go @@ -29,6 +29,7 @@ import ( "github.com/operator-framework/operator-sdk/pkg/sdk" "github.com/pkg/errors" "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -45,6 +46,7 @@ func Publisher(ctx *builder.Context) error { return err } + // #nosec G202 dockerFileContent := []byte(` FROM ` + ctx.Image + ` ADD . /deployments @@ -137,7 +139,11 @@ func Publisher(ctx *builder.Context) error { }, } - sdk.Delete(&pod) + err = sdk.Delete(&pod) + if err != nil && !apierrors.IsNotFound(err) { + return errors.Wrap(err, "cannot delete kaniko builder pod") + } + err = sdk.Create(&pod) if err != nil { return errors.Wrap(err, "cannot create kaniko builder pod") diff --git a/pkg/builder/s2i/publisher.go b/pkg/builder/s2i/publisher.go index 68cd60fdf8..437c8707bc 100644 --- a/pkg/builder/s2i/publisher.go +++ b/pkg/builder/s2i/publisher.go @@ -32,6 +32,7 @@ import ( buildv1 "github.com/openshift/api/build/v1" imagev1 "github.com/openshift/api/image/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/pkg/errors" @@ -71,8 +72,12 @@ func Publisher(ctx *builder.Context) error { }, } - sdk.Delete(&bc) - err := sdk.Create(&bc) + err := sdk.Delete(&bc) + if err != nil && !apierrors.IsNotFound(err) { + return errors.Wrap(err, "cannot delete build config") + } + + err = sdk.Create(&bc) if err != nil { return errors.Wrap(err, "cannot create build config") } @@ -93,7 +98,11 @@ func Publisher(ctx *builder.Context) error { }, } - sdk.Delete(&is) + err = sdk.Delete(&is) + if err != nil && !apierrors.IsNotFound(err) { + return errors.Wrap(err, "cannot delete image stream") + } + err = sdk.Create(&is) if err != nil { return errors.Wrap(err, "cannot create image stream") @@ -149,6 +158,9 @@ func Publisher(ctx *builder.Context) error { } return false, nil }, 5*time.Minute) + if err != nil { + return err + } err = sdk.Get(&is) if err != nil { diff --git a/pkg/builder/springboot/generator.go b/pkg/builder/springboot/generator.go index 5d74c6137b..af59b7a9c7 100644 --- a/pkg/builder/springboot/generator.go +++ b/pkg/builder/springboot/generator.go @@ -95,7 +95,8 @@ func GenerateProject(ctx *builder.Context) error { // for _, d := range ctx.Request.Dependencies { - if strings.HasPrefix(d, "camel:") { + switch { + case strings.HasPrefix(d, "camel:"): if d == "camel:core" { continue } @@ -135,12 +136,12 @@ func GenerateProject(ctx *builder.Context) error { }, }, }) - } else if strings.HasPrefix(d, "mvn:") { + case strings.HasPrefix(d, "mvn:"): mid := strings.TrimPrefix(d, "mvn:") gav := strings.Replace(mid, "/", ":", -1) deps.AddEncodedGAV(gav) - } else if strings.HasPrefix(d, "runtime:") { + case strings.HasPrefix(d, "runtime:"): if d == "runtime:jvm" { // common continue @@ -153,7 +154,7 @@ func GenerateProject(ctx *builder.Context) error { artifactID := strings.Replace(d, "runtime:", "camel-k-runtime-", 1) deps.AddGAV("org.apache.camel.k", artifactID, version.Version) - } else { + default: return fmt.Errorf("unknown dependency type: %s", d) } } diff --git a/pkg/client/cmd/completion_bash.go b/pkg/client/cmd/completion_bash.go index ab390fec8e..ad3ccbffb7 100644 --- a/pkg/client/cmd/completion_bash.go +++ b/pkg/client/cmd/completion_bash.go @@ -18,6 +18,7 @@ limitations under the License. package cmd import ( + "fmt" "os" "strings" @@ -171,7 +172,10 @@ func newCmdCompletionBash(root *cobra.Command) *cobra.Command { Short: "Generates bash completion scripts", Long: bashCompletionCmdLongDescription, Run: func(cmd *cobra.Command, args []string) { - root.GenBashCompletion(os.Stdout) + err := root.GenBashCompletion(os.Stdout) + if err != nil { + fmt.Print(err.Error()) + } }, } } diff --git a/pkg/client/cmd/completion_zsh.go b/pkg/client/cmd/completion_zsh.go index 5217b8e4df..e9e81b2727 100644 --- a/pkg/client/cmd/completion_zsh.go +++ b/pkg/client/cmd/completion_zsh.go @@ -18,6 +18,7 @@ limitations under the License. package cmd import ( + "fmt" "os" "github.com/spf13/cobra" @@ -49,7 +50,10 @@ func newCmdCompletionZsh(root *cobra.Command) *cobra.Command { Short: "Generates zsh completion scripts", Long: zshCompletionCmdLongDescription, Run: func(cmd *cobra.Command, args []string) { - root.GenZshCompletion(os.Stdout) + err := root.GenZshCompletion(os.Stdout) + if err != nil { + fmt.Print(err.Error()) + } }, } } diff --git a/pkg/client/cmd/context_create.go b/pkg/client/cmd/context_create.go index 2b2b2d23ee..497f4d6ed4 100644 --- a/pkg/client/cmd/context_create.go +++ b/pkg/client/cmd/context_create.go @@ -86,7 +86,7 @@ func (command *contextCreateCommand) run(cmd *cobra.Command, args []string) erro // the integration context already exists, let's check that it is // not a platform one which is supposed to be "read only" - if ctx.Labels["camel.apache.org/context.type"] == "platform" { + if ctx.Labels["camel.apache.org/context.type"] == v1alpha1.KamelPlatform { fmt.Printf("integration context \"%s\" is not editable\n", ctx.Name) return nil } @@ -103,11 +103,12 @@ func (command *contextCreateCommand) run(cmd *cobra.Command, args []string) erro } for _, item := range command.dependencies { - if strings.HasPrefix(item, "mvn:") { + switch { + case strings.HasPrefix(item, "mvn:"): ctx.Spec.Dependencies = append(ctx.Spec.Dependencies, item) - } else if strings.HasPrefix(item, "file:") { + case strings.HasPrefix(item, "file:"): ctx.Spec.Dependencies = append(ctx.Spec.Dependencies, item) - } else if strings.HasPrefix(item, "camel-") { + case strings.HasPrefix(item, "camel-"): ctx.Spec.Dependencies = append(ctx.Spec.Dependencies, "camel:"+strings.TrimPrefix(item, "camel-")) } } @@ -145,7 +146,7 @@ func (command *contextCreateCommand) run(cmd *cobra.Command, args []string) erro clone := ctx.DeepCopy() err = sdk.Get(clone) if err != nil { - fmt.Printf(err.Error()) + fmt.Print(err.Error()) return nil } ctx.ResourceVersion = clone.ResourceVersion @@ -153,7 +154,7 @@ func (command *contextCreateCommand) run(cmd *cobra.Command, args []string) erro } if err != nil { - fmt.Printf(err.Error()) + fmt.Print(err.Error()) return nil } diff --git a/pkg/client/cmd/context_delete.go b/pkg/client/cmd/context_delete.go index ff988377ca..d22b61e464 100644 --- a/pkg/client/cmd/context_delete.go +++ b/pkg/client/cmd/context_delete.go @@ -38,10 +38,10 @@ func newContextDeleteCmd(rootCmdOptions *RootCmdOptions) *cobra.Command { Short: "Delete an Integration Context", Long: `Delete an Integration Context.`, RunE: func(cmd *cobra.Command, args []string) error { - if err := impl.validate(cmd, args); err != nil { + if err := impl.validate(args); err != nil { return err } - if err := impl.run(cmd, args); err != nil { + if err := impl.run(args); err != nil { fmt.Println(err.Error()) } @@ -59,7 +59,7 @@ type contextDeleteCommand struct { all bool } -func (command *contextDeleteCommand) validate(cmd *cobra.Command, args []string) error { +func (command *contextDeleteCommand) validate(args []string) error { if command.all && len(args) > 0 { return errors.New("invalid combination: both all flag and named contexts are set") } @@ -70,7 +70,7 @@ func (command *contextDeleteCommand) validate(cmd *cobra.Command, args []string) return nil } -func (command *contextDeleteCommand) run(cmd *cobra.Command, args []string) error { +func (command *contextDeleteCommand) run(args []string) error { names := args if command.all { @@ -82,7 +82,7 @@ func (command *contextDeleteCommand) run(cmd *cobra.Command, args []string) erro names = make([]string, 0, len(ctxList.Items)) for _, item := range ctxList.Items { // only include non platform contexts - if item.Labels["camel.apache.org/context.type"] != "platform" { + if item.Labels["camel.apache.org/context.type"] != v1alpha1.KamelPlatform { names = append(names, item.Name) } } @@ -114,7 +114,7 @@ func (command *contextDeleteCommand) delete(name string) error { // check that it is not a platform one which is supposed to be "read only" // thus not managed by the end user - if ctx.Labels["camel.apache.org/context.type"] == "platform" { + if ctx.Labels["camel.apache.org/context.type"] == v1alpha1.KamelPlatform { // skip platform contexts while deleting all contexts if command.all { return nil diff --git a/pkg/client/cmd/context_get.go b/pkg/client/cmd/context_get.go index f79bf86a2b..af60a9358a 100644 --- a/pkg/client/cmd/context_get.go +++ b/pkg/client/cmd/context_get.go @@ -40,7 +40,7 @@ func newContextGetCmd(rootCmdOptions *RootCmdOptions) *cobra.Command { if err := impl.validate(cmd, args); err != nil { return err } - if err := impl.run(cmd, args); err != nil { + if err := impl.run(); err != nil { fmt.Println(err.Error()) } @@ -49,7 +49,7 @@ func newContextGetCmd(rootCmdOptions *RootCmdOptions) *cobra.Command { } cmd.Flags().BoolVar(&impl.user, "user", true, "Includes user contexts") - cmd.Flags().BoolVar(&impl.platform, "platform", true, "Includes platform contexts") + cmd.Flags().BoolVar(&impl.platform, v1alpha1.KamelPlatform, true, "Includes platform contexts") return &cmd } @@ -65,7 +65,7 @@ func (command *contextGetCommand) validate(cmd *cobra.Command, args []string) er } -func (command *contextGetCommand) run(cmd *cobra.Command, args []string) error { +func (command *contextGetCommand) run() error { ctxList := v1alpha1.NewIntegrationContextList() if err := sdk.List(command.Namespace, &ctxList); err != nil { return err @@ -76,7 +76,7 @@ func (command *contextGetCommand) run(cmd *cobra.Command, args []string) error { for _, ctx := range ctxList.Items { t := ctx.Labels["camel.apache.org/context.type"] u := command.user && t == "user" - p := command.platform && t == "platform" + p := command.platform && t == v1alpha1.KamelPlatform if u || p { fmt.Fprintf(w, "%s\t%s\t%s\n", ctx.Name, t, string(ctx.Status.Phase)) diff --git a/pkg/client/cmd/delete.go b/pkg/client/cmd/delete.go index 5d7411491a..5c3f470d3a 100644 --- a/pkg/client/cmd/delete.go +++ b/pkg/client/cmd/delete.go @@ -38,10 +38,10 @@ func newCmdDelete(rootCmdOptions *RootCmdOptions) *cobra.Command { Use: "delete [integration1] [integration2] ...", Short: "Delete integrations deployed on Kubernetes", RunE: func(cmd *cobra.Command, args []string) error { - if err := impl.validate(cmd, args); err != nil { + if err := impl.validate(args); err != nil { return err } - if err := impl.run(cmd, args); err != nil { + if err := impl.run(args); err != nil { fmt.Println(err.Error()) } @@ -59,7 +59,7 @@ type deleteCmdOptions struct { deleteAll bool } -func (command *deleteCmdOptions) validate(cmd *cobra.Command, args []string) error { +func (command *deleteCmdOptions) validate(args []string) error { if command.deleteAll && len(args) > 0 { return errors.New("invalid combination: both all flag and named integrations are set") } @@ -70,7 +70,7 @@ func (command *deleteCmdOptions) validate(cmd *cobra.Command, args []string) err return nil } -func (command *deleteCmdOptions) run(cmd *cobra.Command, args []string) error { +func (command *deleteCmdOptions) run(args []string) error { if len(args) != 0 && !command.deleteAll { for _, arg := range args { @@ -100,6 +100,7 @@ func (command *deleteCmdOptions) run(cmd *cobra.Command, args []string) error { return err } for _, integration := range integrationList.Items { + integration := integration // pin err := sdk.Delete(&integration) if err != nil { return err diff --git a/pkg/client/cmd/install.go b/pkg/client/cmd/install.go index 5437c6e2eb..98b25c1510 100644 --- a/pkg/client/cmd/install.go +++ b/pkg/client/cmd/install.go @@ -28,7 +28,7 @@ import ( k8serrors "k8s.io/apimachinery/pkg/api/errors" ) -func newCmdInstall(rootCmdOptions *RootCmdOptions) *cobra.Command { +func newCmdInstall(rootCmdOptions *RootCmdOptions) (*cobra.Command, error) { options := installCmdOptions{ RootCmdOptions: rootCmdOptions, } @@ -44,9 +44,12 @@ func newCmdInstall(rootCmdOptions *RootCmdOptions) *cobra.Command { cmd.Flags().StringVar(&options.registry, "registry", "", "A Docker registry that can be used to publish images") cmd.Flags().StringVar(&options.organization, "organization", "", "A organization on the Docker registry that can be used to publish images") cmd.Flags().StringVar(&options.pushSecret, "push-secret", "", "A secret used to push images to the Docker registry") - cmd.ParseFlags(os.Args) + err := cmd.ParseFlags(os.Args) + if err != nil { + return nil, err + } - return &cmd + return &cmd, nil } type installCmdOptions struct { @@ -62,7 +65,8 @@ func (o *installCmdOptions) install(cmd *cobra.Command, args []string) error { err := install.SetupClusterwideResources() if err != nil && k8serrors.IsForbidden(err) { fmt.Println("Current user is not authorized to create cluster-wide objects like custom resource definitions or cluster roles: ", err) - return errors.New("please login as cluster-admin and execute \"kamel install --cluster-setup\" to install cluster-wide resources (one-time operation)") + return errors.New("please login as cluster-admin and execute \"kamel install --cluster-setup\" to install cluster-wide " + + "resources (one-time operation)") } if o.clusterSetupOnly { diff --git a/pkg/client/cmd/root.go b/pkg/client/cmd/root.go index 58cc58ab34..5672b60c71 100644 --- a/pkg/client/cmd/root.go +++ b/pkg/client/cmd/root.go @@ -19,10 +19,11 @@ package cmd import ( "context" - "github.com/operator-framework/operator-sdk/pkg/k8sclient" "os" "time" + "github.com/operator-framework/operator-sdk/pkg/k8sclient" + "github.com/apache/camel-k/pkg/util/kubernetes" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -57,21 +58,27 @@ func NewKamelCommand(ctx context.Context) (*cobra.Command, error) { cmd.PersistentFlags().StringVarP(&options.Namespace, "namespace", "n", "", "Namespace to use for all operations") // Parse the flags before setting the defaults - cmd.ParseFlags(os.Args) + err := cmd.ParseFlags(os.Args) + if err != nil { + return nil, err + } if options.Namespace == "" { current, err := kubernetes.GetClientCurrentNamespace(options.KubeConfig) if err != nil { return nil, errors.Wrap(err, "cannot get current namespace") } - cmd.Flag("namespace").Value.Set(current) + err = cmd.Flag("namespace").Value.Set(current) + if err != nil { + return nil, err + } } // Let's use a fast refresh period when running with the CLI k8sclient.ResetCacheEvery(2 * time.Second) // Initialize the Kubernetes client to allow using the operator-sdk - err := kubernetes.InitKubeClient(options.KubeConfig) + err = kubernetes.InitKubeClient(options.KubeConfig) if err != nil { return nil, err } @@ -81,7 +88,11 @@ func NewKamelCommand(ctx context.Context) (*cobra.Command, error) { cmd.AddCommand(newCmdRun(&options)) cmd.AddCommand(newCmdGet(&options)) cmd.AddCommand(newCmdDelete(&options)) - cmd.AddCommand(newCmdInstall(&options)) + install, err := newCmdInstall(&options) + if err != nil { + return nil, err + } + cmd.AddCommand(install) cmd.AddCommand(newCmdLog(&options)) cmd.AddCommand(newCmdContext(&options)) diff --git a/pkg/client/cmd/run.go b/pkg/client/cmd/run.go index eb5789b323..5d54ec6dde 100644 --- a/pkg/client/cmd/run.go +++ b/pkg/client/cmd/run.go @@ -53,7 +53,7 @@ import ( ) var ( - traitConfigRegexp = regexp.MustCompile("^([a-z-]+)((?:\\.[a-z-]+)+)=(.*)$") + traitConfigRegexp = regexp.MustCompile(`^([a-z-]+)((?:\.[a-z-]+)+)=(.*)$`) ) func newCmdRun(rootCmdOptions *RootCmdOptions) *cobra.Command { @@ -83,7 +83,8 @@ func newCmdRun(rootCmdOptions *RootCmdOptions) *cobra.Command { cmd.Flags().BoolVar(&options.Dev, "dev", false, "Enable Dev mode (equivalent to \"-w --logs --sync\")") cmd.Flags().StringVar(&options.Profile, "profile", "", "Trait profile used for deployment") cmd.Flags().StringSliceVarP(&options.Traits, "trait", "t", nil, "Configure a trait. E.g. \"-t service.enabled=false\"") - cmd.Flags().StringSliceVar(&options.LoggingLevels, "logging-level", nil, "Configure the logging level. E.g. \"--logging-level org.apache.camel=DEBUG\"") + cmd.Flags().StringSliceVar(&options.LoggingLevels, "logging-level", nil, "Configure the logging level. "+ + "E.g. \"--logging-level org.apache.camel=DEBUG\"") cmd.Flags().StringVarP(&options.OutputFormat, "output", "o", "", "Output format. One of: json|yaml") // completion support @@ -152,7 +153,7 @@ func (o *runCmdOptions) run(cmd *cobra.Command, args []string) error { } } - integration, err := o.createIntegration(cmd, args) + integration, err := o.createIntegration(args) if err != nil { return err } @@ -246,7 +247,7 @@ func (o *runCmdOptions) syncIntegration(sources []string) error { return nil } -func (o *runCmdOptions) createIntegration(cmd *cobra.Command, args []string) (*v1alpha1.Integration, error) { +func (o *runCmdOptions) createIntegration(args []string) (*v1alpha1.Integration, error) { return o.updateIntegrationCode(args) } @@ -294,11 +295,12 @@ func (o *runCmdOptions) updateIntegrationCode(sources []string) (*v1alpha1.Integ } for _, item := range o.Dependencies { - if strings.HasPrefix(item, "mvn:") { + switch { + case strings.HasPrefix(item, "mvn:"): integration.Spec.Dependencies = append(integration.Spec.Dependencies, item) - } else if strings.HasPrefix(item, "file:") { + case strings.HasPrefix(item, "file:"): integration.Spec.Dependencies = append(integration.Spec.Dependencies, item) - } else if strings.HasPrefix(item, "camel-") { + case strings.HasPrefix(item, "camel-"): integration.Spec.Dependencies = append(integration.Spec.Dependencies, "camel:"+strings.TrimPrefix(item, "camel-")) } } @@ -431,7 +433,7 @@ func (*runCmdOptions) loadCode(fileName string) (string, error) { defer resp.Body.Close() bodyBytes, err := ioutil.ReadAll(resp.Body) bodyString := string(bodyBytes) - return string(bodyString), err + return bodyString, err } func (*runCmdOptions) configureTrait(integration *v1alpha1.Integration, config string) error { diff --git a/pkg/install/operator.go b/pkg/install/operator.go index 5c4fb0a1d9..3af6a0e9f7 100644 --- a/pkg/install/operator.go +++ b/pkg/install/operator.go @@ -19,6 +19,9 @@ package install import ( "errors" + "strconv" + "time" + "github.com/apache/camel-k/deploy" "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" "github.com/apache/camel-k/pkg/util/knative" @@ -26,8 +29,6 @@ import ( "github.com/apache/camel-k/pkg/util/minishift" "github.com/apache/camel-k/pkg/util/openshift" "github.com/operator-framework/operator-sdk/pkg/sdk" - "strconv" - "time" ) // Operator -- diff --git a/pkg/metadata/metadata_uri_test.go b/pkg/metadata/metadata_uri_test.go index 84da92a1b9..1214ef68a8 100644 --- a/pkg/metadata/metadata_uri_test.go +++ b/pkg/metadata/metadata_uri_test.go @@ -18,9 +18,10 @@ limitations under the License. package metadata import ( + "testing" + "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" "github.com/stretchr/testify/assert" - "testing" ) func TestJava1(t *testing.T) { diff --git a/pkg/metadata/uris.go b/pkg/metadata/uris.go index 2caddc26ec..0c08f9ac3d 100644 --- a/pkg/metadata/uris.go +++ b/pkg/metadata/uris.go @@ -24,17 +24,17 @@ import ( ) var ( - singleQuotedFrom = regexp.MustCompile("from\\s*\\(\\s*'([a-z0-9-]+:[^']+)'\\s*\\)") - doubleQuotedFrom = regexp.MustCompile("from\\s*\\(\\s*\"([a-z0-9-]+:[^\"]+)\"\\s*\\)") - singleQuotedTo = regexp.MustCompile("\\.to\\s*\\(\\s*'([a-z0-9-]+:[^']+)'\\s*\\)") - singleQuotedToD = regexp.MustCompile("\\.toD\\s*\\(\\s*'([a-z0-9-]+:[^']+)'\\s*\\)") - singleQuotedToF = regexp.MustCompile("\\.toF\\s*\\(\\s*'([a-z0-9-]+:[^']+)'[^)]*\\)") - doubleQuotedTo = regexp.MustCompile("\\.to\\s*\\(\\s*\"([a-z0-9-]+:[^\"]+)\"\\s*\\)") - doubleQuotedToD = regexp.MustCompile("\\.toD\\s*\\(\\s*\"([a-z0-9-]+:[^\"]+)\"\\s*\\)") - doubleQuotedToF = regexp.MustCompile("\\.toF\\s*\\(\\s*\"([a-z0-9-]+:[^\"]+)\"[^)]*\\)") - xmlTagFrom = regexp.MustCompile("<\\s*from\\s+[^>]*uri\\s*=\\s*\"([a-z0-9-]+:[^\"]+)\"[^>]*>") - xmlTagTo = regexp.MustCompile("<\\s*to\\s+[^>]*uri\\s*=\\s*\"([a-z0-9-]+:[^\"]+)\"[^>]*>") - xmlTagToD = regexp.MustCompile("<\\s*toD\\s+[^>]*uri\\s*=\\s*\"([a-z0-9-]+:[^\"]+)\"[^>]*>") + singleQuotedFrom = regexp.MustCompile(`from\s*\(\s*'([a-z0-9-]+:[^']+)'\s*\)`) + doubleQuotedFrom = regexp.MustCompile(`from\s*\(\s*"([a-z0-9-]+:[^"]+)"\s*\)`) + singleQuotedTo = regexp.MustCompile(`\.to\s*\(\s*'([a-z0-9-]+:[^']+)'\s*\)`) + singleQuotedToD = regexp.MustCompile(`\.toD\s*\(\s*'([a-z0-9-]+:[^']+)'\s*\)`) + singleQuotedToF = regexp.MustCompile(`\.toF\s*\(\s*'([a-z0-9-]+:[^']+)'[^)]*\)`) + doubleQuotedTo = regexp.MustCompile(`\.to\s*\(\s*"([a-z0-9-]+:[^"]+)"\s*\)`) + doubleQuotedToD = regexp.MustCompile(`\.toD\s*\(\s*"([a-z0-9-]+:[^"]+)"\s*\)`) + doubleQuotedToF = regexp.MustCompile(`\.toF\s*\(\s*"([a-z0-9-]+:[^"]+)"[^)]*\)`) + xmlTagFrom = regexp.MustCompile(`<\s*from\s+[^>]*uri\s*=\s*"([a-z0-9-]+:[^"]+)"[^>]*>`) + xmlTagTo = regexp.MustCompile(`<\s*to\s+[^>]*uri\s*=\s*"([a-z0-9-]+:[^"]+)"[^>]*>`) + xmlTagToD = regexp.MustCompile(`<\s*toD\s+[^>]*uri\s*=\s*"([a-z0-9-]+:[^"]+)"[^>]*>`) ) // discoverFromURIs returns all uris used in a from clause @@ -87,7 +87,7 @@ func findAllDistinctStringSubmatch(data string, regexps ...*regexp.Regexp) []str for _, reg := range regexps { hits := reg.FindAllStringSubmatch(data, -1) for _, hit := range hits { - if hit != nil && len(hit) > 1 { + if len(hit) > 1 { for _, match := range hit[1:] { if _, ok := alreadyFound[match]; !ok { alreadyFound[match] = true diff --git a/pkg/platform/platform.go b/pkg/platform/platform.go index d208c2056d..cf82ed716e 100644 --- a/pkg/platform/platform.go +++ b/pkg/platform/platform.go @@ -49,6 +49,7 @@ func GetCurrentPlatform(namespace string) (*v1alpha1.IntegrationPlatform, error) } for _, platform := range lst.Items { + platform := platform // pin if IsActive(&platform) { return &platform, nil } diff --git a/pkg/stub/action/context/build.go b/pkg/stub/action/context/build.go index 8f7a9bffb7..96255455e9 100644 --- a/pkg/stub/action/context/build.go +++ b/pkg/stub/action/context/build.go @@ -70,11 +70,12 @@ func (action *buildAction) Handle(context *v1alpha1.IntegrationContext) error { } res := b.Submit(r) - if res.Status == builder.StatusSubmitted { + switch res.Status { + case builder.StatusSubmitted: logrus.Info("Build submitted") - } else if res.Status == builder.StatusStarted { + case builder.StatusStarted: logrus.Info("Build started") - } else if res.Status == builder.StatusError { + case builder.StatusError: target := context.DeepCopy() target.Status.Phase = v1alpha1.IntegrationContextPhaseError @@ -84,7 +85,7 @@ func (action *buildAction) Handle(context *v1alpha1.IntegrationContext) error { b.Purge(r) return sdk.Update(target) - } else if res.Status == builder.StatusCompleted { + case builder.StatusCompleted: target := context.DeepCopy() target.Status.Image = res.Image target.Status.Phase = v1alpha1.IntegrationContextPhaseReady @@ -123,6 +124,7 @@ func (action *buildAction) informIntegrations(context *v1alpha1.IntegrationConte return err } for _, integration := range list.Items { + integration := integration // pin if integration.Spec.Context != context.Name { continue } diff --git a/pkg/stub/action/context/initialize.go b/pkg/stub/action/context/initialize.go index f9e8d04dfe..17c49418a4 100644 --- a/pkg/stub/action/context/initialize.go +++ b/pkg/stub/action/context/initialize.go @@ -58,7 +58,11 @@ func (action *initializeAction) Handle(context *v1alpha1.IntegrationContext) err // update the status logrus.Info("Context ", target.Name, " transitioning to state ", v1alpha1.IntegrationContextPhaseBuilding) target.Status.Phase = v1alpha1.IntegrationContextPhaseBuilding - target.Status.Digest = digest.ComputeForIntegrationContext(context) + dgst, err := digest.ComputeForIntegrationContext(context) + if err != nil { + return err + } + target.Status.Digest = dgst return sdk.Update(target) } diff --git a/pkg/stub/action/context/monitor.go b/pkg/stub/action/context/monitor.go index f090ffb96b..41e8c45c2a 100644 --- a/pkg/stub/action/context/monitor.go +++ b/pkg/stub/action/context/monitor.go @@ -41,7 +41,10 @@ func (action *monitorAction) CanHandle(context *v1alpha1.IntegrationContext) boo } func (action *monitorAction) Handle(context *v1alpha1.IntegrationContext) error { - hash := digest.ComputeForIntegrationContext(context) + hash, err := digest.ComputeForIntegrationContext(context) + if err != nil { + return err + } if hash != context.Status.Digest { logrus.Info("IntegrationContext ", context.Name, " needs a rebuild") diff --git a/pkg/stub/action/integration/build.go b/pkg/stub/action/integration/build.go index e4660c8ef9..85eb881c38 100644 --- a/pkg/stub/action/integration/build.go +++ b/pkg/stub/action/integration/build.go @@ -58,7 +58,7 @@ func (action *buildAction) Handle(integration *v1alpha1.Integration) error { } if ctx != nil { - if ctx.Labels["camel.apache.org/context.type"] == "platform" { + if ctx.Labels["camel.apache.org/context.type"] == v1alpha1.KamelPlatform { // This is a platform context and as it is auto generated it may get // out of sync if the integration that has generated it, has been // amended to add/remove dependencies @@ -80,7 +80,11 @@ func (action *buildAction) Handle(integration *v1alpha1.Integration) error { target.Spec.Context = ctx.Name logrus.Info("Integration ", target.Name, " transitioning to state ", v1alpha1.IntegrationPhaseDeploying) target.Status.Phase = v1alpha1.IntegrationPhaseDeploying - target.Status.Digest = digest.ComputeForIntegration(target) + dgst, err := digest.ComputeForIntegration(target) + if err != nil { + return err + } + target.Status.Digest = dgst return sdk.Update(target) } @@ -89,7 +93,11 @@ func (action *buildAction) Handle(integration *v1alpha1.Integration) error { target.Status.Image = ctx.Status.Image target.Spec.Context = ctx.Name target.Status.Phase = v1alpha1.IntegrationPhaseError - target.Status.Digest = digest.ComputeForIntegration(target) + dgst, err := digest.ComputeForIntegration(target) + if err != nil { + return err + } + target.Status.Digest = dgst return sdk.Update(target) } @@ -109,7 +117,7 @@ func (action *buildAction) Handle(integration *v1alpha1.Integration) error { // Add some information for post-processing, this may need to be refactored // to a proper data structure platformCtx.Labels = map[string]string{ - "camel.apache.org/context.type": "platform", + "camel.apache.org/context.type": v1alpha1.KamelPlatform, "camel.apache.org/context.created.by.kind": v1alpha1.IntegrationKind, "camel.apache.org/context.created.by.name": integration.Name, "camel.apache.org/context.created.by.version": integration.ResourceVersion, diff --git a/pkg/stub/action/integration/initialize.go b/pkg/stub/action/integration/initialize.go index b495b11c87..8a21301473 100644 --- a/pkg/stub/action/integration/initialize.go +++ b/pkg/stub/action/integration/initialize.go @@ -75,6 +75,10 @@ func (action *initializeAction) Handle(integration *v1alpha1.Integration) error // update the status logrus.Info("Integration ", target.Name, " transitioning to state ", v1alpha1.IntegrationPhaseBuilding) target.Status.Phase = v1alpha1.IntegrationPhaseBuilding - target.Status.Digest = digest.ComputeForIntegration(integration) + dgst, err := digest.ComputeForIntegration(integration) + if err != nil { + return err + } + target.Status.Digest = dgst return sdk.Update(target) } diff --git a/pkg/stub/action/integration/monitor.go b/pkg/stub/action/integration/monitor.go index ebdb4207a5..756695bacd 100644 --- a/pkg/stub/action/integration/monitor.go +++ b/pkg/stub/action/integration/monitor.go @@ -43,7 +43,11 @@ func (action *monitorAction) CanHandle(integration *v1alpha1.Integration) bool { func (action *monitorAction) Handle(integration *v1alpha1.Integration) error { - hash := digest.ComputeForIntegration(integration) + hash, err := digest.ComputeForIntegration(integration) + if err != nil { + return err + } + if hash != integration.Status.Digest { logrus.Info("Integration ", integration.Name, " needs a rebuild") diff --git a/pkg/stub/action/integration/util.go b/pkg/stub/action/integration/util.go index 27bfb29572..b48e6f1b0b 100644 --- a/pkg/stub/action/integration/util.go +++ b/pkg/stub/action/integration/util.go @@ -44,7 +44,8 @@ func LookupContextForIntegration(integration *v1alpha1.Integration) (*v1alpha1.I } for _, ctx := range ctxList.Items { - if ctx.Labels["camel.apache.org/context.type"] == "platform" { + ctx := ctx // pin + if ctx.Labels["camel.apache.org/context.type"] == v1alpha1.KamelPlatform { ideps := len(integration.Spec.Dependencies) cdeps := len(ctx.Spec.Dependencies) diff --git a/pkg/stub/action/platform/initialize.go b/pkg/stub/action/platform/initialize.go index f4eacde6d4..06e6b796af 100644 --- a/pkg/stub/action/platform/initialize.go +++ b/pkg/stub/action/platform/initialize.go @@ -19,6 +19,7 @@ package platform import ( "errors" + "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" platformutils "github.com/apache/camel-k/pkg/platform" "github.com/apache/camel-k/pkg/util/openshift" @@ -63,11 +64,13 @@ func (action *initializeAction) Handle(platform *v1alpha1.IntegrationPlatform) e // update missing fields in the resource if target.Spec.Cluster == "" { // determine the kind of cluster the platform in installed into - if isOpenshift, err := openshift.IsOpenShift(); err != nil { + isOpenshift, err := openshift.IsOpenShift() + switch { + case err != nil: return err - } else if isOpenshift { + case isOpenshift: target.Spec.Cluster = v1alpha1.IntegrationPlatformClusterOpenShift - } else { + default: target.Spec.Cluster = v1alpha1.IntegrationPlatformClusterKubernetes } } @@ -100,6 +103,7 @@ func (action *initializeAction) isDuplicate(thisPlatform *v1alpha1.IntegrationPl return false, err } for _, platform := range platforms.Items { + platform := platform // pin if platform.Name != thisPlatform.Name && platformutils.IsActive(&platform) { return true, nil } diff --git a/pkg/stub/handler.go b/pkg/stub/handler.go index 18ae6916ed..a2f98cac80 100644 --- a/pkg/stub/handler.go +++ b/pkg/stub/handler.go @@ -19,6 +19,7 @@ package stub import ( ctx "context" + "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" "github.com/apache/camel-k/pkg/stub/action/platform" diff --git a/pkg/trait/builder_test.go b/pkg/trait/builder_test.go index 03b2b04dc7..cf6c064a07 100644 --- a/pkg/trait/builder_test.go +++ b/pkg/trait/builder_test.go @@ -36,6 +36,7 @@ func TestBuilderTraitNotAppliedBecauseOfNilContext(t *testing.T) { } for _, e := range environments { + e := e // pin e.Context = nil t.Run(string(e.Platform.Spec.Cluster), func(t *testing.T) { @@ -56,6 +57,7 @@ func TestBuilderTraitNotAppliedBecauseOfNilPhase(t *testing.T) { } for _, e := range environments { + e := e // pin e.Context.Status.Phase = "" t.Run(string(e.Platform.Spec.Cluster), func(t *testing.T) { diff --git a/pkg/trait/catalog.go b/pkg/trait/catalog.go index d381aeb294..62c2f9fcec 100644 --- a/pkg/trait/catalog.go +++ b/pkg/trait/catalog.go @@ -113,7 +113,9 @@ func (c *Catalog) traitsFor(environment *Environment) []Trait { } func (c *Catalog) apply(environment *Environment) error { - c.configure(environment) + if err := c.configure(environment); err != nil { + return err + } traits := c.traitsFor(environment) for _, trait := range traits { @@ -147,12 +149,14 @@ func (c *Catalog) GetTrait(id string) Trait { return nil } -func (c *Catalog) configure(env *Environment) { +func (c *Catalog) configure(env *Environment) error { if env.Context != nil && env.Context.Spec.Traits != nil { for id, traitSpec := range env.Context.Spec.Traits { catTrait := c.GetTrait(id) if catTrait != nil { - traitSpec.Decode(catTrait) + if err := traitSpec.Decode(catTrait); err != nil { + return err + } } } } @@ -160,16 +164,21 @@ func (c *Catalog) configure(env *Environment) { for id, traitSpec := range env.Integration.Spec.Traits { catTrait := c.GetTrait(id) if catTrait != nil { - traitSpec.Decode(catTrait) + if err := traitSpec.Decode(catTrait); err != nil { + return err + } } } } + + return nil } // ComputeTraitsProperties returns all key/value configuration properties that can be used to configure traits func (c *Catalog) ComputeTraitsProperties() []string { results := make([]string, 0) for _, trait := range c.allTraits() { + trait := trait // pin c.processFields(structs.Fields(trait), func(name string) { results = append(results, string(trait.ID())+"."+name) }) diff --git a/pkg/trait/ingress.go b/pkg/trait/ingress.go index b40d74f823..1688e232c2 100644 --- a/pkg/trait/ingress.go +++ b/pkg/trait/ingress.go @@ -62,7 +62,7 @@ func (i *ingressTrait) apply(e *Environment) error { return errors.New("cannot apply ingress trait: no target service") } - e.Resources.Add(i.getIngressFor(e, service)) + e.Resources.Add(i.getIngressFor(service)) return nil } @@ -77,7 +77,7 @@ func (*ingressTrait) getTargetService(e *Environment) (service *corev1.Service) return } -func (i *ingressTrait) getIngressFor(env *Environment, service *corev1.Service) *v1beta1.Ingress { +func (i *ingressTrait) getIngressFor(service *corev1.Service) *v1beta1.Ingress { ingress := v1beta1.Ingress{ TypeMeta: metav1.TypeMeta{ Kind: "Ingress", diff --git a/pkg/trait/knative.go b/pkg/trait/knative.go index b2cd958509..5f0e10f4d0 100644 --- a/pkg/trait/knative.go +++ b/pkg/trait/knative.go @@ -20,9 +20,10 @@ package trait import ( "encoding/json" "fmt" + "strings" + "github.com/operator-framework/operator-sdk/pkg/sdk" "github.com/pkg/errors" - "strings" "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" @@ -190,6 +191,10 @@ func (*knativeTrait) getSubscriptionFor(e *Environment, channel string) *eventin func (t *knativeTrait) getConfigurationSerialized(e *Environment) (string, error) { env, err := t.getConfiguration(e) + if err != nil { + return "", errors.Wrap(err, "unable fetch environment configuration") + } + res, err := json.Marshal(env) if err != nil { return "", errors.Wrap(err, "unable to serialize Knative configuration") @@ -308,7 +313,7 @@ func (*knativeTrait) retrieveChannel(namespace string, name string) (*eventing.C }, } if err := sdk.Get(&channel); err != nil { - return nil, errors.Wrap(err, "could not retrieve channel " + name + " in namespace " + namespace) + return nil, errors.Wrap(err, "could not retrieve channel "+name+" in namespace "+namespace) } return &channel, nil } diff --git a/pkg/trait/route.go b/pkg/trait/route.go index b2ef62540c..e65b0cb9a5 100644 --- a/pkg/trait/route.go +++ b/pkg/trait/route.go @@ -61,7 +61,7 @@ func (r *routeTrait) apply(e *Environment) error { return errors.New("cannot apply route trait: no target service") } - e.Resources.Add(r.getRouteFor(e, service)) + e.Resources.Add(r.getRouteFor(service)) return nil } @@ -76,7 +76,7 @@ func (*routeTrait) getTargetService(e *Environment) (service *corev1.Service) { return } -func (r *routeTrait) getRouteFor(env *Environment, service *corev1.Service) *routev1.Route { +func (r *routeTrait) getRouteFor(service *corev1.Service) *routev1.Route { route := routev1.Route{ TypeMeta: metav1.TypeMeta{ Kind: "Route", diff --git a/pkg/trait/service.go b/pkg/trait/service.go index 1c9b19be98..a7c927a263 100644 --- a/pkg/trait/service.go +++ b/pkg/trait/service.go @@ -63,15 +63,12 @@ func (s *serviceTrait) autoconfigure(e *Environment) error { } func (s *serviceTrait) apply(e *Environment) (err error) { - var svc *corev1.Service - if svc, err = s.getServiceFor(e); err != nil { - return err - } + svc := s.getServiceFor(e) e.Resources.Add(svc) return nil } -func (s *serviceTrait) getServiceFor(e *Environment) (*corev1.Service, error) { +func (s *serviceTrait) getServiceFor(e *Environment) *corev1.Service { svc := corev1.Service{ TypeMeta: metav1.TypeMeta{ Kind: "Service", @@ -99,7 +96,7 @@ func (s *serviceTrait) getServiceFor(e *Environment) (*corev1.Service, error) { }, } - return &svc, nil + return &svc } func (*serviceTrait) requiresService(environment *Environment) bool { diff --git a/pkg/trait/trait_test.go b/pkg/trait/trait_test.go index 52113952c5..3e78fad4b2 100644 --- a/pkg/trait/trait_test.go +++ b/pkg/trait/trait_test.go @@ -29,6 +29,11 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +const ( + TestDeployment = "test" + TestProperties = "test-properties" +) + func TestOpenShiftTraits(t *testing.T) { env := createTestEnv(v1alpha1.IntegrationPlatformClusterOpenShift, "camel:core") res := processTestEnv(t, env) @@ -38,10 +43,10 @@ func TestOpenShiftTraits(t *testing.T) { assert.NotContains(t, env.ExecutedTraits, ID("route")) assert.Contains(t, env.ExecutedTraits, ID("owner")) assert.NotNil(t, res.GetConfigMap(func(cm *corev1.ConfigMap) bool { - return cm.Name == "test-properties" + return cm.Name == TestProperties })) assert.NotNil(t, res.GetDeployment(func(deployment *appsv1.Deployment) bool { - return deployment.Name == "test" + return deployment.Name == TestDeployment })) } @@ -53,16 +58,16 @@ func TestOpenShiftTraitsWithWeb(t *testing.T) { assert.Contains(t, env.ExecutedTraits, ID("route")) assert.Contains(t, env.ExecutedTraits, ID("owner")) assert.NotNil(t, res.GetConfigMap(func(cm *corev1.ConfigMap) bool { - return cm.Name == "test-properties" + return cm.Name == TestProperties })) assert.NotNil(t, res.GetDeployment(func(deployment *appsv1.Deployment) bool { - return deployment.Name == "test" + return deployment.Name == TestDeployment })) assert.NotNil(t, res.GetService(func(svc *corev1.Service) bool { - return svc.Name == "test" + return svc.Name == TestDeployment })) assert.NotNil(t, res.GetRoute(func(svc *routev1.Route) bool { - return svc.Name == "test" + return svc.Name == TestDeployment })) } @@ -78,7 +83,7 @@ func TestOpenShiftTraitsWithWebAndConfig(t *testing.T) { assert.Contains(t, env.ExecutedTraits, ID("service")) assert.Contains(t, env.ExecutedTraits, ID("route")) assert.NotNil(t, res.GetService(func(svc *corev1.Service) bool { - return svc.Name == "test" && svc.Spec.Ports[0].TargetPort.IntVal == int32(7071) + return svc.Name == TestDeployment && svc.Spec.Ports[0].TargetPort.IntVal == int32(7071) })) } @@ -107,10 +112,10 @@ func TestKubernetesTraits(t *testing.T) { assert.NotContains(t, env.ExecutedTraits, ID("route")) assert.Contains(t, env.ExecutedTraits, ID("owner")) assert.NotNil(t, res.GetConfigMap(func(cm *corev1.ConfigMap) bool { - return cm.Name == "test-properties" + return cm.Name == TestProperties })) assert.NotNil(t, res.GetDeployment(func(deployment *appsv1.Deployment) bool { - return deployment.Name == "test" + return deployment.Name == TestDeployment })) } @@ -122,13 +127,13 @@ func TestKubernetesTraitsWithWeb(t *testing.T) { assert.NotContains(t, env.ExecutedTraits, ID("route")) assert.Contains(t, env.ExecutedTraits, ID("owner")) assert.NotNil(t, res.GetConfigMap(func(cm *corev1.ConfigMap) bool { - return cm.Name == "test-properties" + return cm.Name == TestProperties })) assert.NotNil(t, res.GetDeployment(func(deployment *appsv1.Deployment) bool { - return deployment.Name == "test" + return deployment.Name == TestDeployment })) assert.NotNil(t, res.GetService(func(svc *corev1.Service) bool { - return svc.Name == "test" + return svc.Name == TestDeployment })) } @@ -163,7 +168,7 @@ func createTestEnv(cluster v1alpha1.IntegrationPlatformCluster, dependencies ... return &Environment{ Integration: &v1alpha1.Integration{ ObjectMeta: metav1.ObjectMeta{ - Name: "test", + Name: TestDeployment, Namespace: "ns", }, Spec: v1alpha1.IntegrationSpec{ diff --git a/pkg/trait/types.go b/pkg/trait/types.go index 8e9e22368d..eaaba029e8 100644 --- a/pkg/trait/types.go +++ b/pkg/trait/types.go @@ -87,10 +87,6 @@ func (trait *BaseTrait) autoconfigure(environment *Environment) error { return nil } -func (trait *BaseTrait) apply(environment *Environment) error { - return nil -} - /* Environment */ // A Environment provides the context where the trait is executed diff --git a/pkg/trait/util.go b/pkg/trait/util.go index bbbbb329b9..afb8f23931 100644 --- a/pkg/trait/util.go +++ b/pkg/trait/util.go @@ -91,7 +91,7 @@ func CombineConfigurationAsMap(configurationType string, context *v1alpha1.Integ // CombineConfigurationAsSlice -- func CombineConfigurationAsSlice(configurationType string, context *v1alpha1.IntegrationContext, integration *v1alpha1.Integration) []string { - result := make(map[string]bool, 0) + result := make(map[string]bool) if context != nil { // Add context properties first so integrations can // override it diff --git a/pkg/util/camel/catalog_test.go b/pkg/util/camel/catalog_test.go index 88f0447fef..d7fb0d5bb9 100644 --- a/pkg/util/camel/catalog_test.go +++ b/pkg/util/camel/catalog_test.go @@ -18,8 +18,9 @@ limitations under the License. package camel import ( - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) func TestCatalog(t *testing.T) { diff --git a/pkg/util/digest/digest.go b/pkg/util/digest/digest.go index 2be054f45f..5803a97df0 100644 --- a/pkg/util/digest/digest.go +++ b/pkg/util/digest/digest.go @@ -29,49 +29,67 @@ import ( // ComputeForIntegration a digest of the fields that are relevant for the deployment // Produces a digest that can be used as docker image tag -func ComputeForIntegration(integration *v1alpha1.Integration) string { +func ComputeForIntegration(integration *v1alpha1.Integration) (string, error) { hash := sha256.New() // Operator version is relevant - hash.Write([]byte(version.Version)) + if _, err := hash.Write([]byte(version.Version)); err != nil { + return "", err + } // Integration Context is relevant - hash.Write([]byte(integration.Spec.Context)) + if _, err := hash.Write([]byte(integration.Spec.Context)); err != nil { + return "", err + } // Integration code for _, s := range integration.Spec.Sources { if s.Content != "" { - hash.Write([]byte(s.Content)) + if _, err := hash.Write([]byte(s.Content)); err != nil { + return "", err + } } } // Integration dependencies for _, item := range integration.Spec.Dependencies { - hash.Write([]byte(item)) + if _, err := hash.Write([]byte(item)); err != nil { + return "", err + } } // Integration configuration for _, item := range integration.Spec.Configuration { - hash.Write([]byte(item.String())) + if _, err := hash.Write([]byte(item.String())); err != nil { + return "", err + } } // Add a letter at the beginning and use URL safe encoding - return "v" + base64.RawURLEncoding.EncodeToString(hash.Sum(nil)) + digest := "v" + base64.RawURLEncoding.EncodeToString(hash.Sum(nil)) + return digest, nil } // ComputeForIntegrationContext a digest of the fields that are relevant for the deployment // Produces a digest that can be used as docker image tag -func ComputeForIntegrationContext(context *v1alpha1.IntegrationContext) string { +func ComputeForIntegrationContext(context *v1alpha1.IntegrationContext) (string, error) { hash := sha256.New() // Operator version is relevant - hash.Write([]byte(version.Version)) + if _, err := hash.Write([]byte(version.Version)); err != nil { + return "", err + } for _, item := range context.Spec.Dependencies { - hash.Write([]byte(item)) + if _, err := hash.Write([]byte(item)); err != nil { + return "", err + } } for _, item := range context.Spec.Configuration { - hash.Write([]byte(item.String())) + if _, err := hash.Write([]byte(item.String())); err != nil { + return "", err + } } // Add a letter at the beginning and use URL safe encoding - return "v" + base64.RawURLEncoding.EncodeToString(hash.Sum(nil)) + digest := "v" + base64.RawURLEncoding.EncodeToString(hash.Sum(nil)) + return digest, nil } // Random -- diff --git a/pkg/util/knative/uri_test.go b/pkg/util/knative/uri_test.go index 8bc35b547c..c43fe39f94 100644 --- a/pkg/util/knative/uri_test.go +++ b/pkg/util/knative/uri_test.go @@ -18,8 +18,9 @@ limitations under the License. package knative import ( - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) func TestChannelUri(t *testing.T) { diff --git a/pkg/util/kubernetes/config.go b/pkg/util/kubernetes/config.go index 26ed4f2de1..634e9b805b 100644 --- a/pkg/util/kubernetes/config.go +++ b/pkg/util/kubernetes/config.go @@ -18,10 +18,11 @@ limitations under the License. package kubernetes import ( - "github.com/operator-framework/operator-sdk/pkg/util/k8sutil" "os" "os/user" "path/filepath" + + "github.com/operator-framework/operator-sdk/pkg/util/k8sutil" ) // InitKubeClient initialize the k8s client diff --git a/pkg/util/kubernetes/sanitize.go b/pkg/util/kubernetes/sanitize.go index 95dee403e8..e3351a36fa 100644 --- a/pkg/util/kubernetes/sanitize.go +++ b/pkg/util/kubernetes/sanitize.go @@ -26,11 +26,7 @@ import ( "github.com/stoewer/go-strcase" ) -var disallowedChars *regexp.Regexp - -func init() { - disallowedChars = regexp.MustCompile("[^a-z0-9-]") -} +var disallowedChars = regexp.MustCompile(`[^a-z0-9-]`) // SanitizeName sanitizes the given name to be compatible with k8s func SanitizeName(name string) string { diff --git a/pkg/util/log/annotation_scraper.go b/pkg/util/log/annotation_scraper.go index d3b4331a98..5aad25d4fc 100644 --- a/pkg/util/log/annotation_scraper.go +++ b/pkg/util/log/annotation_scraper.go @@ -62,7 +62,7 @@ func (s *SelectorScraper) Start(ctx context.Context) *bufio.Reader { } func (s *SelectorScraper) periodicSynchronize(ctx context.Context, out *bufio.Writer, clientCloser func() error) { - err := s.synchronize(ctx, out, clientCloser) + err := s.synchronize(ctx, out) if err != nil { logrus.Warn("Could not synchronize log by label " + s.labelSelector) } @@ -76,13 +76,15 @@ func (s *SelectorScraper) periodicSynchronize(ctx context.Context, out *bufio.Wr return true }) - clientCloser() + if err := clientCloser(); err != nil { + logrus.Warn("Unable to close the client", err) + } case <-time.After(2 * time.Second): go s.periodicSynchronize(ctx, out, clientCloser) } } -func (s *SelectorScraper) synchronize(ctx context.Context, out *bufio.Writer, clientCloser func() error) error { +func (s *SelectorScraper) synchronize(ctx context.Context, out *bufio.Writer) error { list, err := s.listPods() if err != nil { return err @@ -128,7 +130,10 @@ func (s *SelectorScraper) addPodScraper(ctx context.Context, name string, out *b go func() { defer podCancel() - out.WriteString(prefix + "Monitoring pod " + name) + if _, err := out.WriteString(prefix + "Monitoring pod " + name); err != nil { + logrus.Error("Cannot write to output: ", err) + return + } for { str, err := podReader.ReadString('\n') if err == io.EOF { @@ -137,7 +142,10 @@ func (s *SelectorScraper) addPodScraper(ctx context.Context, name string, out *b logrus.Error("Cannot read from pod stream: ", err) return } - out.WriteString(prefix + str) + if _, err := out.WriteString(prefix + str); err != nil { + logrus.Error("Cannot write to output: ", err) + return + } out.Flush() if podCtx.Err() != nil { return diff --git a/pkg/util/log/pod_scraper.go b/pkg/util/log/pod_scraper.go index 85e9d33fa8..ba4567ba1b 100644 --- a/pkg/util/log/pod_scraper.go +++ b/pkg/util/log/pod_scraper.go @@ -101,7 +101,9 @@ func (s *PodScraper) handleAndRestart(ctx context.Context, err error, wait time. if ctx.Err() != nil { logrus.Info("Pod ", s.name, " will no longer be monitored") - clientCloser() + if err := clientCloser(); err != nil { + logrus.Warn("Unable to close the client", err) + } return } @@ -110,7 +112,9 @@ func (s *PodScraper) handleAndRestart(ctx context.Context, err error, wait time. case <-time.After(wait): break case <-ctx.Done(): - clientCloser() + if err := clientCloser(); err != nil { + logrus.Warn("Unable to close the client", err) + } return } diff --git a/pkg/util/maven/maven.go b/pkg/util/maven/maven.go index 019723b66d..594d63c6ef 100644 --- a/pkg/util/maven/maven.go +++ b/pkg/util/maven/maven.go @@ -31,10 +31,6 @@ import ( "github.com/sirupsen/logrus" ) -const ( - buildDirPrefix = "maven-" -) - // BuildResult -- type BuildResult struct { Classpath []v1alpha1.Artifact @@ -111,12 +107,13 @@ func ParseGAV(gav string) (Dependency, error) { dep.Type = "jar" cnt := strings.Count(gav, ":") - if cnt == 2 { + switch cnt { + case 2: dep.Version = res[4] - } else if cnt == 3 { + case 3: dep.Type = res[4] dep.Version = res[6] - } else { + default: dep.Type = res[4] dep.Classifier = res[6] dep.Version = res[8] diff --git a/pkg/util/maven/maven_test.go b/pkg/util/maven/maven_test.go index 59e43cb44a..b5d8243e85 100644 --- a/pkg/util/maven/maven_test.go +++ b/pkg/util/maven/maven_test.go @@ -25,7 +25,8 @@ import ( ) const expectedPom = ` - + 4.0.0 org.apache.camel.k.integration camel-k-integration diff --git a/pkg/util/minishift/minishift.go b/pkg/util/minishift/minishift.go index 9e5465c454..b9f6bbca89 100644 --- a/pkg/util/minishift/minishift.go +++ b/pkg/util/minishift/minishift.go @@ -19,10 +19,11 @@ limitations under the License. package minishift import ( + "strconv" + "github.com/operator-framework/operator-sdk/pkg/sdk" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "strconv" ) const ( diff --git a/pkg/util/sync/file_test.go b/pkg/util/sync/file_test.go index efd0bd8e57..1b665c8706 100644 --- a/pkg/util/sync/file_test.go +++ b/pkg/util/sync/file_test.go @@ -45,7 +45,9 @@ func TestFile(t *testing.T) { time.Sleep(100 * time.Millisecond) expectedNumChanges := 3 for i := 0; i < expectedNumChanges; i++ { - ioutil.WriteFile(fileName, []byte("data-"+strconv.Itoa(i)), 0777) + if err := ioutil.WriteFile(fileName, []byte("data-"+strconv.Itoa(i)), 0777); err != nil { + t.Error(err) + } time.Sleep(350 * time.Millisecond) } diff --git a/pkg/util/tar/appender.go b/pkg/util/tar/appender.go index f4fbecb18c..78df6694df 100644 --- a/pkg/util/tar/appender.go +++ b/pkg/util/tar/appender.go @@ -71,12 +71,14 @@ func (t *Appender) AddFile(filePath string, tarDir string) (string, error) { fileName = path.Join(tarDir, fileName) } - t.writer.WriteHeader(&atar.Header{ + if err := t.writer.WriteHeader(&atar.Header{ Name: fileName, Size: info.Size(), Mode: int64(info.Mode()), ModTime: info.ModTime(), - }) + }); err != nil { + return "", err + } file, err := os.Open(filePath) if err != nil { @@ -103,12 +105,14 @@ func (t *Appender) AddFileWithName(fileName string, filePath string, tarDir stri fileName = path.Join(tarDir, fileName) } - t.writer.WriteHeader(&atar.Header{ + if err := t.writer.WriteHeader(&atar.Header{ Name: fileName, Size: info.Size(), Mode: int64(info.Mode()), ModTime: info.ModTime(), - }) + }); err != nil { + return "", err + } file, err := os.Open(filePath) if err != nil { @@ -126,11 +130,13 @@ func (t *Appender) AddFileWithName(fileName string, filePath string, tarDir stri // AppendData appends the given content to a file inside the tar, creating it if it does not exist func (t *Appender) AppendData(data []byte, tarPath string) error { - t.writer.WriteHeader(&atar.Header{ + if err := t.writer.WriteHeader(&atar.Header{ Name: tarPath, Size: int64(len(data)), Mode: 0644, - }) + }); err != nil { + return err + } _, err := t.writer.Write(data) if err != nil { diff --git a/pkg/util/util.go b/pkg/util/util.go index fba0619d8a..805039c9bd 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -94,7 +94,7 @@ func WriteFileWithContent(buildDir string, relativePath string, content string) _, err = file.WriteString(content) if err != nil { - errors.Wrap(err, "could not write to file "+relativePath) + return errors.Wrap(err, "could not write to file "+relativePath) } return nil } diff --git a/version/version.go b/version/version.go index b46ddf098a..938471e7b8 100644 --- a/version/version.go +++ b/version/version.go @@ -19,6 +19,6 @@ limitations under the License. package version var ( - // Global Camel K Version + // Version is the global Camel K Version Version = "0.0.6-SNAPSHOT" )