Skip to content

Commit 161208a

Browse files
authored
Merge pull request #174 from mengqiy/disable_installer
Support disable installer
2 parents 605dc32 + 96e4f8e commit 161208a

18 files changed

+396
-162
lines changed

example/main.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,24 @@ import (
3939
var log = logf.Log.WithName("example-controller")
4040

4141
func main() {
42+
var installWebhookConfig bool
43+
flag.BoolVar(&installWebhookConfig, "install-webhook-config", false,
44+
"enable the installer in the webhook server, so it will install webhook related resources during bootstrapping")
45+
4246
flag.Parse()
4347
logf.SetLogger(logf.ZapLogger(false))
4448
entryLog := log.WithName("entrypoint")
4549

4650
// Setup a Manager
51+
entryLog.Info("setting up manager")
4752
mgr, err := manager.New(config.GetConfigOrDie(), manager.Options{})
4853
if err != nil {
4954
entryLog.Error(err, "unable to set up overall controller manager")
5055
os.Exit(1)
5156
}
5257

5358
// Setup a new controller to Reconciler ReplicaSets
59+
entryLog.Info("Setting up controller")
5460
c, err := controller.New("foo-controller", mgr, controller.Options{
5561
Reconciler: &reconcileReplicaSet{client: mgr.GetClient(), log: log.WithName("reconciler")},
5662
})
@@ -73,6 +79,7 @@ func main() {
7379
}
7480

7581
// Setup webhooks
82+
entryLog.Info("setting up webhooks")
7683
mutatingWebhook, err := builder.NewWebhookBuilder().
7784
Name("mutating.k8s.io").
7885
Mutating().
@@ -99,9 +106,11 @@ func main() {
99106
os.Exit(1)
100107
}
101108

109+
entryLog.Info("setting up webhook server")
102110
as, err := webhook.NewServer("foo-admission-server", mgr, webhook.ServerOptions{
103-
Port: 9876,
104-
CertDir: "/tmp/cert",
111+
Port: 9876,
112+
CertDir: "/tmp/cert",
113+
InstallWebhookConfig: installWebhookConfig,
105114
BootstrapOptions: &webhook.BootstrapOptions{
106115
Secret: &apitypes.NamespacedName{
107116
Namespace: "default",
@@ -122,12 +131,15 @@ func main() {
122131
entryLog.Error(err, "unable to create a new webhook server")
123132
os.Exit(1)
124133
}
134+
135+
entryLog.Info("registering webhooks to the webhook server")
125136
err = as.Register(mutatingWebhook, validatingWebhook)
126137
if err != nil {
127138
entryLog.Error(err, "unable to register webhooks in the admission server")
128139
os.Exit(1)
129140
}
130141

142+
entryLog.Info("starting manager")
131143
if err := mgr.Start(signals.SetupSignalHandler()); err != nil {
132144
entryLog.Error(err, "unable to run manager")
133145
os.Exit(1)

pkg/webhook/bootstrap.go

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,9 @@ import (
2222
"net"
2323
"net/http"
2424
"net/url"
25-
"os"
2625
"path"
2726
"strconv"
2827

29-
"github.com/ghodss/yaml"
30-
3128
"k8s.io/api/admissionregistration/v1beta1"
3229
admissionregistration "k8s.io/api/admissionregistration/v1beta1"
3330
corev1 "k8s.io/api/core/v1"
@@ -117,15 +114,11 @@ func (s *Server) setBootstrappingDefault() {
117114
s.certProvisioner = &cert.Provisioner{
118115
CertWriter: certWriter,
119116
}
120-
if s.Writer == nil {
121-
s.Writer = os.Stdout
122-
}
123117
}
124118

125-
// installWebhookConfig writes the configuration of admissionWebhookConfiguration in yaml format if dryrun is true.
126-
// Otherwise, it creates the the admissionWebhookConfiguration objects and service if any.
119+
// InstallWebhookManifests creates the admissionWebhookConfiguration objects and service if any.
127120
// It also provisions the certificate for the admission server.
128-
func (s *Server) installWebhookConfig() error {
121+
func (s *Server) InstallWebhookManifests() error {
129122
// do defaulting if necessary
130123
s.once.Do(s.setDefault)
131124
if s.err != nil {
@@ -148,40 +141,14 @@ func (s *Server) installWebhookConfig() error {
148141
_, err = s.certProvisioner.Provision(cert.Options{
149142
ClientConfig: cc,
150143
Objects: s.webhookConfigurations,
151-
Dryrun: s.Dryrun,
152144
})
153145
if err != nil {
154146
return err
155147
}
156148

157-
if s.Dryrun {
158-
// TODO: print here
159-
// if dryrun, return the AdmissionWebhookConfiguration in yaml format.
160-
return s.genYamlConfig(objects)
161-
}
162-
163149
return batchCreateOrReplace(s.Client, objects...)
164150
}
165151

166-
// genYamlConfig generates yaml config for admissionWebhookConfiguration
167-
func (s *Server) genYamlConfig(objs []runtime.Object) error {
168-
for _, obj := range objs {
169-
_, err := s.Writer.Write([]byte("---"))
170-
if err != nil {
171-
return err
172-
}
173-
b, err := yaml.Marshal(obj)
174-
if err != nil {
175-
return err
176-
}
177-
_, err = s.Writer.Write(b)
178-
if err != nil {
179-
return err
180-
}
181-
}
182-
return nil
183-
}
184-
185152
func (s *Server) getClientConfig() (*admissionregistration.WebhookClientConfig, error) {
186153
if s.Host != nil && s.Service != nil {
187154
return nil, errors.New("URL and Service can't be set at the same time")

pkg/webhook/internal/cert/generator/certgenerator.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ type Artifacts struct {
2323
Key []byte
2424
// PEM encoded serving certificate
2525
Cert []byte
26+
// PEM encoded CA private key
27+
CAKey []byte
2628
// PEM encoded CA certificate
2729
CACert []byte
2830
}
@@ -31,4 +33,6 @@ type Artifacts struct {
3133
type CertGenerator interface {
3234
// Generate returns a Artifacts struct.
3335
Generate(CommonName string) (*Artifacts, error)
36+
// SetCA sets the PEM-encoded CA private key and CA cert for signing the generated serving cert.
37+
SetCA(caKey, caCert []byte)
3438
}

pkg/webhook/internal/cert/generator/fake/certgenerator.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,37 @@ limitations under the License.
1717
package fake
1818

1919
import (
20+
"bytes"
2021
"fmt"
2122

2223
"sigs.k8s.io/controller-runtime/pkg/webhook/internal/cert/generator"
2324
)
2425

2526
// CertGenerator is a certGenerator for testing.
2627
type CertGenerator struct {
28+
CAKey []byte
29+
CACert []byte
2730
DNSNameToCertArtifacts map[string]*generator.Artifacts
2831
}
2932

3033
var _ generator.CertGenerator = &CertGenerator{}
3134

35+
// SetCA sets the PEM-encoded CA private key and CA cert for signing the generated serving cert.
36+
func (cp *CertGenerator) SetCA(CAKey, CACert []byte) {
37+
cp.CAKey = CAKey
38+
cp.CACert = CACert
39+
}
40+
3241
// Generate generates certificates by matching a common name.
3342
func (cp *CertGenerator) Generate(commonName string) (*generator.Artifacts, error) {
3443
certs, found := cp.DNSNameToCertArtifacts[commonName]
3544
if !found {
3645
return nil, fmt.Errorf("failed to find common name %q in the certGenerator", commonName)
3746
}
47+
if cp.CAKey != nil && cp.CACert != nil &&
48+
!bytes.Contains(cp.CAKey, []byte("invalid")) && !bytes.Contains(cp.CACert, []byte("invalid")) {
49+
certs.CAKey = cp.CAKey
50+
certs.CACert = cp.CACert
51+
}
3852
return certs, nil
3953
}

pkg/webhook/internal/cert/generator/selfsigned.go

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ limitations under the License.
1717
package generator
1818

1919
import (
20+
"crypto/rsa"
2021
"crypto/x509"
2122
"fmt"
23+
"time"
2224

2325
"k8s.io/client-go/util/cert"
2426
)
@@ -30,24 +32,42 @@ func ServiceToCommonName(serviceNamespace, serviceName string) string {
3032

3133
// SelfSignedCertGenerator implements the certGenerator interface.
3234
// It provisions self-signed certificates.
33-
type SelfSignedCertGenerator struct{}
35+
type SelfSignedCertGenerator struct {
36+
caKey []byte
37+
caCert []byte
38+
}
3439

3540
var _ CertGenerator = &SelfSignedCertGenerator{}
3641

42+
// SetCA sets the PEM-encoded CA private key and CA cert for signing the generated serving cert.
43+
func (cp *SelfSignedCertGenerator) SetCA(caKey, caCert []byte) {
44+
cp.caKey = caKey
45+
cp.caCert = caCert
46+
}
47+
3748
// Generate creates and returns a CA certificate, certificate and
3849
// key for the server. serverKey and serverCert are used by the server
3950
// to establish trust for clients, CA certificate is used by the
4051
// client to verify the server authentication chain.
4152
// The cert will be valid for 365 days.
4253
func (cp *SelfSignedCertGenerator) Generate(commonName string) (*Artifacts, error) {
43-
signingKey, err := cert.NewPrivateKey()
44-
if err != nil {
45-
return nil, fmt.Errorf("failed to create the CA private key: %v", err)
46-
}
47-
signingCert, err := cert.NewSelfSignedCACert(cert.Config{CommonName: "webhook-cert-ca"}, signingKey)
48-
if err != nil {
49-
return nil, fmt.Errorf("failed to create the CA cert: %v", err)
54+
var signingKey *rsa.PrivateKey
55+
var signingCert *x509.Certificate
56+
var valid bool
57+
var err error
58+
59+
valid, signingKey, signingCert = cp.validCACert()
60+
if !valid {
61+
signingKey, err = cert.NewPrivateKey()
62+
if err != nil {
63+
return nil, fmt.Errorf("failed to create the CA private key: %v", err)
64+
}
65+
signingCert, err = cert.NewSelfSignedCACert(cert.Config{CommonName: "webhook-cert-ca"}, signingKey)
66+
if err != nil {
67+
return nil, fmt.Errorf("failed to create the CA cert: %v", err)
68+
}
5069
}
70+
5171
key, err := cert.NewPrivateKey()
5272
if err != nil {
5373
return nil, fmt.Errorf("failed to create the private key: %v", err)
@@ -65,6 +85,33 @@ func (cp *SelfSignedCertGenerator) Generate(commonName string) (*Artifacts, erro
6585
return &Artifacts{
6686
Key: cert.EncodePrivateKeyPEM(key),
6787
Cert: cert.EncodeCertPEM(signedCert),
88+
CAKey: cert.EncodePrivateKeyPEM(signingKey),
6889
CACert: cert.EncodeCertPEM(signingCert),
6990
}, nil
7091
}
92+
93+
func (cp *SelfSignedCertGenerator) validCACert() (bool, *rsa.PrivateKey, *x509.Certificate) {
94+
if !ValidCACert(cp.caKey, cp.caCert, cp.caCert, "",
95+
time.Now().AddDate(1, 0, 0)) {
96+
return false, nil, nil
97+
}
98+
99+
var ok bool
100+
key, err := cert.ParsePrivateKeyPEM(cp.caKey)
101+
if err != nil {
102+
return false, nil, nil
103+
}
104+
privateKey, ok := key.(*rsa.PrivateKey)
105+
if !ok {
106+
return false, nil, nil
107+
}
108+
109+
certs, err := cert.ParseCertsPEM(cp.caCert)
110+
if err != nil {
111+
return false, nil, nil
112+
}
113+
if len(certs) != 1 {
114+
return false, nil, nil
115+
}
116+
return true, privateKey, certs[0]
117+
}

0 commit comments

Comments
 (0)