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

Add AgentPool support #279

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 169 additions & 0 deletions apis/compute/v1alpha3/agentpool.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/*
Copyright 2021 The Crossplane Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha3

import (
xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// AgentPoolParameters define the desired state of an Azure Kubernetes Engine
// agent pool.
type AgentPoolParameters struct {
// ResourceGroupName is the name of the resource group that the cluster will
// be created in
// +immutable
ResourceGroupName string `json:"resourceGroupName,omitempty"`
vaspahomov marked this conversation as resolved.
Show resolved Hide resolved

// ResourceGroupNameRef - A reference to a ResourceGroup to retrieve its
// name
// +immutable
// +optional
ResourceGroupNameRef *xpv1.Reference `json:"resourceGroupNameRef,omitempty"`
vaspahomov marked this conversation as resolved.
Show resolved Hide resolved

// ResourceGroupNameSelector - Select a reference to a ResourceGroup to
// retrieve its name
// +optional
ResourceGroupNameSelector *xpv1.Selector `json:"resourceGroupNameSelector,omitempty"`
vaspahomov marked this conversation as resolved.
Show resolved Hide resolved

// AKSClusterName is the name of the AKSCluster that the cluster will
vaspahomov marked this conversation as resolved.
Show resolved Hide resolved
// be created in
// +immutable
AKSClusterName string `json:"aksClusterName,omitempty"`
vaspahomov marked this conversation as resolved.
Show resolved Hide resolved

// AKSClusterNameRef - A reference to a AKSCluster to retrieve its
// id
// +immutable
// +optional
AKSClusterNameRef *xpv1.Reference `json:"aksClusterNameRef,omitempty"`
vaspahomov marked this conversation as resolved.
Show resolved Hide resolved

// AKSClusterNameSelector - Select a reference to a AKSCluster to
// retrieve its ids
// +optional
AKSClusterNameSelector *xpv1.Selector `json:"aksClusterNameSelector,omitempty"`
vaspahomov marked this conversation as resolved.
Show resolved Hide resolved

// VnetSubnetID is the subnet to which the cluster will be deployed.
// +immutable
// +optional
VnetSubnetID string `json:"vnetSubnetID,omitempty"`
vaspahomov marked this conversation as resolved.
Show resolved Hide resolved

// VnetSubnetIDRef - A reference to a Subnet to retrieve its ID
// +immutable
// +optional
VnetSubnetIDRef *xpv1.Reference `json:"vnetSubnetIDRef,omitempty"`
vaspahomov marked this conversation as resolved.
Show resolved Hide resolved

// VnetSubnetIDSelector - Select a reference to a Subnet to retrieve
// its ID
// +optional
VnetSubnetIDSelector *xpv1.Selector `json:"vnetSubnetIDSelector,omitempty"`
vaspahomov marked this conversation as resolved.
Show resolved Hide resolved

// NodeCount is the number of nodes that the cluster will initially be
// created with. This can be scaled over time and defaults to 1.
// +kubebuilder:validation:Maximum=100
// +kubebuilder:validation:Minimum=0
// +optional
NodeCount *int32 `json:"nodeCount,omitempty"`

// MaxNodeCount - Maximum number of nodes for auto-scaling
// +optional
MaxNodeCount *int32 `json:"maxNodeCount,omitempty"`

// MinNodeCount - Minimum number of nodes for auto-scaling
// +optional
MinNodeCount *int32 `json:"minNodeCount,omitempty"`

// EnableAutoScaling - Whether to enable auto-scaler
EnableAutoScaling *bool `json:"enableAutoScaling,omitempty"`

// Mode - AgentPoolMode represents mode of an agent pool.
// Possible values include: 'System', 'User'.
// Default: 'User'
// +optional
// +kubebuilder:validation:Enum=System;User
Mode string `json:"mode,omitempty"`
vaspahomov marked this conversation as resolved.
Show resolved Hide resolved

// AvailabilityZones - Availability zones for nodes.
// +optional
// +immutable
AvailabilityZones []string `json:"availabilityZones,omitempty"`

// NodeVMSize is the name of the worker node VM size, e.g., Standard_B2s,
// Standard_F2s_v2, etc.
// +kubebuilder:validation:Required
NodeVMSize string `json:"nodeVMSize"`

// NodeTaints - Taints added to new nodes during node pool create and scale.
// For example, key=value:NoSchedule.
// +optional
// +immutable
NodeTaints []string `json:"nodeTaints,omitempty"`
}

// An AgentPoolSpec defines the desired state of a AgentPool.
type AgentPoolSpec struct {
xpv1.ResourceSpec `json:",inline"`
AgentPoolParameters `json:",inline"`
}

// An AgentPoolStatus represents the observed state of an AgentPool.
type AgentPoolStatus struct {
xpv1.ResourceStatus `json:",inline"`

// State is the current state of the agent pool.
State string `json:"state,omitempty"`

// NodesCount - Number of agents (VMs) to host docker containers.
// Allowed values must be in the range of 0 to 100 (inclusive).
// The default value is 1.
NodesCount int `json:"nodesCount,omitempty"`

// AvailabilityZones - Availability zones for nodes.
// Must use VirtualMachineScaleSets AgentPoolType.
AvailabilityZones []string `json:"availabilityZones,omitempty"`

// ProviderID is the external ID to identify this resource in the cloud
// provider.
ProviderID string `json:"providerID,omitempty"`
}

// +kubebuilder:object:root=true

// An AgentPool is a managed resource that represents an Azure AgentPool.
// +kubebuilder:printcolumn:name="READY",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].status"
// +kubebuilder:printcolumn:name="SYNCED",type="string",JSONPath=".status.conditions[?(@.type=='Synced')].status"
// +kubebuilder:printcolumn:name="STATE",type="string",JSONPath=".status.state"
// +kubebuilder:printcolumn:name="COUNT",type="integer",JSONPath=".status.nodesCount"
// +kubebuilder:printcolumn:name="AZ",type="string",JSONPath=".status.availabilityZones"
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
// +kubebuilder:resource:scope=Cluster,categories={crossplane,managed,azure}
// +kubebuilder:subresource:status
type AgentPool struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec AgentPoolSpec `json:"spec"`
Status AgentPoolStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true

// AgentPoolList contains a list of AgentPool.
type AgentPoolList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []AgentPool `json:"items"`
}
62 changes: 62 additions & 0 deletions apis/compute/v1alpha3/referencers.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,24 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/crossplane/crossplane-runtime/pkg/reference"
"github.com/crossplane/crossplane-runtime/pkg/resource"

networkv1alpha3 "github.com/crossplane/provider-azure/apis/network/v1alpha3"
"github.com/crossplane/provider-azure/apis/v1alpha3"
)

// AKSClusterName extracts Name from the supplied managed resource, which must be
// a AKSCluster.
func AKSClusterName() reference.ExtractValueFn {
return func(mg resource.Managed) string {
s, ok := mg.(*AKSCluster)
if !ok {
return ""
}
return s.Name
}
}

// ResolveReferences of this AKSCluster.
func (mg *AKSCluster) ResolveReferences(ctx context.Context, c client.Reader) error {
r := reference.NewAPIResolver(c, mg)
Expand Down Expand Up @@ -62,3 +75,52 @@ func (mg *AKSCluster) ResolveReferences(ctx context.Context, c client.Reader) er

return nil
}

// ResolveReferences of this AgentPool.
func (mg *AgentPool) ResolveReferences(ctx context.Context, c client.Reader) error {
r := reference.NewAPIResolver(c, mg)

// Resolve spec.resourceGroupName
rsp, err := r.Resolve(ctx, reference.ResolutionRequest{
CurrentValue: mg.Spec.ResourceGroupName,
Reference: mg.Spec.ResourceGroupNameRef,
Selector: mg.Spec.ResourceGroupNameSelector,
To: reference.To{Managed: &v1alpha3.ResourceGroup{}, List: &v1alpha3.ResourceGroupList{}},
Extract: reference.ExternalName(),
})
if err != nil {
return errors.Wrap(err, "spec.resourceGroupName")
}
mg.Spec.ResourceGroupName = rsp.ResolvedValue
mg.Spec.ResourceGroupNameRef = rsp.ResolvedReference

// Resolve spec.vnetSubnetID
rsp, err = r.Resolve(ctx, reference.ResolutionRequest{
CurrentValue: mg.Spec.VnetSubnetID,
Reference: mg.Spec.VnetSubnetIDRef,
Selector: mg.Spec.VnetSubnetIDSelector,
To: reference.To{Managed: &networkv1alpha3.Subnet{}, List: &networkv1alpha3.SubnetList{}},
Extract: networkv1alpha3.SubnetID(),
})
if err != nil {
return errors.Wrap(err, "spec.vnetSubnetID")
}
mg.Spec.VnetSubnetID = rsp.ResolvedValue
mg.Spec.VnetSubnetIDRef = rsp.ResolvedReference

// Resolve spec.aksClusterName
rsp, err = r.Resolve(ctx, reference.ResolutionRequest{
CurrentValue: mg.Spec.AKSClusterName,
Reference: mg.Spec.AKSClusterNameRef,
Selector: mg.Spec.AKSClusterNameSelector,
To: reference.To{Managed: &AKSCluster{}, List: &AKSClusterList{}},
Extract: AKSClusterName(),
})
if err != nil {
return errors.Wrap(err, "spec.aksClusterName")
}
mg.Spec.AKSClusterName = rsp.ResolvedValue
mg.Spec.AKSClusterNameRef = rsp.ResolvedReference

return nil
}
6 changes: 6 additions & 0 deletions apis/compute/v1alpha3/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,14 @@ var (
AKSClusterGroupKind = schema.GroupKind{Group: Group, Kind: AKSClusterKind}.String()
AKSClusterKindAPIVersion = AKSClusterKind + "." + SchemeGroupVersion.String()
AKSClusterGroupVersionKind = SchemeGroupVersion.WithKind(AKSClusterKind)

AgentPoolKind = reflect.TypeOf(AgentPool{}).Name()
AgentPoolGroupKind = schema.GroupKind{Group: Group, Kind: AgentPoolKind}.String()
AgentPoolKindAPIVersion = AgentPoolKind + "." + SchemeGroupVersion.String()
AgentPoolGroupVersionKind = SchemeGroupVersion.WithKind(AgentPoolKind)
)

func init() {
SchemeBuilder.Register(&AKSCluster{}, &AKSClusterList{})
SchemeBuilder.Register(&AgentPool{}, &AgentPoolList{})
}
12 changes: 12 additions & 0 deletions apis/compute/v1alpha3/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ import (
const (
// DefaultNodeCount is the default node count for a cluster.
DefaultNodeCount = 1

// AgentPoolProfileName is a format string for the name of the automatically
// created cluster agent pool profile
AgentPoolProfileName = "agentpool"

// NetworkContributorRoleID lets the AKS cluster managed networks, but not
// access them.
NetworkContributorRoleID = "/providers/Microsoft.Authorization/roleDefinitions/4d97b98b-1d4f-4787-a291-c67834d212e7"

// AppCredsValidYears default value creds lifetime limit
AppCredsValidYears = 5
)

// AKSClusterParameters define the desired state of an Azure Kubernetes Engine
Expand All @@ -50,6 +61,7 @@ type AKSClusterParameters struct {

// VnetSubnetID is the subnet to which the cluster will be deployed.
// +optional
// +immutable
VnetSubnetID string `json:"vnetSubnetID,omitempty"`

// ResourceGroupNameRef - A reference to a Subnet to retrieve its ID
Expand Down
Loading