Skip to content

Commit

Permalink
Add AgentPool support
Browse files Browse the repository at this point in the history
Signed-off-by: vaspahomov <[email protected]>
  • Loading branch information
vaspahomov committed Sep 27, 2021
1 parent 1c07021 commit d74cd2f
Show file tree
Hide file tree
Showing 18 changed files with 1,675 additions and 38 deletions.
168 changes: 168 additions & 0 deletions apis/compute/v1alpha3/agentpool.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/*
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"`

// ResourceGroupNameRef - A reference to a ResourceGroup to retrieve its
// name
// +immutable
// +optional
ResourceGroupNameRef *xpv1.Reference `json:"resourceGroupNameRef,omitempty"`

// ResourceGroupNameSelector - Select a reference to a ResourceGroup to
// retrieve its name
// +optional
ResourceGroupNameSelector *xpv1.Selector `json:"resourceGroupNameSelector,omitempty"`

// AKSClusterName is the name of the AKSCluster that the cluster will
// be created in
// +immutable
AKSClusterName string `json:"aksClusterName,omitempty"`

// AKSClusterNameRef - A reference to a AKSCluster to retrieve its
// id
// +immutable
// +optional
AKSClusterNameRef *xpv1.Reference `json:"aksClusterNameRef,omitempty"`

// AKSClusterNameSelector - Select a reference to a AKSCluster to
// retrieve its ids
// +optional
AKSClusterNameSelector *xpv1.Selector `json:"aksClusterNameSelector,omitempty"`

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

// VnetSubnetIDRef - A reference to a Subnet to retrieve its ID
// +immutable
// +optional
VnetSubnetIDRef *xpv1.Reference `json:"vnetSubnetIDRef,omitempty"`

// VnetSubnetIDSelector - Select a reference to a Subnet to retrieve
// its ID
// +optional
VnetSubnetIDSelector *xpv1.Selector `json:"vnetSubnetIDSelector,omitempty"`

// 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"`

// 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

0 comments on commit d74cd2f

Please sign in to comment.