Documentation
¶
Index ¶
- Constants
- func CanaryCertificateName() types.NamespacedName
- func CanaryDaemonSetName() types.NamespacedName
- func CanaryDaemonSetPodSelector(canaryControllerName string) *metav1.LabelSelector
- func CanaryNetworkPolicyName() types.NamespacedName
- func CanaryRouteName() types.NamespacedName
- func CanaryServiceAccountName() types.NamespacedName
- func CanaryServiceName() types.NamespacedName
- func ClientCAConfigMapName(ic *operatorv1.IngressController) types.NamespacedName
- func DefaultIngressCertConfigMapName() types.NamespacedName
- func FeatureGateClusterConfigName() types.NamespacedName
- func GatewayAPIModeChangePredicate() predicate.Predicate
- func GatewayDNSRecordName(gateway *gatewayapiv1.Gateway, host string) types.NamespacedName
- func GatewayHasOurController(logger logr.Logger, crclient client.Reader, checkRevLabel bool) func(o client.Object) bool
- func GatewayNetworkPolicyName(gateway *gatewayapiv1.Gateway) types.NamespacedName
- func HttpErrorCodePageConfigMapName(ic *operatorv1.IngressController) types.NamespacedName
- func InfrastructureClusterConfigName() types.NamespacedName
- func IngressClassName(ingressControllerName string) types.NamespacedName
- func IngressClusterConfigName() types.NamespacedName
- func IngressClusterOperatorName() types.NamespacedName
- func IngressControllerDeploymentLabel(ic *operatorv1.IngressController) string
- func IngressControllerDeploymentPodSelector(ic *operatorv1.IngressController) *metav1.LabelSelector
- func IngressControllerServiceMonitorName(ic *operatorv1.IngressController) types.NamespacedName
- func IngressWakeUpMapper(cacheReader client.Reader, listFactory func() client.ObjectList, ...) handler.MapFunc
- func InternalIngressControllerServiceName(ic *operatorv1.IngressController) types.NamespacedName
- func IstioName(operandNamespace string) types.NamespacedName
- func IstiodNetworkPolicyName() types.NamespacedName
- func LoadBalancerServiceName(ic *operatorv1.IngressController) types.NamespacedName
- func LoadBalancerServiceNameFromGatewayName(gatewayName string) types.NamespacedName
- func LoadBalancerServiceNameFromICName(icName string) types.NamespacedName
- func MetricsTLSOptsFromAPIServer(log logr.Logger, apiConfig *configv1.APIServer) ([]func(*tls.Config), error)
- func NodePortServiceName(ic *operatorv1.IngressController) types.NamespacedName
- func RouterCASecretName(operatorNamespace string) types.NamespacedName
- func RouterCertsGlobalSecretName() types.NamespacedName
- func RouterDeploymentName(ci *operatorv1.IngressController) types.NamespacedName
- func RouterEffectiveDefaultCertificateSecretName(ci *operatorv1.IngressController, namespace string) types.NamespacedName
- func RouterNetworkPolicyName(ci *operatorv1.IngressController) types.NamespacedName
- func RouterOperatorGeneratedDefaultCertificateSecretName(ci *operatorv1.IngressController, namespace string) types.NamespacedName
- func RouterPodDisruptionBudgetName(ic *operatorv1.IngressController) types.NamespacedName
- func RsyslogConfigMapName(ic *operatorv1.IngressController) types.NamespacedName
- func ServiceCAConfigMapName() types.NamespacedName
- func ServiceMeshOperatorSubscriptionName() types.NamespacedName
- func TLSConfigFromProfile(log logr.Logger, spec *configv1.TLSProfileSpec) (*tls.Config, error)
- func TLSGroupToCurveID(group configv1.TLSGroup) (tls.CurveID, bool)
- func TLSProfileSpecForSecurityProfile(profile *configv1.TLSSecurityProfile) *configv1.TLSProfileSpec
- func WildcardDNSRecordName(ic *operatorv1.IngressController) types.NamespacedName
- type GatewayAPIModeAccessor
- func (m *GatewayAPIModeAccessor) AllowDependents() bool
- func (m *GatewayAPIModeAccessor) BlockDependents()
- func (m *GatewayAPIModeAccessor) DependentPredicate() predicate.Predicate
- func (m *GatewayAPIModeAccessor) DesiredMode() operatorv1alpha1.GatewayAPIManagementMode
- func (m *GatewayAPIModeAccessor) GateEnabled() bool
- func (m *GatewayAPIModeAccessor) GetLastAppliedMode() *operatorv1alpha1.GatewayAPIManagementMode
- func (m *GatewayAPIModeAccessor) GetTransitionState() TransitionState
- func (m *GatewayAPIModeAccessor) SetCRDsEstablished(established bool)
- func (m *GatewayAPIModeAccessor) SetLastAppliedMode(mode operatorv1alpha1.GatewayAPIManagementMode)
- func (m *GatewayAPIModeAccessor) SetTransitionState(state TransitionState)
- func (m *GatewayAPIModeAccessor) ShouldManageCRDs() bool
- func (m *GatewayAPIModeAccessor) TransitionEvents() <-chan event.GenericEvent
- func (m *GatewayAPIModeAccessor) Update(desired operatorv1alpha1.GatewayAPIManagementMode, ...)
- type SailUninstaller
- type TransitionState
Constants ¶
const ( // GlobalMachineSpecifiedConfigNamespace is the location for global // config. In particular, the operator will put the configmap with the // CA certificate in this namespace. GlobalMachineSpecifiedConfigNamespace = "openshift-config-managed" // GlobalUserSpecifiedConfigNamespace is the namespace for configuring OpenShift. GlobalUserSpecifiedConfigNamespace = "openshift-config" // IngressOperatorOwnedAnnotation is the key for the annotation that // indicates that the ingress operator owns the annotated resource. // Note that this annotation is currently only intended to be added to // subscriptions, and only when creating a new subscription. IngressOperatorOwnedAnnotation = "ingress.operator.openshift.io/owned" // ControllerDeploymentLabel identifies a deployment as an ingress controller // deployment, and the value is the name of the owning ingress controller. ControllerDeploymentLabel = "ingresscontroller.operator.openshift.io/deployment-ingresscontroller" // ControllerDeploymentHashLabel identifies an ingress controller // deployment's generation. This label is used for affinity, to // colocate replicas of different generations of the same ingress // controller, and for anti-affinity, to prevent colocation of replicas // of the same generation of the same ingress controller. ControllerDeploymentHashLabel = "ingresscontroller.operator.openshift.io/hash" // CanaryDaemonsetLabel identifies a daemonset as an ingress canary daemonset, and // the value is the name of the owning canary controller. CanaryDaemonSetLabel = "ingresscanary.operator.openshift.io/daemonset-ingresscanary" DefaultOperatorNamespace = "openshift-ingress-operator" DefaultOperandNamespace = "openshift-ingress" // DefaultCanaryNamespace is the default namespace for // the ingress canary check resources. DefaultCanaryNamespace = "openshift-ingress-canary" // Remote worker label, used for node affinity of router deployment. // Router should not run on remote worker nodes RemoteWorkerLabel = "node.openshift.io/remote-worker" // OpenshiftOperatorNamespace is the default namespace for // the openshift operator resources. OpenshiftOperatorNamespace = "openshift-operators" // OpenShiftGatewayClassControllerName is the string by which a // gatewayclass identifies itself as belonging to OpenShift Istio. If a // gatewayclass's spec.controllerName field is set to this value, then // the gatewayclass is ours. OpenShiftGatewayClassControllerName = "openshift.io/gateway-controller/v1" // OpenShiftDefaultGatewayClassName is the name of the default // gatewayclass that Istio creates when it is installed. OpenShiftDefaultGatewayClassName = "openshift-default" // OpenShiftGatewayCARootCertName is the name of the configmap with the // CA bundle that Istio creates for the Istio CR that this operator // creates. OpenShiftGatewayCARootCertName = "openshift-gw-ca-root-cert" // IstioRevLabelKey is the key for the gateway label that Istio checks // for to determine whether it should reconcile that gateway. IstioRevLabelKey = "istio.io/rev" GatewayClassIndexFieldName = "gatewayclassController" // GatewayNameLabelKey is the key of a label that Istio adds to // deployments that it creates for gateways that it manages. Istio uses // this label in the selector of any service that it creates for a // gateway. GatewayNameLabelKey = "gateway.networking.k8s.io/gateway-name" // ManagedByIstioLabelKey is the key of a label that Istio adds to // resources that it manages. ManagedByIstioLabelKey = "gateway.istio.io/managed" // ServiceMeshOperatorSubscriptionPackage represents the name of the package // on a OLM subscription that installs OSSM ServiceMeshOperatorSubscriptionPackage = "servicemeshoperator3" )
Variables ¶
This section is empty.
Functions ¶
func CanaryCertificateName ¶
func CanaryCertificateName() types.NamespacedName
func CanaryDaemonSetName ¶
func CanaryDaemonSetName() types.NamespacedName
func CanaryDaemonSetPodSelector ¶
func CanaryDaemonSetPodSelector(canaryControllerName string) *metav1.LabelSelector
func CanaryNetworkPolicyName ¶
func CanaryNetworkPolicyName() types.NamespacedName
func CanaryRouteName ¶
func CanaryRouteName() types.NamespacedName
func CanaryServiceAccountName ¶
func CanaryServiceAccountName() types.NamespacedName
func CanaryServiceName ¶
func CanaryServiceName() types.NamespacedName
func ClientCAConfigMapName ¶
func ClientCAConfigMapName(ic *operatorv1.IngressController) types.NamespacedName
ClientCAConfigMapName returns the namespaced name for the operator-managed client CA configmap, which is a copy of the user-managed configmap from the openshift-config namespace.
func DefaultIngressCertConfigMapName ¶
func DefaultIngressCertConfigMapName() types.NamespacedName
DefaultIngressCertConfigMapName returns the namespaced name for the default ingress cert configmap. The operator uses this configmap to publish the public key that golang clients can use to trust the default ingress wildcard serving cert.
func FeatureGateClusterConfigName ¶
func FeatureGateClusterConfigName() types.NamespacedName
FeatureGateClusterConfigName returns the namespaced name of the featuregates.config.openshift.io resource of the cluster.
func GatewayAPIModeChangePredicate ¶
GatewayAPIModeChangePredicate filters Ingress wake-up events for dependent Gateway API controllers. A wake-up is needed only when the effective management mode or one of the three Gateway API readiness conditions changes; other Ingress updates must not enqueue every dependent resource.
func GatewayDNSRecordName ¶
func GatewayDNSRecordName(gateway *gatewayapiv1.Gateway, host string) types.NamespacedName
GatewayDNSRecordName returns the namespaced name for a DNSRecord CR associated with a Gateway. This CR is created in the Gateway's namespace and is named using the Gateway's name, listener's hashed host name, and the suffix "-wildcard".
func GatewayHasOurController ¶
func GatewayHasOurController(logger logr.Logger, crclient client.Reader, checkRevLabel bool) func(o client.Object) bool
GatewayHasOurController returns a function that will use the provided logger and clients, receive an object and return a boolean that represents if the provided object is a Gateway managed by our Gateway Class. The checkRevLabel is used by controllers that want to check if the "istio.io/rev" label is already set, meaning the reconciliation already happened. Some controllers may opt-in to this behavior to ignore the rest of the reconciliation
func GatewayNetworkPolicyName ¶
func GatewayNetworkPolicyName(gateway *gatewayapiv1.Gateway) types.NamespacedName
func HttpErrorCodePageConfigMapName ¶
func HttpErrorCodePageConfigMapName(ic *operatorv1.IngressController) types.NamespacedName
HttpErrorCodePageConfigMapName returns the namespaced name for the errorpage configmap.
func InfrastructureClusterConfigName ¶
func InfrastructureClusterConfigName() types.NamespacedName
InfrastructureClusterConfigName returns the namespaced name of the infrastructure.config.openshift.io resource of the cluster.
func IngressClassName ¶
func IngressClassName(ingressControllerName string) types.NamespacedName
func IngressClusterConfigName ¶
func IngressClusterConfigName() types.NamespacedName
IngressClusterConfigName returns the namespaced name of the ingress.config.openshift.io resource for the operator.
func IngressClusterOperatorName ¶
func IngressClusterOperatorName() types.NamespacedName
IngressClusterOperatorName returns the namespaced name of the ClusterOperator resource for the operator.
func IngressControllerDeploymentLabel ¶
func IngressControllerDeploymentLabel(ic *operatorv1.IngressController) string
func IngressControllerDeploymentPodSelector ¶
func IngressControllerDeploymentPodSelector(ic *operatorv1.IngressController) *metav1.LabelSelector
func IngressControllerServiceMonitorName ¶
func IngressControllerServiceMonitorName(ic *operatorv1.IngressController) types.NamespacedName
func IngressWakeUpMapper ¶
func IngressWakeUpMapper(cacheReader client.Reader, listFactory func() client.ObjectList, listOpts ...client.ListOption) handler.MapFunc
IngressWakeUpMapper returns a handler.MapFunc that lists objects from the cache and converts them to reconcile.Requests. Used for Ingress wake-up watches to enqueue work when transitioning from Unmanaged to Managed mode.
The listFactory parameter is called on each invocation to create a fresh ObjectList, preventing race conditions when multiple watch events fire concurrently.
func InternalIngressControllerServiceName ¶
func InternalIngressControllerServiceName(ic *operatorv1.IngressController) types.NamespacedName
func IstioName ¶
func IstioName(operandNamespace string) types.NamespacedName
IstioName returns the namespaced name for the Istio CR that the ingress operator creates when Gateway API is enabled.
func IstiodNetworkPolicyName ¶
func IstiodNetworkPolicyName() types.NamespacedName
func LoadBalancerServiceName ¶
func LoadBalancerServiceName(ic *operatorv1.IngressController) types.NamespacedName
func LoadBalancerServiceNameFromGatewayName ¶
func LoadBalancerServiceNameFromGatewayName(gatewayName string) types.NamespacedName
func LoadBalancerServiceNameFromICName ¶
func LoadBalancerServiceNameFromICName(icName string) types.NamespacedName
func MetricsTLSOptsFromAPIServer ¶
func MetricsTLSOptsFromAPIServer(log logr.Logger, apiConfig *configv1.APIServer) ([]func(*tls.Config), error)
MetricsTLSOptsFromAPIServer returns controller-runtime Metrics TLSOpts that apply the cluster TLS security profile to the operator metrics endpoint when APIServer.spec.tlsAdherence requires newly adhering components to honor it.
When ShouldHonorClusterTLSProfile returns false (Legacy / NoOpinion), this returns nil so the metrics server keeps its individual TLS defaults. Unrecognized tlsAdherence values are treated as Strict and logged as a warning for forward compatibility.
func NodePortServiceName ¶
func NodePortServiceName(ic *operatorv1.IngressController) types.NamespacedName
func RouterCASecretName ¶
func RouterCASecretName(operatorNamespace string) types.NamespacedName
RouterCASecretName returns the namespaced name for the router CA secret. This secret holds the CA certificate that the operator will use to create default certificates for ingresscontrollers.
func RouterCertsGlobalSecretName ¶
func RouterCertsGlobalSecretName() types.NamespacedName
RouterCertsGlobalSecretName returns the namespaced name for the router certs secret. The operator uses this secret to publish the default certificates and their keys, so that the authentication operator can configure the OAuth server to use the same certificates.
func RouterDeploymentName ¶
func RouterDeploymentName(ci *operatorv1.IngressController) types.NamespacedName
RouterDeploymentName returns the namespaced name for the router deployment.
func RouterEffectiveDefaultCertificateSecretName ¶
func RouterEffectiveDefaultCertificateSecretName(ci *operatorv1.IngressController, namespace string) types.NamespacedName
RouterEffectiveDefaultCertificateSecretName returns the namespaced name for the in-use router default certificate secret.
func RouterNetworkPolicyName ¶
func RouterNetworkPolicyName(ci *operatorv1.IngressController) types.NamespacedName
RouterNetworkPolicyName returns the namespaced name for the router network policy.
func RouterOperatorGeneratedDefaultCertificateSecretName ¶
func RouterOperatorGeneratedDefaultCertificateSecretName(ci *operatorv1.IngressController, namespace string) types.NamespacedName
RouterOperatorGeneratedDefaultCertificateSecretName returns the namespaced name for the operator-generated router default certificate secret.
func RouterPodDisruptionBudgetName ¶
func RouterPodDisruptionBudgetName(ic *operatorv1.IngressController) types.NamespacedName
RouterPodDisruptionBudgetName returns the namespaced name for the router deployment's pod disruption budget.
func RsyslogConfigMapName ¶
func RsyslogConfigMapName(ic *operatorv1.IngressController) types.NamespacedName
RsyslogConfigMapName returns the namespaced name for the rsyslog configmap.
func ServiceCAConfigMapName ¶
func ServiceCAConfigMapName() types.NamespacedName
ServiceCAConfigMapName returns the namespaced name for the configmap with the service CA bundle.
func ServiceMeshOperatorSubscriptionName ¶
func ServiceMeshOperatorSubscriptionName() types.NamespacedName
ServiceMeshOperatorSubscriptionName returns the namespaced name for a Subscription CR to install the OpenShift Service Mesh Operator.
func TLSConfigFromProfile ¶
TLSConfigFromProfile builds a *tls.Config from the given TLSProfileSpec. Cipher names in the spec are expected to use OpenSSL naming (the format used in the configv1.TLSProfileSpec.Ciphers field). Groups that cannot be mapped to a Go CurveID are skipped (with a warning on log) so that the operator does not fail when the API advertises groups the runtime does not yet support. Callers should bind resource context on log (for example with WithValues) so skipped-group warnings identify the related object.
func TLSGroupToCurveID ¶
TLSGroupToCurveID converts a configv1.TLSGroup name to its crypto/tls CurveID. The second return value is false when the group is not supported by the Go runtime.
func TLSProfileSpecForSecurityProfile ¶
func TLSProfileSpecForSecurityProfile(profile *configv1.TLSSecurityProfile) *configv1.TLSProfileSpec
TLSProfileSpecForSecurityProfile returns a TLS profile spec based on the provided security profile, or the "Intermediate" profile if an unknown security profile type is provided or the profile is nil. Note that the return value must not be mutated by the caller; the caller must make a copy if it needs to mutate the value.
func WildcardDNSRecordName ¶
func WildcardDNSRecordName(ic *operatorv1.IngressController) types.NamespacedName
Types ¶
type GatewayAPIModeAccessor ¶
type GatewayAPIModeAccessor struct {
// contains filtered or unexported fields
}
GatewayAPIModeAccessor provides thread-safe access to the resolved Gateway API management mode and its derived state. It is constructed once in operator.go and passed to the gatewayapi controller as the sole writer. Dependent controllers read AllowDependents and wire DependentPredicate into their watches.
func NewGatewayAPIModeAccessor ¶
func NewGatewayAPIModeAccessor(gateEnabled bool) *GatewayAPIModeAccessor
NewGatewayAPIModeAccessor creates a GatewayAPIModeAccessor. When gateEnabled is false the accessor operates in legacy mode: AllowDependents tracks only whether the managed CRDs have been established, with no dependency on the Ingress CR.
func (*GatewayAPIModeAccessor) AllowDependents ¶
func (m *GatewayAPIModeAccessor) AllowDependents() bool
AllowDependents reports whether dependent controllers should be active.
Gate OFF: true once all managed CRDs are established (legacy path). Gate ON: true only when Managed + Present + Compliant are all True.
func (*GatewayAPIModeAccessor) BlockDependents ¶
func (m *GatewayAPIModeAccessor) BlockDependents()
BlockDependents immediately sets managed=false so that AllowDependents returns false right away, ahead of the full Update() call later in the same reconcile that computes present/compliant. Used when transitioning to Unmanaged to close the window between beginning Sail uninstall and a concurrently in-flight gatewayclass reconcile that may still observe AllowDependents()==true.
func (*GatewayAPIModeAccessor) DependentPredicate ¶
func (m *GatewayAPIModeAccessor) DependentPredicate() predicate.Predicate
DependentPredicate returns a predicate that passes create, update, and generic events only when AllowDependents is true. Delete events always pass so controllers can perform finalizer cleanup after the mode stops allowing normal dependent processing.
func (*GatewayAPIModeAccessor) DesiredMode ¶
func (m *GatewayAPIModeAccessor) DesiredMode() operatorv1alpha1.GatewayAPIManagementMode
DesiredMode returns the desired management mode from the Ingress CR spec. Defaults to Managed when the CR is absent or the field is empty.
func (*GatewayAPIModeAccessor) GateEnabled ¶
func (m *GatewayAPIModeAccessor) GateEnabled() bool
GateEnabled returns whether the GatewayAPIManagementMode feature gate was enabled at operator startup.
func (*GatewayAPIModeAccessor) GetLastAppliedMode ¶
func (m *GatewayAPIModeAccessor) GetLastAppliedMode() *operatorv1alpha1.GatewayAPIManagementMode
GetLastAppliedMode returns the mode that was last successfully reconciled to completion. Returns nil if no reconcile has completed.
func (*GatewayAPIModeAccessor) GetTransitionState ¶
func (m *GatewayAPIModeAccessor) GetTransitionState() TransitionState
GetTransitionState returns the current mode transition state. It is safe for concurrent use and is read by the status controller.
func (*GatewayAPIModeAccessor) SetCRDsEstablished ¶
func (m *GatewayAPIModeAccessor) SetCRDsEstablished(established bool)
SetCRDsEstablished is called by the gatewayapi reconciler in the gate-off (legacy) path once allManagedCRDsEstablished returns true.
func (*GatewayAPIModeAccessor) SetLastAppliedMode ¶
func (m *GatewayAPIModeAccessor) SetLastAppliedMode(mode operatorv1alpha1.GatewayAPIManagementMode)
SetLastAppliedMode records the mode that was successfully reconciled to completion. Called at the end of a successful gate-ON reconcile.
func (*GatewayAPIModeAccessor) SetTransitionState ¶
func (m *GatewayAPIModeAccessor) SetTransitionState(state TransitionState)
SetTransitionState is called by the gatewayapi reconciler to signal mode transition progress. The status controller reads this to compute ClusterOperator Progressing and Degraded conditions.
func (*GatewayAPIModeAccessor) ShouldManageCRDs ¶
func (m *GatewayAPIModeAccessor) ShouldManageCRDs() bool
ShouldManageCRDs reports whether the reconciler should ensure (create/update) Gateway API CRDs and aggregated RBAC. Returns true only when the resolved Managed condition is True -- i.e., the desired mode is Managed and takeover is not blocked.
func (*GatewayAPIModeAccessor) TransitionEvents ¶
func (m *GatewayAPIModeAccessor) TransitionEvents() <-chan event.GenericEvent
TransitionEvents returns a channel that receives a coalesced notification whenever the Gateway API management-mode transition state changes. The status controller consumes these events to update ClusterOperator status without periodic polling.
func (*GatewayAPIModeAccessor) Update ¶
func (m *GatewayAPIModeAccessor) Update(desired operatorv1alpha1.GatewayAPIManagementMode, managed, present, compliant bool)
Update is called by the gatewayapi reconciler to refresh the mode accessor after computing conditions from the Ingress CR and CRD state.
type SailUninstaller ¶
SailUninstaller provides the ability to uninstall the CIO-managed Istio instance. The gatewayapi controller uses this interface to trigger Sail uninstall when transitioning to Unmanaged mode.
type TransitionState ¶
type TransitionState struct {
// InProgress is true while the gatewayapi controller is
// actively performing operations required by a mode change
// (e.g., deleting VAP, uninstalling Sail, installing CRDs).
InProgress bool
// Target is the management mode that the system is
// transitioning toward.
Target operatorv1alpha1.GatewayAPIManagementMode
// Error is non-nil when a required transition operation has
// failed (e.g., VAP delete, Sail uninstall).
Error error
}
TransitionState describes the progress of a Gateway API management mode transition. The gatewayapi controller sets this state and the status controller reads it to compute ClusterOperator Progressing and Degraded conditions.
Directories
¶
| Path | Synopsis |
|---|---|
|
The certificate controller is responsible for the following:
|
The certificate controller is responsible for the following: |
|
The certificate-publisher controller is responsible for publishing the certificate and key of the ingresscontroller for the cluster ingress domain to the "router-certs" secret in the "openshift-config-managed" namespace and for publishing the certificate for the default ingresscontroller to the "default-ingress-cert" configmap in the same namespace.
|
The certificate-publisher controller is responsible for publishing the certificate and key of the ingresscontroller for the cluster ingress domain to the "router-certs" secret in the "openshift-config-managed" namespace and for publishing the certificate for the default ingresscontroller to the "default-ingress-cert" configmap in the same namespace. |
|
The listenerset-status controller watches for ListenerSet resources targeting OpenShift-managed Gateways and sets Accepted=False on them.
|
The listenerset-status controller watches for ListenerSet resources targeting OpenShift-managed Gateways and sets Accepted=False on them. |
|
test
|
|