1
0
mirror of https://github.com/openshift/installer.git synced 2026-02-05 06:46:36 +01:00
Files
installer/pkg/asset/manifests/proxy.go
Bear 5166c3e4e4 Fix issue CORS-4275 Add Windows support
This PR improves cross-platform compatibility.
It solves two main issues:
1. inconsistent line endings
2. inconsistent path separators

Path separators, in installer, needs to target two different
environments:
1. the OS where the installer runs
2. the OS where the injected files been used

This PR unified path separators used in 2 to be UNIX path separators,
while in 1 to be platform-dependant.

Ref: https://forum.golangbridge.org/t/filepath-join-or-path-join/13479

Known issues:
The spawn processes, including etcd.exe, kube-apiserver.exe,
and openshift-installer.exe, will not exit once installation
aborted or completed. Users need to manually terminate those
processes in task manager.
2025-10-29 14:53:54 -02:30

203 lines
6.1 KiB
Go

package manifests
import (
"context"
"fmt"
"net/url"
"path"
"strings"
"github.com/pkg/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
"sigs.k8s.io/yaml"
configv1 "github.com/openshift/api/config/v1"
"github.com/openshift/installer/pkg/asset"
"github.com/openshift/installer/pkg/asset/installconfig"
"github.com/openshift/installer/pkg/types"
"github.com/openshift/installer/pkg/types/aws"
"github.com/openshift/installer/pkg/types/azure"
"github.com/openshift/installer/pkg/types/gcp"
"github.com/openshift/installer/pkg/types/openstack"
)
var proxyCfgFilename = path.Join(manifestDir, "cluster-proxy-01-config.yaml")
// Proxy generates the cluster-proxy-*.yml files.
type Proxy struct {
FileList []*asset.File
Config *configv1.Proxy
}
var _ asset.WritableAsset = (*Proxy)(nil)
// Name returns a human-friendly name for the asset.
func (*Proxy) Name() string {
return "Proxy Config"
}
// Dependencies returns all of the dependencies directly needed to generate
// the asset.
func (*Proxy) Dependencies() []asset.Asset {
return []asset.Asset{
&installconfig.InstallConfig{},
&Networking{},
}
}
// Generate generates the Proxy config and its CRD.
func (p *Proxy) Generate(_ context.Context, dependencies asset.Parents) error {
installConfig := &installconfig.InstallConfig{}
network := &Networking{}
dependencies.Get(installConfig, network)
p.Config = &configv1.Proxy{
TypeMeta: metav1.TypeMeta{
APIVersion: configv1.SchemeGroupVersion.String(),
Kind: "Proxy",
},
ObjectMeta: metav1.ObjectMeta{
Name: "cluster",
// not namespaced
},
}
if installConfig.Config.Proxy != nil {
p.Config.Spec = configv1.ProxySpec{
HTTPProxy: installConfig.Config.Proxy.HTTPProxy,
HTTPSProxy: installConfig.Config.Proxy.HTTPSProxy,
NoProxy: installConfig.Config.Proxy.NoProxy,
}
}
if installConfig.Config.AdditionalTrustBundlePolicy == types.PolicyAlways ||
installConfig.Config.Proxy != nil {
if installConfig.Config.AdditionalTrustBundle != "" {
p.Config.Spec.TrustedCA = configv1.ConfigMapNameReference{
Name: additionalTrustBundleConfigMapName,
}
}
}
if p.Config.Spec.HTTPProxy != "" || p.Config.Spec.HTTPSProxy != "" {
noProxy, err := createNoProxy(installConfig, network)
if err != nil {
return err
}
if installConfig.Config.Proxy.NoProxy == "*" {
noProxy = installConfig.Config.Proxy.NoProxy
}
p.Config.Status = configv1.ProxyStatus{
HTTPProxy: installConfig.Config.Proxy.HTTPProxy,
HTTPSProxy: installConfig.Config.Proxy.HTTPSProxy,
NoProxy: noProxy,
}
}
configData, err := yaml.Marshal(p.Config)
if err != nil {
return errors.Wrapf(err, "failed to create %s manifests from InstallConfig", p.Name())
}
p.FileList = []*asset.File{
{
Filename: proxyCfgFilename,
Data: configData,
},
}
return nil
}
// createNoProxy combines user-provided & platform-specific values to create a comma-separated
// list of unique NO_PROXY values. Platform values are: serviceCIDR, podCIDR, machineCIDR,
// localhost, 127.0.0.1, api.clusterdomain, api-int.clusterdomain.
// If platform is AWS, GCP, Azure, or OpenStack add 169.254.169.254 to the list of NO_PROXY addresses.
// If platform is AWS, add ".ec2.internal" for region us-east-1 or for all other regions add
// ".<aws_region>.compute.internal" to the list of NO_PROXY addresses. We should not proxy
// the instance metadata services:
// https://docs.openstack.org/nova/latest/user/metadata.html
// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html
// https://docs.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service
// https://cloud.google.com/compute/docs/storing-retrieving-metadata
func createNoProxy(installConfig *installconfig.InstallConfig, network *Networking) (string, error) {
internalAPIServer, err := url.Parse(getInternalAPIServerURL(installConfig.Config))
if err != nil {
return "", errors.New("failed parsing internal API server when creating Proxy manifest")
}
set := sets.NewString(
"127.0.0.1",
"localhost",
".svc",
".cluster.local",
internalAPIServer.Hostname(),
)
platform := installConfig.Config.Platform.Name()
// FIXME: The cluster-network-operator duplicates this code in pkg/util/proxyconfig/no_proxy.go,
// if altering this list of platforms, you must ALSO alter the code in cluster-network-operator.
switch platform {
case aws.Name, gcp.Name, azure.Name, openstack.Name:
set.Insert("169.254.169.254")
}
// TODO: Add support for additional cloud providers.
if platform == aws.Name {
region := installConfig.Config.AWS.Region
if region == "us-east-1" {
set.Insert(".ec2.internal")
} else {
set.Insert(fmt.Sprintf(".%s.compute.internal", region))
}
}
// TODO: IBM[#95]: proxy
if platform == azure.Name && installConfig.Azure.CloudName != azure.PublicCloud {
// https://learn.microsoft.com/en-us/azure/virtual-network/what-is-ip-address-168-63-129-16
set.Insert("168.63.129.16")
if installConfig.Azure.CloudName == azure.StackCloud {
set.Insert(installConfig.Config.Azure.ARMEndpoint)
}
}
// From https://cloud.google.com/vpc/docs/special-configurations add GCP metadata.
// "metadata.google.internal." added due to https://bugzilla.redhat.com/show_bug.cgi?id=1754049
if platform == gcp.Name {
set.Insert("metadata", "metadata.google.internal", "metadata.google.internal.")
}
for _, network := range installConfig.Config.Networking.ServiceNetwork {
set.Insert(network.String())
}
for _, network := range installConfig.Config.Networking.MachineNetwork {
set.Insert(network.CIDR.String())
}
for _, clusterNetwork := range network.Config.Spec.ClusterNetwork {
set.Insert(clusterNetwork.CIDR)
}
for _, userValue := range strings.Split(installConfig.Config.Proxy.NoProxy, ",") {
if userValue != "" {
set.Insert(userValue)
}
}
return strings.Join(set.List(), ","), nil
}
// Files returns the files generated by the asset.
func (p *Proxy) Files() []*asset.File {
return p.FileList
}
// Load loads the already-rendered files back from disk.
func (p *Proxy) Load(f asset.FileFetcher) (bool, error) {
return false, nil
}