sigs.k8s.io/kubebuilder/v3@v3.14.0/pkg/plugins/common/kustomize/v2/init.go (about)

     1  /*
     2  Copyright 2022 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package v2
    18  
    19  import (
    20  	"fmt"
    21  	"os"
    22  	"path/filepath"
    23  	"strings"
    24  
    25  	"github.com/spf13/pflag"
    26  
    27  	"sigs.k8s.io/kubebuilder/v3/pkg/config"
    28  	"sigs.k8s.io/kubebuilder/v3/pkg/internal/validation"
    29  	"sigs.k8s.io/kubebuilder/v3/pkg/machinery"
    30  	"sigs.k8s.io/kubebuilder/v3/pkg/plugin"
    31  	"sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2/scaffolds"
    32  )
    33  
    34  var _ plugin.InitSubcommand = &initSubcommand{}
    35  
    36  type initSubcommand struct {
    37  	config config.Config
    38  
    39  	// config options
    40  	domain          string
    41  	name            string
    42  	componentConfig bool
    43  }
    44  
    45  func (p *initSubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta *plugin.SubcommandMetadata) {
    46  	subcmdMeta.Description = `Initialize a common project including the following files:
    47    - a "PROJECT" file that stores project configuration
    48    - several YAML files for project deployment under the "config" directory
    49  
    50  NOTE: This plugin requires kustomize version v5 and kubectl >= 1.22.
    51  `
    52  	subcmdMeta.Examples = fmt.Sprintf(`  # Initialize a common project with your domain and name in copyright
    53    %[1]s init --plugins common/v3 --domain example.org
    54  
    55    # Initialize a common project defining a specific project version
    56    %[1]s init --plugins common/v3 --project-version 3
    57  `, cliMeta.CommandName)
    58  }
    59  
    60  func (p *initSubcommand) BindFlags(fs *pflag.FlagSet) {
    61  	fs.StringVar(&p.domain, "domain", "my.domain", "domain for groups")
    62  	fs.StringVar(&p.name, "project-name", "", "name of this project")
    63  	fs.BoolVar(&p.componentConfig, "component-config", false,
    64  		"create a versioned ComponentConfig file, may be 'true' or 'false'")
    65  	_ = fs.MarkDeprecated("component-config", "the ComponentConfig has been deprecated in the "+
    66  		"Controller-Runtime since its version 0.15.0. Moreover, it has undergone breaking changes and is no longer "+
    67  		"functioning as intended. As a result, this tool, which heavily relies on the Controller Runtime, "+
    68  		"has also deprecated this feature, no longer guaranteeing its functionality from version 3.11.0 onwards. "+
    69  		"You can find additional details on https://github.com/kubernetes-sigs/controller-runtime/issues/895.")
    70  }
    71  
    72  func (p *initSubcommand) InjectConfig(c config.Config) error {
    73  	p.config = c
    74  
    75  	if err := p.config.SetDomain(p.domain); err != nil {
    76  		return err
    77  	}
    78  
    79  	// Assign a default project name
    80  	if p.name == "" {
    81  		dir, err := os.Getwd()
    82  		if err != nil {
    83  			return fmt.Errorf("error getting current directory: %v", err)
    84  		}
    85  		p.name = strings.ToLower(filepath.Base(dir))
    86  	}
    87  	// Check if the project name is a valid k8s namespace (DNS 1123 label).
    88  	if err := validation.IsDNS1123Label(p.name); err != nil {
    89  		return fmt.Errorf("project name (%s) is invalid: %v", p.name, err)
    90  	}
    91  	if err := p.config.SetProjectName(p.name); err != nil {
    92  		return err
    93  	}
    94  
    95  	if p.componentConfig {
    96  		if err := p.config.SetComponentConfig(); err != nil {
    97  			return err
    98  		}
    99  	}
   100  
   101  	return nil
   102  }
   103  
   104  func (p *initSubcommand) Scaffold(fs machinery.Filesystem) error {
   105  	scaffolder := scaffolds.NewInitScaffolder(p.config)
   106  	scaffolder.InjectFS(fs)
   107  	return scaffolder.Scaffold()
   108  }