func (o MasterOptions) CreateCerts() error { masterAddr, err := o.MasterArgs.GetMasterAddress() if err != nil { return err } publicMasterAddr, err := o.MasterArgs.GetMasterPublicAddress() if err != nil { return err } signerName := admin.DefaultSignerName() hostnames, err := o.MasterArgs.GetServerCertHostnames() if err != nil { return err } mintAllCertsOptions := admin.CreateMasterCertsOptions{ CertDir: o.MasterArgs.ConfigDir.Value(), SignerName: signerName, Hostnames: hostnames.List(), APIServerURL: masterAddr.String(), APIServerCAFiles: o.MasterArgs.APIServerCAFiles, CABundleFile: admin.DefaultCABundleFile(o.MasterArgs.ConfigDir.Value()), PublicAPIServerURL: publicMasterAddr.String(), Output: cmdutil.NewGLogWriterV(3), } if err := mintAllCertsOptions.Validate(nil); err != nil { return err } if err := mintAllCertsOptions.CreateMasterCerts(); err != nil { return err } return nil }
func (o NodeOptions) CreateNodeConfig() error { getSignerOptions := &admin.SignerCertOptions{ CertFile: admin.DefaultCertFilename(o.NodeArgs.MasterCertDir, admin.CAFilePrefix), KeyFile: admin.DefaultKeyFilename(o.NodeArgs.MasterCertDir, admin.CAFilePrefix), SerialFile: admin.DefaultSerialFilename(o.NodeArgs.MasterCertDir, admin.CAFilePrefix), } var dnsIP string if len(o.NodeArgs.ClusterDNS) > 0 { dnsIP = o.NodeArgs.ClusterDNS.String() } masterAddr, err := o.NodeArgs.KubeConnectionArgs.GetKubernetesAddress(o.NodeArgs.DefaultKubernetesURL) if err != nil { return err } hostnames, err := o.NodeArgs.GetServerCertHostnames() if err != nil { return err } nodeConfigDir := o.NodeArgs.ConfigDir.Value() createNodeConfigOptions := admin.CreateNodeConfigOptions{ SignerCertOptions: getSignerOptions, NodeConfigDir: nodeConfigDir, NodeName: o.NodeArgs.NodeName, Hostnames: hostnames.List(), VolumeDir: o.NodeArgs.VolumeDir, ImageTemplate: o.NodeArgs.ImageFormatArgs.ImageTemplate, AllowDisabledDocker: o.NodeArgs.AllowDisabledDocker, DNSDomain: o.NodeArgs.ClusterDomain, DNSIP: dnsIP, ListenAddr: o.NodeArgs.ListenArg.ListenAddr, NetworkPluginName: o.NodeArgs.NetworkPluginName, APIServerURL: masterAddr.String(), APIServerCAFiles: []string{admin.DefaultCABundleFile(o.NodeArgs.MasterCertDir)}, NodeClientCAFile: getSignerOptions.CertFile, ExpireDays: o.ExpireDays, Output: cmdutil.NewGLogWriterV(3), } if err := createNodeConfigOptions.Validate(nil); err != nil { return err } if err := createNodeConfigOptions.CreateNodeFolder(); err != nil { return err } return nil }
// BuildSerializeableMasterConfig takes the MasterArgs (partially complete config) and uses them along with defaulting behavior to create the fully specified // config object for starting the master func (args MasterArgs) BuildSerializeableMasterConfig() (*configapi.MasterConfig, error) { masterPublicAddr, err := args.GetMasterPublicAddress() if err != nil { return nil, err } assetPublicAddr, err := args.GetAssetPublicAddress() if err != nil { return nil, err } dnsBindAddr, err := args.GetDNSBindAddress() if err != nil { return nil, err } listenServingInfo := servingInfoForAddr(&args.ListenArg.ListenAddr) // always include the all-in-one server's web console as an allowed CORS origin // always include localhost as an allowed CORS origin // always include master public address as an allowed CORS origin corsAllowedOrigins := sets.NewString(args.CORSAllowedOrigins...) corsAllowedOrigins.Insert(assetPublicAddr.Host, masterPublicAddr.Host, "localhost", "127.0.0.1") etcdAddress, err := args.GetEtcdAddress() if err != nil { return nil, err } builtInEtcd := !args.EtcdAddr.Provided var etcdConfig *configapi.EtcdConfig if builtInEtcd { etcdConfig, err = args.BuildSerializeableEtcdConfig() if err != nil { return nil, err } } builtInKubernetes := len(args.KubeConnectionArgs.ClientConfigLoadingRules.ExplicitPath) == 0 var kubernetesMasterConfig *configapi.KubernetesMasterConfig if builtInKubernetes { kubernetesMasterConfig, err = args.BuildSerializeableKubeMasterConfig() if err != nil { return nil, err } } oauthConfig, err := args.BuildSerializeableOAuthConfig() if err != nil { return nil, err } kubeletClientInfo := admin.DefaultMasterKubeletClientCertInfo(args.ConfigDir.Value()) etcdClientInfo := admin.DefaultMasterEtcdClientCertInfo(args.ConfigDir.Value()) serviceServingCertSigner := admin.DefaultServiceSignerCAInfo(args.ConfigDir.Value()) dnsServingInfo := servingInfoForAddr(&dnsBindAddr) config := &configapi.MasterConfig{ ServingInfo: configapi.HTTPServingInfo{ ServingInfo: listenServingInfo, }, CORSAllowedOrigins: corsAllowedOrigins.List(), MasterPublicURL: masterPublicAddr.String(), KubernetesMasterConfig: kubernetesMasterConfig, EtcdConfig: etcdConfig, OAuthConfig: oauthConfig, PauseControllers: args.PauseControllers, AssetConfig: &configapi.AssetConfig{ ServingInfo: configapi.HTTPServingInfo{ ServingInfo: listenServingInfo, }, LogoutURL: "", MasterPublicURL: masterPublicAddr.String(), PublicURL: assetPublicAddr.String(), }, DNSConfig: &configapi.DNSConfig{ BindAddress: dnsServingInfo.BindAddress, BindNetwork: dnsServingInfo.BindNetwork, AllowRecursiveQueries: true, }, MasterClients: configapi.MasterClients{ OpenShiftLoopbackKubeConfig: admin.DefaultKubeConfigFilename(args.ConfigDir.Value(), bootstrappolicy.MasterUnqualifiedUsername), ExternalKubernetesKubeConfig: args.KubeConnectionArgs.ClientConfigLoadingRules.ExplicitPath, }, EtcdClientInfo: configapi.EtcdConnectionInfo{ URLs: []string{etcdAddress.String()}, }, KubeletClientInfo: configapi.KubeletConnectionInfo{ Port: ports.KubeletPort, }, PolicyConfig: configapi.PolicyConfig{ BootstrapPolicyFile: args.GetPolicyFile(), OpenShiftSharedResourcesNamespace: bootstrappolicy.DefaultOpenShiftSharedResourcesNamespace, }, ImageConfig: configapi.ImageConfig{ Format: args.ImageFormatArgs.ImageTemplate.Format, Latest: args.ImageFormatArgs.ImageTemplate.Latest, }, ProjectConfig: configapi.ProjectConfig{ DefaultNodeSelector: "", ProjectRequestMessage: "", ProjectRequestTemplate: "", // Allocator defaults on SecurityAllocator: &configapi.SecurityAllocator{}, }, NetworkConfig: configapi.MasterNetworkConfig{ NetworkPluginName: args.NetworkArgs.NetworkPluginName, ClusterNetworkCIDR: args.NetworkArgs.ClusterNetworkCIDR, HostSubnetLength: args.NetworkArgs.HostSubnetLength, ServiceNetworkCIDR: args.NetworkArgs.ServiceNetworkCIDR, }, VolumeConfig: configapi.MasterVolumeConfig{ DynamicProvisioningEnabled: true, }, ControllerConfig: configapi.ControllerConfig{ ServiceServingCert: configapi.ServiceServingCert{ Signer: &serviceServingCertSigner, }, }, } if args.ListenArg.UseTLS() { config.ServingInfo.ServerCert = admin.DefaultMasterServingCertInfo(args.ConfigDir.Value()) config.ServingInfo.ClientCA = admin.DefaultAPIClientCAFile(args.ConfigDir.Value()) config.AssetConfig.ServingInfo.ServerCert = admin.DefaultAssetServingCertInfo(args.ConfigDir.Value()) if oauthConfig != nil { s := admin.DefaultCABundleFile(args.ConfigDir.Value()) oauthConfig.MasterCA = &s } // Only set up ca/cert info for kubelet connections if we're self-hosting Kubernetes if builtInKubernetes { config.KubeletClientInfo.CA = admin.DefaultRootCAFile(args.ConfigDir.Value()) config.KubeletClientInfo.ClientCert = kubeletClientInfo.CertLocation config.ServiceAccountConfig.MasterCA = admin.DefaultCABundleFile(args.ConfigDir.Value()) } // Only set up ca/cert info for etcd connections if we're self-hosting etcd if builtInEtcd { config.EtcdClientInfo.CA = admin.DefaultRootCAFile(args.ConfigDir.Value()) config.EtcdClientInfo.ClientCert = etcdClientInfo.CertLocation } } if builtInKubernetes { // When we start Kubernetes, we're responsible for generating all the managed service accounts config.ServiceAccountConfig.ManagedNames = []string{ bootstrappolicy.DefaultServiceAccountName, bootstrappolicy.BuilderServiceAccountName, bootstrappolicy.DeployerServiceAccountName, } // We also need the private key file to give to the token generator config.ServiceAccountConfig.PrivateKeyFile = admin.DefaultServiceAccountPrivateKeyFile(args.ConfigDir.Value()) // We also need the public key file to give to the authenticator config.ServiceAccountConfig.PublicKeyFiles = []string{ admin.DefaultServiceAccountPublicKeyFile(args.ConfigDir.Value()), } } else { // When running against an external Kubernetes, we're only responsible for the builder and deployer accounts. // We don't have the private key, but we need to get the public key to authenticate signed tokens. // TODO: JTL: take arg for public key(s)? config.ServiceAccountConfig.ManagedNames = []string{ bootstrappolicy.BuilderServiceAccountName, bootstrappolicy.DeployerServiceAccountName, } config.ServiceAccountConfig.PublicKeyFiles = []string{} } // embed a default policy for generated config defaultImagePolicy, err := bootstrap.Asset("pkg/image/admission/imagepolicy/api/v1/default-policy.yaml") if err != nil { return nil, fmt.Errorf("unable to find default image admission policy: %v", err) } // TODO: this should not be necessary, runtime.Unknown#MarshalJSON should handle YAML content type correctly defaultImagePolicy, err = yaml.ToJSON(defaultImagePolicy) if err != nil { return nil, err } if config.AdmissionConfig.PluginConfig == nil { config.AdmissionConfig.PluginConfig = make(map[string]configapi.AdmissionPluginConfig) } config.AdmissionConfig.PluginConfig[imagepolicyapi.PluginName] = configapi.AdmissionPluginConfig{ Configuration: &runtime.Unknown{Raw: defaultImagePolicy}, } internal, err := applyDefaults(config, configapiv1.SchemeGroupVersion) if err != nil { return nil, err } config = internal.(*configapi.MasterConfig) // When creating a new config, use Protobuf configapi.SetProtobufClientDefaults(config.MasterClients.OpenShiftLoopbackClientConnectionOverrides) configapi.SetProtobufClientDefaults(config.MasterClients.ExternalKubernetesClientConnectionOverrides) return config, nil }
// BuildSerializeableMasterConfig takes the MasterArgs (partially complete config) and uses them along with defaulting behavior to create the fully specified // config object for starting the master func (args MasterArgs) BuildSerializeableMasterConfig() (*configapi.MasterConfig, error) { masterPublicAddr, err := args.GetMasterPublicAddress() if err != nil { return nil, err } assetPublicAddr, err := args.GetAssetPublicAddress() if err != nil { return nil, err } dnsBindAddr, err := args.GetDNSBindAddress() if err != nil { return nil, err } listenServingInfo := servingInfoForAddr(&args.ListenArg.ListenAddr) // always include the all-in-one server's web console as an allowed CORS origin // always include localhost as an allowed CORS origin // always include master public address as an allowed CORS origin corsAllowedOrigins := sets.NewString(args.CORSAllowedOrigins...) corsAllowedOrigins.Insert(assetPublicAddr.Host, masterPublicAddr.Host, "localhost", "127.0.0.1") etcdAddress, err := args.GetEtcdAddress() if err != nil { return nil, err } builtInEtcd := !args.EtcdAddr.Provided var etcdConfig *configapi.EtcdConfig if builtInEtcd { etcdConfig, err = args.BuildSerializeableEtcdConfig() if err != nil { return nil, err } } builtInKubernetes := len(args.KubeConnectionArgs.ClientConfigLoadingRules.ExplicitPath) == 0 var kubernetesMasterConfig *configapi.KubernetesMasterConfig if builtInKubernetes { kubernetesMasterConfig, err = args.BuildSerializeableKubeMasterConfig() if err != nil { return nil, err } } oauthConfig, err := args.BuildSerializeableOAuthConfig() if err != nil { return nil, err } kubeletClientInfo := admin.DefaultMasterKubeletClientCertInfo(args.ConfigDir.Value()) etcdClientInfo := admin.DefaultMasterEtcdClientCertInfo(args.ConfigDir.Value()) dnsServingInfo := servingInfoForAddr(&dnsBindAddr) config := &configapi.MasterConfig{ ServingInfo: configapi.HTTPServingInfo{ ServingInfo: listenServingInfo, }, CORSAllowedOrigins: corsAllowedOrigins.List(), MasterPublicURL: masterPublicAddr.String(), KubernetesMasterConfig: kubernetesMasterConfig, EtcdConfig: etcdConfig, OAuthConfig: oauthConfig, PauseControllers: args.PauseControllers, AssetConfig: &configapi.AssetConfig{ ServingInfo: configapi.HTTPServingInfo{ ServingInfo: listenServingInfo, }, LogoutURL: "", MasterPublicURL: masterPublicAddr.String(), PublicURL: assetPublicAddr.String(), }, DNSConfig: &configapi.DNSConfig{ BindAddress: dnsServingInfo.BindAddress, BindNetwork: dnsServingInfo.BindNetwork, }, MasterClients: configapi.MasterClients{ OpenShiftLoopbackKubeConfig: admin.DefaultKubeConfigFilename(args.ConfigDir.Value(), bootstrappolicy.MasterUnqualifiedUsername), ExternalKubernetesKubeConfig: args.KubeConnectionArgs.ClientConfigLoadingRules.ExplicitPath, }, EtcdClientInfo: configapi.EtcdConnectionInfo{ URLs: []string{etcdAddress.String()}, }, KubeletClientInfo: configapi.KubeletConnectionInfo{ Port: ports.KubeletPort, }, PolicyConfig: configapi.PolicyConfig{ BootstrapPolicyFile: args.GetPolicyFile(), OpenShiftSharedResourcesNamespace: bootstrappolicy.DefaultOpenShiftSharedResourcesNamespace, }, ImageConfig: configapi.ImageConfig{ Format: args.ImageFormatArgs.ImageTemplate.Format, Latest: args.ImageFormatArgs.ImageTemplate.Latest, }, ProjectConfig: configapi.ProjectConfig{ DefaultNodeSelector: "", ProjectRequestMessage: "", ProjectRequestTemplate: "", // Allocator defaults on SecurityAllocator: &configapi.SecurityAllocator{}, }, NetworkConfig: configapi.MasterNetworkConfig{ NetworkPluginName: args.NetworkArgs.NetworkPluginName, ClusterNetworkCIDR: args.NetworkArgs.ClusterNetworkCIDR, HostSubnetLength: args.NetworkArgs.HostSubnetLength, ServiceNetworkCIDR: args.NetworkArgs.ServiceNetworkCIDR, }, } if args.ListenArg.UseTLS() { config.ServingInfo.ServerCert = admin.DefaultMasterServingCertInfo(args.ConfigDir.Value()) config.ServingInfo.ClientCA = admin.DefaultAPIClientCAFile(args.ConfigDir.Value()) config.AssetConfig.ServingInfo.ServerCert = admin.DefaultAssetServingCertInfo(args.ConfigDir.Value()) if oauthConfig != nil { s := admin.DefaultCABundleFile(args.ConfigDir.Value()) oauthConfig.MasterCA = &s } // Only set up ca/cert info for kubelet connections if we're self-hosting Kubernetes if builtInKubernetes { config.KubeletClientInfo.CA = admin.DefaultRootCAFile(args.ConfigDir.Value()) config.KubeletClientInfo.ClientCert = kubeletClientInfo.CertLocation config.ServiceAccountConfig.MasterCA = admin.DefaultCABundleFile(args.ConfigDir.Value()) } // Only set up ca/cert info for etcd connections if we're self-hosting etcd if builtInEtcd { config.EtcdClientInfo.CA = admin.DefaultRootCAFile(args.ConfigDir.Value()) config.EtcdClientInfo.ClientCert = etcdClientInfo.CertLocation } } if builtInKubernetes { // When we start Kubernetes, we're responsible for generating all the managed service accounts config.ServiceAccountConfig.ManagedNames = []string{ bootstrappolicy.DefaultServiceAccountName, bootstrappolicy.BuilderServiceAccountName, bootstrappolicy.DeployerServiceAccountName, } // We also need the private key file to give to the token generator config.ServiceAccountConfig.PrivateKeyFile = admin.DefaultServiceAccountPrivateKeyFile(args.ConfigDir.Value()) // We also need the public key file to give to the authenticator config.ServiceAccountConfig.PublicKeyFiles = []string{ admin.DefaultServiceAccountPublicKeyFile(args.ConfigDir.Value()), } } else { // When running against an external Kubernetes, we're only responsible for the builder and deployer accounts. // We don't have the private key, but we need to get the public key to authenticate signed tokens. // TODO: JTL: take arg for public key(s)? config.ServiceAccountConfig.ManagedNames = []string{ bootstrappolicy.BuilderServiceAccountName, bootstrappolicy.DeployerServiceAccountName, } config.ServiceAccountConfig.PublicKeyFiles = []string{} } internal, err := applyDefaults(config, configapiv1.SchemeGroupVersion) if err != nil { return nil, err } return internal.(*configapi.MasterConfig), nil }