Skip to content

Commit

Permalink
feat: populate plugin Programmed condition (#4412)
Browse files Browse the repository at this point in the history
Populate the Programmed condition for KongPlugin and KongClusterPlugin
resources.
  • Loading branch information
czeslavo authored Jul 26, 2023
1 parent 74e7f71 commit d0fe1e4
Show file tree
Hide file tree
Showing 11 changed files with 298 additions and 96 deletions.
10 changes: 6 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,11 @@ Adding a new version? You'll need three changes:
updates. The controller will now send configuration to such Gateways and will
actively monitor their readiness for accepting configuration updates.
[#4368](https://github.com/Kong/kubernetes-ingress-controller/pull/4368
- `KongConsumer` CRD was extended with `Status.Conditions` field. It will now
contain the `Programmed` condition describing whether an object was successfully
translated into Kong entities and sent to Kong.
[#4409](https://github.com/Kong/kubernetes-ingress-controller/pull/4409
- `KongConsumer`, `KongPlugin`, and `KongClusterPlugin` CRDs were extended with
`Status.Conditions` field. It will contain the `Programmed` condition describing
whether an object was successfully translated into Kong entities and sent to Kong.
[#4409](https://github.com/Kong/kubernetes-ingress-controller/pull/4409)
[#4412](https://github.com/Kong/kubernetes-ingress-controller/pull/4412)

### Changed

Expand Down Expand Up @@ -184,6 +185,7 @@ Adding a new version? You'll need three changes:
This was caused by a bug in `NodeAgent` that was sending the updates
despite the fact that the configuration status was not changed.
[#4324](https://github.com/Kong/kubernetes-ingress-controller/pull/4324)

## [2.10.2]

> Release date: 2023-07-07
Expand Down
4 changes: 4 additions & 0 deletions hack/generators/controllers/networking/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ var inputControllersNeeded = &typesNeeded{
Plural: "kongplugins",
CacheType: "Plugin",
NeedsStatusPermissions: true,
ConfigStatusNotificationsEnabled: true,
ProgrammedConditionUpdatesEnabled: true,
AcceptsIngressClassNameAnnotation: false,
AcceptsIngressClassNameSpec: false,
NeedsUpdateReferences: true,
Expand All @@ -129,6 +131,8 @@ var inputControllersNeeded = &typesNeeded{
Plural: "kongclusterplugins",
CacheType: "ClusterPlugin",
NeedsStatusPermissions: true,
ConfigStatusNotificationsEnabled: true,
ProgrammedConditionUpdatesEnabled: true,
AcceptsIngressClassNameAnnotation: true,
AcceptsIngressClassNameSpec: false,
NeedsUpdateReferences: true,
Expand Down
50 changes: 50 additions & 0 deletions internal/controllers/configuration/zz_generated_controllers.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 3 additions & 5 deletions internal/dataplane/kongstate/kongstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ func buildPlugins(log logrus.FieldLogger, s store.Storer, pluginRels map[string]
}

for _, rel := range relations.GetCombinations() {
plugin := *plugin.DeepCopy()
plugin := plugin.DeepCopy()
// ID is populated because that is read by decK and in_memory
// translator too
if rel.Service != "" {
Expand All @@ -292,7 +292,7 @@ func buildPlugins(log logrus.FieldLogger, s store.Storer, pluginRels map[string]
if rel.Consumer != "" {
plugin.Consumer = &kong.Consumer{ID: kong.String(rel.Consumer)}
}
plugins = append(plugins, Plugin{plugin})
plugins = append(plugins, plugin)
}
}

Expand Down Expand Up @@ -347,9 +347,7 @@ func globalPlugins(log logrus.FieldLogger, s store.Storer) ([]Plugin, error) {
continue
}
if plugin, err := kongPluginFromK8SClusterPlugin(s, k8sPlugin); err == nil {
res[pluginName] = Plugin{
Plugin: plugin,
}
res[pluginName] = plugin
} else {
log.WithFields(logrus.Fields{
"kongclusterplugin_name": k8sPlugin.Name,
Expand Down
9 changes: 9 additions & 0 deletions internal/dataplane/kongstate/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"

"github.com/kong/go-kong/kong"
"sigs.k8s.io/controller-runtime/pkg/client"
)

type PortMode int
Expand Down Expand Up @@ -78,4 +79,12 @@ func (c *Certificate) SanitizedCopy() *Certificate {
// Plugin represents a plugin Object in Kong.
type Plugin struct {
kong.Plugin
K8sParent client.Object
}

func (p Plugin) DeepCopy() Plugin {
return Plugin{
Plugin: *p.Plugin.DeepCopy(),
K8sParent: p.K8sParent,
}
}
77 changes: 41 additions & 36 deletions internal/dataplane/kongstate/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ func getKongIngressFromObjAnnotations(
}

// getPlugin constructs a plugins from a KongPlugin resource.
func getPlugin(s store.Storer, namespace, name string) (kong.Plugin, error) {
var plugin kong.Plugin
func getPlugin(s store.Storer, namespace, name string) (Plugin, error) {
var plugin Plugin
k8sPlugin, err := s.GetKongPlugin(namespace, name)
if err != nil {
// if no namespaced plugin definition, then
Expand Down Expand Up @@ -114,15 +114,15 @@ func getPlugin(s store.Storer, namespace, name string) (kong.Plugin, error) {
func kongPluginFromK8SClusterPlugin(
s store.Storer,
k8sPlugin configurationv1.KongClusterPlugin,
) (kong.Plugin, error) {
) (Plugin, error) {
var config kong.Configuration
config, err := RawConfigToConfiguration(k8sPlugin.Config)
if err != nil {
return kong.Plugin{}, fmt.Errorf("could not parse KongPlugin %v/%v config: %w",
return Plugin{}, fmt.Errorf("could not parse KongPlugin %s/%s config: %w",
k8sPlugin.Namespace, k8sPlugin.Name, err)
}
if k8sPlugin.ConfigFrom != nil && len(config) > 0 {
return kong.Plugin{},
return Plugin{},
fmt.Errorf("KongClusterPlugin '/%v' has both "+
"Config and ConfigFrom set", k8sPlugin.Name)
}
Expand All @@ -132,23 +132,26 @@ func kongPluginFromK8SClusterPlugin(
s,
(*k8sPlugin.ConfigFrom).SecretValue)
if err != nil {
return kong.Plugin{},
fmt.Errorf("error parsing config for KongClusterPlugin %v: %w",
return Plugin{},
fmt.Errorf("error parsing config for KongClusterPlugin %s: %w",
k8sPlugin.Name, err)
}
}
kongPlugin := plugin{
Name: k8sPlugin.PluginName,
Config: config,

RunOn: k8sPlugin.RunOn,
Ordering: k8sPlugin.Ordering,
InstanceName: k8sPlugin.InstanceName,
Disabled: k8sPlugin.Disabled,
Protocols: protocolsToStrings(k8sPlugin.Protocols),
Tags: util.GenerateTagsForObject(&k8sPlugin),
}.toKongPlugin()
return kongPlugin, nil
return Plugin{
Plugin: plugin{
Name: k8sPlugin.PluginName,
Config: config,

RunOn: k8sPlugin.RunOn,
Ordering: k8sPlugin.Ordering,
InstanceName: k8sPlugin.InstanceName,
Disabled: k8sPlugin.Disabled,
Protocols: protocolsToStrings(k8sPlugin.Protocols),
Tags: util.GenerateTagsForObject(&k8sPlugin),
}.toKongPlugin(),
K8sParent: &k8sPlugin,
}, nil
}

func protocolPointersToStringPointers(protocols []*configurationv1.KongProtocol) (res []*string) {
Expand All @@ -168,41 +171,43 @@ func protocolsToStrings(protocols []configurationv1.KongProtocol) (res []string)
func kongPluginFromK8SPlugin(
s store.Storer,
k8sPlugin configurationv1.KongPlugin,
) (kong.Plugin, error) {
) (Plugin, error) {
var config kong.Configuration
config, err := RawConfigToConfiguration(k8sPlugin.Config)
if err != nil {
return kong.Plugin{}, fmt.Errorf("could not parse KongPlugin %v/%v config: %w",
return Plugin{}, fmt.Errorf("could not parse KongPlugin %s/%s config: %w",
k8sPlugin.Namespace, k8sPlugin.Name, err)
}
if k8sPlugin.ConfigFrom != nil && len(config) > 0 {
return kong.Plugin{},
fmt.Errorf("KongPlugin '%v/%v' has both "+
"Config and ConfigFrom set",
return Plugin{},
fmt.Errorf("KongPlugin '%s/%s' has both Config and ConfigFrom set",
k8sPlugin.Namespace, k8sPlugin.Name)
}
if k8sPlugin.ConfigFrom != nil {
var err error
config, err = SecretToConfiguration(s,
(*k8sPlugin.ConfigFrom).SecretValue, k8sPlugin.Namespace)
if err != nil {
return kong.Plugin{},
fmt.Errorf("error parsing config for KongPlugin '%v/%v': %w",
return Plugin{},
fmt.Errorf("error parsing config for KongPlugin '%s/%s': %w",
k8sPlugin.Name, k8sPlugin.Namespace, err)
}
}
kongPlugin := plugin{
Name: k8sPlugin.PluginName,
Config: config,

RunOn: k8sPlugin.RunOn,
Ordering: k8sPlugin.Ordering,
InstanceName: k8sPlugin.InstanceName,
Disabled: k8sPlugin.Disabled,
Protocols: protocolsToStrings(k8sPlugin.Protocols),
Tags: util.GenerateTagsForObject(&k8sPlugin),
}.toKongPlugin()
return kongPlugin, nil
return Plugin{
Plugin: plugin{
Name: k8sPlugin.PluginName,
Config: config,

RunOn: k8sPlugin.RunOn,
Ordering: k8sPlugin.Ordering,
InstanceName: k8sPlugin.InstanceName,
Disabled: k8sPlugin.Disabled,
Protocols: protocolsToStrings(k8sPlugin.Protocols),
Tags: util.GenerateTagsForObject(&k8sPlugin),
}.toKongPlugin(),
K8sParent: &k8sPlugin,
}, nil
}

func RawConfigToConfiguration(config apiextensionsv1.JSON) (kong.Configuration, error) {
Expand Down
6 changes: 4 additions & 2 deletions internal/dataplane/kongstate/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ func TestKongPluginFromK8SClusterPlugin(t *testing.T) {
t.Errorf("kongPluginFromK8SClusterPlugin error = %v, wantErr %v", err, tt.wantErr)
return
}
assert.Equal(tt.want, got)
assert.Equal(tt.want, got.Plugin)
assert.NotEmpty(t, got.K8sParent)
})
}
}
Expand Down Expand Up @@ -294,7 +295,8 @@ func TestKongPluginFromK8SPlugin(t *testing.T) {
}
// don't care about tags in this test
got.Tags = nil
assert.Equal(tt.want, got)
assert.Equal(tt.want, got.Plugin)
assert.NotEmpty(t, got.K8sParent)
})
}
}
Expand Down
3 changes: 3 additions & 0 deletions internal/dataplane/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,9 @@ func (p *Parser) BuildKongConfig() KongConfigBuildingResult {

// process annotation plugins
result.FillPlugins(p.logger, p.storer)
for _, pl := range result.Plugins {
p.registerSuccessfullyParsedObject(pl.K8sParent)
}

// generate Certificates and SNIs
ingressCerts := p.getCerts(ingressRules.SecretNameToSNIs)
Expand Down
Loading

0 comments on commit d0fe1e4

Please sign in to comment.