Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes error when unmarshalling AKS ingress resources with TLS hosts #2405

Merged
merged 3 commits into from
Jun 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion cli/azd/pkg/project/service_target_aks.go
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ func (t *aksTarget) getIngressEndpoints(

var endpoints []string
var protocol string
if ingress.Spec.Tls == nil {
if len(ingress.Spec.Tls) == 0 {
protocol = "http"
} else {
protocol = "https"
Expand Down
72 changes: 36 additions & 36 deletions cli/azd/pkg/tools/kubectl/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,78 +14,78 @@ const (
)

type Resource struct {
ApiVersion string `json:"apiVersion"`
Kind string `json:"kind"`
Metadata ResourceMetadata `json:"metadata"`
ApiVersion string `json:"apiVersion" yaml:"apiVersion"`
Kind string `json:"kind" yaml:"kind"`
Metadata ResourceMetadata `json:"metadata" yaml:"metadata"`
}

type List[T any] struct {
Resource
Items []T `json:"items"`
Items []T `json:"items" yaml:"items"`
}

type ResourceWithSpec[T any, S any] struct {
Resource
Spec T `json:"spec"`
Status S `json:"status"`
Spec T `json:"spec" yaml:"spec"`
Status S `json:"status" yaml:"status"`
}

type ResourceMetadata struct {
Name string `json:"name"`
Namespace string `json:"namespace"`
Name string `json:"name" yaml:"name"`
Namespace string `json:"namespace" yaml:"namespace"`
Annotations map[string]any
}

type Deployment ResourceWithSpec[DeploymentSpec, DeploymentStatus]

type DeploymentSpec struct {
Replicas int `yaml:"replicas"`
Replicas int `json:"replicas" yaml:"replicas"`
}

type DeploymentStatus struct {
AvailableReplicas int `yaml:"availableReplicas"`
ReadyReplicas int `yaml:"readyReplicas"`
Replicas int `yaml:"replicas"`
UpdatedReplicas int `yaml:"updatedReplicas"`
AvailableReplicas int `json:"availableReplicas" yaml:"availableReplicas"`
ReadyReplicas int `json:"readyReplicas" yaml:"readyReplicas"`
Replicas int `json:"replicas" yaml:"replicas"`
UpdatedReplicas int `json:"updatedReplicas" yaml:"updatedReplicas"`
}

type Ingress ResourceWithSpec[IngressSpec, IngressStatus]

type IngressSpec struct {
IngressClassName string `json:"ingressClassName"`
Tls *IngressTls
Rules []IngressRule
IngressClassName string `json:"ingressClassName" yaml:"ingressClassName"`
Tls []IngressTls `json:"tls" yaml:"tls"`
Rules []IngressRule `json:"rules" yaml:"rules"`
}

type IngressTls struct {
Hosts []string `yaml:"hosts"`
SecretName string `yaml:"secretName"`
Hosts []string `json:"hosts" yaml:"hosts"`
SecretName string `json:"secretName" yaml:"secretName"`
}

type IngressRule struct {
Host *string `yaml:"host"`
Http IngressRuleHttp `yaml:"http"`
Host *string `json:"host" yaml:"host"`
Http IngressRuleHttp `json:"http" yaml:"http"`
}

type IngressRuleHttp struct {
Paths []IngressPath `yaml:"paths"`
Paths []IngressPath `json:"paths" yaml:"paths"`
}

type IngressPath struct {
Path string `yaml:"path"`
PathType string `yaml:"pathType"`
Path string `json:"path" yaml:"path"`
PathType string `json:"pathType" yaml:"pathType"`
}

type IngressStatus struct {
LoadBalancer LoadBalancer `json:"loadBalancer"`
LoadBalancer LoadBalancer `json:"loadBalancer" yaml:"loadBalancer"`
}

type LoadBalancer struct {
Ingress []LoadBalancerIngress `json:"ingress"`
Ingress []LoadBalancerIngress `json:"ingress" yaml:"ingress"`
}

type LoadBalancerIngress struct {
Ip string `json:"ip"`
Ip string `json:"ip" yaml:"ip"`
}

type Service ResourceWithSpec[ServiceSpec, ServiceStatus]
Expand All @@ -100,28 +100,28 @@ const (
)

type ServiceSpec struct {
Type ServiceType `json:"type"`
ClusterIp string `json:"clusterIP"`
ClusterIps []string `json:"clusterIPs"`
Ports []Port `json:"ports"`
Type ServiceType `json:"type" yaml:"type"`
ClusterIp string `json:"clusterIP" yaml:"clusterIP"`
ClusterIps []string `json:"clusterIPs" yaml:"clusterIPs"`
Ports []Port `json:"ports" yaml:"ports"`
}

type ServiceStatus struct {
LoadBalancer LoadBalancer `json:"loadBalancer"`
LoadBalancer LoadBalancer `json:"loadBalancer" yaml:"loadBalancer"`
}

type Port struct {
Port int `json:"port"`
// The target port can be a valid port number or well known service name like 'redis'
TargetPort any `json:"targetPort"`
Protocol string `json:"protocol"`
TargetPort any `json:"targetPort" yaml:"targetPort"`
Protocol string `json:"protocol" yaml:"protocol"`
}

func (p *Port) UnmarshalJSON(data []byte) error {
var aux struct {
Port int `json:"port"`
TargetPort any `json:"targetPort"`
Protocol string `json:"protocol"`
Port int `json:"port" yaml:"port"`
TargetPort any `json:"targetPort" yaml:"targetPort"`
Protocol string `json:"protocol" yaml:"protocol"`
}

if err := json.Unmarshal(data, &aux); err != nil {
Expand Down
28 changes: 28 additions & 0 deletions cli/azd/pkg/tools/kubectl/models_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package kubectl
import (
"encoding/json"
"fmt"
"os"
"testing"

"github.com/stretchr/testify/require"
"gopkg.in/yaml.v3"
)

func Test_Port_TargetPort_Unmarshalling(t *testing.T) {
Expand Down Expand Up @@ -44,3 +46,29 @@ func Test_Port_TargetPort_Unmarshalling(t *testing.T) {
})
}
}

func Test_Ingress_UnMarshalling(t *testing.T) {
t.Run("json", func(t *testing.T) {
var ingressResources List[Ingress]
ingressBytes, err := os.ReadFile("../../../test/testdata/k8s/ingress.json")
require.NoError(t, err)

err = json.Unmarshal(ingressBytes, &ingressResources)
require.NoError(t, err)

require.Equal(t, "myapp.centralus.cloudapp.azure.com", *ingressResources.Items[0].Spec.Rules[0].Host)
require.Equal(t, "myapp.centralus.cloudapp.azure.com", ingressResources.Items[0].Spec.Tls[0].Hosts[0])
})

t.Run("yaml", func(t *testing.T) {
var ingressResources List[Ingress]
ingressBytes, err := os.ReadFile("../../../test/testdata/k8s/ingress.yaml")
require.NoError(t, err)

err = yaml.Unmarshal(ingressBytes, &ingressResources)
require.NoError(t, err)

require.Equal(t, "myapp.centralus.cloudapp.azure.com", *ingressResources.Items[0].Spec.Rules[0].Host)
require.Equal(t, "myapp.centralus.cloudapp.azure.com", ingressResources.Items[0].Spec.Tls[0].Hosts[0])
})
}
60 changes: 60 additions & 0 deletions cli/azd/test/testdata/k8s/ingress.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"apiVersion": "v1",
"items": [
{
"apiVersion": "networking.k8s.io/v1",
"kind": "Ingress",
"metadata": {
"creationTimestamp": "2023-06-10T12:33:44Z",
"generation": 1,
"name": "ratings-web-https",
"namespace": "ratingsapp"
},
"spec": {
"rules": [
{
"host": "myapp.centralus.cloudapp.azure.com",
"http": {
"paths": [
{
"backend": {
"service": {
"name": "ratings-web",
"port": {
"number": 80
}
}
},
"path": "/",
"pathType": "Prefix"
}
]
}
}
],
"tls": [
{
"hosts": [
"myapp.centralus.cloudapp.azure.com"
],
"secretName": "aks-tls-akv"
}
]
},
"status": {
"loadBalancer": {
"ingress": [
{
"ip": "1.2.3.4"
}
]
}
}
}
],
"kind": "List",
"metadata": {
"resourceVersion": "",
"selfLink": ""
}
}
33 changes: 33 additions & 0 deletions cli/azd/test/testdata/k8s/ingress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
apiVersion: v1
items:
- apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
creationTimestamp: "2023-06-10T12:33:44Z"
generation: 1
name: ratings-web-https
namespace: ratingsapp
spec:
rules:
- host: myapp.centralus.cloudapp.azure.com
http:
paths:
- backend:
service:
name: ratings-web
port:
number: 80
path: "/"
pathType: Prefix
tls:
- hosts:
- myapp.centralus.cloudapp.azure.com
secretName: aks-tls-akv
status:
loadBalancer:
ingress:
- ip: 1.2.3.4
kind: List
metadata:
resourceVersion: ""
selfLink: ""