-
Notifications
You must be signed in to change notification settings - Fork 4.7k
/
cmd.go
166 lines (140 loc) · 5.54 KB
/
cmd.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
package openshift_apiserver
import (
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"path"
"github.com/spf13/cobra"
"k8s.io/klog"
kerrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd/api"
"k8s.io/kubernetes/pkg/api/legacyscheme"
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/util/templates"
configv1 "github.com/openshift/api/config/v1"
legacyconfigv1 "github.com/openshift/api/legacyconfig/v1"
openshiftcontrolplanev1 "github.com/openshift/api/openshiftcontrolplane/v1"
"github.com/openshift/library-go/pkg/config/helpers"
"github.com/openshift/library-go/pkg/serviceability"
"github.com/openshift/origin/pkg/api/legacy"
"github.com/openshift/origin/pkg/cmd/openshift-kube-apiserver/configdefault"
configapi "github.com/openshift/origin/pkg/cmd/server/apis/config"
configapilatest "github.com/openshift/origin/pkg/cmd/server/apis/config/latest"
"github.com/openshift/origin/pkg/cmd/server/apis/config/validation"
"github.com/openshift/origin/pkg/configconversion"
)
const RecommendedStartAPIServerName = "openshift-apiserver"
type OpenShiftAPIServer struct {
ConfigFile string
Output io.Writer
}
var longDescription = templates.LongDesc(`
Start an apiserver that contains the OpenShift resources`)
func NewOpenShiftAPIServerCommand(name, basename string, out, errout io.Writer, stopCh <-chan struct{}) *cobra.Command {
options := &OpenShiftAPIServer{Output: out}
cmd := &cobra.Command{
Use: name,
Short: "Launch OpenShift apiserver",
Long: longDescription,
Run: func(c *cobra.Command, args []string) {
rest.CommandNameOverride = name
legacy.InstallInternalLegacyAll(legacyscheme.Scheme)
kcmdutil.CheckErr(options.Validate())
serviceability.StartProfiler()
if err := options.WithoutNetworkingAPI().RunAPIServer(stopCh); err != nil {
if kerrors.IsInvalid(err) {
if details := err.(*kerrors.StatusError).ErrStatus.Details; details != nil {
fmt.Fprintf(errout, "Invalid %s %s\n", details.Kind, details.Name)
for _, cause := range details.Causes {
fmt.Fprintf(errout, " %s: %s\n", cause.Field, cause.Message)
}
os.Exit(255)
}
}
klog.Fatal(err)
}
},
}
flags := cmd.Flags()
// This command only supports reading from config
flags.StringVar(&options.ConfigFile, "config", "", "Location of the master configuration file to run from.")
cmd.MarkFlagFilename("config", "yaml", "yml")
cmd.MarkFlagRequired("config")
return cmd
}
func (o *OpenShiftAPIServer) Validate() error {
if len(o.ConfigFile) == 0 {
return errors.New("--config is required for this command")
}
return nil
}
func (o *OpenShiftAPIServer) WithoutNetworkingAPI() *OpenShiftAPIServer {
featureKeepRemovedNetworkingAPI = false
return o
}
// RunAPIServer takes the options, starts the API server and waits until stopCh is closed or initial listening fails.
func (o *OpenShiftAPIServer) RunAPIServer(stopCh <-chan struct{}) error {
// try to decode into our new types first. right now there is no validation, no file path resolution. this unsticks the operator to start.
// TODO add those things
configContent, err := ioutil.ReadFile(o.ConfigFile)
if err != nil {
return err
}
scheme := runtime.NewScheme()
utilruntime.Must(openshiftcontrolplanev1.Install(scheme))
codecs := serializer.NewCodecFactory(scheme)
obj, err := runtime.Decode(codecs.UniversalDecoder(openshiftcontrolplanev1.GroupVersion, configv1.GroupVersion), configContent)
switch {
case runtime.IsMissingVersion(err): // fall through to legacy master config
case runtime.IsMissingKind(err): // fall through to legacy master config
case runtime.IsNotRegisteredError(err): // fall through to legacy master config
case err != nil:
return err
case err == nil:
// Resolve relative to CWD
absoluteConfigFile, err := api.MakeAbs(o.ConfigFile, "")
if err != nil {
return err
}
configFileLocation := path.Dir(absoluteConfigFile)
config := obj.(*openshiftcontrolplanev1.OpenShiftAPIServerConfig)
if err := helpers.ResolvePaths(configconversion.GetOpenShiftAPIServerConfigFileReferences(config), configFileLocation); err != nil {
return err
}
configdefault.SetRecommendedOpenShiftAPIServerConfigDefaults(config)
return RunOpenShiftAPIServer(config, stopCh)
}
// TODO this code disappears once the kube-core operator switches to external types
// TODO we will simply run some defaulting code and convert
// reading internal gives us defaulting that we need for now
masterConfig, err := configapilatest.ReadAndResolveMasterConfig(o.ConfigFile)
if err != nil {
return err
}
validationResults := validation.ValidateMasterConfig(masterConfig, nil)
if len(validationResults.Warnings) != 0 {
for _, warning := range validationResults.Warnings {
klog.Warningf("%v", warning)
}
}
if len(validationResults.Errors) != 0 {
return kerrors.NewInvalid(configapi.Kind("MasterConfig"), "master-config.yaml", validationResults.Errors)
}
// round trip to external
externalMasterConfig, err := configapi.Scheme.ConvertToVersion(masterConfig, legacyconfigv1.LegacySchemeGroupVersion)
if err != nil {
return err
}
openshiftAPIServerConfig, err := configconversion.ConvertMasterConfigToOpenShiftAPIServerConfig(externalMasterConfig.(*legacyconfigv1.MasterConfig))
if err != nil {
return err
}
configdefault.SetRecommendedOpenShiftAPIServerConfigDefaults(openshiftAPIServerConfig)
return RunOpenShiftAPIServer(openshiftAPIServerConfig, stopCh)
}